From: Alan Mackenzie Date: Mon, 12 Apr 2010 15:15:07 +0000 (+0000) Subject: Reverse change 2010-02-04T21:15:37Z!acm@muc.de: "Change strategy for marking < and... X-Git-Url: https://git.hcoop.net/bpt/emacs.git/commitdiff_plain/7af4bf3aea19289d47e46d9007e786ac1956bcb7 Reverse change 2010-02-04T21:15:37Z!acm@muc.de: "Change strategy for marking < and > as template delimiters: mark them strictly in matching pairs." --- diff --git a/lisp/ChangeLog b/lisp/ChangeLog index f155bbee4f..3519861965 100644 --- a/lisp/ChangeLog +++ b/lisp/ChangeLog @@ -695,33 +695,6 @@ (doc-view-pdf->png): Don't rely on doc-view-pdf/ps->png for the few windows that are not yet showing images. -2010-02-04 Alan Mackenzie - - Change strategy for marking < and > as template delimiters: mark - them strictly in matching pairs. - - * cc-mode.el (c-before-change): - Use c-get-state-before-change-functions. - (c-common-init): Adapt to use - c-get-state-before-change-functions (note plural). - - * cc-langs.el (c-no-parens-syntax-table): New syntax table, used - for searching syntactically for matching s. - (c-get-state-before-change-functions): New language variable (note - the plural) which supersedes c-get-state-before-change-function. - - * cc-engine.el (c-clear-<-pair-props, c-clear->-pair-props) - (c-clear-<>-pair-props, c-clear-<-pair-props-if-match-after) - (c-clear->-pair-props-if-match-before) - (c-before-change-check-<>-operators): New functions. - (c-after-change-check-<>-operators): Use macro - c-unmark-<->-as-paren. - - * cc-defs.el (c-search-backward-char-property): New macro. - - * cc-cmds.el (c-electric-lt-gt): Do not set text properties on < - and > any more. (These will be handled by font locking.) - 2010-02-04 Michael Albinus * dired.el (dired-revert): If DIRED-DIRECTORY is a cons cell, call diff --git a/lisp/progmodes/cc-cmds.el b/lisp/progmodes/cc-cmds.el index 56fc803254..4eade6edf5 100644 --- a/lisp/progmodes/cc-cmds.el +++ b/lisp/progmodes/cc-cmds.el @@ -1086,76 +1086,104 @@ numeric argument is supplied, or the point is inside a literal." (interactive "*P") (let ((c-echo-syntactic-information-p nil) - final-pos close-paren-inserted found-delim) + final-pos close-paren-inserted) (self-insert-command (prefix-numeric-value arg)) (setq final-pos (point)) -;;;; 2010-01-31: There used to be code here to put a syntax-table text -;;;; property on the new < or > and its mate (if any) when they are template -;;;; parens. This is now done in an after-change function. + (c-save-buffer-state (c-parse-and-markup-<>-arglists + c-restricted-<>-arglists + <-pos) - ;; Indent the line if appropriate. - (when (and c-electric-flag c-syntactic-indentation c-recognize-<>-arglists) - (setq found-delim - (if (eq last-command-event ?<) - ;; 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. - (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 C++ >> operator. ...... - (or (and (c-major-mode-is 'c++-mode) + (when c-recognize-<>-arglists + (if (eq last-command-event ?<) + (when (and (progn + (backward-char) + (= (point) + (progn + (c-beginning-of-current-token) + (point)))) (progn - (goto-char (1- final-pos)) - (c-beginning-of-current-token) - (looking-at ">>")) - (>= (match-end 0) final-pos)) - ;; ...., or search back for a < which isn't already marked as an - ;; opening template delimiter. - (save-restriction - (widen) - ;; Narrow to avoid `c-forward-<>-arglist' below searching past - ;; our position. - (narrow-to-region (point-min) final-pos) - (goto-char final-pos) - (while - (and - (progn - (c-syntactic-skip-backward "^<;}" nil t) - (eq (char-before) ?<)) - (progn - (backward-char) - (looking-at "\\s\(")))) - (and (eq (char-after) ?<) - (not (looking-at "\\s\(")) - (progn (c-backward-syntactic-ws) - (c-simple-skip-symbol-backward)) - (or (looking-at c-opt-<>-sexp-key) - (not (looking-at c-keywords-regexp))))))))) + (c-backward-token-2) + (looking-at c-opt-<>-sexp-key))) + (c-mark-<-as-paren (1- final-pos))) + + ;; It's a ">". Check if there's an earlier "<" which either has + ;; open paren syntax already or that can be recognized as an arglist + ;; together with this ">". Note that this won't work in cases like + ;; "template " but they ought to be rare. + + (save-restriction + ;; Narrow to avoid that `c-forward-<>-arglist' below searches past + ;; our position. + (narrow-to-region (point-min) final-pos) + + (while (and + (progn + (goto-char final-pos) + (c-syntactic-skip-backward "^<;}" nil t) + (eq (char-before) ?<)) + (progn + (backward-char) + ;; If the "<" already got open paren syntax we know we + ;; have the matching closer. Handle it and exit the + ;; loop. + (if (looking-at "\\s\(") + (progn + (c-mark->-as-paren (1- final-pos)) + (setq close-paren-inserted t) + nil) + t)) + (progn + (setq <-pos (point)) + (c-backward-syntactic-ws) + (c-simple-skip-symbol-backward)) + (or (looking-at c-opt-<>-sexp-key) + (not (looking-at c-keywords-regexp))) + + (let ((c-parse-and-markup-<>-arglists t) + c-restricted-<>-arglists + (containing-sexp + (c-most-enclosing-brace (c-parse-state)))) + (when (and containing-sexp + (progn (goto-char containing-sexp) + (eq (char-after) ?\()) + (not (eq (get-text-property (point) 'c-type) + 'c-decl-arg-start))) + (setq c-restricted-<>-arglists t)) + (goto-char <-pos) + (c-forward-<>-arglist nil)) + + ;; Loop here if the "<" we found above belongs to a nested + ;; angle bracket sexp. When we start over we'll find the + ;; previous or surrounding sexp. + (if (< (point) final-pos) + t + (setq close-paren-inserted t) + nil))))))) (goto-char final-pos) - (when found-delim - (indent-according-to-mode) - (when (and (eq (char-before) ?>) - (not executing-kbd-macro) - blink-paren-function) - ;; Note: Most paren blink functions, such as the standard - ;; `blink-matching-open', currently doesn't handle paren chars - ;; marked with text properties very well. Maybe we should avoid - ;; this call for the time being? - (funcall blink-paren-function))))) + + ;; Indent the line if appropriate. + (when (and c-electric-flag c-syntactic-indentation) + (backward-char) + (when (prog1 (or (looking-at "\\s\(\\|\\s\)") + (and (c-major-mode-is 'c++-mode) + (progn + (c-beginning-of-current-token) + (looking-at "<<\\|>>")) + (= (match-end 0) final-pos))) + (goto-char final-pos)) + (indent-according-to-mode))) + + (when (and close-paren-inserted + (not executing-kbd-macro) + blink-paren-function) + ;; Note: Most paren blink functions, such as the standard + ;; `blink-matching-open', currently doesn't handle paren chars + ;; marked with text properties very well. Maybe we should avoid + ;; this call for the time being? + (funcall blink-paren-function)))) (defun c-electric-paren (arg) "Insert a parenthesis. diff --git a/lisp/progmodes/cc-defs.el b/lisp/progmodes/cc-defs.el index 7eb0016ff4..bb91dee6ce 100644 --- a/lisp/progmodes/cc-defs.el +++ b/lisp/progmodes/cc-defs.el @@ -1029,44 +1029,6 @@ MODE is either a mode symbol or a list of mode symbols." ;; Emacs. `(remove-text-properties ,from ,to '(,property nil)))) -(defmacro c-search-forward-char-property (property value &optional limit) - "Search forward for a text-property PROPERTY having value VALUE. -LIMIT bounds the search. The comparison is done with `equal'. - -Leave point just after the character, and set the match data on -this character, and return point. If VALUE isn't found, Return -nil; point is then left undefined." - `(let ((place (point))) - (while - (and - (< place ,(or limit '(point-max))) - (not (equal (get-text-property place ,property) ,value))) - (setq place (next-single-property-change - place ,property nil ,(or limit '(point-max))))) - (when (< place ,(or limit '(point-max))) - (goto-char place) - (search-forward-regexp ".") ; to set the match-data. - (point)))) - -(defmacro c-search-backward-char-property (property value &optional limit) - "Search backward for a text-property PROPERTY having value VALUE. -LIMIT bounds the search. The comparison is done with `equal'. - -Leave point just before the character, set the match data on this -character, and return point. If VALUE isn't found, Return nil; -point is then left undefined." - `(let ((place (point))) - (while - (and - (> place ,(or limit '(point-min))) - (not (equal (get-text-property (1- place) ,property) ,value))) - (setq place (previous-single-property-change - place ,property nil ,(or limit '(point-min))))) - (when (> place ,(or limit '(point-max))) - (goto-char place) - (search-backward-regexp ".") ; to set the match-data. - (point)))) - (defun c-clear-char-property-with-value-function (from to property value) "Remove all text-properties PROPERTY from the region (FROM, TO) which have the value VALUE, as tested by `equal'. These diff --git a/lisp/progmodes/cc-engine.el b/lisp/progmodes/cc-engine.el index 3b7f6e4ea0..9d0af1d53c 100644 --- a/lisp/progmodes/cc-engine.el +++ b/lisp/progmodes/cc-engine.el @@ -4880,168 +4880,7 @@ comment at the start of cc-engine.el for more info." ))) -;; Setting and removing syntax properties on < and > in languages (C++ -;; and Java) where they can be template/generic delimiters as well as -;; their normal meaning of "less/greater than". - -;; Normally, < and > have syntax 'punctuation'. When they are found to -;; be delimiters, they are marked as such with the category properties -;; c-<-as-paren-syntax, c->-as-paren-syntax respectively. - -;; STRATEGY: -;; -;; It is impossible to determine with certainty whether a <..> pair in -;; C++ is two comparison operators or is template delimiters, unless -;; one duplicates a lot of a C++ compiler. For example, the following -;; code fragment: -;; -;; foo (a < b, c > d) ; -;; -;; could be a function call with two integer parameters (each a -;; relational expression), or it could be a constructor for class foo -;; taking one parameter d of templated type "a < b, c >". They are -;; somewhat easier to distinguish in Java. -;; -;; The strategy now (2010-01) adopted is to mark and unmark < and -;; > IN MATCHING PAIRS ONLY. [Previously, they were marked -;; individually when their context so indicated. This gave rise to -;; intractible problems when one of a matching pair was deleted, or -;; pulled into a literal.] -;; -;; At each buffer change, the syntax-table properties are removed in a -;; before-change function and reapplied, when needed, in an -;; after-change function. It is far more important that the -;; properties get removed when they they are spurious than that they -;; be present when wanted. -;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; -(defun c-clear-<-pair-props (&optional pos) - ;; POS (default point) is at a < character. If it is marked with - ;; open paren syntax-table text property, remove the property, - ;; together with the close paren property on the matching > (if - ;; any). - (save-excursion - (if pos - (goto-char pos) - (setq pos (point))) - (when (equal (c-get-char-property (point) 'syntax-table) - c-<-as-paren-syntax) - (with-syntax-table c-no-parens-syntax-table ; ignore unbalanced [,{,(,.. - (c-go-list-forward)) - (when (equal (c-get-char-property (1- (point)) 'syntax-table) - c->-as-paren-syntax) ; should always be true. - (c-clear-char-property (1- (point)) 'syntax-table)) - (c-clear-char-property pos 'syntax-table)))) - -(defun c-clear->-pair-props (&optional pos) - ;; POS (default point) is at a > character. If it is marked with - ;; close paren syntax-table property, remove the property, together - ;; with the open paren property on the matching < (if any). - (save-excursion - (if pos - (goto-char pos) - (setq pos (point))) - (when (equal (c-get-char-property (point) 'syntax-table) - c->-as-paren-syntax) - (with-syntax-table c-no-parens-syntax-table ; ignore unbalanced [,{,(,.. - (c-go-up-list-backward)) - (when (equal (c-get-char-property (point) 'syntax-table) - c-<-as-paren-syntax) ; should always be true. - (c-clear-char-property (point) 'syntax-table)) - (c-clear-char-property pos 'syntax-table)))) - -(defun c-clear-<>-pair-props (&optional pos) - ;; POS (default point) is at a < or > character. If it has an - ;; open/close paren syntax-table property, remove this property both - ;; from the current character and its partner (which will also be - ;; thusly marked). - (cond - ((eq (char-after) ?\<) - (c-clear-<-pair-props pos)) - ((eq (char-after) ?\>) - (c-clear->-pair-props pos)) - (t (c-benign-error - "c-clear-<>-pair-props called from wrong position")))) - -(defun c-clear-<-pair-props-if-match-after (lim &optional pos) - ;; POS (default point) is at a < character. If it is both marked - ;; with open/close paren syntax-table property, and has a matching > - ;; (also marked) which is after LIM, remove the property both from - ;; the current > and its partner. - (save-excursion - (if pos - (goto-char pos) - (setq pos (point))) - (when (equal (c-get-char-property (point) 'syntax-table) - c-<-as-paren-syntax) - (with-syntax-table c-no-parens-syntax-table ; ignore unbalanced [,{,(,.. - (c-go-list-forward)) - (when (and (>= (point) lim) - (equal (c-get-char-property (1- (point)) 'syntax-table) - c->-as-paren-syntax)) ; should always be true. - (c-unmark-<->-as-paren (1- (point))) - (c-unmark-<->-as-paren pos))))) - -(defun c-clear->-pair-props-if-match-before (lim &optional pos) - ;; POS (default point) is at a > character. If it is both marked - ;; with open/close paren syntax-table property, and has a matching < - ;; (also marked) which is before LIM, remove the property both from - ;; the current < and its partner. - (save-excursion - (if pos - (goto-char pos) - (setq pos (point))) - (when (equal (c-get-char-property (point) 'syntax-table) - c->-as-paren-syntax) - (with-syntax-table c-no-parens-syntax-table ; ignore unbalanced [,{,(,.. - (c-go-up-list-backward)) - (when (and (<= (point) lim) - (equal (c-get-char-property (point) 'syntax-table) - c-<-as-paren-syntax)) ; should always be true. - (c-unmark-<->-as-paren (point)) - (c-unmark-<->-as-paren pos))))) - -(defun c-before-change-check-<>-operators (beg end) - ;; Unmark certain pairs of "< .... >" which are currently marked as - ;; template/generic delimiters. (This marking is via syntax-table - ;; text properties). - ;; - ;; These pairs are those which are in the current "statement" (i.e., - ;; the region between the {, }, or ; before BEG and the one after - ;; END), and which enclose any part of the interval (BEG END). - ;; - ;; Note that in C++ (?and Java), template/generic parens cannot - ;; enclose a brace or semicolon, so we use these as bounds on the - ;; region we must work on. - ;; - ;; This function is called from before-change-functions (via - ;; c-get-state-before-change-functions). Thus the buffer is widened, - ;; and point is undefined, both at entry and exit. - ;; - ;; FIXME!!! This routine ignores the possibility of macros entirely. - ;; 2010-01-29. - (save-excursion - (let ((beg-lit-limits (progn (goto-char beg) (c-literal-limits))) - (end-lit-limits (progn (goto-char end) (c-literal-limits)))) - ;; Locate the barrier before the changed region - (goto-char (if beg-lit-limits (car beg-lit-limits) beg)) - (c-syntactic-skip-backward "^;{}" (max (- beg 2048) (point-min))) - - ;; Remove the syntax-table properties from each pertinent <...> pair. - ;; Firsly, the ones with the < before beg and > after beg. - (while (c-search-forward-char-property 'category 'c-<-as-paren-syntax beg) - (c-clear-<-pair-props-if-match-after beg (1- (point)))) - - ;; Locate the barrier after END. - (goto-char (if end-lit-limits (cdr end-lit-limits) end)) - (c-syntactic-re-search-forward "[;{}]" - (min (+ end 2048) (point-max)) 'end) - - ;; Remove syntax-table properties from the remaining pertinent <...> - ;; pairs, those with a > after end and < before end. - (while (c-search-backward-char-property 'category 'c->-as-paren-syntax end) - (c-clear->-pair-props-if-match-before end))))) - - +;; Handling of small scale constructs like types and names. (defun c-after-change-check-<>-operators (beg end) ;; This is called from `after-change-functions' when @@ -5063,7 +4902,7 @@ comment at the start of cc-engine.el for more info." (< beg (setq beg (match-end 0)))) (while (progn (skip-chars-forward "^<>" beg) (< (point) beg)) - (c-clear-<>-pair-props) + (c-clear-char-property (point) 'syntax-table) (forward-char)))) (when (< beg end) @@ -5078,13 +4917,9 @@ comment at the start of cc-engine.el for more info." (< end (setq end (match-end 0)))) (while (progn (skip-chars-forward "^<>" end) (< (point) end)) - (c-clear-<>-pair-props) + (c-clear-char-property (point) 'syntax-table) (forward-char))))))) - - -;; Handling of small scale constructs like types and names. - ;; Dynamically bound variable that instructs `c-forward-type' to also ;; treat possible types (i.e. those that it normally returns 'maybe or ;; 'found for) as actual types (and always return 'found for them). diff --git a/lisp/progmodes/cc-langs.el b/lisp/progmodes/cc-langs.el index d3669f259d..e4c61b32a2 100644 --- a/lisp/progmodes/cc-langs.el +++ b/lisp/progmodes/cc-langs.el @@ -391,27 +391,6 @@ The syntax tables aren't stored directly since they're quite large." (and (c-lang-const c++-make-template-syntax-table) (funcall (c-lang-const c++-make-template-syntax-table)))) -(c-lang-defconst c-no-parens-syntax-table - ;; A variant of the standard syntax table which is used to find matching - ;; "<"s and ">"s which have been marked as parens using syntax table - ;; properties. The other paren characters (e.g. "{", ")" "]") are given a - ;; non-paren syntax here. so that the list commands will work on "< ... >" - ;; even when there's unbalanced other parens inside them. - ;; - ;; This variable is nil for languages which don't have template stuff. - t `(lambda () - (if (c-lang-const c-recognize-<>-arglists) - (let ((table (funcall ,(c-lang-const c-make-mode-syntax-table)))) - (modify-syntax-entry ?\( "." table) - (modify-syntax-entry ?\) "." table) - (modify-syntax-entry ?\[ "." table) - (modify-syntax-entry ?\] "." table) - (modify-syntax-entry ?\{ "." table) - (modify-syntax-entry ?\} "." table) - table)))) -(c-lang-defvar c-no-parens-syntax-table - (funcall (c-lang-const c-no-parens-syntax-table))) - (c-lang-defconst c-identifier-syntax-modifications "A list that describes the modifications that should be done to the mode syntax table to get a syntax table that matches all identifiers @@ -444,36 +423,26 @@ the new syntax, as accepted by `modify-syntax-entry'." classifies symbol constituents like '_' and '$' as word constituents, so that all identifiers are recognized as words.") -(c-lang-defconst c-get-state-before-change-functions - ;; For documentation see the following c-lang-defvar of the same name. - ;; The value here may be a list of functions or a single function. - t nil - c++ '(c-extend-region-for-CPP c-before-change-check-<>-operators) - (c objc) 'c-extend-region-for-CPP - ;; java 'c-before-change-check-<>-operators - awk 'c-awk-record-region-clear-NL) -(c-lang-defvar c-get-state-before-change-functions - (let ((fs (c-lang-const c-get-state-before-change-functions))) - (if (listp fs) - fs - (list fs))) - "If non-nil, a list of functions called from c-before-change-hook. -Typically these will record enough state to allow +(c-lang-defconst c-get-state-before-change-function + "If non-nil, a function called from c-before-change-hook. +Typically it will record enough state to allow `c-before-font-lock-function' to extend the region to fontify, and may do such things as removing text-properties which must be recalculated. -These functions will be run in the order given. Each of them -takes 2 parameters, the BEG and END supplied to every +It takes 2 parameters, the BEG and END supplied to every before-change function; on entry, the buffer will have been widened and match-data will have been saved; point is undefined on both entry and exit; the return value is ignored. -The functions are called even when font locking isn't enabled. - -When the mode is initialized, the functions are called with -parameters \(point-min) and \(point-max).") - +When the mode is initialized, this function is called with +parameters \(point-min) and \(point-max)." + t nil + (c c++ objc) 'c-extend-region-for-CPP + awk 'c-awk-record-region-clear-NL) +(c-lang-defvar c-get-state-before-change-function + (c-lang-const c-get-state-before-change-function)) + (c-lang-defconst c-before-font-lock-function "If non-nil, a function called just before font locking. Typically it will extend the region about to be fontified \(see diff --git a/lisp/progmodes/cc-mode.el b/lisp/progmodes/cc-mode.el index 57f87c04b8..91fc29cdfa 100644 --- a/lisp/progmodes/cc-mode.el +++ b/lisp/progmodes/cc-mode.el @@ -641,12 +641,8 @@ compatible with old code; callers should always specify it." (save-restriction (widen) (save-excursion - (if c-get-state-before-change-functions - (let ((beg (point-min)) - (end (point-max))) - (mapc (lambda (fn) - (funcall fn beg end)) - c-get-state-before-change-functions))) + (if c-get-state-before-change-function + (funcall c-get-state-before-change-function (point-min) (point-max))) (if c-before-font-lock-function (funcall c-before-font-lock-function (point-min) (point-max) (- (point-max) (point-min)))))) @@ -779,7 +775,7 @@ Note that the style variables are always made local to the buffer." (defmacro c-run-mode-hooks (&rest hooks) ;; Emacs 21.1 has introduced a system with delayed mode hooks that - ;; requires the use of the new function `run-mode-hooks'. + ;; require the use of the new function `run-mode-hooks'. (if (cc-bytecomp-fboundp 'run-mode-hooks) `(run-mode-hooks ,@hooks) `(progn ,@(mapcar (lambda (hook) `(run-hooks ,hook)) hooks)))) @@ -812,8 +808,8 @@ Note that the style variables are always made local to the buffer." ;; has already been widened, and match-data saved. The return value is ;; meaningless. ;; - ;; This function is in the C/C++/ObjC values of - ;; `c-get-state-before-change-functions' and is called exclusively as a + ;; This function is the C/C++/ObjC value of + ;; `c-get-state-before-change-function' and is called exclusively as a ;; before change function. (goto-char beg) (c-beginning-of-macro) @@ -926,8 +922,8 @@ Note that the style variables are always made local to the buffer." ))))) (defun c-before-change (beg end) - ;; Function to be put on `before-change-functions'. Primarily, this calls - ;; the language dependent `c-get-state-before-change-functions'. It is + ;; Function to be put on `before-change-function'. Primarily, this calls + ;; the language dependent `c-get-state-before-change-function'. It is ;; otherwise used only to remove stale entries from the `c-found-types' ;; cache, and to record entries which a `c-after-change' function might ;; confirm as stale. @@ -1005,10 +1001,8 @@ Note that the style variables are always made local to the buffer." ;; larger than (beg end). (setq c-new-BEG beg c-new-END end) - (if c-get-state-before-change-functions - (mapc (lambda (fn) - (funcall fn beg end)) - c-get-state-before-change-functions)) + (if c-get-state-before-change-function + (funcall c-get-state-before-change-function beg end)) )))) (defun c-after-change (beg end old-len)