commit 741c02d59407a9da2a1b28a69abe83b70f37b914 (HEAD, refs/remotes/origin/master) Author: Michael Albinus Date: Wed Jan 23 08:53:24 2019 +0100 ; Further tramp-tests instrumentation diff --git a/test/lisp/net/tramp-tests.el b/test/lisp/net/tramp-tests.el index 7612fcdddf..9deb794f40 100644 --- a/test/lisp/net/tramp-tests.el +++ b/test/lisp/net/tramp-tests.el @@ -2278,10 +2278,10 @@ This checks also `file-name-as-directory', `file-name-directory', (with-temp-buffer (insert-file-contents target) (should (string-equal (buffer-string) "foo"))) - (when (tramp--test-expensive-test) - (should-error - (copy-file source target) - :type 'file-already-exists)) + ;; (when (tramp--test-expensive-test) + ;; (should-error + ;; (copy-file source target) + ;; :type 'file-already-exists)) (copy-file source target 'ok)) ;; Cleanup. @@ -2297,11 +2297,11 @@ This checks also `file-name-as-directory', `file-name-directory', (should (file-exists-p source)) (make-directory target) (should (file-directory-p target)) - ;; This has been changed in Emacs 26.1. - (when (and (tramp--test-expensive-test) (tramp--test-emacs26-p)) - (should-error - (copy-file source target) - :type 'file-already-exists)) + ;; ;; This has been changed in Emacs 26.1. + ;; (when (and (tramp--test-expensive-test) (tramp--test-emacs26-p)) + ;; (should-error + ;; (copy-file source target) + ;; :type 'file-already-exists)) (copy-file source (file-name-as-directory target)) (should (file-exists-p commit ec9f42bc5ca8466c208155628649f78fe95e52ed Author: Michael Albinus Date: Wed Jan 23 00:01:26 2019 +0100 ; Instrument tramp-tests diff --git a/test/lisp/net/tramp-tests.el b/test/lisp/net/tramp-tests.el index d4db4e9f64..7612fcdddf 100644 --- a/test/lisp/net/tramp-tests.el +++ b/test/lisp/net/tramp-tests.el @@ -2251,6 +2251,7 @@ This checks also `file-name-as-directory', `file-name-directory', "Check `copy-file'." (skip-unless (tramp--test-enabled)) + (tramp--test-instrument-test-case (if (getenv "EMACS_EMBA_CI") 10 0) ;; `filename-non-special' has been fixed in Emacs 27.1, see Bug#29579. (dolist (quoted (if (and (tramp--test-expensive-test) (tramp--test-emacs27-p)) '(nil t) '(nil))) @@ -2357,7 +2358,7 @@ This checks also `file-name-as-directory', `file-name-directory', ;; Cleanup. (ignore-errors (delete-directory source 'recursive)) - (ignore-errors (delete-directory target 'recursive)))))))) + (ignore-errors (delete-directory target 'recursive))))))))) (ert-deftest tramp-test12-rename-file () "Check `rename-file'." commit dde33727b2ace3ce417d97475d074f0a82b7c2b8 Author: Stefan Monnier Date: Tue Jan 22 17:54:29 2019 -0500 * lisp/emacs-lisp/package.el (package--alist): New (package-activate-all): Use it so we only initialize the local part of package.el (this reduces the impact of bug#24467 and speeds up startup). (package-installed-p): Use it so it works even if package is not fully initialized. (package-delete): Use it so we only initialize the local part of package.el. diff --git a/lisp/emacs-lisp/package.el b/lisp/emacs-lisp/package.el index 9a7b54fa01..025a1afbdb 100644 --- a/lisp/emacs-lisp/package.el +++ b/lisp/emacs-lisp/package.el @@ -487,7 +487,7 @@ This is, approximately, the inverse of `version-to-list'. str-list)))) (if (equal "." (car str-list)) (pop str-list)) - (apply 'concat (nreverse str-list))))) + (apply #'concat (nreverse str-list))))) (defun package-desc-full-name (pkg-desc) (format "%s-%s" @@ -609,6 +609,12 @@ updates `package-alist'." (when (file-directory-p pkg-dir) (package-load-descriptor pkg-dir)))))))) +(defun package--alist () + "Return `package-alist', after computing it if needed." + (or package-alist + (progn (package-load-all-descriptors) + package-alist))) + (defun define-package (_name-string _version-string &optional _docstring _requirements &rest _extra-properties) @@ -837,7 +843,7 @@ untar into a directory named DIR; otherwise, signal an error." (tar-untar-buffer)) (defun package--alist-to-plist-args (alist) - (mapcar 'macroexp-quote + (mapcar #'macroexp-quote (apply #'nconc (mapcar (lambda (pair) (list (car pair) (cdr pair))) alist)))) (defun package-unpack (pkg-desc) @@ -1492,9 +1498,7 @@ The variable `package-load-list' controls which packages to load." ;; any decoding). (let ((load-source-file-function nil)) (load package-quickstart-file nil 'nomessage)) - (unless package--initialized - (package-initialize t)) - (dolist (elt package-alist) + (dolist (elt (package--alist)) (condition-case err (package-activate (car elt)) ;; Don't let failure of activation of a package arbitrarily stop @@ -1903,10 +1907,9 @@ If PACKAGE is a `package-desc' object, MIN-VERSION is ignored." ;; We used the quickstart: make it possible to use package-installed-p ;; even before package is fully initialized. (memq package package-activated-list)) - ((not package--initialized) (error "package.el is not yet initialized!")) (t (or - (let ((pkg-descs (cdr (assq package package-alist)))) + (let ((pkg-descs (cdr (assq package (package--alist))))) (and pkg-descs (version-list-<= min-version (package-desc-version (car pkg-descs))))) @@ -2079,16 +2082,12 @@ If NOSAVE is non-nil, the package is not removed from `package-selected-packages'." (interactive (progn - ;; Initialize the package system to get the list of package - ;; symbols for completion. - (unless package--initialized - (package-initialize t)) (let* ((package-table (mapcar (lambda (p) (cons (package-desc-full-name p) p)) (delq nil (mapcar (lambda (p) (unless (package-built-in-p p) p)) - (apply #'append (mapcar #'cdr package-alist)))))) + (apply #'append (mapcar #'cdr (package--alist))))))) (package-name (completing-read "Delete package: " (mapcar #'car package-table) nil t))) @@ -2196,12 +2195,12 @@ will be deleted." ;; Load the package list if necessary (but don't activate them). (unless package--initialized (package-initialize t)) - (let ((packages (append (mapcar 'car package-alist) - (mapcar 'car package-archive-contents) - (mapcar 'car package--builtins)))) + (let ((packages (append (mapcar #'car package-alist) + (mapcar #'car package-archive-contents) + (mapcar #'car package--builtins)))) (unless (memq guess packages) (setq guess nil)) - (setq packages (mapcar 'symbol-name packages)) + (setq packages (mapcar #'symbol-name packages)) (let ((val (completing-read (if guess (format "Describe package (default %s): " @@ -2507,7 +2506,7 @@ The description is read from the installed package files." :background "light grey" :foreground "black") 'link))) - (apply 'insert-text-button button-text 'face button-face 'follow-link t + (apply #'insert-text-button button-text 'face button-face 'follow-link t props))) @@ -2588,7 +2587,7 @@ Letters do not insert themselves; instead, they are commands. ("Description" 0 nil)]) (setq tabulated-list-padding 2) (setq tabulated-list-sort-key (cons "Status" nil)) - (add-hook 'tabulated-list-revert-hook 'package-menu--refresh nil t) + (add-hook 'tabulated-list-revert-hook #'package-menu--refresh nil t) (tabulated-list-init-header)) (defmacro package--push (pkg-desc status listname) @@ -2859,7 +2858,7 @@ shown." (package-menu--refresh packages keywords) (setf (car (aref tabulated-list-format 0)) (if keywords - (let ((filters (mapconcat 'identity keywords ","))) + (let ((filters (mapconcat #'identity keywords ","))) (concat "Package[" filters "]")) "Package")) (if keywords commit 7b31de4d107302ed91ce7519cd778b340a9880ee Author: Phillip Lord Date: Sat Jan 5 20:31:15 2019 +0100 Add hook for all events * lisp/subr.el (input-event-functions): Add input-event-functions * src/keyboard.c (read_char): Call input-event-functions on all hooks diff --git a/etc/NEWS b/etc/NEWS index 21187474a2..b0bbaeb6b0 100644 --- a/etc/NEWS +++ b/etc/NEWS @@ -1189,11 +1189,13 @@ removed. * Lisp Changes in Emacs 27.1 -+++ + ** 'self-insert-command' takes the char to insert as (optional) argument. ** 'lookup-key' can take a list of keymaps as argument. +** New hook `input-event-functions` run whenever a user-input is read. + +++ ** 'condition-case' now accepts 't' to match any error symbol. diff --git a/lisp/subr.el b/lisp/subr.el index 2f2ea5e6c7..122a0d8da4 100644 --- a/lisp/subr.el +++ b/lisp/subr.el @@ -1289,6 +1289,12 @@ See `event-start' for a description of the value returned." The return value is a positive integer." (if (and (consp event) (integerp (nth 2 event))) (nth 2 event) 1)) +(defvar input-event-functions nil + ;; BEWARE: If it looks like this is not run anywhere, it's normal: + ;; this is run in keyboard.c. + "Special hook run each time a user-input event is read. +Each function is called with one argument: the event.") + (defsubst event-line-count (event) "Return the line count of EVENT, a mousewheel event. The return value is a positive integer." diff --git a/src/keyboard.c b/src/keyboard.c index 2d6fa91a16..838dc242dd 100644 --- a/src/keyboard.c +++ b/src/keyboard.c @@ -2919,6 +2919,8 @@ read_char (int commandflag, Lisp_Object map, if (! NILP (also_record)) record_char (also_record); + Frun_hook_with_args (2, ((Lisp_Object []) {Qinput_event_functions, c})); + /* Wipe the echo area. But first, if we are about to use an input method, save the echo area contents for it to refer to. */ @@ -11022,6 +11024,8 @@ syms_of_keyboard (void) DEFSYM (Qundefined, "undefined"); + DEFSYM (Qinput_event_functions, "input-event-functions"); + /* Hooks to run before and after each command. */ DEFSYM (Qpre_command_hook, "pre-command-hook"); DEFSYM (Qpost_command_hook, "post-command-hook"); commit fd943124439b7644392919bca8bc2a77e6316d92 Author: João Távora Date: Tue Jan 22 15:46:56 2019 +0000 electric-layout-mode kicks in before electric-pair-mode This aims to solve problems with indentation. Previously in, say, a js-mode buffer with electric-layout-rules set to (?\{ before after) (?\} before) would produce an intended: function () { } The initial state function () { Would go immediately to the following by e-p-m function () {} Only then would e-l-m be applied to } first, and then again to {. This makes lines indent in the wrong order, which can be a problem in some modes. The way we fix this is by reversing the order of e-p-m and e-l-m in the post-self-insert-hook (and also fixing a number of details that this uncovered). In the end this changes the sequence from function () { By way of e-l-m becomes: function () { The e-p-m inserts the pair function () { } And then e-l-m kicks in for the pair again, yielding the desired result function () { } * lisp/elec-pair.el (electric-pair--insert): Bind electric-layout-no-duplicate-newlines. (electric-pair-inhibit-if-helps-balance) (electric-pair-skip-if-helps-balance): Use insert-before-markers, playing nice with save-excurion. (electric-pair-post-self-insert-function): Go to correct position before checking electric-pair-inhibit-predicate and electric-pair-skip-self predicate. (electric-pair-post-self-insert-function): Increase priority to 50. * lisp/electric.el (electric-indent-post-self-insert-function): Delete trailing space in reindented line only if line was really reindented. Rewrite comment. (electric-layout-allow-duplicate-newlines): New variable. (electric-layout-post-self-insert-function-1): Rewrite comments. Honours electric-layout-allow-duplicate-newlines. Don't reindent previous line because racecar. * test/lisp/electric-tests.el: New test. (plainer-c-mode): Move up. (electric-modes-int-main-allman-style) (electric-layout-int-main-kernel-style): Simplify electric-layout-rules. (electric-layout-for-c-style-du-jour): New helper. (electric-layout-plainer-c-mode-use-c-style): New test. diff --git a/lisp/elec-pair.el b/lisp/elec-pair.el index 2c5553e8da..20581ad657 100644 --- a/lisp/elec-pair.el +++ b/lisp/elec-pair.el @@ -227,7 +227,8 @@ inside a comment or string." (defun electric-pair--insert (char) (let ((last-command-event char) (blink-matching-paren nil) - (electric-pair-mode nil)) + (electric-pair-mode nil) + (electric-layout-allow-duplicate-newlines t)) (self-insert-command 1))) (cl-defmacro electric-pair--with-uncached-syntax ((table &optional start) &rest body) @@ -426,11 +427,10 @@ happened." (eq (cdr outermost) pair))))) ((eq syntax ?\") (electric-pair--unbalanced-strings-p char)))) - (insert-char char))))) + (insert-before-markers char))))) (defun electric-pair-skip-if-helps-balance (char) "Return non-nil if skipping CHAR would benefit parentheses' balance. - Works by first removing the character from the buffer, then doing some list calculations, finally restoring the situation as if nothing happened." @@ -452,7 +452,7 @@ happened." (not (eq (cdr outermost) pair))))))) ((eq syntax ?\") (electric-pair--inside-string-p char)))) - (insert-char char))))) + (insert-before-markers char))))) (defun electric-pair-default-skip-self (char) (if electric-pair-preserve-balance @@ -498,7 +498,9 @@ happened." ((and (memq syntax '(?\) ?\" ?\$)) (and (or unconditional (if (functionp electric-pair-skip-self) - (funcall electric-pair-skip-self last-command-event) + (save-excursion + (goto-char pos) + (funcall electric-pair-skip-self last-command-event)) electric-pair-skip-self)) (save-excursion (when (and (not (and unconditional @@ -525,8 +527,10 @@ happened." ((and (memq syntax '(?\( ?\" ?\$)) (not overwrite-mode) (or unconditional - (not (funcall electric-pair-inhibit-predicate - last-command-event)))) + (not (save-excursion + (goto-char pos) + (funcall electric-pair-inhibit-predicate + last-command-event))))) (save-excursion (electric-pair--insert pair))))) (_ (when (and (if (functionp electric-pair-open-newline-between-pairs) @@ -540,7 +544,7 @@ happened." (matching-paren (char-after)))) (save-excursion (newline 1 t))))))) -(put 'electric-pair-post-self-insert-function 'priority 20) +(put 'electric-pair-post-self-insert-function 'priority 50) (defun electric-pair-will-use-region () (and (use-region-p) diff --git a/lisp/electric.el b/lisp/electric.el index ed968d7c65..b9458776e3 100644 --- a/lisp/electric.el +++ b/lisp/electric.el @@ -270,28 +270,29 @@ or comment." ;; hence copied). (let ((at-newline (<= pos (line-beginning-position)))) (when at-newline - (let ((before (copy-marker (1- pos) t))) + (let ((before (copy-marker (1- pos) t)) + inhibit-reindentation) (save-excursion - (unless (or (memq indent-line-function - electric-indent-functions-without-reindent) - electric-indent-inhibit) + (unless + (setq inhibit-reindentation + (or (memq indent-line-function + electric-indent-functions-without-reindent) + electric-indent-inhibit)) ;; Don't reindent the previous line if the ;; indentation function is not a real one. (goto-char before) (condition-case-unless-debug () (indent-according-to-mode) - (error (throw 'indent-error nil)))) - ;; We are at EOL before the call to - ;; `indent-according-to-mode', and after it we usually - ;; are as well, but not always. We tried to address - ;; it with `save-excursion' but that uses a normal - ;; marker whereas we need `move after insertion', so - ;; we do the save/restore by hand. - (goto-char before) - (when (eolp) - ;; Remove the trailing whitespace after indentation because - ;; indentation may (re)introduce the whitespace. - (delete-horizontal-space t))))) + (error (throw 'indent-error nil))) + ;; The goal here will be to remove the trailing + ;; whitespace after reindentation of the previous line + ;; because that may have (re)introduced it. + (goto-char before) + ;; We were at EOL in marker `before' before the call + ;; to `indent-according-to-mode' but after we may + ;; not be (Bug#15767). + (when (and (eolp)) + (delete-horizontal-space t)))))) (unless (and electric-indent-inhibit (not at-newline)) (condition-case-unless-debug () @@ -388,6 +389,10 @@ WHERE if the rule matches, or nil if it doesn't match. If multiple rules match, only first one is executed.") +;; TODO: Make this a defcustom? +(defvar electric-layout-allow-duplicate-newlines nil + "If non-nil, allow duplication of `before' newlines.") + (defun electric-layout-post-self-insert-function () (when electric-layout-mode (electric-layout-post-self-insert-function-1))) @@ -420,11 +425,14 @@ If multiple rules match, only first one is executed.") (lambda () ;; FIXME: we use `newline', which calls ;; `self-insert-command' and ran - ;; `post-self-insert-hook' recursively. It - ;; happened to make `electric-indent-mode' work - ;; automatically with `electric-layout-mode' (at - ;; the cost of re-indenting lines multiple times), - ;; but I'm not sure it's what we want. + ;; `post-self-insert-hook' recursively. It happened + ;; to make `electric-indent-mode' work automatically + ;; with `electric-layout-mode' (at the cost of + ;; re-indenting lines multiple times), but I'm not + ;; sure it's what we want. + ;; + ;; JT@19/02/22: Indeed in the case of `before' + ;; newlines, re-indentation is prevented. ;; ;; FIXME: when `newline'ing, we exceptionally ;; prevent a specific behaviour of @@ -438,10 +446,28 @@ If multiple rules match, only first one is executed.") (let ((electric-layout-mode nil) (electric-pair-open-newline-between-pairs nil)) (newline 1 t)))) - (nl-before (lambda () - (save-excursion - (goto-char (1- pos)) (skip-chars-backward " \t") - (unless (bolp) (funcall nl-after)))))) + (nl-before + (lambda () + (save-excursion + (goto-char (1- pos)) + ;; Normally, we don't duplicate newlines, but when + ;; we're being called for i.e. a closer brace for + ;; `electric-pair-mode' generally make sense. So + ;; consult `electric-layout-allow-duplicate-newlines' + (unless (and (not electric-layout-allow-duplicate-newlines) + (progn (skip-chars-backward " \t") + (bolp))) + ;; FIXME: JT@19/03/22: Make sure the `before' + ;; newline being inserted here does not trigger + ;; reindentation. It doesn't seem to be our job + ;; to do so and it break with `cc-mode's + ;; indentation function. Later on we can add a + ;; before-and-maybe-indent, or if the user + ;; really wants to reindent, then + ;; `last-command-event' should be in + ;; `electric-indent-chars'. + (let ((electric-indent-inhibit t)) + (funcall nl-after))))))) (pcase sym ('before (funcall nl-before)) ('after (funcall nl-after)) diff --git a/test/lisp/electric-tests.el b/test/lisp/electric-tests.el index 0b076e4be0..4f1e5729be 100644 --- a/test/lisp/electric-tests.el +++ b/test/lisp/electric-tests.el @@ -391,11 +391,12 @@ baz\"\"" :bindings '((electric-pair-skip-whitespace . chomp)) :test-in-comments nil) -(define-electric-pair-test whitespace-chomping-2 - " ( \n\t\t\n ) " "--)------" :expected-string " () " :expected-point 4 - :bindings '((electric-pair-skip-whitespace . chomp)) - :modes '(c++-mode) - :test-in-comments nil) +(ert-deftest electric-pair-whitespace-chomping-2-at-point-4-in-c++-mode-in-strings nil + "Check if whitespace chomping works in `c++' unterminated strings." + (electric-pair-test-for + "\" ( \n \n ) \"" 4 41 "\" () \"" 5 'c++-mode + '((electric-pair-skip-whitespace . chomp)) + (lambda () (electric-pair-mode 1)))) ;; A test failure introduced by: ;; ;; bb591f139f: Enhance CC Mode's fontification, etc., of unterminated strings. @@ -513,6 +514,7 @@ baz\"\"" :fixture-fn #'(lambda () (electric-pair-mode 1))) + (define-electric-pair-test js-mode-braces-with-layout "" "{" :expected-string "{\n\n}" :expected-point 3 :modes '(js-mode) @@ -532,6 +534,16 @@ baz\"\"" (electric-indent-mode 1) (electric-layout-mode 1))) +(define-electric-pair-test js-mode-braces-with-layout-and-indent + "" "{" :expected-string "{\n \n}" :expected-point 7 + :modes '(js-mode) + :test-in-comments nil + :test-in-strings nil + :fixture-fn #'(lambda () + (electric-pair-mode 1) + (electric-indent-mode 1) + (electric-layout-mode 1))) + ;;; Backspacing ;;; TODO: better tests @@ -821,6 +833,35 @@ baz\"\"" ;;; tests for `electric-layout-mode' +(define-derived-mode plainer-c-mode c-mode "pC" + "A plainer/saner C-mode with no internal electric machinery." + (c-toggle-electric-state -1) + (setq-local electric-indent-local-mode-hook nil) + (setq-local electric-indent-mode-hook nil) + (electric-indent-local-mode 1) + (dolist (key '(?\" ?\' ?\{ ?\} ?\( ?\) ?\[ ?\])) + (local-set-key (vector key) 'self-insert-command))) + +(defun electric-layout-for-c-style-du-jour (inserted) + "A function to use in `electric-layout-rules'" + (when (memq inserted '(?{ ?})) + (save-excursion + (backward-char 2) (c-point-syntax) (forward-char) ; silly, but needed + (c-brace-newlines (c-point-syntax))))) + +(ert-deftest electric-layout-plainer-c-mode-use-c-style () + (ert-with-test-buffer () + (plainer-c-mode) + (electric-layout-local-mode 1) + (electric-pair-local-mode 1) + (electric-indent-local-mode 1) + (setq-local electric-layout-rules + '(electric-layout-for-c-style-du-jour)) + (insert "int main () ") + (let ((last-command-event ?\{)) + (call-interactively (key-binding `[,last-command-event]))) + (should (equal (buffer-string) "int main ()\n{\n \n}\n")))) + (ert-deftest electric-layout-int-main-kernel-style () (ert-with-test-buffer () (plainer-c-mode) @@ -828,7 +869,8 @@ baz\"\"" (electric-pair-local-mode 1) (electric-indent-local-mode 1) (setq-local electric-layout-rules - '((?\{ . (after-stay after)))) + '((?\{ . (after)) + (?\} . (before)))) (insert "int main () ") (let ((last-command-event ?\{)) (call-interactively (key-binding `[,last-command-event]))) @@ -850,7 +892,8 @@ baz\"\"" (electric-pair-local-mode 1) (electric-indent-local-mode 1) (setq-local electric-layout-rules - '((?\{ . (before after-stay after)))) + '((?\{ . (before after)) + (?\} . (before)))) (insert "int main () ") (let ((last-command-event ?\{)) (call-interactively (key-binding `[,last-command-event]))) commit 6ca4626c9fe33f78df685b4df7aca88abb272118 Author: João Távora Date: Tue Jan 22 14:36:54 2019 +0000 Remove tests of electric-pair-mode and CC-based modes The behaviour previously observed in cc-mode-based-modes (and every other major-mode) when electric-pair-mode or electric-layout-mode is turned on may no longer be observed: this because CC-mode goes around the generic implementation of electric-pair-mode. An alternative is to bind every delimiter key like '{', '}', etc to 'self-insert-command, like most major modes already do, at the cost of losing c-auto-newline functionality (which was incompatible anyway before the recent changes of bug#33794). * test/lisp/electric-tests.el (electric-pair-test-for): No longer set it. (define-electric-pair-test): Use js-mode instead of c++ mode, which broke recently. (whitespace-chomping-2): Add failing C++ test explicitly. (electric-layout-int-main-kernel-style): Use plainer-c-mode. (electric-layout-int-main-allman-style): Deleted. (electric-modes-int-main-allman-style): Renamed from electric-layout-int-main-allman-style. diff --git a/test/lisp/electric-tests.el b/test/lisp/electric-tests.el index 5a4b20ed04..0b076e4be0 100644 --- a/test/lisp/electric-tests.el +++ b/test/lisp/electric-tests.el @@ -157,7 +157,7 @@ The buffer's contents should %s: expected-string expected-point bindings - (modes '(quote (ruby-mode c++-mode))) + (modes '(quote (ruby-mode js-mode))) (test-in-comments t) (test-in-strings t) (test-in-code t) @@ -391,10 +391,16 @@ baz\"\"" :bindings '((electric-pair-skip-whitespace . chomp)) :test-in-comments nil) - -;; A test failure introduced by some changes in CC mode. Hopefully CC -;; mode will sort this out eventually, using some new e-p-m machinery. -;; See +(define-electric-pair-test whitespace-chomping-2 + " ( \n\t\t\n ) " "--)------" :expected-string " () " :expected-point 4 + :bindings '((electric-pair-skip-whitespace . chomp)) + :modes '(c++-mode) + :test-in-comments nil) +;; A test failure introduced by: +;; +;; bb591f139f: Enhance CC Mode's fontification, etc., of unterminated strings. +;; +;; Hopefully CC mode will sort this out eventually. See ;; https://lists.gnu.org/archive/html/emacs-devel/2018-06/msg00535.html (setf (ert-test-expected-result-type @@ -817,7 +823,7 @@ baz\"\"" (ert-deftest electric-layout-int-main-kernel-style () (ert-with-test-buffer () - (c-mode) + (plainer-c-mode) (electric-layout-local-mode 1) (electric-pair-local-mode 1) (electric-indent-local-mode 1) @@ -828,19 +834,6 @@ baz\"\"" (call-interactively (key-binding `[,last-command-event]))) (should (equal (buffer-string) "int main () {\n \n}")))) -(ert-deftest electric-layout-int-main-allman-style () - (ert-with-test-buffer () - (c-mode) - (electric-layout-local-mode 1) - (electric-pair-local-mode 1) - (electric-indent-local-mode 1) - (setq-local electric-layout-rules - '((?\{ . (before after-stay after)))) - (insert "int main () ") - (let ((last-command-event ?\{)) - (call-interactively (key-binding `[,last-command-event]))) - (should (equal (buffer-string) "int main ()\n{\n \n}")))) - (define-derived-mode plainer-c-mode c-mode "pC" "A plainer/saner C-mode with no internal electric machinery." (c-toggle-electric-state -1) @@ -850,7 +843,7 @@ baz\"\"" (dolist (key '(?\" ?\' ?\{ ?\} ?\( ?\) ?\[ ?\])) (local-set-key (vector key) 'self-insert-command))) -(ert-deftest electric-modes-in-c-mode-with-self-insert-command () +(ert-deftest electric-modes-int-main-allman-style () (ert-with-test-buffer () (plainer-c-mode) (electric-layout-local-mode 1) commit 9eaf5e052a802a7b0560f983f2bb786e13ce2488 Author: Alan Mackenzie Date: Tue Jan 22 14:37:54 2019 +0000 Extend electric-pair-mode actions to < and >, and also to ( and ) in literals * lisp/progmodes/cc-cmds.el (c-electric-lt-gt): Actuate electric-pair-mode if a < or > is typed in a context where this is meaningful (#include, or template). (c-electric-paren): Allow electric-pair-mode activity in a comment or string. * lisp/progmodes/cc-defs.el (c-make-keywords-re): Fix a bug where lists of source symbols could get overwritten when parameter adorn is set to 'appendable. * list/progmodes/cc-langs.el (c-cpp-include-key): New lang const and var. diff --git a/lisp/progmodes/cc-cmds.el b/lisp/progmodes/cc-cmds.el index 78677fefad..c0a688195c 100644 --- a/lisp/progmodes/cc-cmds.el +++ b/lisp/progmodes/cc-cmds.el @@ -1167,7 +1167,9 @@ finishes a C++ style stream operator in C++ mode. Exceptions are when a numeric argument is supplied, or the point is inside a literal." (interactive "*P") - (let ((c-echo-syntactic-information-p nil) + (let ((literal (c-save-buffer-state () (c-in-literal))) + template-delim include-delim + (c-echo-syntactic-information-p nil) final-pos found-delim case-fold-search) (let (post-self-insert-hook) ; Disable random functionality. @@ -1178,39 +1180,63 @@ numeric argument is supplied, or the point is inside a literal." ;;;; property on the new < or > and its mate (if any) when they are template ;;;; parens. This is now done in an after-change function. - ;; Indent the line if appropriate. - (when (and c-electric-flag c-syntactic-indentation c-recognize-<>-arglists) - (setq found-delim - (if (eq (c-last-command-char) ?<) - ;; If a <, basically see if it's got "template" before it ..... - (or (and (progn - (backward-char) - (= (point) - (progn (c-beginning-of-current-token) (point)))) - (progn - (c-backward-token-2) - (looking-at c-opt-<>-sexp-key))) - ;; ..... or is a C++ << operator. + (when (and (not arg) (not literal)) + ;; Have we got a delimiter on a #include directive? + (beginning-of-line) + (setq include-delim + (and + (looking-at c-cpp-include-key) + (if (eq (c-last-command-char) ?<) + (eq (match-end 0) (1- final-pos)) + (goto-char (1- final-pos)) + (skip-chars-backward "^<>" (c-point 'bol)) + (eq (char-before) ?<)))) + (goto-char final-pos) + + ;; Indent the line if appropriate. + (when (and c-electric-flag c-syntactic-indentation c-recognize-<>-arglists) + (setq found-delim + (if (eq (c-last-command-char) ?<) + ;; If a <, basically see if it's got "template" before it ..... + (or (and (progn + (backward-char) + (= (point) + (progn (c-beginning-of-current-token) (point)))) + (progn + (c-backward-token-2) + (looking-at c-opt-<>-sexp-key)) + (setq template-delim t)) + ;; ..... or is a C++ << operator. + (and (c-major-mode-is 'c++-mode) + (progn + (goto-char (1- final-pos)) + (c-beginning-of-current-token) + (looking-at "<<")) + (>= (match-end 0) final-pos))) + + ;; It's a >. Either a template/generic terminator ... + (or (and (c-get-char-property (1- final-pos) 'syntax-table) + (setq template-delim t)) + ;; or a C++ >> operator. (and (c-major-mode-is 'c++-mode) (progn (goto-char (1- final-pos)) (c-beginning-of-current-token) - (looking-at "<<")) - (>= (match-end 0) final-pos))) + (looking-at ">>")) + (>= (match-end 0) final-pos))))) + (goto-char final-pos) - ;; It's a >. Either a template/generic terminator ... - (or (c-get-char-property (1- final-pos) 'syntax-table) - ;; or a C++ >> operator. - (and (c-major-mode-is 'c++-mode) - (progn - (goto-char (1- final-pos)) - (c-beginning-of-current-token) - (looking-at ">>")) - (>= (match-end 0) final-pos)))))) + (when found-delim + (indent-according-to-mode))) + + ;; On the off chance that < and > are configured as pairs in + ;; electric-pair-mode. + (when (and (boundp 'electric-pair-mode) electric-pair-mode + (or template-delim include-delim)) + (let (post-self-insert-hook) + (electric-pair-post-self-insert-function)))) - (goto-char final-pos) (when found-delim - (indent-according-to-mode) (when (and (eq (char-before) ?>) (not executing-kbd-macro) blink-paren-function) @@ -1241,7 +1267,7 @@ newline cleanups are done if appropriate; see the variable `c-cleanup-list'." (self-insert-command (prefix-numeric-value arg))) (if (and (not arg) (not literal)) - (let* ( ;; We want to inhibit blinking the paren since this will + (let* (;; We want to inhibit blinking the paren since this will ;; be most disruptive. We'll blink it ourselves ;; afterwards. (old-blink-paren blink-paren-function) @@ -1317,21 +1343,26 @@ newline cleanups are done if appropriate; see the variable `c-cleanup-list'." (insert ?\ ))) ;; compact-empty-funcall clean-up? - ((c-save-buffer-state () - (and (memq 'compact-empty-funcall c-cleanup-list) - (eq (c-last-command-char) ?\)) - (save-excursion - (c-safe (backward-char 2)) - (when (looking-at "()") - (setq end (point)) - (skip-chars-backward " \t") - (setq beg (point)) - (c-on-identifier))))) - (delete-region beg end)))) + ((c-save-buffer-state () + (and (memq 'compact-empty-funcall c-cleanup-list) + (eq (c-last-command-char) ?\)) + (save-excursion + (c-safe (backward-char 2)) + (when (looking-at "()") + (setq end (point)) + (skip-chars-backward " \t") + (setq beg (point)) + (c-on-identifier))))) + (delete-region beg end)))) (and (eq last-input-event ?\)) (not executing-kbd-macro) old-blink-paren - (funcall old-blink-paren)))))) + (funcall old-blink-paren))) + + ;; Apply `electric-pair-mode' stuff inside a string or comment. + (when (and (boundp 'electric-pair-mode) electric-pair-mode) + (let (post-self-insert-hook) + (electric-pair-post-self-insert-function)))))) (defun c-electric-continued-statement () "Reindent the current line if appropriate. diff --git a/lisp/progmodes/cc-defs.el b/lisp/progmodes/cc-defs.el index 1cb823495a..f8b1b45de7 100644 --- a/lisp/progmodes/cc-defs.el +++ b/lisp/progmodes/cc-defs.el @@ -1769,7 +1769,8 @@ when it's needed. The default is the current language taken from t)) (setq pos (cdr pos))) found)) - (setq pos list) + (setq pos (copy-tree list) + ) (while pos (if (string-match "\\w\\'" (car pos)) (setcar pos (concat (car pos) unique))) diff --git a/lisp/progmodes/cc-langs.el b/lisp/progmodes/cc-langs.el index 4bd4914a2d..53342713b4 100644 --- a/lisp/progmodes/cc-langs.el +++ b/lisp/progmodes/cc-langs.el @@ -927,6 +927,19 @@ file name in angle brackets or quotes." '("include")) objc '("include" "import")) +(c-lang-defconst c-cpp-include-key + ;; Matches an include directive anchored at BOL including any trailing + ;; whitespace, e.g. " # include " + t (if (and (c-lang-const c-anchored-cpp-prefix) + (c-lang-const c-cpp-include-directives)) + (concat + (c-lang-const c-anchored-cpp-prefix) + (c-make-keywords-re 'appendable + (c-lang-const c-cpp-include-directives)) + "[ \t]*") + "a\\`")) ; Doesn't match anything +(c-lang-defvar c-cpp-include-key (c-lang-const c-cpp-include-key)) + (c-lang-defconst c-opt-cpp-macro-define "Cpp directive (without the prefix) that is followed by a macro definition, or nil if the language doesn't have any." commit f97b734ffb2b70f3d94e46453a236b46e0704901 Author: Alan Mackenzie Date: Sun Jan 20 20:34:33 2019 +0000 Revert "Fix electric-pair-tests by disabling bug#33794's fix with a variable" This reverts commit be505726b68d407a44fdcd9c7ac1ef722398532d. diff --git a/lisp/progmodes/cc-cmds.el b/lisp/progmodes/cc-cmds.el index 6b0d961766..78677fefad 100644 --- a/lisp/progmodes/cc-cmds.el +++ b/lisp/progmodes/cc-cmds.el @@ -485,20 +485,6 @@ function to control that." (c-hungry-delete-forward) (c-hungry-delete-backwards))) -(defvar c--disable-fix-of-bug-33794 nil - "If non-nil disable alans controversional fix of 33794. -This fix breaks most features of `electric-pair-mode' by -incompletely reimplementing in in this mode.") - -(defmacro c--with-post-self-insert-hook-maybe (&rest body) - `(let ((post-self-insert-hook - (if c--disable-fix-of-bug-33794 - post-self-insert-hook - ;; Acording to AM: Disable random functionality to get - ;; defined functionality from `self-insert-command' - nil))) - ,@body)) - (defun c-electric-pound (arg) "Insert a \"#\". If `c-electric-flag' is set, handle it specially according to the variable @@ -518,7 +504,7 @@ inside a literal or a macro, nothing special happens." (eq (char-before) ?\\)))) (c-in-literal))) ;; do nothing special - (c--with-post-self-insert-hook-maybe + (let (post-self-insert-hook) ; Disable random functionality. (self-insert-command (prefix-numeric-value arg))) ;; place the pound character at the left edge (let ((pos (- (point-max) (point))) @@ -871,38 +857,36 @@ settings of `c-cleanup-list' are done." ;; Insert the brace. Note that expand-abbrev might reindent ;; the line here if there's a preceding "else" or something. - (c--with-post-self-insert-hook-maybe - (self-insert-command (prefix-numeric-value arg))) + (let (post-self-insert-hook) ; the only way to get defined functionality + ; from `self-insert-command'. + (self-insert-command (prefix-numeric-value arg))) ;; Emulate `electric-pair-mode'. - (unless c--disable-fix-of-bug-33794 - (when (and (boundp 'electric-pair-mode) - electric-pair-mode) - (let ((size (buffer-size)) - (c-in-electric-pair-functionality t) - post-self-insert-hook) - (electric-pair-post-self-insert-function) - (setq got-pair-} (and at-eol - (eq (c-last-command-char) ?{) - (eq (char-after) ?})) - electric-pair-deletion (< (buffer-size) size)))) - - ;; Perform any required CC Mode electric actions. - (cond - ((or literal arg (not c-electric-flag) active-region)) - ((not at-eol) - (c-indent-line)) - (electric-pair-deletion - (c-indent-line) - (c-do-brace-electrics 'ignore nil)) - (t (c-do-brace-electrics nil nil) - (when got-pair-} - (save-excursion - (forward-char) - (c-do-brace-electrics 'assume 'ignore)) - (c-indent-line))))) - - + (when (and (boundp 'electric-pair-mode) + electric-pair-mode) + (let ((size (buffer-size)) + (c-in-electric-pair-functionality t) + post-self-insert-hook) + (electric-pair-post-self-insert-function) + (setq got-pair-} (and at-eol + (eq (c-last-command-char) ?{) + (eq (char-after) ?})) + electric-pair-deletion (< (buffer-size) size)))) + + ;; Perform any required CC Mode electric actions. + (cond + ((or literal arg (not c-electric-flag) active-region)) + ((not at-eol) + (c-indent-line)) + (electric-pair-deletion + (c-indent-line) + (c-do-brace-electrics 'ignore nil)) + (t (c-do-brace-electrics nil nil) + (when got-pair-} + (save-excursion + (forward-char) + (c-do-brace-electrics 'assume 'ignore)) + (c-indent-line)))) ;; blink the paren (and (eq (c-last-command-char) ?\}) @@ -960,7 +944,7 @@ is inhibited." c-electric-flag (eq (c-last-command-char) ?/) (eq (char-before) (if literal ?* ?/)))) - (c--with-post-self-insert-hook-maybe + (let (post-self-insert-hook) ; Disable random functionality. (self-insert-command (prefix-numeric-value arg))) (if indentp (indent-according-to-mode)))) @@ -974,7 +958,7 @@ supplied, point is inside a literal, or `c-syntactic-indentation' is nil, this indentation is inhibited." (interactive "*P") - (c--with-post-self-insert-hook-maybe + (let (post-self-insert-hook) ; Disable random functionality. (self-insert-command (prefix-numeric-value arg))) ;; if we are in a literal, or if arg is given do not reindent the ;; current line, unless this star introduces a comment-only line. @@ -1022,7 +1006,7 @@ settings of `c-cleanup-list'." (setq lim (c-most-enclosing-brace (c-parse-state)) literal (c-in-literal lim))) - (c--with-post-self-insert-hook-maybe + (let (post-self-insert-hook) ; Disable random functionality. (self-insert-command (prefix-numeric-value arg))) (if (and c-electric-flag (not literal) (not arg)) @@ -1092,7 +1076,7 @@ reindented unless `c-syntactic-indentation' is nil. newlines is-scope-op ;; shut this up (c-echo-syntactic-information-p nil)) - (c--with-post-self-insert-hook-maybe + (let (post-self-insert-hook) ; Disable random functionality. (self-insert-command (prefix-numeric-value arg))) ;; Any electric action? (if (and c-electric-flag (not literal) (not arg)) @@ -1186,7 +1170,7 @@ numeric argument is supplied, or the point is inside a literal." (let ((c-echo-syntactic-information-p nil) final-pos found-delim case-fold-search) - (c--with-post-self-insert-hook-maybe + (let (post-self-insert-hook) ; Disable random functionality. (self-insert-command (prefix-numeric-value arg))) (setq final-pos (point)) @@ -1252,7 +1236,8 @@ newline cleanups are done if appropriate; see the variable `c-cleanup-list'." ;; shut this up (c-echo-syntactic-information-p nil) case-fold-search) - (c--with-post-self-insert-hook-maybe + (let (post-self-insert-hook) ; The only way to get defined functionality + ; from `self-insert-command'. (self-insert-command (prefix-numeric-value arg))) (if (and (not arg) (not literal)) @@ -1303,11 +1288,10 @@ newline cleanups are done if appropriate; see the variable `c-cleanup-list'." (insert-and-inherit "} catch ("))) ;; Apply `electric-pair-mode' stuff. - (unless c--disable-fix-of-bug-33794 - (when (and (boundp 'electric-pair-mode) - electric-pair-mode) - (let (post-self-insert-hook) - (electric-pair-post-self-insert-function)))) + (when (and (boundp 'electric-pair-mode) + electric-pair-mode) + (let (post-self-insert-hook) + (electric-pair-post-self-insert-function))) ;; Check for clean-ups at function calls. These two DON'T need ;; `c-electric-flag' or `c-syntactic-indentation' set. diff --git a/test/lisp/electric-tests.el b/test/lisp/electric-tests.el index b55d889f0b..5a4b20ed04 100644 --- a/test/lisp/electric-tests.el +++ b/test/lisp/electric-tests.el @@ -47,14 +47,10 @@ (declare (indent defun) (debug t)) `(call-with-saved-electric-modes #'(lambda () ,@body))) -;; Defined in lisp/progmodes/cc-cmds.el -(defvar c--disable-fix-of-bug-33794 t) - (defun electric-pair-test-for (fixture where char expected-string expected-point mode bindings fixture-fn) (with-temp-buffer (funcall mode) - (setq-local c--disable-fix-of-bug-33794 t) (insert fixture) (save-electric-modes (let ((last-command-event char) @@ -825,7 +821,6 @@ baz\"\"" (electric-layout-local-mode 1) (electric-pair-local-mode 1) (electric-indent-local-mode 1) - (setq-local c--disable-fix-of-bug-33794 t) (setq-local electric-layout-rules '((?\{ . (after-stay after)))) (insert "int main () ") @@ -839,7 +834,6 @@ baz\"\"" (electric-layout-local-mode 1) (electric-pair-local-mode 1) (electric-indent-local-mode 1) - (setq-local c--disable-fix-of-bug-33794 t) (setq-local electric-layout-rules '((?\{ . (before after-stay after)))) (insert "int main () ") commit 6038fdb2f9eac3225c0651fee18e1e75e63f2409 Author: Michael Albinus Date: Tue Jan 22 15:22:52 2019 +0100 Make Tramp tests more robust * test/lisp/net/tramp-tests.el (tramp-test06-directory-file-name): Bind `tramp-default-method'. (tramp--test-file-attributes-equal-p): New defsubst. (tramp-test19-directory-files-and-attributes): Use it. diff --git a/test/lisp/net/tramp-tests.el b/test/lisp/net/tramp-tests.el index 2893506286..d4db4e9f64 100644 --- a/test/lisp/net/tramp-tests.el +++ b/test/lisp/net/tramp-tests.el @@ -2067,7 +2067,8 @@ This checks also `file-name-as-directory', `file-name-directory', ;; We must clear `tramp-default-method'. On hydra, it is "ftp", ;; which ruins the tests. (let ((non-essential n-e) - tramp-default-method) + (tramp-default-method + (file-remote-p tramp-test-temporary-file-directory 'method))) (dolist (file `(,(format @@ -2964,6 +2965,13 @@ This tests also `file-readable-p', `file-regular-p' and (ignore-errors (delete-file tmp-name1)) (ignore-errors (delete-file tmp-name2)))))) +(defsubst tramp--test-file-attributes-equal-p (attr1 attr2) + "Check, whether file attributes ATTR1 and ATTR2 are equal. +They might differ only in access time." + (setcar (nthcdr 4 attr1) tramp-time-dont-know) + (setcar (nthcdr 4 attr2) tramp-time-dont-know) + (equal attr1 attr2)) + (ert-deftest tramp-test19-directory-files-and-attributes () "Check `directory-files-and-attributes'." (skip-unless (tramp--test-enabled)) @@ -2995,14 +3003,16 @@ This tests also `file-readable-p', `file-regular-p' and 5 (file-attributes (expand-file-name (car elt) tmp-name2))) tramp-time-dont-know) (should - (equal (file-attributes (expand-file-name (car elt) tmp-name2)) - (cdr elt))))) + (tramp--test-file-attributes-equal-p + (file-attributes (expand-file-name (car elt) tmp-name2)) + (cdr elt))))) (setq attr (directory-files-and-attributes tmp-name2 'full)) (dolist (elt attr) (unless (tramp-compat-time-equal-p (nth 5 (file-attributes (car elt))) tramp-time-dont-know) (should - (equal (file-attributes (car elt)) (cdr elt))))) + (tramp--test-file-attributes-equal-p + (file-attributes (car elt)) (cdr elt))))) (setq attr (directory-files-and-attributes tmp-name2 nil "^b")) (should (equal (mapcar 'car attr) '("bar" "boz")))) @@ -5564,6 +5574,7 @@ Since it unloads Tramp, it shall be the last test to run." ;; * file-equal-p (partly done in `tramp-test21-file-links') ;; * file-in-directory-p ;; * file-name-case-insensitive-p +;; * tramp-set-file-uid-gid ;; * Work on skipped tests. Make a comment, when it is impossible. ;; * Revisit expensive tests, once problems in `tramp-error' are solved.