diff options
| -rw-r--r-- | lisp/ChangeLog | 16 | ||||
| -rw-r--r-- | lisp/simple.el | 178 |
2 files changed, 92 insertions, 102 deletions
diff --git a/lisp/ChangeLog b/lisp/ChangeLog index 4fe6afdf457..ead2c35b192 100644 --- a/lisp/ChangeLog +++ b/lisp/ChangeLog | |||
| @@ -1,7 +1,19 @@ | |||
| 1 | 2010-09-02 Stefan Monnier <monnier@iro.umontreal.ca> | ||
| 2 | |||
| 3 | * simple.el (newline): Eliminate optimization. | ||
| 4 | Use post-self-insert-hook to set hard-newline and things before | ||
| 5 | running post-self-insert-hook. | ||
| 6 | (blink-matching-check-mismatch): New function. | ||
| 7 | (blink-matching-check-function): New variable. | ||
| 8 | (blink-matching-open): Use them. | ||
| 9 | Skip back forward over prefix chars skipped by forward-sexp. | ||
| 10 | Don't check if the parens are backslash escaped. | ||
| 11 | (blink-paren-post-self-insert-function): Check backslash escaping here. | ||
| 12 | |||
| 1 | 2010-09-02 Chong Yidong <cyd@stupidchicken.com> | 13 | 2010-09-02 Chong Yidong <cyd@stupidchicken.com> |
| 2 | 14 | ||
| 3 | * emacs-lisp/package.el (package-menu-mode-map): Change | 15 | * emacs-lisp/package.el (package-menu-mode-map): |
| 4 | package-menu-revert bindings to revert-buffer. | 16 | Change package-menu-revert bindings to revert-buffer. |
| 5 | (package-menu-mode): Set revert-buffer-function. | 17 | (package-menu-mode): Set revert-buffer-function. |
| 6 | (package-menu-revert): Doc fix. | 18 | (package-menu-revert): Doc fix. |
| 7 | 19 | ||
diff --git a/lisp/simple.el b/lisp/simple.el index 60d82dd3a48..4511208e434 100644 --- a/lisp/simple.el +++ b/lisp/simple.el | |||
| @@ -457,72 +457,38 @@ Call `auto-fill-function' if the current column number is greater | |||
| 457 | than the value of `fill-column' and ARG is nil." | 457 | than the value of `fill-column' and ARG is nil." |
| 458 | (interactive "*P") | 458 | (interactive "*P") |
| 459 | (barf-if-buffer-read-only) | 459 | (barf-if-buffer-read-only) |
| 460 | ;; Inserting a newline at the end of a line produces better redisplay in | 460 | (let ((was-page-start (and (bolp) |
| 461 | ;; try_window_id than inserting at the beginning of a line, and the textual | ||
| 462 | ;; result is the same. So, if we're at beginning of line, pretend to be at | ||
| 463 | ;; the end of the previous line. | ||
| 464 | (let ((flag (and (not (bobp)) | ||
| 465 | (bolp) | ||
| 466 | ;; Make sure no functions want to be told about | ||
| 467 | ;; the range of the changes. | ||
| 468 | (not after-change-functions) | ||
| 469 | (not before-change-functions) | ||
| 470 | ;; Make sure there are no markers here. | ||
| 471 | (not (buffer-has-markers-at (1- (point)))) | ||
| 472 | (not (buffer-has-markers-at (point))) | ||
| 473 | ;; Make sure no text properties want to know | ||
| 474 | ;; where the change was. | ||
| 475 | (not (get-char-property (1- (point)) 'modification-hooks)) | ||
| 476 | (not (get-char-property (1- (point)) 'insert-behind-hooks)) | ||
| 477 | (or (eobp) | ||
| 478 | (not (get-char-property (point) 'insert-in-front-hooks))) | ||
| 479 | ;; Make sure the newline before point isn't intangible. | ||
| 480 | (not (get-char-property (1- (point)) 'intangible)) | ||
| 481 | ;; Make sure the newline before point isn't read-only. | ||
| 482 | (not (get-char-property (1- (point)) 'read-only)) | ||
| 483 | ;; Make sure the newline before point isn't invisible. | ||
| 484 | (not (get-char-property (1- (point)) 'invisible)) | ||
| 485 | ;; Make sure the newline before point has the same | ||
| 486 | ;; properties as the char before it (if any). | ||
| 487 | (< (or (previous-property-change (point)) -2) | ||
| 488 | (- (point) 2)))) | ||
| 489 | (was-page-start (and (bolp) | ||
| 490 | (looking-at page-delimiter))) | 461 | (looking-at page-delimiter))) |
| 491 | (beforepos (point))) | 462 | (beforepos (point))) |
| 492 | (if flag (backward-char 1)) | ||
| 493 | ;; Call self-insert so that auto-fill, abbrev expansion etc. happens. | 463 | ;; Call self-insert so that auto-fill, abbrev expansion etc. happens. |
| 494 | ;; Set last-command-event to tell self-insert what to insert. | 464 | ;; Set last-command-event to tell self-insert what to insert. |
| 495 | (let ((last-command-event ?\n) | 465 | (let ((last-command-event ?\n) |
| 496 | ;; Don't auto-fill if we have a numeric argument. | 466 | ;; Don't auto-fill if we have a numeric argument. |
| 497 | ;; Also not if flag is true (it would fill wrong line); | 467 | (auto-fill-function (if arg nil auto-fill-function)) |
| 498 | ;; there is no need to since we're at BOL. | 468 | (post-self-insert-hook post-self-insert-hook)) |
| 499 | (auto-fill-function (if (or arg flag) nil auto-fill-function))) | 469 | ;; Do the rest in post-self-insert-hook, because we want to do it |
| 500 | (unwind-protect | 470 | ;; *before* other functions on that hook. |
| 501 | (self-insert-command (prefix-numeric-value arg)) | 471 | (add-hook 'post-self-insert-hook |
| 502 | ;; If we get an error in self-insert-command, put point at right place. | 472 | (lambda () |
| 503 | (if flag (forward-char 1)))) | 473 | ;; Mark the newline(s) `hard'. |
| 504 | ;; Even if we did *not* get an error, keep that forward-char; | 474 | (if use-hard-newlines |
| 505 | ;; all further processing should apply to the newline that the user | 475 | (set-hard-newline-properties |
| 506 | ;; thinks he inserted. | 476 | (- (point) (prefix-numeric-value arg)) (point))) |
| 507 | 477 | ;; If the newline leaves the previous line blank, and we | |
| 508 | ;; Mark the newline(s) `hard'. | 478 | ;; have a left margin, delete that from the blank line. |
| 509 | (if use-hard-newlines | 479 | (save-excursion |
| 510 | (set-hard-newline-properties | 480 | (goto-char beforepos) |
| 511 | (- (point) (prefix-numeric-value arg)) (point))) | 481 | (beginning-of-line) |
| 512 | ;; If the newline leaves the previous line blank, | 482 | (and (looking-at "[ \t]$") |
| 513 | ;; and we have a left margin, delete that from the blank line. | 483 | (> (current-left-margin) 0) |
| 514 | (or flag | 484 | (delete-region (point) |
| 515 | (save-excursion | 485 | (line-end-position)))) |
| 516 | (goto-char beforepos) | 486 | ;; Indent the line after the newline, except in one case: |
| 517 | (beginning-of-line) | 487 | ;; when we added the newline at the beginning of a line which |
| 518 | (and (looking-at "[ \t]$") | 488 | ;; starts a page. |
| 519 | (> (current-left-margin) 0) | 489 | (or was-page-start |
| 520 | (delete-region (point) (progn (end-of-line) (point)))))) | 490 | (move-to-left-margin nil t)))) |
| 521 | ;; Indent the line after the newline, except in one case: | 491 | (self-insert-command (prefix-numeric-value arg)))) |
| 522 | ;; when we added the newline at the beginning of a line | ||
| 523 | ;; which starts a page. | ||
| 524 | (or was-page-start | ||
| 525 | (move-to-left-margin nil t))) | ||
| 526 | nil) | 492 | nil) |
| 527 | 493 | ||
| 528 | (defun set-hard-newline-properties (from to) | 494 | (defun set-hard-newline-properties (from to) |
| @@ -5503,21 +5469,40 @@ it skips the contents of comments that end before point." | |||
| 5503 | :type 'boolean | 5469 | :type 'boolean |
| 5504 | :group 'paren-blinking) | 5470 | :group 'paren-blinking) |
| 5505 | 5471 | ||
| 5472 | (defun blink-matching-check-mismatch (start end) | ||
| 5473 | "Return whether or not START...END are matching parens. | ||
| 5474 | END is the current point and START is the blink position. | ||
| 5475 | START might be nil if no matching starter was found. | ||
| 5476 | Returns non-nil if we find there is a mismatch." | ||
| 5477 | (let* ((end-syntax (syntax-after (1- end))) | ||
| 5478 | (matching-paren (and (consp end-syntax) | ||
| 5479 | (eq (syntax-class end-syntax) 5) | ||
| 5480 | (cdr end-syntax)))) | ||
| 5481 | ;; For self-matched chars like " and $, we can't know when they're | ||
| 5482 | ;; mismatched or unmatched, so we can only do it for parens. | ||
| 5483 | (when matching-paren | ||
| 5484 | (not (and start | ||
| 5485 | (or | ||
| 5486 | (eq (char-after start) matching-paren) | ||
| 5487 | ;; The cdr might hold a new paren-class info rather than | ||
| 5488 | ;; a matching-char info, in which case the two CDRs | ||
| 5489 | ;; should match. | ||
| 5490 | (eq matching-paren (cdr-safe (syntax-after start))))))))) | ||
| 5491 | |||
| 5492 | (defvar blink-matching-check-function #'blink-matching-check-mismatch | ||
| 5493 | "Function to check parentheses mismatches. | ||
| 5494 | The function takes two arguments (START and END) where START is the | ||
| 5495 | position just before the opening token and END is the position right after. | ||
| 5496 | START can be nil, if it was not found. | ||
| 5497 | The function should return non-nil if the two tokens do not match.") | ||
| 5498 | |||
| 5506 | (defun blink-matching-open () | 5499 | (defun blink-matching-open () |
| 5507 | "Move cursor momentarily to the beginning of the sexp before point." | 5500 | "Move cursor momentarily to the beginning of the sexp before point." |
| 5508 | (interactive) | 5501 | (interactive) |
| 5509 | (when (and (> (point) (point-min)) | 5502 | (when (and (not (bobp)) |
| 5510 | blink-matching-paren | 5503 | blink-matching-paren) |
| 5511 | ;; Verify an even number of quoting characters precede the close. | ||
| 5512 | (= 1 (logand 1 (- (point) | ||
| 5513 | (save-excursion | ||
| 5514 | (forward-char -1) | ||
| 5515 | (skip-syntax-backward "/\\") | ||
| 5516 | (point)))))) | ||
| 5517 | (let* ((oldpos (point)) | 5504 | (let* ((oldpos (point)) |
| 5518 | (message-log-max nil) ; Don't log messages about paren matching. | 5505 | (message-log-max nil) ; Don't log messages about paren matching. |
| 5519 | (atdollar (eq (syntax-class (syntax-after (1- oldpos))) 8)) | ||
| 5520 | (isdollar) | ||
| 5521 | (blinkpos | 5506 | (blinkpos |
| 5522 | (save-excursion | 5507 | (save-excursion |
| 5523 | (save-restriction | 5508 | (save-restriction |
| @@ -5532,38 +5517,25 @@ it skips the contents of comments that end before point." | |||
| 5532 | (condition-case () | 5517 | (condition-case () |
| 5533 | (progn | 5518 | (progn |
| 5534 | (forward-sexp -1) | 5519 | (forward-sexp -1) |
| 5520 | ;; backward-sexp skips backward over prefix chars, | ||
| 5521 | ;; so move back to the matching paren. | ||
| 5522 | (while (and (< (point) (1- oldpos)) | ||
| 5523 | (let ((code (car (syntax-after (point))))) | ||
| 5524 | (or (eq (logand 65536 code) 6) | ||
| 5525 | (eq (logand 1048576 code) 1048576)))) | ||
| 5526 | (forward-char 1)) | ||
| 5535 | (point)) | 5527 | (point)) |
| 5536 | (error nil)))))) | 5528 | (error nil)))))) |
| 5537 | (matching-paren | 5529 | (mismatch (funcall blink-matching-check-function blinkpos oldpos))) |
| 5538 | (and blinkpos | ||
| 5539 | ;; Not syntax '$'. | ||
| 5540 | (not (setq isdollar | ||
| 5541 | (eq (syntax-class (syntax-after blinkpos)) 8))) | ||
| 5542 | (let ((syntax (syntax-after blinkpos))) | ||
| 5543 | (and (consp syntax) | ||
| 5544 | (eq (syntax-class syntax) 4) | ||
| 5545 | (cdr syntax)))))) | ||
| 5546 | (cond | 5530 | (cond |
| 5547 | ;; isdollar is for: | 5531 | (mismatch |
| 5548 | ;; http://lists.gnu.org/archive/html/emacs-devel/2007-10/msg00871.html | 5532 | (if blinkpos |
| 5549 | ((not (or (and isdollar blinkpos) | ||
| 5550 | (and atdollar (not blinkpos)) ; see below | ||
| 5551 | (eq matching-paren (char-before oldpos)) | ||
| 5552 | ;; The cdr might hold a new paren-class info rather than | ||
| 5553 | ;; a matching-char info, in which case the two CDRs | ||
| 5554 | ;; should match. | ||
| 5555 | (eq matching-paren (cdr (syntax-after (1- oldpos)))))) | ||
| 5556 | (if (minibufferp) | ||
| 5557 | (minibuffer-message " [Mismatched parentheses]") | ||
| 5558 | (message "Mismatched parentheses"))) | ||
| 5559 | ((not blinkpos) | ||
| 5560 | (or blink-matching-paren-distance | ||
| 5561 | ;; Don't complain when `$' with no blinkpos, because it | ||
| 5562 | ;; could just be the first one typed in the buffer. | ||
| 5563 | atdollar | ||
| 5564 | (if (minibufferp) | 5533 | (if (minibufferp) |
| 5565 | (minibuffer-message " [Unmatched parenthesis]") | 5534 | (minibuffer-message " [Mismatched parentheses]") |
| 5566 | (message "Unmatched parenthesis")))) | 5535 | (message "Mismatched parentheses")) |
| 5536 | (if (minibufferp) | ||
| 5537 | (minibuffer-message " [Unmatched parenthesis]") | ||
| 5538 | (message "Unmatched parenthesis")))) | ||
| 5567 | ((pos-visible-in-window-p blinkpos) | 5539 | ((pos-visible-in-window-p blinkpos) |
| 5568 | ;; Matching open within window, temporarily move to blinkpos but only | 5540 | ;; Matching open within window, temporarily move to blinkpos but only |
| 5569 | ;; if `blink-matching-paren-on-screen' is non-nil. | 5541 | ;; if `blink-matching-paren-on-screen' is non-nil. |
| @@ -5615,7 +5587,13 @@ More precisely, a char with closeparen syntax is self-inserted.") | |||
| 5615 | (memq (char-syntax last-command-event) '(?\) ?\$)) | 5587 | (memq (char-syntax last-command-event) '(?\) ?\$)) |
| 5616 | blink-paren-function | 5588 | blink-paren-function |
| 5617 | (not executing-kbd-macro) | 5589 | (not executing-kbd-macro) |
| 5618 | (not noninteractive)) | 5590 | (not noninteractive) |
| 5591 | ;; Verify an even number of quoting characters precede the close. | ||
| 5592 | (= 1 (logand 1 (- (point) | ||
| 5593 | (save-excursion | ||
| 5594 | (forward-char -1) | ||
| 5595 | (skip-syntax-backward "/\\") | ||
| 5596 | (point)))))) | ||
| 5619 | (funcall blink-paren-function))) | 5597 | (funcall blink-paren-function))) |
| 5620 | 5598 | ||
| 5621 | (add-hook 'post-self-insert-hook #'blink-paren-post-self-insert-function | 5599 | (add-hook 'post-self-insert-hook #'blink-paren-post-self-insert-function |