diff options
Diffstat (limited to 'lisp')
31 files changed, 882 insertions, 487 deletions
diff --git a/lisp/auth-source.el b/lisp/auth-source.el index c26935fcc97..7402ab21d74 100644 --- a/lisp/auth-source.el +++ b/lisp/auth-source.el @@ -2129,7 +2129,7 @@ MODE can be \"login\" or \"password\"." (if user (auth-source-search :host host - :user "yourusername" + :user user :max 1 :require '(:user :secret) :create nil) diff --git a/lisp/buff-menu.el b/lisp/buff-menu.el index 77b325ff25d..9f618bcb7de 100644 --- a/lisp/buff-menu.el +++ b/lisp/buff-menu.el @@ -102,9 +102,6 @@ This is set by the prefix argument to `buffer-menu' and related commands.") (make-variable-buffer-local 'Buffer-menu-files-only) -(defvar Info-current-file) ; from info.el -(defvar Info-current-node) ; from info.el - (defvar Buffer-menu-mode-map (let ((map (make-sparse-keymap)) (menu-map (make-sparse-keymap))) @@ -702,21 +699,7 @@ means list those buffers and no others." (defun Buffer-menu--pretty-file-name (file) (cond (file (abbreviate-file-name file)) - ((and (boundp 'list-buffers-directory) - list-buffers-directory) - list-buffers-directory) - ((eq major-mode 'Info-mode) - (Buffer-menu-info-node-description Info-current-file)) + ((bound-and-true-p list-buffers-directory)) (t ""))) -(defun Buffer-menu-info-node-description (file) - (cond - ((equal file "dir") "*Info Directory*") - ((eq file 'apropos) "*Info Apropos*") - ((eq file 'history) "*Info History*") - ((eq file 'toc) "*Info TOC*") - ((not (stringp file)) "") ; Avoid errors - (t - (concat "(" (file-name-nondirectory file) ") " Info-current-node)))) - ;;; buff-menu.el ends here diff --git a/lisp/calendar/parse-time.el b/lisp/calendar/parse-time.el index 7651c5da1f4..b781cb0eb48 100644 --- a/lisp/calendar/parse-time.el +++ b/lisp/calendar/parse-time.el @@ -1,4 +1,4 @@ -;;; parse-time.el --- parsing time strings +;;; parse-time.el --- parsing time strings -*- lexical-binding: t -*- ;; Copyright (C) 1996, 2000-2017 Free Software Foundation, Inc. @@ -203,12 +203,9 @@ any values that are unknown are returned as nil." (time-second 2digit) (time-secfrac "\\(\\.[0-9]+\\)?") (time-numoffset (concat "\\([-+]\\)" time-hour ":?" time-minute "?")) - (time-offset (concat "Z" time-numoffset)) (partial-time (concat time-hour colon time-minute colon time-second time-secfrac)) - (full-date (concat date-fullyear dash date-month dash date-mday)) - (full-time (concat partial-time time-offset)) - (date-time (concat full-date "T" full-time))) + (full-date (concat date-fullyear dash date-month dash date-mday))) (list (concat "^" full-date) (concat "T" partial-time) (concat "\\(Z\\|" time-numoffset "\\)"))) @@ -225,7 +222,7 @@ If DATE-STRING cannot be parsed, it falls back to (time-re (nth 1 parse-time-iso8601-regexp)) (tz-re (nth 2 parse-time-iso8601-regexp)) re-start - time seconds minute hour fractional-seconds + time seconds minute hour day month year day-of-week dst tz) ;; We need to populate 'time' with ;; (SEC MIN HOUR DAY MON YEAR DOW DST TZ) @@ -240,9 +237,6 @@ If DATE-STRING cannot be parsed, it falls back to (setq hour (string-to-number (match-string 1 date-string)) minute (string-to-number (match-string 2 date-string)) seconds (string-to-number (match-string 3 date-string)) - fractional-seconds (string-to-number (or - (match-string 4 date-string) - "0")) re-start (match-end 0)) (when (string-match tz-re date-string re-start) (if (string= "Z" (match-string 1 date-string)) diff --git a/lisp/cus-start.el b/lisp/cus-start.el index a790419b86f..51c43c7d21a 100644 --- a/lisp/cus-start.el +++ b/lisp/cus-start.el @@ -511,6 +511,7 @@ since it could result in memory overflow and make Emacs crash." (scroll-step windows integer) (scroll-conservatively windows integer) (scroll-margin windows integer) + (maximum-scroll-margin windows float "26.1") (hscroll-margin windows integer "22.1") (hscroll-step windows number "22.1") (truncate-partial-width-windows diff --git a/lisp/dired.el b/lisp/dired.el index 350f6a7d2e3..2733372eb7b 100644 --- a/lisp/dired.el +++ b/lisp/dired.el @@ -59,6 +59,10 @@ 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. +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." diff --git a/lisp/doc-view.el b/lisp/doc-view.el index 2c11cd23a7f..172ea163c18 100644 --- a/lisp/doc-view.el +++ b/lisp/doc-view.el @@ -442,6 +442,9 @@ Typically \"page-%s.png\".") (defun doc-view-revert-buffer (&optional ignore-auto noconfirm) "Like `revert-buffer', but preserves the buffer's current modes." (interactive (list (not current-prefix-arg))) + (if (< undo-outer-limit (* 2 (buffer-size))) + ;; It's normal for this operation to result in a very large undo entry. + (setq-local undo-outer-limit (* 2 (buffer-size)))) (cl-labels ((revert () (let (revert-buffer-function) (revert-buffer ignore-auto noconfirm 'preserve-modes)))) @@ -1763,6 +1766,8 @@ toggle between displaying the document or editing it as text. (unless doc-view-doc-type (doc-view-set-doc-type)) (doc-view-set-up-single-converter) + (unless (memq doc-view-doc-type '(ps)) + (setq-local require-final-newline nil)) (doc-view-make-safe-dir doc-view-cache-directory) ;; Handle compressed files, remote files, files inside archives diff --git a/lisp/emacs-lisp/edebug.el b/lisp/emacs-lisp/edebug.el index db54d1eeb20..ec0f08de356 100644 --- a/lisp/emacs-lisp/edebug.el +++ b/lisp/emacs-lisp/edebug.el @@ -112,6 +112,18 @@ and some not, use `def-edebug-spec' to specify an `edebug-form-spec'." :type 'boolean :group 'edebug) +(defcustom edebug-max-depth 150 + "Maximum recursion depth when instrumenting code. +This limit is intended to stop recursion if an Edebug specification +contains an infinite loop. When Edebug is instrumenting code +containing very large quoted lists, it may reach this limit and give +the error message \"Too deep - perhaps infinite loop in spec?\". +Make this limit larger to countermand that, but you may also need to +increase `max-lisp-eval-depth' and `max-specpdl-size'." + :type 'integer + :group 'edebug + :version "26.1") + (defcustom edebug-save-windows t "If non-nil, Edebug saves and restores the window configuration. That takes some time, so if your program does not care what happens to @@ -1452,7 +1464,6 @@ expressions; a `progn' form will be returned enclosing these forms." (defvar edebug-after-dotted-spec nil) (defvar edebug-matching-depth 0) ;; initial value -(defconst edebug-max-depth 150) ;; maximum number of matching recursions. ;;; Failure to match diff --git a/lisp/emacs-lisp/ert-x.el b/lisp/emacs-lisp/ert-x.el index 7d99cb30274..4cf9d9609e9 100644 --- a/lisp/emacs-lisp/ert-x.el +++ b/lisp/emacs-lisp/ert-x.el @@ -97,7 +97,7 @@ To be used in ERT tests. If BODY finishes successfully, the test buffer is killed; if there is an error, the test buffer is kept around on error for further inspection. Its name is derived from the name of the test and the result of NAME-FORM." - (declare (debug ((form) body)) + (declare (debug ((":name" form) body)) (indent 1)) `(ert--call-with-test-buffer ,name-form (lambda () ,@body))) @@ -285,6 +285,30 @@ BUFFER defaults to current buffer. Does not modify BUFFER." (kill-buffer clone))))))) +(defmacro ert-with-message-capture (var &rest body) + "Execute BODY while collecting anything written with `message' in VAR. + +Capture all messages produced by `message' when it is called from +Lisp, and concatenate them separated by newlines into one string. + +This is useful for separating the issuance of messages by the +code under test from the behavior of the *Messages* buffer." + (declare (debug (symbolp body)) + (indent 1)) + (let ((g-advice (cl-gensym))) + `(let* ((,var "") + (,g-advice (lambda (func &rest args) + (if (or (null args) (equal (car args) "")) + (apply func args) + (let ((msg (apply #'format-message args))) + (setq ,var (concat ,var msg "\n")) + (funcall func "%s" msg)))))) + (advice-add 'message :around ,g-advice) + (unwind-protect + (progn ,@body) + (advice-remove 'message ,g-advice))))) + + (provide 'ert-x) ;;; ert-x.el ends here diff --git a/lisp/emacs-lisp/let-alist.el b/lisp/emacs-lisp/let-alist.el index a45fc0a05c3..cf82fe3ec63 100644 --- a/lisp/emacs-lisp/let-alist.el +++ b/lisp/emacs-lisp/let-alist.el @@ -4,7 +4,7 @@ ;; Author: Artur Malabarba <emacs@endlessparentheses.com> ;; Package-Requires: ((emacs "24.1")) -;; Version: 1.0.4 +;; Version: 1.0.5 ;; Keywords: extensions lisp ;; Prefix: let-alist ;; Separator: - diff --git a/lisp/emacs-lisp/pcase.el b/lisp/emacs-lisp/pcase.el index 54678c5f324..46a5eedd150 100644 --- a/lisp/emacs-lisp/pcase.el +++ b/lisp/emacs-lisp/pcase.el @@ -89,7 +89,8 @@ (functionp &rest form) sexp)) -(def-edebug-spec pcase-MACRO pcase--edebug-match-macro) +;; See bug#24717 +(put 'pcase-MACRO 'edebug-form-spec 'pcase--edebug-match-macro) ;; Only called from edebug. (declare-function get-edebug-spec "edebug" (symbol)) diff --git a/lisp/emacs-lisp/subr-x.el b/lisp/emacs-lisp/subr-x.el index 7736225b5fa..f7a846927c0 100644 --- a/lisp/emacs-lisp/subr-x.el +++ b/lisp/emacs-lisp/subr-x.el @@ -115,12 +115,16 @@ threading." binding)) bindings))) -(defmacro if-let (bindings then &rest else) - "Process BINDINGS and if all values are non-nil eval THEN, else ELSE. -Argument BINDINGS is a list of tuples whose car is a symbol to be -bound and (optionally) used in THEN, and its cadr is a sexp to be -evalled to set symbol's value. In the special case you only want -to bind a single value, BINDINGS can just be a plain tuple." +(defmacro if-let* (bindings then &rest else) + "Bind variables according to VARLIST and eval THEN or ELSE. +Each binding is evaluated in turn with `let*', and evaluation +stops if a binding value is nil. If all are non-nil, the value +of THEN is returned, or the last form in ELSE is returned. +Each element of VARLIST is a symbol (which is bound to nil) +or a list (SYMBOL VALUEFORM) (which binds SYMBOL to the value of VALUEFORM). +In the special case you only want to bind a single value, +VARLIST can just be a plain tuple. +\n(fn VARLIST THEN ELSE...)" (declare (indent 2) (debug ([&or (&rest (symbolp form)) (symbolp form)] form body))) (when (and (<= (length bindings) 2) @@ -132,15 +136,23 @@ to bind a single value, BINDINGS can just be a plain tuple." ,then ,@else))) -(defmacro when-let (bindings &rest body) - "Process BINDINGS and if all values are non-nil eval BODY. -Argument BINDINGS is a list of tuples whose car is a symbol to be -bound and (optionally) used in BODY, and its cadr is a sexp to be -evalled to set symbol's value. In the special case you only want -to bind a single value, BINDINGS can just be a plain tuple." +(defmacro when-let* (bindings &rest body) + "Bind variables according to VARLIST and conditionally eval BODY. +Each binding is evaluated in turn with `let*', and evaluation +stops if a binding value is nil. If all are non-nil, the value +of the last form in BODY is returned. +Each element of VARLIST is a symbol (which is bound to nil) +or a list (SYMBOL VALUEFORM) (which binds SYMBOL to the value of VALUEFORM). +In the special case you only want to bind a single value, +VARLIST can just be a plain tuple. +\n(fn VARLIST BODY...)" (declare (indent 1) (debug if-let)) (list 'if-let bindings (macroexp-progn body))) +(defalias 'if-let 'if-let*) +(defalias 'when-let 'when-let*) +(defalias 'and-let* 'when-let*) + (defsubst hash-table-empty-p (hash-table) "Check whether HASH-TABLE is empty (has 0 elements)." (zerop (hash-table-count hash-table))) @@ -214,6 +226,11 @@ user enters `recenter', `scroll-up', or `scroll-down' responses, perform the requested window recentering or scrolling and ask again. +When `use-dialog-box' is t (the default), this function can pop +up a dialog window to collect the user input. That functionality +requires `display-popup-menus-p' to return t. Otherwise, a text +dialog will be used. + The return value is the matching entry from the CHOICES list. Usage example: diff --git a/lisp/emulation/edt-mapper.el b/lisp/emulation/edt-mapper.el index 24a8f039fa5..457ad55dd6c 100644 --- a/lisp/emulation/edt-mapper.el +++ b/lisp/emulation/edt-mapper.el @@ -57,9 +57,9 @@ ;; Usage: ;; Simply load this file into emacs (version 19 or higher) -;; using the following command. +;; and run the function edt-mapper, using the following command. -;; emacs -q -l edt-mapper.el +;; emacs -q -l edt-mapper -f edt-mapper ;; The "-q" option prevents loading of your init file (commands ;; therein might confuse this program). @@ -96,10 +96,6 @@ ;;; Code: -;; Otherwise it just hangs. This seems preferable. -(if noninteractive - (error "edt-mapper cannot be loaded in batch mode")) - ;;; ;;; Decide Emacs Variant, GNU Emacs or XEmacs (aka Lucid Emacs). ;;; Determine Window System, and X Server Vendor (if appropriate). @@ -124,6 +120,8 @@ ;;; ;;; Key variables ;;; + +;; FIXME some/all of these should be let-bound, not global. (defvar edt-key nil) (defvar edt-enter nil) (defvar edt-return nil) @@ -137,88 +135,116 @@ (defvar edt-save-function-key-map) ;;; -;;; Determine Terminal Type (if appropriate). -;;; - -(if (and edt-window-system (not (eq edt-window-system 'tty))) - (setq edt-term nil) - (setq edt-term (getenv "TERM"))) - -;;; -;;; Implements a workaround for a feature that was added to simple.el. -;;; -;;; Many function keys have no Emacs functions assigned to them by -;;; default. A subset of these are typically assigned functions in the -;;; EDT emulation. This includes all the keypad keys and a some others -;;; like Delete. -;;; -;;; Logic in simple.el maps some of these unassigned function keys to -;;; ordinary typing keys. Where this is the case, a call to -;;; read-key-sequence, below, does not return the name of the function -;;; key pressed by the user but, instead, it returns the name of the -;;; key to which it has been mapped. It needs to know the name of the -;;; key pressed by the user. As a workaround, we assign a function to -;;; each of the unassigned function keys of interest, here. These -;;; assignments override the mapping to other keys and are only -;;; temporary since, when edt-mapper is finished executing, it causes -;;; Emacs to exit. -;;; - -(mapc - (lambda (function-key) - (if (not (lookup-key (current-global-map) function-key)) - (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] - [kp-tab] - [kp-enter] - [kp-multiply] - [kp-add] - [kp-separator] - [kp-subtract] - [kp-decimal] - [kp-divide] - [kp-equal] - [backspace] - [delete] - [tab] - [linefeed] - [clear])) - -;;; -;;; Make sure the window is big enough to display the instructions, -;;; except where window cannot be re-sized. -;;; - -(if (and edt-window-system (not (eq edt-window-system 'tty))) - (set-frame-size (selected-frame) 80 36)) - -;;; -;;; Create buffers - Directions and Keys +;;; Key mapping functions ;;; -(if (not (get-buffer "Directions")) (generate-new-buffer "Directions")) -(if (not (get-buffer "Keys")) (generate-new-buffer "Keys")) +(defun edt-map-key (ident descrip) + (interactive) + (if (featurep 'xemacs) + (progn + (setq edt-key-seq (read-key-sequence (format "Press %s%s: " ident descrip))) + (setq edt-key (concat "[" (format "%s" (event-key (aref edt-key-seq 0))) "]")) + (cond ((not (equal edt-key edt-return)) + (set-buffer "Keys") + (insert (format " (\"%s\" . %s)\n" ident edt-key)) + (set-buffer "Directions")) + ;; bogosity to get next prompt to come up, if the user hits <CR>! + ;; check periodically to see if this is still needed... + (t + (set-buffer "Keys") + (insert (format " (\"%s\" . \"\" )\n" ident)) + (set-buffer "Directions")))) + (setq edt-key (read-key-sequence (format "Press %s%s: " ident descrip))) + (cond ((not (equal edt-key edt-return)) + (set-buffer "Keys") + (insert (if (vectorp edt-key) + (format " (\"%s\" . %s)\n" ident edt-key) + (format " (\"%s\" . \"%s\")\n" ident edt-key))) + (set-buffer "Directions")) + ;; bogosity to get next prompt to come up, if the user hits <CR>! + ;; check periodically to see if this is still needed... + (t + (set-buffer "Keys") + (insert (format " (\"%s\" . \"\" )\n" ident)) + (set-buffer "Directions")))) + edt-key) -;;; -;;; Put header in the Keys buffer -;;; -(set-buffer "Keys") -(insert "\ +(defun edt-mapper () + (if noninteractive + (user-error "edt-mapper cannot be loaded in batch mode")) + ;; Determine Terminal Type (if appropriate). + (if (and edt-window-system (not (eq edt-window-system 'tty))) + (setq edt-term nil) + (setq edt-term (getenv "TERM"))) + ;; + ;; Implements a workaround for a feature that was added to simple.el. + ;; + ;; Many function keys have no Emacs functions assigned to them by + ;; default. A subset of these are typically assigned functions in the + ;; EDT emulation. This includes all the keypad keys and a some others + ;; like Delete. + ;; + ;; Logic in simple.el maps some of these unassigned function keys to + ;; ordinary typing keys. Where this is the case, a call to + ;; read-key-sequence, below, does not return the name of the function + ;; key pressed by the user but, instead, it returns the name of the + ;; key to which it has been mapped. It needs to know the name of the + ;; key pressed by the user. As a workaround, we assign a function to + ;; each of the unassigned function keys of interest, here. These + ;; assignments override the mapping to other keys and are only + ;; temporary since, when edt-mapper is finished executing, it causes + ;; Emacs to exit. + ;; + (mapc + (lambda (function-key) + (if (not (lookup-key (current-global-map) function-key)) + (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] + [kp-tab] + [kp-enter] + [kp-multiply] + [kp-add] + [kp-separator] + [kp-subtract] + [kp-decimal] + [kp-divide] + [kp-equal] + [backspace] + [delete] + [tab] + [linefeed] + [clear])) + ;; + ;; Make sure the window is big enough to display the instructions, + ;; except where window cannot be re-sized. + ;; + (if (and edt-window-system (not (eq edt-window-system 'tty))) + (set-frame-size (selected-frame) 80 36)) + ;; + ;; Create buffers - Directions and Keys + ;; + (if (not (get-buffer "Directions")) (generate-new-buffer "Directions")) + (if (not (get-buffer "Keys")) (generate-new-buffer "Keys")) + ;; + ;; Put header in the Keys buffer + ;; + (set-buffer "Keys") + (insert "\ ;; ;; Key definitions for the EDT emulation within GNU Emacs ;; -(defconst *EDT-keys* +\(defconst *EDT-keys* '( -") - -;;; -;;; Display directions -;;; -(switch-to-buffer "Directions") -(if (and edt-window-system (not (eq edt-window-system 'tty))) - (insert " + ") + + ;; + ;; Display directions + ;; + (switch-to-buffer "Directions") + (if (and edt-window-system (not (eq edt-window-system 'tty))) + (insert " EDT MAPPER You will be asked to press keys to create a custom mapping (under a @@ -240,7 +266,7 @@ just press RETURN at the prompt. ") - (insert " + (insert " EDT MAPPER You will be asked to press keys to create a custom mapping of your @@ -259,39 +285,39 @@ ")) -(delete-other-windows) - -;;; -;;; Save <CR> for future reference. -;;; -;;; For GNU Emacs, running in a Window System, first hide bindings in -;;; function-key-map. -;;; -(cond - ((featurep 'xemacs) - (setq edt-return-seq (read-key-sequence "Hit carriage-return <CR> to continue ")) - (setq edt-return (concat "[" (format "%s" (event-key (aref edt-return-seq 0))) "]"))) - (t - (if edt-window-system - (progn - (setq edt-save-function-key-map function-key-map) - (setq function-key-map (make-sparse-keymap)))) - (setq edt-return (read-key-sequence "Hit carriage-return <CR> to continue ")))) - -;;; -;;; Remove prefix-key bindings to F1 and F2 in global-map so they can be -;;; bound in the EDT Emulation mode. -;;; -(global-unset-key [f1]) -(global-unset-key [f2]) - -;;; -;;; Display Keypad Diagram and Begin Prompting for Keys -;;; -(set-buffer "Directions") -(delete-region (point-min) (point-max)) -(if (and edt-window-system (not (eq edt-window-system 'tty))) - (insert " + (delete-other-windows) + + ;; + ;; Save <CR> for future reference. + ;; + ;; For GNU Emacs, running in a Window System, first hide bindings in + ;; function-key-map. + ;; + (cond + ((featurep 'xemacs) + (setq edt-return-seq (read-key-sequence "Hit carriage-return <CR> to continue ")) + (setq edt-return (concat "[" (format "%s" (event-key (aref edt-return-seq 0))) "]"))) + (t + (if edt-window-system + (progn + (setq edt-save-function-key-map function-key-map) + (setq function-key-map (make-sparse-keymap)))) + (setq edt-return (read-key-sequence "Hit carriage-return <CR> to continue ")))) + + ;; + ;; Remove prefix-key bindings to F1 and F2 in global-map so they can be + ;; bound in the EDT Emulation mode. + ;; + (global-unset-key [f1]) + (global-unset-key [f2]) + + ;; + ;; Display Keypad Diagram and Begin Prompting for Keys + ;; + (set-buffer "Directions") + (delete-region (point-min) (point-max)) + (if (and edt-window-system (not (eq edt-window-system 'tty))) + (insert " PRESS THE KEY SPECIFIED IN THE MINIBUFFER BELOW. @@ -321,11 +347,11 @@ REMEMBER: JUST PRESS RETURN TO SKIP MAPPING A KEY. ") - (progn - (insert " + (progn + (insert " GENERATING A CUSTOM CONFIGURATION FILE FOR TERMINAL TYPE: ") - (insert (format "%s." edt-term)) - (insert " + (insert (format "%s." edt-term)) + (insert " PRESS THE KEY SPECIFIED IN THE MINIBUFFER BELOW. @@ -347,142 +373,109 @@ REMEMBER: JUST PRESS RETURN TO SKIP MAPPING A KEY."))) -;;; -;;; Key mapping functions -;;; -(defun edt-map-key (ident descrip) - (interactive) - (if (featurep 'xemacs) - (progn - (setq edt-key-seq (read-key-sequence (format "Press %s%s: " ident descrip))) - (setq edt-key (concat "[" (format "%s" (event-key (aref edt-key-seq 0))) "]")) - (cond ((not (equal edt-key edt-return)) - (set-buffer "Keys") - (insert (format " (\"%s\" . %s)\n" ident edt-key)) - (set-buffer "Directions")) - ;; bogosity to get next prompt to come up, if the user hits <CR>! - ;; check periodically to see if this is still needed... - (t - (set-buffer "Keys") - (insert (format " (\"%s\" . \"\" )\n" ident)) - (set-buffer "Directions")))) - (setq edt-key (read-key-sequence (format "Press %s%s: " ident descrip))) - (cond ((not (equal edt-key edt-return)) - (set-buffer "Keys") - (insert (if (vectorp edt-key) - (format " (\"%s\" . %s)\n" ident edt-key) - (format " (\"%s\" . \"%s\")\n" ident edt-key))) - (set-buffer "Directions")) - ;; bogosity to get next prompt to come up, if the user hits <CR>! - ;; check periodically to see if this is still needed... - (t - (set-buffer "Keys") - (insert (format " (\"%s\" . \"\" )\n" ident)) - (set-buffer "Directions")))) - edt-key) -(set-buffer "Keys") -(insert " + (set-buffer "Keys") + (insert " ;; ;; Arrows ;; ") -(set-buffer "Directions") + (set-buffer "Directions") -(edt-map-key "UP" " - The Up Arrow Key") -(edt-map-key "DOWN" " - The Down Arrow Key") -(edt-map-key "LEFT" " - The Left Arrow Key") -(edt-map-key "RIGHT" " - The Right Arrow Key") + (edt-map-key "UP" " - The Up Arrow Key") + (edt-map-key "DOWN" " - The Down Arrow Key") + (edt-map-key "LEFT" " - The Left Arrow Key") + (edt-map-key "RIGHT" " - The Right Arrow Key") -(set-buffer "Keys") -(insert " + (set-buffer "Keys") + (insert " ;; ;; PF keys ;; ") -(set-buffer "Directions") + (set-buffer "Directions") -(edt-map-key "PF1" " - The PF1 (GOLD) Key") -(edt-map-key "PF2" " - The Keypad PF2 Key") -(edt-map-key "PF3" " - The Keypad PF3 Key") -(edt-map-key "PF4" " - The Keypad PF4 Key") + (edt-map-key "PF1" " - The PF1 (GOLD) Key") + (edt-map-key "PF2" " - The Keypad PF2 Key") + (edt-map-key "PF3" " - The Keypad PF3 Key") + (edt-map-key "PF4" " - The Keypad PF4 Key") -(set-buffer "Keys") -(insert " + (set-buffer "Keys") + (insert " ;; ;; KP0-9 KP- KP, KPP and KPE ;; ") -(set-buffer "Directions") - -(edt-map-key "KP0" " - The Keypad 0 Key") -(edt-map-key "KP1" " - The Keypad 1 Key") -(edt-map-key "KP2" " - The Keypad 2 Key") -(edt-map-key "KP3" " - The Keypad 3 Key") -(edt-map-key "KP4" " - The Keypad 4 Key") -(edt-map-key "KP5" " - The Keypad 5 Key") -(edt-map-key "KP6" " - The Keypad 6 Key") -(edt-map-key "KP7" " - The Keypad 7 Key") -(edt-map-key "KP8" " - The Keypad 8 Key") -(edt-map-key "KP9" " - The Keypad 9 Key") -(edt-map-key "KP-" " - The Keypad - Key") -(edt-map-key "KP," " - The Keypad , Key") -(edt-map-key "KPP" " - The Keypad . Key") -(edt-map-key "KPE" " - The Keypad Enter Key") -;; Save the enter key -(setq edt-enter edt-key) -(setq edt-enter-seq edt-key-seq) - - -(set-buffer "Keys") -(insert " + (set-buffer "Directions") + + (edt-map-key "KP0" " - The Keypad 0 Key") + (edt-map-key "KP1" " - The Keypad 1 Key") + (edt-map-key "KP2" " - The Keypad 2 Key") + (edt-map-key "KP3" " - The Keypad 3 Key") + (edt-map-key "KP4" " - The Keypad 4 Key") + (edt-map-key "KP5" " - The Keypad 5 Key") + (edt-map-key "KP6" " - The Keypad 6 Key") + (edt-map-key "KP7" " - The Keypad 7 Key") + (edt-map-key "KP8" " - The Keypad 8 Key") + (edt-map-key "KP9" " - The Keypad 9 Key") + (edt-map-key "KP-" " - The Keypad - Key") + (edt-map-key "KP," " - The Keypad , Key") + (edt-map-key "KPP" " - The Keypad . Key") + (edt-map-key "KPE" " - The Keypad Enter Key") + ;; Save the enter key + (setq edt-enter edt-key) + (setq edt-enter-seq edt-key-seq) + + + (set-buffer "Keys") + (insert " ;; ;; Editing keypad (FIND, INSERT, REMOVE) ;; (SELECT, PREVIOUS, NEXT) ;; ") -(set-buffer "Directions") + (set-buffer "Directions") -(edt-map-key "FIND" " - The Find key on the editing keypad") -(edt-map-key "INSERT" " - The Insert key on the editing keypad") -(edt-map-key "REMOVE" " - The Remove key on the editing keypad") -(edt-map-key "SELECT" " - The Select key on the editing keypad") -(edt-map-key "PREVIOUS" " - The Prev Scr key on the editing keypad") -(edt-map-key "NEXT" " - The Next Scr key on the editing keypad") + (edt-map-key "FIND" " - The Find key on the editing keypad") + (edt-map-key "INSERT" " - The Insert key on the editing keypad") + (edt-map-key "REMOVE" " - The Remove key on the editing keypad") + (edt-map-key "SELECT" " - The Select key on the editing keypad") + (edt-map-key "PREVIOUS" " - The Prev Scr key on the editing keypad") + (edt-map-key "NEXT" " - The Next Scr key on the editing keypad") -(set-buffer "Keys") -(insert " + (set-buffer "Keys") + (insert " ;; ;; F1-14 Help Do F17-F20 ;; ") -(set-buffer "Directions") - -(edt-map-key "F1" " - F1 Function Key") -(edt-map-key "F2" " - F2 Function Key") -(edt-map-key "F3" " - F3 Function Key") -(edt-map-key "F4" " - F4 Function Key") -(edt-map-key "F5" " - F5 Function Key") -(edt-map-key "F6" " - F6 Function Key") -(edt-map-key "F7" " - F7 Function Key") -(edt-map-key "F8" " - F8 Function Key") -(edt-map-key "F9" " - F9 Function Key") -(edt-map-key "F10" " - F10 Function Key") -(edt-map-key "F11" " - F11 Function Key") -(edt-map-key "F12" " - F12 Function Key") -(edt-map-key "F13" " - F13 Function Key") -(edt-map-key "F14" " - F14 Function Key") -(edt-map-key "HELP" " - HELP Function Key") -(edt-map-key "DO" " - DO Function Key") -(edt-map-key "F17" " - F17 Function Key") -(edt-map-key "F18" " - F18 Function Key") -(edt-map-key "F19" " - F19 Function Key") -(edt-map-key "F20" " - F20 Function Key") - -(set-buffer "Directions") -(delete-region (point-min) (point-max)) -(insert " + (set-buffer "Directions") + + (edt-map-key "F1" " - F1 Function Key") + (edt-map-key "F2" " - F2 Function Key") + (edt-map-key "F3" " - F3 Function Key") + (edt-map-key "F4" " - F4 Function Key") + (edt-map-key "F5" " - F5 Function Key") + (edt-map-key "F6" " - F6 Function Key") + (edt-map-key "F7" " - F7 Function Key") + (edt-map-key "F8" " - F8 Function Key") + (edt-map-key "F9" " - F9 Function Key") + (edt-map-key "F10" " - F10 Function Key") + (edt-map-key "F11" " - F11 Function Key") + (edt-map-key "F12" " - F12 Function Key") + (edt-map-key "F13" " - F13 Function Key") + (edt-map-key "F14" " - F14 Function Key") + (edt-map-key "HELP" " - HELP Function Key") + (edt-map-key "DO" " - DO Function Key") + (edt-map-key "F17" " - F17 Function Key") + (edt-map-key "F18" " - F18 Function Key") + (edt-map-key "F19" " - F19 Function Key") + (edt-map-key "F20" " - F20 Function Key") + + (set-buffer "Directions") + (delete-region (point-min) (point-max)) + (insert " ADDITIONAL FUNCTION KEYS Your keyboard may have additional function keys which do not correspond @@ -501,53 +494,53 @@ When you are done, just press RETURN at the \"EDT Key Name:\" prompt. ") -(switch-to-buffer "Directions") -;;; -;;; Add support for extras keys -;;; -(set-buffer "Keys") -(insert "\ + (switch-to-buffer "Directions") + ;; + ;; Add support for extras keys + ;; + (set-buffer "Keys") + (insert "\ ;; ;; Extra Keys ;; ") -;;; -;;; Restore function-key-map. -;;; -(if (and edt-window-system (not (featurep 'xemacs))) - (setq function-key-map edt-save-function-key-map)) -(setq EDT-key-name "") -(while (not - (string-equal (setq EDT-key-name (read-string "EDT Key Name: ")) "")) - (edt-map-key EDT-key-name "")) - -; -; No more keys to add, so wrap up. -; -(set-buffer "Keys") -(insert "\ + ;; + ;; Restore function-key-map. + ;; + (if (and edt-window-system (not (featurep 'xemacs))) + (setq function-key-map edt-save-function-key-map)) + (setq EDT-key-name "") + (while (not + (string-equal (setq EDT-key-name (read-string "EDT Key Name: ")) "")) + (edt-map-key EDT-key-name "")) + + ;; + ;; No more keys to add, so wrap up. + ;; + (set-buffer "Keys") + (insert "\ ) ) ") -;;; -;;; Save the key mapping program -;;; -;;; -;;; Save the key mapping file -;;; -(let ((file (concat - "~/.edt-" (if (featurep 'xemacs) "xemacs" "gnu") - (if edt-term (concat "-" edt-term)) - (if edt-xserver (concat "-" edt-xserver)) - (if edt-window-system (concat "-" (upcase (symbol-name edt-window-system)))) - "-keys"))) - (set-visited-file-name - (read-file-name (format "Save key mapping to file (default %s): " file) nil file))) -(save-buffer) - -(message "That's it! Press any key to exit") -(sit-for 600) -(kill-emacs t) + ;; + ;; Save the key mapping program + ;; + ;; + ;; Save the key mapping file + ;; + (let ((file (concat + "~/.edt-" (if (featurep 'xemacs) "xemacs" "gnu") + (if edt-term (concat "-" edt-term)) + (if edt-xserver (concat "-" edt-xserver)) + (if edt-window-system (concat "-" (upcase (symbol-name edt-window-system)))) + "-keys"))) + (set-visited-file-name + (read-file-name (format "Save key mapping to file (default %s): " file) nil file))) + (save-buffer) + + (message "That's it! Press any key to exit") + (sit-for 600) + (kill-emacs t)) ;;; edt-mapper.el ends here diff --git a/lisp/emulation/edt.el b/lisp/emulation/edt.el index 31f555b0326..a6b2d785ac5 100644 --- a/lisp/emulation/edt.el +++ b/lisp/emulation/edt.el @@ -1928,6 +1928,8 @@ Optional argument NOT-YES changes the default to negative." ;;; INITIALIZATION COMMANDS. ;;; +(declare-function edt-mapper "edt-mapper" ()) + ;;; ;;; Function used to load LK-201 key mapping file generated by edt-mapper.el. ;;; @@ -1968,7 +1970,7 @@ created." You can do this by quitting Emacs and then invoking Emacs again as follows: - emacs -q -l edt-mapper + emacs -q -l edt-mapper -f edt-mapper [NOTE: If you do nothing out of the ordinary in your init file, and the search for edt-mapper is successful, you can try running it now.] @@ -1983,7 +1985,9 @@ created." (insert (format "Ah yes, there it is, in \n\n %s \n\n" path)) (if (edt-y-or-n-p "Do you want to run it now? ") - (load-file path) + (progn + (load-file path) + (edt-mapper)) (error "EDT Emulation not configured"))) (insert (substitute-command-keys "Nope, I can't seem to find it. :-(\n\n")) diff --git a/lisp/files.el b/lisp/files.el index 25392fdcc71..b7d104853c3 100644 --- a/lisp/files.el +++ b/lisp/files.el @@ -5134,6 +5134,14 @@ Before and after saving the buffer, this function runs "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'. +This allows you to stop `save-some-buffers' from asking +about certain files that you'd usually rather not save." + :group 'auto-save + :type 'function + :version "26.1") + (defun save-some-buffers (&optional arg pred) "Save some modified file-visiting buffers. Asks user about each one. You can answer `y' to save, `n' not to save, `C-r' to look at the @@ -5149,10 +5157,13 @@ If PRED is nil, all the file-visiting buffers are considered. If PRED is t, then certain non-file buffers will also be considered. If PRED is a zero-argument function, it indicates for each buffer whether to consider it or not when called with that buffer current. +PRED defaults to the value of `save-some-buffers-default-predicate'. See `save-some-buffers-action-alist' if you want to change the additional actions you can take on files." (interactive "P") + (unless pred + (setq pred save-some-buffers-default-predicate)) (save-window-excursion (let* (queried autosaved-buffers files-done abbrevs-done) @@ -6572,7 +6583,7 @@ normally equivalent short `-D' option is just passed on to (unless (equal switches "") ;; Split the switches at any spaces so we can ;; pass separate options as separate args. - (split-string switches))) + (split-string-and-unquote switches))) ;; Avoid lossage if FILE starts with `-'. '("--") (progn @@ -6812,6 +6823,8 @@ asks whether processes should be killed. Runs the members of `kill-emacs-query-functions' in turn and stops if any returns nil. If `confirm-kill-emacs' is non-nil, calls it." (interactive "P") + ;; Don't use save-some-buffers-default-predicate, because we want + ;; to ask about all the buffers before killing Emacs. (save-some-buffers arg t) (let ((confirm confirm-kill-emacs)) (and diff --git a/lisp/gnus/gnus-art.el b/lisp/gnus/gnus-art.el index 43e1231914c..a4ff840f755 100644 --- a/lisp/gnus/gnus-art.el +++ b/lisp/gnus/gnus-art.el @@ -1713,9 +1713,10 @@ regexp." ;; (modify-syntax-entry ?- "w" table) (modify-syntax-entry ?> ")<" table) (modify-syntax-entry ?< "(>" table) - ;; make M-. in article buffers work for `foo' strings - (modify-syntax-entry ?' " " table) - (modify-syntax-entry ?` " " table) + ;; make M-. in article buffers work for `foo' strings, + ;; and still allow C-s C-w to yank ' to the search ring + (modify-syntax-entry ?' "'" table) + (modify-syntax-entry ?` "'" table) table) "Syntax table used in article mode buffers. Initialized from `text-mode-syntax-table'.") diff --git a/lisp/ibuffer.el b/lisp/ibuffer.el index c6e5e471a36..71bf1d6dcc2 100644 --- a/lisp/ibuffer.el +++ b/lisp/ibuffer.el @@ -1319,13 +1319,14 @@ a new window in the current frame, splitting vertically." (cl-assert (derived-mode-p 'ibuffer-mode))) (defun ibuffer-buffer-file-name () - (or buffer-file-name - (let ((dirname (or (and (boundp 'dired-directory) - (if (stringp dired-directory) - dired-directory - (car dired-directory))) - (bound-and-true-p list-buffers-directory)))) - (and dirname (expand-file-name dirname))))) + (cond + ((buffer-file-name)) + ((bound-and-true-p list-buffers-directory)) + ((let ((dirname (and (boundp 'dired-directory) + (if (stringp dired-directory) + dired-directory + (car dired-directory))))) + (and dirname (expand-file-name dirname)))))) (define-ibuffer-op ibuffer-do-save () "Save marked buffers as with `save-buffer'." diff --git a/lisp/image-dired.el b/lisp/image-dired.el index 901225fa2e9..2a4064560a7 100644 --- a/lisp/image-dired.el +++ b/lisp/image-dired.el @@ -94,6 +94,7 @@ ;; * WARNING: The "database" format used might be changed so keep a ;; backup of `image-dired-db-file' when testing new versions. ;; +;; * `image-dired-display-image-mode' does not support animation ;; ;; TODO ;; ==== @@ -228,7 +229,7 @@ Used together with `image-dired-cmd-create-thumbnail-options'." :group 'image-dired) (defcustom image-dired-cmd-create-thumbnail-options - '("-size" "%wx%h" "%f" "-resize" "%wx%h>" "-strip" "jpeg:%t") + '("-size" "%wx%h" "%f[0]" "-resize" "%wx%h>" "-strip" "jpeg:%t") "Options of command used to create thumbnail image. Used with `image-dired-cmd-create-thumbnail-program'. Available format specifiers are: %w which is replaced by @@ -246,7 +247,7 @@ Used together with `image-dired-cmd-create-temp-image-options'." :group 'image-dired) (defcustom image-dired-cmd-create-temp-image-options - '("-size" "%wx%h" "%f" "-resize" "%wx%h>" "-strip" "jpeg:%t") + '("-size" "%wx%h" "%f[0]" "-resize" "%wx%h>" "-strip" "jpeg:%t") "Options of command used to create temporary image for display window. Used together with `image-dired-cmd-create-temp-image-program', Available format specifiers are: %w and %h which are replaced by @@ -316,7 +317,7 @@ Available format specifiers are described in :group 'image-dired) (defcustom image-dired-cmd-create-standard-thumbnail-options - (append '("-size" "%wx%h" "%f") + (append '("-size" "%wx%h" "%f[0]") (unless (or image-dired-cmd-pngcrush-program image-dired-cmd-pngnq-program) (list @@ -1626,6 +1627,7 @@ Resized or in full-size." :group 'image-dired (buffer-disable-undo) (image-mode-setup-winprops) + (setq cursor-type nil) (add-hook 'file-name-at-point-functions 'image-dired-file-name-at-point nil t)) (defvar image-dired-minor-mode-map diff --git a/lisp/indent.el b/lisp/indent.el index db31f0454ce..fdd184c7998 100644 --- a/lisp/indent.el +++ b/lisp/indent.el @@ -487,9 +487,9 @@ line, but does not move past any whitespace that was explicitly inserted (if (memq (current-justification) '(center right)) (skip-chars-forward " \t"))) -(defvar indent-region-function nil +(defvar indent-region-function #'indent-region-line-by-line "Short cut function to indent region using `indent-according-to-mode'. -A value of nil means really run `indent-according-to-mode' on each line.") +Default is to really run `indent-according-to-mode' on each line.") (defun indent-region (start end &optional column) "Indent each nonblank line in the region. @@ -541,24 +541,26 @@ column to indent to; if it is nil, use one of the three methods above." (funcall indent-region-function start end)) ;; Else, use a default implementation that calls indent-line-function on ;; each line. - (t - (save-excursion - (setq end (copy-marker end)) - (goto-char start) - (let ((pr (unless (minibufferp) - (make-progress-reporter "Indenting region..." (point) end)))) - (while (< (point) end) - (or (and (bolp) (eolp)) - (indent-according-to-mode)) - (forward-line 1) - (and pr (progress-reporter-update pr (point)))) - (and pr (progress-reporter-done pr)) - (move-marker end nil))))) + (t (indent-region-line-by-line start end))) ;; In most cases, reindenting modifies the buffer, but it may also ;; leave it unmodified, in which case we have to deactivate the mark ;; by hand. (setq deactivate-mark t)) +(defun indent-region-line-by-line (start end) + (save-excursion + (setq end (copy-marker end)) + (goto-char start) + (let ((pr (unless (minibufferp) + (make-progress-reporter "Indenting region..." (point) end)))) + (while (< (point) end) + (or (and (bolp) (eolp)) + (indent-according-to-mode)) + (forward-line 1) + (and pr (progress-reporter-update pr (point)))) + (and pr (progress-reporter-done pr)) + (move-marker end nil)))) + (define-obsolete-function-alias 'indent-relative-maybe 'indent-relative-first-indent-point "26.1") diff --git a/lisp/info.el b/lisp/info.el index e32b6b35632..0cfcec32f82 100644 --- a/lisp/info.el +++ b/lisp/info.el @@ -1599,6 +1599,16 @@ escaped (\\\",\\\\)." parameter-alist)) parameter-alist)) +(defun Info-node-description (file) + (cond + ((equal file "dir") "*Info Directory*") + ((eq file 'apropos) "*Info Apropos*") + ((eq file 'history) "*Info History*") + ((eq file 'toc) "*Info TOC*") + ((not (stringp file)) "") ; Avoid errors + (t + (concat "(" (file-name-nondirectory file) ") " Info-current-node)))) + (defun Info-display-images-node () "Display images in current node." (save-excursion @@ -1693,6 +1703,7 @@ escaped (\\\",\\\\)." (setq Info-history-forward nil)) (if (not (eq Info-fontify-maximum-menu-size nil)) (Info-fontify-node)) + (setq list-buffers-directory (Info-node-description Info-current-file)) (Info-display-images-node) (Info-hide-cookies-node) (run-hooks 'Info-selection-hook))))) diff --git a/lisp/mh-e/mh-compat.el b/lisp/mh-e/mh-compat.el index aae751e8d2d..3f3990e8695 100644 --- a/lisp/mh-e/mh-compat.el +++ b/lisp/mh-e/mh-compat.el @@ -283,16 +283,6 @@ DOCSTRING arguments." See documentation for `make-obsolete-variable' for a description of the arguments OBSOLETE-NAME, CURRENT-NAME, and perhaps WHEN and ACCESS-TYPE. This macro is used by XEmacs that lacks WHEN and -ACCESS-TYPE arguments." - (if (featurep 'xemacs) - `(make-obsolete-variable ,obsolete-name ,current-name) - `(make-obsolete-variable ,obsolete-name ,current-name ,when ,access-type))) - -(defmacro mh-make-obsolete-variable (obsolete-name current-name &optional when access-type) - "Make the byte-compiler warn that OBSOLETE-NAME is obsolete. -See documentation for `make-obsolete-variable' for a description -of the arguments OBSOLETE-NAME, CURRENT-NAME, and perhaps WHEN -and ACCESS-TYPE. This macro is used by XEmacs that lacks WHEN and ACCESS-TYPE arguments and by Emacs versions that lack ACCESS-TYPE, introduced in Emacs 24." (if (featurep 'xemacs) diff --git a/lisp/net/tramp.el b/lisp/net/tramp.el index fc7fdd30850..48dcd5edd11 100644 --- a/lisp/net/tramp.el +++ b/lisp/net/tramp.el @@ -3614,18 +3614,36 @@ connection buffer." ;;; Utility functions: -(defun tramp-accept-process-output (&optional proc timeout timeout-msecs) +(defun tramp-accept-process-output (proc timeout) "Like `accept-process-output' for Tramp processes. This is needed in order to hide `last-coding-system-used', which is set for process communication also." + ;; FIXME: There are problems, when an asynchronous process runs in + ;; parallel, and also timers are active. See + ;; <http://lists.gnu.org/archive/html/tramp-devel/2017-01/msg00010.html>. + (when (and timer-event-last + (string-prefix-p "*tramp/" (process-name proc)) + (let (result) + (maphash + (lambda (key _value) + (and (processp key) + (not (string-prefix-p "*tramp/" (process-name key))) + (tramp-compat-process-live-p key) + (setq result t))) + tramp-cache-data) + result)) + (sit-for 0.01 'nodisp)) (with-current-buffer (process-buffer proc) (let (buffer-read-only last-coding-system-used) ;; Under Windows XP, accept-process-output doesn't return - ;; sometimes. So we add an additional timeout. - (with-timeout ((or timeout 1)) - (accept-process-output proc timeout timeout-msecs (and proc t))) - (tramp-message proc 10 "%s %s\n%s" - proc (process-status proc) (buffer-string))))) + ;; sometimes. So we add an additional timeout. JUST-THIS-ONE + ;; is set due to Bug#12145. + (tramp-message + proc 10 "%s %s %s\n%s" + proc (process-status proc) + (with-timeout (timeout) + (accept-process-output proc timeout nil t)) + (buffer-string))))) (defun tramp-check-for-regexp (proc regexp) "Check, whether REGEXP is contained in process buffer of PROC. diff --git a/lisp/progmodes/cc-align.el b/lisp/progmodes/cc-align.el index 7cb36c4396b..0f7e4b598dc 100644 --- a/lisp/progmodes/cc-align.el +++ b/lisp/progmodes/cc-align.el @@ -1221,6 +1221,18 @@ Works with: arglist-cont, arglist-cont-nonempty." (vector (progn (goto-char alignto) (current-column))))))) +(defun c-lineup-under-anchor (langelem) + "Line up the current line directly under the anchor position in LANGELEM. + +This is like 0, except it supersedes any indentation already calculated for +previous syntactic elements in the syntactic context. + +Works with: Any syntactic symbol which has an anchor position." + (save-excursion + (goto-char (c-langelem-pos langelem)) + (vector (current-column)))) + + (defun c-lineup-dont-change (langelem) "Do not change the indentation of the current line. diff --git a/lisp/progmodes/cc-engine.el b/lisp/progmodes/cc-engine.el index fd7aa50840f..dfd7aebd569 100644 --- a/lisp/progmodes/cc-engine.el +++ b/lisp/progmodes/cc-engine.el @@ -10260,13 +10260,22 @@ comment at the start of cc-engine.el for more info." (t nil))))) (setq pos (point)) - (if (and after-type-id-pos - (goto-char after-type-id-pos) - (setq res (c-back-over-member-initializers)) - (goto-char res) - (eq (car (c-beginning-of-decl-1 lim)) 'same)) - (cons (point) nil) ; Return value. - + (cond + ((and after-type-id-pos + (goto-char after-type-id-pos) + (setq res (c-back-over-member-initializers)) + (goto-char res) + (eq (car (c-beginning-of-decl-1 lim)) 'same)) + (cons (point) nil)) ; Return value. + + ((and after-type-id-pos + (progn + (c-backward-syntactic-ws) + (eq (char-before) ?\())) + ;; Single identifier between '(' and '{'. We have a bracelist. + (cons after-type-id-pos nil)) + + (t (goto-char pos) ;; Checks to do on all sexps before the brace, up to the ;; beginning of the statement. @@ -10368,7 +10377,7 @@ comment at the start of cc-engine.el for more info." ; languages where ; `c-opt-inexpr-brace-list-key' is ; non-nil and we have macros. - (t t))) ;; The caller can go up one level. + (t t)))) ;; The caller can go up one level. ))) (defun c-inside-bracelist-p (containing-sexp paren-state) @@ -10493,6 +10502,30 @@ comment at the start of cc-engine.el for more info." (c-at-statement-start-p)) (make-obsolete 'c-looking-at-bos 'c-at-statement-start-p "22.1") +(defun c-looking-at-statement-block () + ;; Point is at an opening brace. If this is a statement block (i.e. the + ;; elements in it are terminated by semicolons) return t. Otherwise, return + ;; nil. + (let ((here (point))) + (prog1 + (if (c-go-list-forward) + (let ((there (point))) + (backward-char) + (c-syntactic-skip-backward + "^;," here t) + (cond + ((eq (char-before) ?\;) t) + ((eq (char-before) ?,) nil) + (t (goto-char here) + (forward-char) + (and (c-syntactic-re-search-forward "{" there t t) + (progn (backward-char) + (c-looking-at-statement-block)))))) + (forward-char) + (and (c-syntactic-re-search-forward "[;,]" nil t t) + (eq (char-before) ?\;))) + (goto-char here)))) + (defun c-looking-at-inexpr-block (lim containing-sexp &optional check-at-end) ;; Return non-nil if we're looking at the beginning of a block ;; inside an expression. The value returned is actually a cons of @@ -10648,15 +10681,7 @@ comment at the start of cc-engine.el for more info." (and (c-major-mode-is 'c++-mode) (save-excursion (goto-char block-follows) - (if (c-go-list-forward) - (progn - (backward-char) - (c-syntactic-skip-backward - "^;," block-follows t) - (not (eq (char-before) ?\;))) - (or (not (c-syntactic-re-search-forward - "[;,]" nil t t)) - (not (eq (char-before) ?\;))))))) + (not (c-looking-at-statement-block))))) nil (cons 'inexpr-statement (point))))) @@ -10792,17 +10817,20 @@ comment at the start of cc-engine.el for more info." syntax-extra-args stop-at-boi-only containing-sexp - paren-state) + paren-state + &optional fixed-anchor) ;; Add the indicated SYNTAX-SYMBOL to `c-syntactic-context', extending it as ;; needed with further syntax elements of the types `substatement', - ;; `inexpr-statement', `arglist-cont-nonempty', `statement-block-intro', and - ;; `defun-block-intro'. + ;; `inexpr-statement', `arglist-cont-nonempty', `statement-block-intro', + ;; `defun-block-intro', and `brace-list-intro'. ;; - ;; Do the generic processing to anchor the given syntax symbol on - ;; the preceding statement: Skip over any labels and containing - ;; statements on the same line, and then search backward until we - ;; find a statement or block start that begins at boi without a - ;; label or comment. + ;; Do the generic processing to anchor the given syntax symbol on the + ;; preceding statement: First skip over any labels and containing statements + ;; on the same line. If FIXED-ANCHOR is non-nil, use this as the + ;; anchor-point for the given syntactic symbol, and don't make syntactic + ;; entries for constructs beginning on lines before that containing + ;; ANCHOR-POINT. Otherwise search backward until we find a statement or + ;; block start that begins at boi without a label or comment. ;; ;; Point is assumed to be at the prospective anchor point for the ;; given SYNTAX-SYMBOL. More syntax entries are added if we need to @@ -10831,6 +10859,7 @@ comment at the start of cc-engine.el for more info." (let ((syntax-last c-syntactic-context) (boi (c-point 'boi)) + (anchor-boi (c-point 'boi)) ;; Set when we're on a label, so that we don't stop there. ;; FIXME: To be complete we should check if we're on a label ;; now at the start. @@ -10908,7 +10937,9 @@ comment at the start of cc-engine.el for more info." (c-add-syntax 'substatement nil)))) ))) - containing-sexp) + containing-sexp + (or (null fixed-anchor) + (> containing-sexp anchor-boi))) ;; Now we have to go out of this block. (goto-char containing-sexp) @@ -10982,6 +11013,14 @@ comment at the start of cc-engine.el for more info." (cdr (assoc (match-string 1) c-other-decl-block-key-in-symbols-alist)) (max (c-point 'boi paren-pos) (point)))) + ((save-excursion + (goto-char paren-pos) + (c-looking-at-or-maybe-in-bracelist containing-sexp)) + (if (save-excursion + (goto-char paren-pos) + (c-looking-at-statement-block)) + (c-add-syntax 'defun-block-intro nil) + (c-add-syntax 'brace-list-intro nil))) (t (c-add-syntax 'defun-block-intro nil)))) (c-add-syntax 'statement-block-intro nil))) @@ -11001,7 +11040,10 @@ comment at the start of cc-engine.el for more info." (setq q (cdr (car p))) ; e.g. (nil 28) [from (arglist-cont-nonempty nil 28)] (while q (unless (car q) - (setcar q (point))) + (setcar q (if (or (cdr p) + (null fixed-anchor)) + (point) + fixed-anchor))) (setq q (cdr q))) (setq p (cdr p)))) ))) @@ -12354,7 +12396,8 @@ comment at the start of cc-engine.el for more info." (c-forward-syntactic-ws (c-point 'eol)) (c-looking-at-special-brace-list (point))))) (c-add-syntax 'brace-entry-open (point)) - (c-add-syntax 'brace-list-entry (point)) + (c-add-stmt-syntax 'brace-list-entry nil t containing-sexp + paren-state (point)) )) )))) @@ -12848,7 +12891,7 @@ Cannot combine absolute offsets %S and %S in `add' method" ;; ;; Note that topmost-intro always has an anchor position at bol, for ;; historical reasons. It's often used together with other symbols - ;; that has more sane positions. Since we always use the first + ;; that have more sane positions. Since we always use the first ;; found anchor position, we rely on that these other symbols always ;; precede topmost-intro in the LANGELEMS list. ;; diff --git a/lisp/progmodes/cc-styles.el b/lisp/progmodes/cc-styles.el index d3505490505..b3848a74f97 100644 --- a/lisp/progmodes/cc-styles.el +++ b/lisp/progmodes/cc-styles.el @@ -67,6 +67,7 @@ (arglist-close . c-lineup-arglist) (inline-open . 0) (brace-list-open . +) + (brace-list-intro . c-lineup-arglist-intro-after-paren) (topmost-intro-cont . (first c-lineup-topmost-intro-cont c-lineup-gnu-DEFUN-intro-cont)))) diff --git a/lisp/progmodes/cc-vars.el b/lisp/progmodes/cc-vars.el index a6a96d15188..1114b21381d 100644 --- a/lisp/progmodes/cc-vars.el +++ b/lisp/progmodes/cc-vars.el @@ -1115,7 +1115,7 @@ can always override the use of `c-default-style' by making calls to ;; Anchor pos: At the brace list decl start(*). (brace-list-intro . +) ;; Anchor pos: At the brace list decl start(*). - (brace-list-entry . 0) + (brace-list-entry . c-lineup-under-anchor) ;; Anchor pos: At the first non-ws char after the open paren if ;; the first token is on the same line, otherwise boi at that ;; token. diff --git a/lisp/progmodes/js.el b/lisp/progmodes/js.el index 74dd4add9e2..e42e01481b6 100644 --- a/lisp/progmodes/js.el +++ b/lisp/progmodes/js.el @@ -3849,6 +3849,7 @@ If one hasn't been set, or if it's stale, prompt for a new one." comment-start-skip "\\(//+\\|/\\*+\\)\\s *") (setq-local comment-line-break-function #'c-indent-new-comment-line) (setq-local c-block-comment-start-regexp "/\\*") + (setq-local comment-multi-line t) (setq-local electric-indent-chars (append "{}():;," electric-indent-chars)) ;FIXME: js2-mode adds "[]*". diff --git a/lisp/progmodes/xref.el b/lisp/progmodes/xref.el index a507755d42e..a8933b0103e 100644 --- a/lisp/progmodes/xref.el +++ b/lisp/progmodes/xref.el @@ -918,11 +918,7 @@ IGNORES is a list of glob patterns." (grep-compute-defaults) (defvar grep-find-template) (defvar grep-highlight-matches) - ;; 'grep -E -foo' results in 'grep: oo: No such file or directory'. - ;; while 'grep -e -foo' inexplicably doesn't. - (when (eq (aref regexp 0) ?-) - (setq regexp (concat "\\" regexp))) - (let* ((grep-find-template (replace-regexp-in-string "-e " "-E " + (let* ((grep-find-template (replace-regexp-in-string "<C>" "<C> -E" grep-find-template t t)) (grep-highlight-matches nil) (command (xref--rgrep-command (xref--regexp-to-extended regexp) diff --git a/lisp/replace.el b/lisp/replace.el index ff917344453..a825040a979 100644 --- a/lisp/replace.el +++ b/lisp/replace.el @@ -1304,6 +1304,19 @@ If the value is nil, don't highlight the buffer names specially." :type 'face :group 'matching) +(defcustom list-matching-lines-current-line-face 'lazy-highlight + "Face used by \\[list-matching-lines] to highlight the current line." + :type 'face + :group 'matching + :version "26.1") + +(defcustom list-matching-lines-jump-to-current-line nil + "If non-nil, \\[list-matching-lines] shows the current line highlighted. +Set the point right after such line when there are matches after it." +:type 'boolean +:group 'matching +:version "26.1") + (defcustom list-matching-lines-prefix-face 'shadow "Face used by \\[list-matching-lines] to show the prefix column. If the face doesn't differ from the default face, @@ -1360,7 +1373,15 @@ invoke `occur'." "*") (or unique-p (not interactive-p))))) -(defun occur (regexp &optional nlines) +;; Region limits when `occur' applies on a region. +(defvar occur--region-start nil) +(defvar occur--region-end nil) +(defvar occur--matches-threshold nil) +(defvar occur--orig-line nil) +(defvar occur--orig-line-str nil) +(defvar occur--final-pos nil) + +(defun occur (regexp &optional nlines region) "Show all lines in the current buffer containing a match for REGEXP. If a match spreads across multiple lines, all those lines are shown. @@ -1369,9 +1390,17 @@ before if NLINES is negative. NLINES defaults to `list-matching-lines-default-context-lines'. Interactively it is the prefix arg. +Optional arg REGION, if non-nil, mean restrict search to the +specified region. Otherwise search the entire buffer. +REGION must be a list of (START . END) positions as returned by +`region-bounds'. + The lines are shown in a buffer named `*Occur*'. It serves as a menu to find any of the occurrences in this buffer. \\<occur-mode-map>\\[describe-mode] in that buffer will explain how. +If `list-matching-lines-jump-to-current-line' is non-nil, then show +the current line highlighted with `list-matching-lines-current-line-face' +and set point at the first match after such line. If REGEXP contains upper case characters (excluding those preceded by `\\') and `search-upper-case' is non-nil, the matching is case-sensitive. @@ -1386,8 +1415,30 @@ For example, providing \"defun\\s +\\(\\S +\\)\" for REGEXP and program. When there is no parenthesized subexpressions in REGEXP the entire match is collected. In any case the searched buffer is not modified." - (interactive (occur-read-primary-args)) - (occur-1 regexp nlines (list (current-buffer)))) + (interactive + (nconc (occur-read-primary-args) + (and (use-region-p) (list (region-bounds))))) + (let* ((start (and (caar region) (max (caar region) (point-min)))) + (end (and (cdar region) (min (cdar region) (point-max)))) + (in-region-p (or start end))) + (when in-region-p + (or start (setq start (point-min))) + (or end (setq end (point-max)))) + (let ((occur--region-start start) + (occur--region-end end) + (occur--matches-threshold + (and in-region-p + (line-number-at-pos (min start end)))) + (occur--orig-line + (line-number-at-pos (point))) + (occur--orig-line-str + (buffer-substring-no-properties + (line-beginning-position) + (line-end-position)))) + (save-excursion ; If no matches `occur-1' doesn't restore the point. + (and in-region-p (narrow-to-region start end)) + (occur-1 regexp nlines (list (current-buffer))) + (and in-region-p (widen)))))) (defvar ido-ignore-item-temp-list) @@ -1482,7 +1533,8 @@ See also `multi-occur'." (occur-mode)) (let ((inhibit-read-only t) ;; Don't generate undo entries for creation of the initial contents. - (buffer-undo-list t)) + (buffer-undo-list t) + (occur--final-pos nil)) (erase-buffer) (let ((count (if (stringp nlines) @@ -1534,6 +1586,10 @@ See also `multi-occur'." (if (= count 0) (kill-buffer occur-buf) (display-buffer occur-buf) + (when occur--final-pos + (set-window-point + (get-buffer-window occur-buf 'all-frames) + occur--final-pos)) (setq next-error-last-buffer occur-buf) (setq buffer-read-only t) (set-buffer-modified-p nil) @@ -1545,19 +1601,26 @@ See also `multi-occur'." (let ((global-lines 0) ;; total count of matching lines (global-matches 0) ;; total count of matches (coding nil) - (case-fold-search case-fold)) + (case-fold-search case-fold) + (in-region-p (and occur--region-start occur--region-end)) + (multi-occur-p (cdr buffers))) ;; Map over all the buffers (dolist (buf buffers) (when (buffer-live-p buf) (let ((lines 0) ;; count of matching lines (matches 0) ;; count of matches - (curr-line 1) ;; line count + (curr-line ;; line count + (or occur--matches-threshold 1)) + (orig-line occur--orig-line) + (orig-line-str occur--orig-line-str) + (orig-line-shown-p) (prev-line nil) ;; line number of prev match endpt (prev-after-lines nil) ;; context lines of prev match (matchbeg 0) (origpt nil) (begpt nil) (endpt nil) + (finalpt nil) (marker nil) (curstring "") (ret nil) @@ -1658,6 +1721,18 @@ See also `multi-occur'." (nth 0 ret)))) ;; Actually insert the match display data (with-current-buffer out-buf + (when (and list-matching-lines-jump-to-current-line + (not multi-occur-p) + (not orig-line-shown-p) + (>= curr-line orig-line)) + (insert + (concat + (propertize + (format "%7d:%s" orig-line orig-line-str) + 'face list-matching-lines-current-line-face + 'mouse-face 'mode-line-highlight + 'help-echo "Current line") "\n")) + (setq orig-line-shown-p t finalpt (point))) (insert data))) (goto-char endpt)) (if endpt @@ -1671,6 +1746,18 @@ See also `multi-occur'." (forward-line 1)) (goto-char (point-max))) (setq prev-line (1- curr-line))) + ;; Insert original line if haven't done yet. + (when (and list-matching-lines-jump-to-current-line + (not multi-occur-p) + (not orig-line-shown-p)) + (with-current-buffer out-buf + (insert + (concat + (propertize + (format "%7d:%s" orig-line orig-line-str) + 'face list-matching-lines-current-line-face + 'mouse-face 'mode-line-highlight + 'help-echo "Current line") "\n")))) ;; Flush remaining context after-lines. (when prev-after-lines (with-current-buffer out-buf @@ -1684,7 +1771,7 @@ See also `multi-occur'." (let ((beg (point)) end) (insert (propertize - (format "%d match%s%s%s in buffer: %s\n" + (format "%d match%s%s%s in buffer: %s%s\n" matches (if (= matches 1) "" "es") ;; Don't display the same number of lines ;; and matches in case of 1 match per line. @@ -1694,13 +1781,21 @@ See also `multi-occur'." ;; Don't display regexp for multi-buffer. (if (> (length buffers) 1) "" (occur-regexp-descr regexp)) - (buffer-name buf)) + (buffer-name buf) + (if in-region-p + (format " within region: %d-%d" + occur--region-start + occur--region-end) + "")) 'read-only t)) (setq end (point)) (add-text-properties beg end `(occur-title ,buf)) (when title-face - (add-face-text-property beg end title-face))) - (goto-char (point-min))))))) + (add-face-text-property beg end title-face)) + (goto-char (if finalpt + (setq occur--final-pos + (cl-incf finalpt (- end beg))) + (point-min))))))))) ;; Display total match count and regexp for multi-buffer. (when (and (not (zerop global-lines)) (> (length buffers) 1)) (goto-char (point-min)) diff --git a/lisp/subr.el b/lisp/subr.el index a6ba05c2021..a204577ddf9 100644 --- a/lisp/subr.el +++ b/lisp/subr.el @@ -1417,8 +1417,10 @@ be a list of the form returned by `event-start' and `event-end'." ;; bug#23850 (make-obsolete 'string-to-unibyte "use `encode-coding-string'." "26.1") (make-obsolete 'string-as-unibyte "use `encode-coding-string'." "26.1") +(make-obsolete 'string-make-unibyte "use `encode-coding-string'." "26.1") (make-obsolete 'string-to-multibyte "use `decode-coding-string'." "26.1") (make-obsolete 'string-as-multibyte "use `decode-coding-string'." "26.1") +(make-obsolete 'string-make-multibyte "use `decode-coding-string'." "26.1") (defun log10 (x) "Return (log X 10), the log base 10 of X." diff --git a/lisp/textmodes/css-mode.el b/lisp/textmodes/css-mode.el index c81c3f62e16..0c7d76f7924 100644 --- a/lisp/textmodes/css-mode.el +++ b/lisp/textmodes/css-mode.el @@ -32,9 +32,11 @@ ;;; Code: +(require 'eww) (require 'seq) (require 'sgml-mode) (require 'smie) +(require 'subr-x) (defgroup css nil "Cascading Style Sheets (CSS) editing mode." @@ -621,6 +623,12 @@ cannot be completed sensibly: `custom-ident', (modify-syntax-entry ?- "_" st) st)) +(defvar css-mode-map + (let ((map (make-sparse-keymap))) + (define-key map [remap info-lookup-symbol] 'css-lookup-symbol) + map) + "Keymap used in `css-mode'.") + (eval-and-compile (defconst css--uri-re (concat @@ -734,7 +742,30 @@ cannot be completed sensibly: `custom-ident', (defconst css-smie-grammar (smie-prec2->grammar - (smie-precs->prec2 '((assoc ";") (assoc ",") (left ":"))))) + (smie-precs->prec2 + '((assoc ";") + ;; Colons that belong to a CSS property. These get a higher + ;; precedence than other colons, such as colons in selectors, + ;; which are represented by a plain ":" token. + (left ":-property") + (assoc ",") + (assoc ":"))))) + +(defun css--colon-inside-selector-p () + "Return t if point looks to be inside a CSS selector. +This function is intended to be good enough to help SMIE during +tokenization, but should not be regarded as a reliable function +for determining whether point is within a selector." + (save-excursion + (re-search-forward "[{};)]" nil t) + (eq (char-before) ?\{))) + +(defun css--colon-inside-funcall () + "Return t if point is inside a function call." + (when-let (opening-paren-pos (nth 1 (syntax-ppss))) + (save-excursion + (goto-char opening-paren-pos) + (eq (char-after) ?\()))) (defun css-smie--forward-token () (cond @@ -748,7 +779,13 @@ cannot be completed sensibly: `custom-ident', ";") ((progn (forward-comment (point-max)) (looking-at "[;,:]")) - (forward-char 1) (match-string 0)) + (forward-char 1) + (if (equal (match-string 0) ":") + (if (or (css--colon-inside-selector-p) + (css--colon-inside-funcall)) + ":" + ":-property") + (match-string 0))) (t (smie-default-forward-token)))) (defun css-smie--backward-token () @@ -759,7 +796,13 @@ cannot be completed sensibly: `custom-ident', ((and (eq (char-before) ?\}) (scss-smie--not-interpolation-p) (> pos (point))) ";") ((memq (char-before) '(?\; ?\, ?\:)) - (forward-char -1) (string (char-after))) + (forward-char -1) + (if (eq (char-after) ?\:) + (if (or (css--colon-inside-selector-p) + (css--colon-inside-funcall)) + ":" + ":-property") + (string (char-after)))) (t (smie-default-backward-token))))) (defun css-smie-rules (kind token) @@ -1087,5 +1130,112 @@ pseudo-elements, pseudo-classes, at-rules, and bang-rules." (setq-local font-lock-defaults (list (scss-font-lock-keywords) nil t))) + + +(defvar css--mdn-lookup-history nil) + +(defcustom css-lookup-url-format + "https://developer.mozilla.org/en-US/docs/Web/CSS/%s?raw¯os" + "Format for a URL where CSS documentation can be found. +The format should include a single \"%s\" substitution. +The name of the CSS property, @-id, pseudo-class, or pseudo-element +to look up will be substituted there." + :version "26.1" + :type 'string + :group 'css) + +(defun css--mdn-after-render () + (setf header-line-format nil) + (goto-char (point-min)) + (let ((window (get-buffer-window (current-buffer) 'visible))) + (when window + (when (re-search-forward "^Summary" nil 'move) + (beginning-of-line) + (set-window-start window (point)))))) + +(defconst css--mdn-symbol-regexp + (concat "\\(" + ;; @-ids. + "\\(@" (regexp-opt css-at-ids) "\\)" + "\\|" + ;; ;; Known properties. + (regexp-opt css-property-ids t) + "\\|" + ;; Pseudo-classes. + "\\(:" (regexp-opt css-pseudo-class-ids) "\\)" + "\\|" + ;; Pseudo-elements with either one or two ":"s. + "\\(::?" (regexp-opt css-pseudo-element-ids) "\\)" + "\\)") + "Regular expression to match the CSS symbol at point.") + +(defconst css--mdn-property-regexp + (concat "\\_<" (regexp-opt css-property-ids t) "\\s-*\\(?:\\=\\|:\\)") + "Regular expression to match a CSS property.") + +(defconst css--mdn-completion-list + (nconc + ;; @-ids. + (mapcar (lambda (atrule) (concat "@" atrule)) css-at-ids) + ;; Pseudo-classes. + (mapcar (lambda (class) (concat ":" class)) css-pseudo-class-ids) + ;; Pseudo-elements with either one or two ":"s. + (mapcar (lambda (elt) (concat ":" elt)) css-pseudo-element-ids) + (mapcar (lambda (elt) (concat "::" elt)) css-pseudo-element-ids) + ;; Properties. + css-property-ids) + "List of all symbols available for lookup via MDN.") + +(defun css--mdn-find-symbol () + "A helper for `css-lookup-symbol' that finds the symbol at point. +Returns the symbol, a string, or nil if none found." + (save-excursion + ;; Skip backward over a word first. + (skip-chars-backward "-[:alnum:] \t") + ;; Now skip ":" or "@" to see if it's a pseudo-element or at-id. + (skip-chars-backward "@:") + (if (looking-at css--mdn-symbol-regexp) + (match-string-no-properties 0) + (let ((bound (save-excursion + (beginning-of-line) + (point)))) + (when (re-search-backward css--mdn-property-regexp bound t) + (match-string-no-properties 1)))))) + +;;;###autoload +(defun css-lookup-symbol (symbol) + "Display the CSS documentation for SYMBOL, as found on MDN. +When this command is used interactively, it picks a default +symbol based on the CSS text before point -- either an @-keyword, +a property name, a pseudo-class, or a pseudo-element, depending +on what is seen near point." + (interactive + (list + (let* ((sym (css--mdn-find-symbol)) + (enable-recursive-minibuffers t) + (value (completing-read + (if sym + (format "Describe CSS symbol (default %s): " sym) + "Describe CSS symbol: ") + css--mdn-completion-list nil nil nil + 'css--mdn-lookup-history sym))) + (if (equal value "") sym value)))) + (when symbol + ;; If we see a single-colon pseudo-element like ":after", turn it + ;; into "::after". + (when (and (eq (aref symbol 0) ?:) + (member (substring symbol 1) css-pseudo-element-ids)) + (setq symbol (concat ":" symbol))) + (let ((url (format css-lookup-url-format symbol)) + (buffer (get-buffer-create "*MDN CSS*"))) + (save-selected-window + ;; Make sure to display the buffer before calling `eww', as + ;; that calls `pop-to-buffer-same-window'. + (switch-to-buffer-other-window buffer) + (with-current-buffer buffer + (eww-mode) + (add-hook 'eww-after-render-hook #'css--mdn-after-render nil t) + (eww url)))))) + (provide 'css-mode) ;;; css-mode.el ends here diff --git a/lisp/vc/diff-mode.el b/lisp/vc/diff-mode.el index e609ca9f943..31c33e6a720 100644 --- a/lisp/vc/diff-mode.el +++ b/lisp/vc/diff-mode.el @@ -437,6 +437,9 @@ See http://lists.gnu.org/archive/html/emacs-devel/2007-11/msg01990.html") (defconst diff-hunk-header-re (concat "^\\(?:" diff-hunk-header-re-unified ".*\\|\\*\\{15\\}.*\n\\*\\*\\* .+ \\*\\*\\*\\*\\|[0-9]+\\(,[0-9]+\\)?[acd][0-9]+\\(,[0-9]+\\)?\\)$")) (defconst diff-file-header-re (concat "^\\(--- .+\n\\+\\+\\+ \\|\\*\\*\\* .+\n--- \\|[^-+!<>0-9@* \n]\\).+\n" (substring diff-hunk-header-re 1))) + +(defconst diff-separator-re "^--+ ?$") + (defvar diff-narrowed-to nil) (defun diff-hunk-style (&optional style) @@ -647,28 +650,36 @@ If the prefix ARG is given, restrict the view to the current file instead." (if arg (diff-bounds-of-file) (diff-bounds-of-hunk))) (set (make-local-variable 'diff-narrowed-to) (if arg 'file 'hunk))) +(defun diff--some-hunks-p () + (save-excursion + (goto-char (point-min)) + (re-search-forward diff-hunk-header-re nil t))) + (defun diff-hunk-kill () "Kill the hunk at point." (interactive) - (let* ((hunk-bounds (diff-bounds-of-hunk)) - (file-bounds (ignore-errors (diff-bounds-of-file))) - ;; If the current hunk is the only one for its file, kill the - ;; file header too. - (bounds (if (and file-bounds - (progn (goto-char (car file-bounds)) - (= (progn (diff-hunk-next) (point)) - (car hunk-bounds))) - (progn (goto-char (cadr hunk-bounds)) - ;; bzr puts a newline after the last hunk. - (while (looking-at "^\n") - (forward-char 1)) - (= (point) (cadr file-bounds)))) - file-bounds - hunk-bounds)) - (inhibit-read-only t)) - (apply 'kill-region bounds) - (goto-char (car bounds)) - (diff-beginning-of-hunk t))) + (if (not (diff--some-hunks-p)) + (error "No hunks") + (diff-beginning-of-hunk t) + (let* ((hunk-bounds (diff-bounds-of-hunk)) + (file-bounds (ignore-errors (diff-bounds-of-file))) + ;; If the current hunk is the only one for its file, kill the + ;; file header too. + (bounds (if (and file-bounds + (progn (goto-char (car file-bounds)) + (= (progn (diff-hunk-next) (point)) + (car hunk-bounds))) + (progn (goto-char (cadr hunk-bounds)) + ;; bzr puts a newline after the last hunk. + (while (looking-at "^\n") + (forward-char 1)) + (= (point) (cadr file-bounds)))) + file-bounds + hunk-bounds)) + (inhibit-read-only t)) + (apply 'kill-region bounds) + (goto-char (car bounds)) + (ignore-errors (diff-beginning-of-hunk t))))) (defun diff-beginning-of-file-and-junk () "Go to the beginning of file-related diff-info. @@ -720,9 +731,12 @@ data such as \"Index: ...\" and such." (defun diff-file-kill () "Kill current file's hunks." (interactive) - (let ((inhibit-read-only t)) - (apply 'kill-region (diff-bounds-of-file))) - (diff-beginning-of-hunk t)) + (if (not (diff--some-hunks-p)) + (error "No hunks") + (diff-beginning-of-hunk t) + (let ((inhibit-read-only t)) + (apply 'kill-region (diff-bounds-of-file))) + (ignore-errors (diff-beginning-of-hunk t)))) (defun diff-kill-junk () "Kill spurious empty diffs." @@ -1537,15 +1551,20 @@ Only works for unified diffs." (pcase (char-after) (?\s (cl-decf before) (cl-decf after) t) (?- - (if (and (looking-at diff-file-header-re) - (zerop before) (zerop after)) - ;; No need to query: this is a case where two patches - ;; are concatenated and only counting the lines will - ;; give the right result. Let's just add an empty - ;; line so that our code which doesn't count lines - ;; will not get confused. - (progn (save-excursion (insert "\n")) nil) - (cl-decf before) t)) + (cond + ((and (looking-at diff-separator-re) + (zerop before) (zerop after)) + nil) + ((and (looking-at diff-file-header-re) + (zerop before) (zerop after)) + ;; No need to query: this is a case where two patches + ;; are concatenated and only counting the lines will + ;; give the right result. Let's just add an empty + ;; line so that our code which doesn't count lines + ;; will not get confused. + (save-excursion (insert "\n")) nil) + (t + (cl-decf before) t))) (?+ (cl-decf after) t) (_ (cond @@ -2000,57 +2019,58 @@ Return new point, if it was moved." "Highlight changes of hunk at point at a finer granularity." (interactive) (require 'smerge-mode) - (save-excursion - (diff-beginning-of-hunk t) - (let* ((start (point)) - (style (diff-hunk-style)) ;Skips the hunk header as well. - (beg (point)) - (props-c '((diff-mode . fine) (face diff-refine-changed))) - (props-r '((diff-mode . fine) (face diff-refine-removed))) - (props-a '((diff-mode . fine) (face diff-refine-added))) - ;; Be careful to go back to `start' so diff-end-of-hunk gets - ;; to read the hunk header's line info. - (end (progn (goto-char start) (diff-end-of-hunk) (point)))) - - (remove-overlays beg end 'diff-mode 'fine) - - (goto-char beg) - (pcase style - (`unified - (while (re-search-forward "^-" end t) - (let ((beg-del (progn (beginning-of-line) (point))) - beg-add end-add) - (when (and (diff--forward-while-leading-char ?- end) - ;; Allow for "\ No newline at end of file". - (progn (diff--forward-while-leading-char ?\\ end) - (setq beg-add (point))) - (diff--forward-while-leading-char ?+ end) - (progn (diff--forward-while-leading-char ?\\ end) - (setq end-add (point)))) - (smerge-refine-subst beg-del beg-add beg-add end-add - nil 'diff-refine-preproc props-r props-a))))) - (`context - (let* ((middle (save-excursion (re-search-forward "^---"))) - (other middle)) - (while (re-search-forward "^\\(?:!.*\n\\)+" middle t) - (smerge-refine-subst (match-beginning 0) (match-end 0) - (save-excursion - (goto-char other) - (re-search-forward "^\\(?:!.*\n\\)+" end) - (setq other (match-end 0)) - (match-beginning 0)) - other - (if diff-use-changed-face props-c) - 'diff-refine-preproc - (unless diff-use-changed-face props-r) - (unless diff-use-changed-face props-a))))) - (_ ;; Normal diffs. - (let ((beg1 (1+ (point)))) - (when (re-search-forward "^---.*\n" end t) - ;; It's a combined add&remove, so there's something to do. - (smerge-refine-subst beg1 (match-beginning 0) - (match-end 0) end - nil 'diff-refine-preproc props-r props-a)))))))) + (when (diff--some-hunks-p) + (save-excursion + (diff-beginning-of-hunk t) + (let* ((start (point)) + (style (diff-hunk-style)) ;Skips the hunk header as well. + (beg (point)) + (props-c '((diff-mode . fine) (face diff-refine-changed))) + (props-r '((diff-mode . fine) (face diff-refine-removed))) + (props-a '((diff-mode . fine) (face diff-refine-added))) + ;; Be careful to go back to `start' so diff-end-of-hunk gets + ;; to read the hunk header's line info. + (end (progn (goto-char start) (diff-end-of-hunk) (point)))) + + (remove-overlays beg end 'diff-mode 'fine) + + (goto-char beg) + (pcase style + (`unified + (while (re-search-forward "^-" end t) + (let ((beg-del (progn (beginning-of-line) (point))) + beg-add end-add) + (when (and (diff--forward-while-leading-char ?- end) + ;; Allow for "\ No newline at end of file". + (progn (diff--forward-while-leading-char ?\\ end) + (setq beg-add (point))) + (diff--forward-while-leading-char ?+ end) + (progn (diff--forward-while-leading-char ?\\ end) + (setq end-add (point)))) + (smerge-refine-subst beg-del beg-add beg-add end-add + nil 'diff-refine-preproc props-r props-a))))) + (`context + (let* ((middle (save-excursion (re-search-forward "^---"))) + (other middle)) + (while (re-search-forward "^\\(?:!.*\n\\)+" middle t) + (smerge-refine-subst (match-beginning 0) (match-end 0) + (save-excursion + (goto-char other) + (re-search-forward "^\\(?:!.*\n\\)+" end) + (setq other (match-end 0)) + (match-beginning 0)) + other + (if diff-use-changed-face props-c) + 'diff-refine-preproc + (unless diff-use-changed-face props-r) + (unless diff-use-changed-face props-a))))) + (_ ;; Normal diffs. + (let ((beg1 (1+ (point)))) + (when (re-search-forward "^---.*\n" end t) + ;; It's a combined add&remove, so there's something to do. + (smerge-refine-subst beg1 (match-beginning 0) + (match-end 0) end + nil 'diff-refine-preproc props-r props-a))))))))) (defun diff-undo (&optional arg) "Perform `undo', ignoring the buffer's read-only status." |