diff options
| author | Alan Mackenzie | 2007-03-08 21:50:51 +0000 |
|---|---|---|
| committer | Alan Mackenzie | 2007-03-08 21:50:51 +0000 |
| commit | 9c184ed25c8db6d68268c06dbba1736eb4f003e5 (patch) | |
| tree | 6a87b1467c0c8b9024d69d595043e73e683c1114 | |
| parent | 4cc4ad8ae5e861baf67d28669bcb589864334e63 (diff) | |
| download | emacs-9c184ed25c8db6d68268c06dbba1736eb4f003e5.tar.gz emacs-9c184ed25c8db6d68268c06dbba1736eb4f003e5.zip | |
(c-unfind-enclosing-token, c-unfind-coalesced-tokens, c-before-change): new
functions;
(c-maybe-stale-found-type): new variable.
An ad hoc attempt to remove stale tokens from the cache `c-found-types'.
| -rw-r--r-- | lisp/progmodes/cc-mode.el | 141 |
1 files changed, 139 insertions, 2 deletions
diff --git a/lisp/progmodes/cc-mode.el b/lisp/progmodes/cc-mode.el index e2891bde98d..a79ca3cac6e 100644 --- a/lisp/progmodes/cc-mode.el +++ b/lisp/progmodes/cc-mode.el | |||
| @@ -412,8 +412,142 @@ preferably use the `c-mode-menu' language constant directly." | |||
| 412 | ;; temporary changes in some font lock support modes, causing extra | 412 | ;; temporary changes in some font lock support modes, causing extra |
| 413 | ;; unnecessary work and font lock glitches due to interactions between | 413 | ;; unnecessary work and font lock glitches due to interactions between |
| 414 | ;; various text properties. | 414 | ;; various text properties. |
| 415 | 415 | ;; | |
| 416 | (defun c-after-change (beg end len) | 416 | ;; (2007-02-12): The macro `combine-after-change-calls' ISN'T used any |
| 417 | ;; more. | ||
| 418 | |||
| 419 | (defun c-unfind-enclosing-token (pos) | ||
| 420 | ;; If POS is wholly inside a token, remove that id from | ||
| 421 | ;; `c-found-types', should it be present. Return t if we were in an | ||
| 422 | ;; id, else nil. | ||
| 423 | (save-excursion | ||
| 424 | (let ((tok-beg (progn (goto-char pos) | ||
| 425 | (and (c-beginning-of-current-token) (point)))) | ||
| 426 | (tok-end (progn (goto-char pos) | ||
| 427 | (and (c-end-of-current-token) (point))))) | ||
| 428 | (when (and tok-beg tok-end) | ||
| 429 | (c-unfind-type (buffer-substring-no-properties tok-beg tok-end)) | ||
| 430 | t)))) | ||
| 431 | |||
| 432 | (defun c-unfind-coalesced-tokens (beg end) | ||
| 433 | ;; unless the non-empty region (beg end) is entirely WS and there's at | ||
| 434 | ;; least one character of WS just before or after this region, remove | ||
| 435 | ;; the tokens which touch the region from `c-found-types' should they | ||
| 436 | ;; be present. | ||
| 437 | (or (c-partial-ws-p beg end) | ||
| 438 | (save-excursion | ||
| 439 | (progn | ||
| 440 | (goto-char beg) | ||
| 441 | (or (eq beg (point-min)) | ||
| 442 | (c-skip-ws-backward (1- beg)) | ||
| 443 | (/= (point) beg) | ||
| 444 | (= (c-backward-token-2) 1) | ||
| 445 | (c-unfind-type (buffer-substring-no-properties | ||
| 446 | (point) beg))) | ||
| 447 | (goto-char end) | ||
| 448 | (or (eq end (point-max)) | ||
| 449 | (c-skip-ws-forward (1+ end)) | ||
| 450 | (/= (point) end) | ||
| 451 | (progn (forward-char) (c-end-of-current-token) nil) | ||
| 452 | (c-unfind-type (buffer-substring-no-properties | ||
| 453 | end (point)))))))) | ||
| 454 | |||
| 455 | ;; c-maybe-stale-found-type records a place near the region being | ||
| 456 | ;; changed where an element of `found-types' might become stale. It | ||
| 457 | ;; is set in c-before-change and is either nil, or has the form: | ||
| 458 | ;; | ||
| 459 | ;; (c-decl-id-start "foo" 97 107 " (* ooka) " "o"), where | ||
| 460 | ;; | ||
| 461 | ;; o - `c-decl-id-start' is the c-type text property value at buffer | ||
| 462 | ;; pos 96. | ||
| 463 | ;; | ||
| 464 | ;; o - 97 107 is the region potentially containing the stale type - | ||
| 465 | ;; this is delimited by a non-nil c-type text property at 96 and | ||
| 466 | ;; either another one or a ";", "{", or "}" at 107. | ||
| 467 | ;; | ||
| 468 | ;; o - " (* ooka) " is the (before change) buffer portion containing | ||
| 469 | ;; the suspect type (here "ooka"). | ||
| 470 | ;; | ||
| 471 | ;; o - "o" is the buffer contents which is about to be deleted. This | ||
| 472 | ;; would be the empty string for an insertion. | ||
| 473 | (defvar c-maybe-stale-found-type nil) | ||
| 474 | (make-variable-buffer-local 'c-maybe-stale-found-type) | ||
| 475 | |||
| 476 | (defun c-before-change (beg end) | ||
| 477 | ;; Function to be put on `before-change-function'. Currently | ||
| 478 | ;; (2007-02) it is used only to remove stale entries from the | ||
| 479 | ;; `c-found-types' cache, and to record entries which a | ||
| 480 | ;; `c-after-change' function might confirm as stale. | ||
| 481 | ;; | ||
| 482 | ;; Note that this function must be FAST rather than accurate. Note | ||
| 483 | ;; also that it only has any effect when font locking is enabled. | ||
| 484 | ;; We exploit this by checking for font-lock-*-face instead of doing | ||
| 485 | ;; rigourous syntactic analysis. | ||
| 486 | |||
| 487 | ;; If either change boundary is wholly inside an identifier, delete | ||
| 488 | ;; it/them from the cache. Don't worry about being inside a string | ||
| 489 | ;; or a comment - "wrongly" removing a symbol from `c-found-types' | ||
| 490 | ;; isn't critical. | ||
| 491 | (setq c-maybe-stale-found-type nil) | ||
| 492 | (save-restriction | ||
| 493 | (widen) | ||
| 494 | (save-excursion | ||
| 495 | ;; Are we inserting/deleting stuff in the middle of an identifier? | ||
| 496 | (c-unfind-enclosing-token beg) | ||
| 497 | (c-unfind-enclosing-token end) | ||
| 498 | ;; Are we coalescing two tokens together, e.g. "fo o" -> "foo"? | ||
| 499 | (when (< beg end) | ||
| 500 | (c-unfind-coalesced-tokens beg end)) | ||
| 501 | ;; Are we (potentially) disrupting the syntactic context which | ||
| 502 | ;; makes a type a type? E.g. by inserting stuff after "foo" in | ||
| 503 | ;; "foo bar;", or before "foo" in "typedef foo *bar;"? | ||
| 504 | ;; | ||
| 505 | ;; We search for appropriate c-type properties "near" the change. | ||
| 506 | ;; First, find an appropriate boundary for this property search. | ||
| 507 | (let (lim | ||
| 508 | type type-pos | ||
| 509 | marked-id term-pos | ||
| 510 | (end1 | ||
| 511 | (if (eq (get-text-property end 'face) 'font-lock-comment-face) | ||
| 512 | (previous-single-property-change end 'face) | ||
| 513 | end))) | ||
| 514 | (when (>= end1 beg) ; Don't hassle about changes entirely in comments. | ||
| 515 | ;; Find a limit for the search for a `c-type' property | ||
| 516 | (while | ||
| 517 | (and (/= (skip-chars-backward "^;{}") 0) | ||
| 518 | (> (point) (point-min)) | ||
| 519 | (memq (c-get-char-property (1- (point)) 'face) | ||
| 520 | '(font-lock-comment-face font-lock-string-face)))) | ||
| 521 | (setq lim (max (point-min) (1- (point)))) | ||
| 522 | |||
| 523 | ;; Look for the latest `c-type' property before end1 | ||
| 524 | (when (and (> end1 1) | ||
| 525 | (setq type-pos | ||
| 526 | (if (get-text-property (1- end1) 'c-type) | ||
| 527 | end1 | ||
| 528 | (previous-single-property-change end1 'c-type nil lim)))) | ||
| 529 | (setq type (get-text-property (max (1- type-pos) lim) 'c-type)) | ||
| 530 | |||
| 531 | (when (memq type '(c-decl-id-start c-decl-type-start)) | ||
| 532 | ;; Get the identifier, if any, that the property is on. | ||
| 533 | (goto-char (1- type-pos)) | ||
| 534 | (setq marked-id | ||
| 535 | (when (looking-at "\\(\\sw\\|\\s_\\)") | ||
| 536 | (c-beginning-of-current-token) | ||
| 537 | (buffer-substring-no-properties (point) type-pos))) | ||
| 538 | |||
| 539 | (goto-char end1) | ||
| 540 | (skip-chars-forward "^;{}") ; FIXME!!! loop for comment, maybe | ||
| 541 | (setq lim (point)) | ||
| 542 | (setq term-pos | ||
| 543 | (or (next-single-property-change end 'c-type nil lim) lim)) | ||
| 544 | (setq c-maybe-stale-found-type | ||
| 545 | (list type marked-id | ||
| 546 | type-pos term-pos | ||
| 547 | (buffer-substring-no-properties type-pos term-pos) | ||
| 548 | (buffer-substring-no-properties beg end)))))))))) | ||
| 549 | |||
| 550 | (defun c-after-change (beg end old-len) | ||
| 417 | ;; Function put on `after-change-functions' to adjust various caches | 551 | ;; Function put on `after-change-functions' to adjust various caches |
| 418 | ;; etc. Prefer speed to finesse here, since there will be an order | 552 | ;; etc. Prefer speed to finesse here, since there will be an order |
| 419 | ;; of magnitude more calls to this function than any of the | 553 | ;; of magnitude more calls to this function than any of the |
| @@ -441,6 +575,7 @@ preferably use the `c-mode-menu' language constant directly." | |||
| 441 | (when (> beg end) | 575 | (when (> beg end) |
| 442 | (setq beg end))) | 576 | (setq beg end))) |
| 443 | 577 | ||
| 578 | (c-trim-found-types beg end old-len) ; maybe we don't need all of these. | ||
| 444 | (c-invalidate-sws-region-after beg end) | 579 | (c-invalidate-sws-region-after beg end) |
| 445 | (c-invalidate-state-cache beg) | 580 | (c-invalidate-state-cache beg) |
| 446 | (c-invalidate-find-decl-cache beg) | 581 | (c-invalidate-find-decl-cache beg) |
| @@ -577,6 +712,8 @@ that requires a literal mode spec at compile time." | |||
| 577 | 712 | ||
| 578 | ;; Install the functions that ensure that various internal caches | 713 | ;; Install the functions that ensure that various internal caches |
| 579 | ;; don't become invalid due to buffer changes. | 714 | ;; don't become invalid due to buffer changes. |
| 715 | (make-local-hook 'before-change-functions) | ||
| 716 | (add-hook 'before-change-functions 'c-before-change nil t) | ||
| 580 | (make-local-hook 'after-change-functions) | 717 | (make-local-hook 'after-change-functions) |
| 581 | (add-hook 'after-change-functions 'c-after-change nil t)) | 718 | (add-hook 'after-change-functions 'c-after-change nil t)) |
| 582 | 719 | ||