(when (> ol-end end)
(overlay-put (make-overlay end ol-end) 'face face))))
+\f
+(defmacro c-looking-at-c++-attribute ()
+ ;; If we're in C++ Mode, and point is at the [[ introducing an attribute,
+ ;; return the position of the end of the attribute, otherwise return nil.
+ ;; The match data are NOT preserved over this macro.
+ `(and
+ (c-major-mode-is 'c++-mode)
+ (looking-at "\\[\\[")
+ (save-excursion
+ (and
+ (c-go-list-forward)
+ (eq (char-before) ?\])
+ (eq (char-before (1- (point))) ?\])
+ (point)))))
+
\f
;; `c-beginning-of-statement-1' and accompanying stuff.
c-opt-cpp-symbol ; usually "#"
(substring c-stmt-delim-chars 1)) ; e.g. ";{}?:"
c-stmt-delim-chars))
+ (skip-chars
+ (if (c-major-mode-is 'c++-mode)
+ (concat (substring skip-chars 0 1) ; "^"
+ "[" ; to catch C++ attributes
+ (substring skip-chars 1)) ; e.g. "#;{}?:"
+ skip-chars))
(non-skip-list
(append (substring skip-chars 1) nil)) ; e.g. (?# ?\; ?{ ?} ?? ?:)
- lit-range lit-start vsemi-pos)
+ lit-range lit-start vsemi-pos attr-end)
(save-restriction
(widen)
(save-excursion
;; In a string/comment?
((setq lit-range (c-literal-limits from))
(goto-char (cdr lit-range)))
+ ;; Skip over a C++ attribute?
+ ((eq (char-after) ?\[)
+ (if (setq attr-end (c-looking-at-c++-attribute))
+ (goto-char attr-end)
+ (forward-char)))
((eq (char-after) ?:)
(forward-char)
(if (and (eq (char-after) ?:)
(def-edebug-spec c-remove-is-and-in-sws t)
;; The type of literal position `end' is in a `before-change-functions'
-;; function - one of `c', `c++', `pound', or nil (but NOT `string').
+;; function - one of `c', `c++', `pound', `noise', `attribute' or nil (but NOT
+;; `string').
(defvar c-sws-lit-type nil)
-;; A cons (START . STOP) of the bounds of the comment or CPP construct
+;; A cons (START . STOP) of the bounds of the comment or CPP construct, etc.,
;; enclosing END, if any, else nil.
(defvar c-sws-lit-limits nil)
+(defun c-enclosing-c++-attribute ()
+ ;; If we're in C++ Mode, and point is within a correctly balanced [[ ... ]]
+ ;; attribute structure, return a cons of its starting and ending positions.
+ ;; Otherwise, return nil. We use the c-{in,is}-sws-face text properties for
+ ;; this determination, this macro being intended only for use in the *-sws-*
+ ;; functions and macros. The match data are NOT preserved over this macro.
+ (let (attr-end pos-is-sws)
+ (and
+ (c-major-mode-is 'c++-mode)
+ (> (point) (point-min))
+ (setq pos-is-sws
+ (if (get-text-property (1- (point)) 'c-is-sws)
+ (1- (point))
+ (1- (previous-single-property-change
+ (point) 'c-is-sws nil (point-min)))))
+ (save-excursion
+ (goto-char pos-is-sws)
+ (setq attr-end (c-looking-at-c++-attribute)))
+ (> attr-end (point))
+ (cons pos-is-sws attr-end))))
+
+(defun c-slow-enclosing-c++-attribute ()
+ ;; Like `c-enclosing-c++-attribute', but does not depend on the c-i[ns]-sws
+ ;; properties being set.
+ (and
+ (c-major-mode-is 'c++-mode)
+ (save-excursion
+ (let ((paren-state (c-parse-state))
+ cand)
+ (while
+ (progn
+ (setq cand
+ (catch 'found-cand
+ (while (cdr paren-state)
+ (when (and (numberp (car paren-state))
+ (numberp (cadr paren-state))
+ (eq (car paren-state)
+ (1+ (cadr paren-state)))
+ (eq (char-after (car paren-state)) ?\[)
+ (eq (char-after (cadr paren-state)) ?\[))
+ (throw 'found-cand (cadr paren-state)))
+ (setq paren-state (cdr paren-state)))))
+ (and cand
+ (not
+ (and (c-go-list-forward cand)
+ (eq (char-before) ?\])
+ (eq (char-before (1- (point))) ?\])))))
+ (setq paren-state (cdr paren-state)))
+ (and cand (cons cand (point)))))))
+
(defun c-invalidate-sws-region-before (beg end)
;; Called from c-before-change. BEG and END are the bounds of the change
;; region, the standard parameters given to all before-change-functions.
;; if so note its bounds in `c-sws-lit-limits' and type in `c-sws-lit-type'.
(setq c-sws-lit-type nil
c-sws-lit-limits nil)
- (save-excursion
- (goto-char end)
- (let* ((limits (c-literal-limits))
- (lit-type (c-literal-type limits)))
- (cond
- ((memq lit-type '(c c++))
- (setq c-sws-lit-type lit-type
- c-sws-lit-limits limits))
- ((c-beginning-of-macro)
- (setq c-sws-lit-type 'pound
- c-sws-lit-limits (cons (point)
- (progn (c-end-of-macro) (point)))))
- ((progn (skip-syntax-backward "w_")
- (looking-at c-noise-macro-name-re))
- (setq c-sws-lit-type 'noise
- c-sws-lit-limits (cons (match-beginning 1) (match-end 1))))
- (t))))
- (save-excursion
- (goto-char beg)
- (skip-syntax-backward "w_")
- (when (looking-at c-noise-macro-name-re)
- (setq c-sws-lit-type 'noise)
- (if (consp c-sws-lit-limits)
- (setcar c-sws-lit-limits (match-beginning 1))
- (setq c-sws-lit-limits (cons (match-beginning 1) (match-end 1)))))))
+ (save-match-data
+ (save-excursion
+ (goto-char end)
+ (let* ((limits (c-literal-limits))
+ (lit-type (c-literal-type limits)))
+ (cond
+ ((memq lit-type '(c c++))
+ (setq c-sws-lit-type lit-type
+ c-sws-lit-limits limits))
+ ((c-beginning-of-macro)
+ (setq c-sws-lit-type 'pound
+ c-sws-lit-limits (cons (point)
+ (progn (c-end-of-macro) (point)))))
+ ((eq lit-type 'string))
+ ((setq c-sws-lit-limits (c-enclosing-c++-attribute))
+ (setq c-sws-lit-type 'attribute))
+ ((progn (skip-syntax-backward "w_")
+ (looking-at c-noise-macro-name-re))
+ (setq c-sws-lit-type 'noise
+ c-sws-lit-limits (cons (match-beginning 1) (match-end 1))))
+ (t))))
+ (save-excursion
+ (goto-char beg)
+ (let ((attr-limits (c-enclosing-c++-attribute)))
+ (if attr-limits
+ (if (consp c-sws-lit-limits)
+ (setcar c-sws-lit-limits (car attr-limits))
+ (setq c-sws-lit-limits attr-limits))
+ (skip-syntax-backward "w_")
+ (when (looking-at c-noise-macro-name-re)
+ (setq c-sws-lit-type 'noise)
+ (if (consp c-sws-lit-limits)
+ (setcar c-sws-lit-limits (match-beginning 1))
+ (setq c-sws-lit-limits (cons (match-beginning 1)
+ (match-end 1))))))))))
(defun c-invalidate-sws-region-after-del (beg end _old-len)
;; Text has been deleted, OLD-LEN characters of it starting from position
(when (and (eolp) (not (eobp)))
(setq end (1+ (point)))))
- (when (eq c-sws-lit-type 'noise)
+ (when (memq c-sws-lit-type '(noise attribute))
(setq beg (car c-sws-lit-limits)
end (cdr c-sws-lit-limits))) ; This last setting may be redundant.
(when (or (looking-at c-syntactic-ws-start)
(and c-opt-cpp-prefix
(looking-at c-noise-macro-name-re))
+ (and (c-major-mode-is 'c++-mode)
+ (looking-at "\\[\\["))
(looking-at c-doc-line-join-re))
(setq rung-end-pos (min (1+ (point)) (point-max)))
(goto-char (match-end 1))
(not (eobp)))
+ ((setq next-rung-pos (c-looking-at-c++-attribute))
+ (goto-char next-rung-pos)
+ (not (eobp)))
+
((looking-at c-doc-line-join-re)
;; Skip over a line join in (e.g.) Pike autodoc.
(goto-char (match-end 0))
"c-forward-sws clearing thoroughly at %s for cache separation"
(1- last-put-in-sws-pos))
(c-remove-is-and-in-sws (1- last-put-in-sws-pos)
- last-put-in-sws-pos))))
- ))))
+ last-put-in-sws-pos))))))))
(defun c-backward-sws ()
;; Used by `c-backward-syntactic-ws' to implement the unbounded search.
;; part of the simple ws region.
(rung-pos (point)) next-rung-pos last-put-in-sws-pos
rung-is-marked simple-ws-beg cmt-skip-pos
- (doc-line-join-here (concat c-doc-line-join-re "\\=")))
+ (doc-line-join-here (concat c-doc-line-join-re "\\="))
+ attr-end)
;; Skip simple horizontal ws and do a quick check on the preceding
;; character to see if it's anything that can't end syntactic ws, so we can
(memq (char-before) c-doc-line-join-end-ch) ; For speed.
(re-search-backward doc-line-join-here
(c-point 'bopl) t))
+ (and
+ (c-major-mode-is 'c++-mode)
+ (eq (char-before) ?\])
+ (eq (char-before (1- (point))) ?\])
+ (save-excursion
+ (and (c-go-list-backward)
+ (looking-at "\\[\\[")))
+ (setq attr-end (point)))
(progn
(backward-char)
(or (looking-at c-syntactic-ws-end)
;; Try to find a rung position in the simple ws preceding point, so that
;; we can get a cache hit even if the last bit of the simple ws has
;; changed recently.
- (setq simple-ws-beg (or (match-end 1) ; Noise macro
+ (setq simple-ws-beg (or attr-end ; After attribute.
+ (match-end 1) ; Noise macro, etc.
(match-end 0))) ; c-syntactic-ws-end
(skip-chars-backward " \t\n\r\f\v")
(if (setq rung-is-marked (text-property-any
(goto-char next-rung-pos)
t)
+ ((and (c-major-mode-is 'c++-mode)
+ (eq (char-before) ?\])
+ (eq (char-before (1- (point))) ?\])
+ (save-excursion
+ (and (c-go-list-backward)
+ (setq next-rung-pos (point))
+ (looking-at "\\[\\["))))
+ (goto-char next-rung-pos)
+ t)
+
((and
(memq (char-before) c-doc-line-join-end-ch) ; For speed.
(re-search-backward doc-line-join-here (c-point 'bopl) t)))))