diff options
| author | Mattias EngdegÄrd | 2021-04-30 17:09:21 +0200 |
|---|---|---|
| committer | Mattias EngdegÄrd | 2021-04-30 17:31:20 +0200 |
| commit | 1167253f75badf9e7df1bf983c2ebeb2d37d3881 (patch) | |
| tree | 8e8b97591a7298fa63bd17d2f50a43d514e4256f | |
| parent | ab7a61e0efd0684bc37a556d12f36521f9f61782 (diff) | |
| download | emacs-1167253f75badf9e7df1bf983c2ebeb2d37d3881.tar.gz emacs-1167253f75badf9e7df1bf983c2ebeb2d37d3881.zip | |
Don't signal scan-error in interactive sexp-based commands
This takes care of unfinished business from df0f32f04850 (bug#43489).
* lisp/emacs-lisp/lisp.el (end-of-defun, mark-defun):
* lisp/reposition.el (reposition-window):
* lisp/simple.el (transpose-sexps): Convert nasty-looking scan-error
into a human-readable message.
| -rw-r--r-- | lisp/emacs-lisp/lisp.el | 246 | ||||
| -rw-r--r-- | lisp/reposition.el | 232 | ||||
| -rw-r--r-- | lisp/simple.el | 73 |
3 files changed, 291 insertions, 260 deletions
diff --git a/lisp/emacs-lisp/lisp.el b/lisp/emacs-lisp/lisp.el index 46ca94869c7..2495277ba23 100644 --- a/lisp/emacs-lisp/lisp.el +++ b/lisp/emacs-lisp/lisp.el | |||
| @@ -503,7 +503,7 @@ If ARG is positive, that's the end of the buffer. | |||
| 503 | Otherwise, that's the beginning of the buffer." | 503 | Otherwise, that's the beginning of the buffer." |
| 504 | (if (> arg 0) (point-max) (point-min))) | 504 | (if (> arg 0) (point-max) (point-min))) |
| 505 | 505 | ||
| 506 | (defun end-of-defun (&optional arg) | 506 | (defun end-of-defun (&optional arg interactive) |
| 507 | "Move forward to next end of defun. | 507 | "Move forward to next end of defun. |
| 508 | With argument, do it that many times. | 508 | With argument, do it that many times. |
| 509 | Negative argument -N means move back to Nth preceding end of defun. | 509 | Negative argument -N means move back to Nth preceding end of defun. |
| @@ -513,129 +513,145 @@ matches the open-parenthesis that starts a defun; see function | |||
| 513 | `beginning-of-defun'. | 513 | `beginning-of-defun'. |
| 514 | 514 | ||
| 515 | If variable `end-of-defun-function' is non-nil, its value | 515 | If variable `end-of-defun-function' is non-nil, its value |
| 516 | is called as a function to find the defun's end." | 516 | is called as a function to find the defun's end. |
| 517 | (interactive "^p") | 517 | |
| 518 | (or (not (eq this-command 'end-of-defun)) | 518 | If INTERACTIVE is non-nil, as it is interactively, |
| 519 | (eq last-command 'end-of-defun) | 519 | report errors as appropriate for this kind of usage." |
| 520 | (and transient-mark-mode mark-active) | 520 | (interactive "^p\nd") |
| 521 | (push-mark)) | 521 | (if interactive |
| 522 | (if (or (null arg) (= arg 0)) (setq arg 1)) | 522 | (condition-case e |
| 523 | (let ((pos (point)) | 523 | (end-of-defun arg nil) |
| 524 | (beg (progn (end-of-line 1) (beginning-of-defun-raw 1) (point))) | 524 | (scan-error (user-error (cadr e)))) |
| 525 | (skip (lambda () | 525 | (or (not (eq this-command 'end-of-defun)) |
| 526 | ;; When comparing point against pos, we want to consider that if | 526 | (eq last-command 'end-of-defun) |
| 527 | ;; point was right after the end of the function, it's still | 527 | (and transient-mark-mode mark-active) |
| 528 | ;; considered as "in that function". | 528 | (push-mark)) |
| 529 | ;; E.g. `eval-defun' from right after the last close-paren. | 529 | (if (or (null arg) (= arg 0)) (setq arg 1)) |
| 530 | (unless (bolp) | 530 | (let ((pos (point)) |
| 531 | (skip-chars-forward " \t") | 531 | (beg (progn (end-of-line 1) (beginning-of-defun-raw 1) (point))) |
| 532 | (if (looking-at "\\s<\\|\n") | 532 | (skip (lambda () |
| 533 | (forward-line 1)))))) | 533 | ;; When comparing point against pos, we want to consider that |
| 534 | (funcall end-of-defun-function) | 534 | ;; if point was right after the end of the function, it's |
| 535 | (when (<= arg 1) | 535 | ;; still considered as "in that function". |
| 536 | (funcall skip)) | 536 | ;; E.g. `eval-defun' from right after the last close-paren. |
| 537 | (cond | 537 | (unless (bolp) |
| 538 | ((> arg 0) | 538 | (skip-chars-forward " \t") |
| 539 | ;; Moving forward. | 539 | (if (looking-at "\\s<\\|\n") |
| 540 | (if (> (point) pos) | 540 | (forward-line 1)))))) |
| 541 | ;; We already moved forward by one because we started from | 541 | (funcall end-of-defun-function) |
| 542 | ;; within a function. | 542 | (when (<= arg 1) |
| 543 | (setq arg (1- arg)) | 543 | (funcall skip)) |
| 544 | ;; We started from after the end of the previous function. | 544 | (cond |
| 545 | (goto-char pos)) | 545 | ((> arg 0) |
| 546 | (unless (zerop arg) | 546 | ;; Moving forward. |
| 547 | (beginning-of-defun-raw (- arg)) | 547 | (if (> (point) pos) |
| 548 | (funcall end-of-defun-function))) | 548 | ;; We already moved forward by one because we started from |
| 549 | ((< arg 0) | 549 | ;; within a function. |
| 550 | ;; Moving backward. | 550 | (setq arg (1- arg)) |
| 551 | (if (< (point) pos) | 551 | ;; We started from after the end of the previous function. |
| 552 | ;; We already moved backward because we started from between | 552 | (goto-char pos)) |
| 553 | ;; two functions. | 553 | (unless (zerop arg) |
| 554 | (setq arg (1+ arg)) | 554 | (beginning-of-defun-raw (- arg)) |
| 555 | ;; We started from inside a function. | 555 | (funcall end-of-defun-function))) |
| 556 | (goto-char beg)) | 556 | ((< arg 0) |
| 557 | (unless (zerop arg) | 557 | ;; Moving backward. |
| 558 | (if (< (point) pos) | ||
| 559 | ;; We already moved backward because we started from between | ||
| 560 | ;; two functions. | ||
| 561 | (setq arg (1+ arg)) | ||
| 562 | ;; We started from inside a function. | ||
| 563 | (goto-char beg)) | ||
| 564 | (unless (zerop arg) | ||
| 565 | (beginning-of-defun-raw (- arg)) | ||
| 566 | (setq beg (point)) | ||
| 567 | (funcall end-of-defun-function)))) | ||
| 568 | (funcall skip) | ||
| 569 | (while (and (< arg 0) (>= (point) pos)) | ||
| 570 | ;; We intended to move backward, but this ended up not doing so: | ||
| 571 | ;; Try harder! | ||
| 572 | (goto-char beg) | ||
| 558 | (beginning-of-defun-raw (- arg)) | 573 | (beginning-of-defun-raw (- arg)) |
| 559 | (setq beg (point)) | 574 | (if (>= (point) beg) |
| 560 | (funcall end-of-defun-function)))) | 575 | (setq arg 0) |
| 561 | (funcall skip) | 576 | (setq beg (point)) |
| 562 | (while (and (< arg 0) (>= (point) pos)) | 577 | (funcall end-of-defun-function) |
| 563 | ;; We intended to move backward, but this ended up not doing so: | 578 | (funcall skip)))))) |
| 564 | ;; Try harder! | 579 | |
| 565 | (goto-char beg) | 580 | (defun mark-defun (&optional arg interactive) |
| 566 | (beginning-of-defun-raw (- arg)) | ||
| 567 | (if (>= (point) beg) | ||
| 568 | (setq arg 0) | ||
| 569 | (setq beg (point)) | ||
| 570 | (funcall end-of-defun-function) | ||
| 571 | (funcall skip))))) | ||
| 572 | |||
| 573 | (defun mark-defun (&optional arg) | ||
| 574 | "Put mark at end of this defun, point at beginning. | 581 | "Put mark at end of this defun, point at beginning. |
| 575 | The defun marked is the one that contains point or follows point. | 582 | The defun marked is the one that contains point or follows point. |
| 576 | With positive ARG, mark this and that many next defuns; with negative | 583 | With positive ARG, mark this and that many next defuns; with negative |
| 577 | ARG, change the direction of marking. | 584 | ARG, change the direction of marking. |
| 578 | 585 | ||
| 579 | If the mark is active, it marks the next or previous defun(s) after | 586 | If the mark is active, it marks the next or previous defun(s) after |
| 580 | the one(s) already marked." | 587 | the one(s) already marked. |
| 581 | (interactive "p") | 588 | |
| 582 | (setq arg (or arg 1)) | 589 | If INTERACTIVE is non-nil, as it is interactively, |
| 583 | ;; There is no `mark-defun-back' function - see | 590 | report errors as appropriate for this kind of usage." |
| 584 | ;; https://lists.gnu.org/r/bug-gnu-emacs/2016-11/msg00079.html | 591 | (interactive "p\nd") |
| 585 | ;; for explanation | 592 | (if interactive |
| 586 | (when (eq last-command 'mark-defun-back) | 593 | (condition-case e |
| 587 | (setq arg (- arg))) | 594 | (mark-defun arg nil) |
| 588 | (when (< arg 0) | 595 | (scan-error (user-error (cadr e)))) |
| 589 | (setq this-command 'mark-defun-back)) | 596 | (setq arg (or arg 1)) |
| 590 | (cond ((use-region-p) | 597 | ;; There is no `mark-defun-back' function - see |
| 591 | (if (>= arg 0) | 598 | ;; https://lists.gnu.org/r/bug-gnu-emacs/2016-11/msg00079.html |
| 592 | (set-mark | 599 | ;; for explanation |
| 593 | (save-excursion | 600 | (when (eq last-command 'mark-defun-back) |
| 594 | (goto-char (mark)) | 601 | (setq arg (- arg))) |
| 595 | ;; change the dotimes below to (end-of-defun arg) once bug #24427 is fixed | 602 | (when (< arg 0) |
| 596 | (dotimes (_ignore arg) | 603 | (setq this-command 'mark-defun-back)) |
| 597 | (end-of-defun)) | 604 | (cond ((use-region-p) |
| 598 | (point))) | 605 | (if (>= arg 0) |
| 599 | (beginning-of-defun-comments (- arg)))) | 606 | (set-mark |
| 600 | (t | 607 | (save-excursion |
| 601 | (let ((opoint (point)) | 608 | (goto-char (mark)) |
| 602 | beg end) | 609 | ;; change the dotimes below to (end-of-defun arg) |
| 603 | (push-mark opoint) | 610 | ;; once bug #24427 is fixed |
| 604 | ;; Try first in this order for the sake of languages with nested | ||
| 605 | ;; functions where several can end at the same place as with the | ||
| 606 | ;; offside rule, e.g. Python. | ||
| 607 | (beginning-of-defun-comments) | ||
| 608 | (setq beg (point)) | ||
| 609 | (end-of-defun) | ||
| 610 | (setq end (point)) | ||
| 611 | (when (or (and (<= (point) opoint) | ||
| 612 | (> arg 0)) | ||
| 613 | (= beg (point-min))) ; we were before the first defun! | ||
| 614 | ;; beginning-of-defun moved back one defun so we got the wrong | ||
| 615 | ;; one. If ARG < 0, however, we actually want to go back. | ||
| 616 | (goto-char opoint) | ||
| 617 | (end-of-defun) | ||
| 618 | (setq end (point)) | ||
| 619 | (beginning-of-defun-comments) | ||
| 620 | (setq beg (point))) | ||
| 621 | (goto-char beg) | ||
| 622 | (cond ((> arg 0) | ||
| 623 | ;; change the dotimes below to (end-of-defun arg) once bug #24427 is fixed | ||
| 624 | (dotimes (_ignore arg) | 611 | (dotimes (_ignore arg) |
| 625 | (end-of-defun)) | 612 | (end-of-defun)) |
| 626 | (setq end (point)) | 613 | (point))) |
| 627 | (push-mark end nil t) | 614 | (beginning-of-defun-comments (- arg)))) |
| 628 | (goto-char beg)) | 615 | (t |
| 629 | (t | 616 | (let ((opoint (point)) |
| 630 | (goto-char beg) | 617 | beg end) |
| 631 | (unless (= arg -1) ; beginning-of-defun behaves | 618 | (push-mark opoint) |
| 632 | ; strange with zero arg - see | 619 | ;; Try first in this order for the sake of languages with nested |
| 633 | ; https://lists.gnu.org/r/bug-gnu-emacs/2017-02/msg00196.html | 620 | ;; functions where several can end at the same place as with the |
| 634 | (beginning-of-defun (1- (- arg)))) | 621 | ;; offside rule, e.g. Python. |
| 635 | (push-mark end nil t)))))) | 622 | (beginning-of-defun-comments) |
| 636 | (skip-chars-backward "[:space:]\n") | 623 | (setq beg (point)) |
| 637 | (unless (bobp) | 624 | (end-of-defun) |
| 638 | (forward-line 1))) | 625 | (setq end (point)) |
| 626 | (when (or (and (<= (point) opoint) | ||
| 627 | (> arg 0)) | ||
| 628 | (= beg (point-min))) ; we were before the first defun! | ||
| 629 | ;; beginning-of-defun moved back one defun so we got the wrong | ||
| 630 | ;; one. If ARG < 0, however, we actually want to go back. | ||
| 631 | (goto-char opoint) | ||
| 632 | (end-of-defun) | ||
| 633 | (setq end (point)) | ||
| 634 | (beginning-of-defun-comments) | ||
| 635 | (setq beg (point))) | ||
| 636 | (goto-char beg) | ||
| 637 | (cond ((> arg 0) | ||
| 638 | ;; change the dotimes below to (end-of-defun arg) | ||
| 639 | ;; once bug #24427 is fixed | ||
| 640 | (dotimes (_ignore arg) | ||
| 641 | (end-of-defun)) | ||
| 642 | (setq end (point)) | ||
| 643 | (push-mark end nil t) | ||
| 644 | (goto-char beg)) | ||
| 645 | (t | ||
| 646 | (goto-char beg) | ||
| 647 | (unless (= arg -1) | ||
| 648 | ;; beginning-of-defun behaves strange with zero arg - see | ||
| 649 | ;; lists.gnu.org/r/bug-gnu-emacs/2017-02/msg00196.html | ||
| 650 | (beginning-of-defun (1- (- arg)))) | ||
| 651 | (push-mark end nil t)))))) | ||
| 652 | (skip-chars-backward "[:space:]\n") | ||
| 653 | (unless (bobp) | ||
| 654 | (forward-line 1)))) | ||
| 639 | 655 | ||
| 640 | (defvar narrow-to-defun-include-comments nil | 656 | (defvar narrow-to-defun-include-comments nil |
| 641 | "If non-nil, `narrow-to-defun' will also show comments preceding the defun.") | 657 | "If non-nil, `narrow-to-defun' will also show comments preceding the defun.") |
diff --git a/lisp/reposition.el b/lisp/reposition.el index 008fa009fdc..02bee4165a8 100644 --- a/lisp/reposition.el +++ b/lisp/reposition.el | |||
| @@ -38,7 +38,7 @@ | |||
| 38 | ;;; Code: | 38 | ;;; Code: |
| 39 | 39 | ||
| 40 | ;;;###autoload | 40 | ;;;###autoload |
| 41 | (defun reposition-window (&optional arg) | 41 | (defun reposition-window (&optional arg interactive) |
| 42 | "Make the current definition and/or comment visible. | 42 | "Make the current definition and/or comment visible. |
| 43 | Further invocations move it to the top of the window or toggle the | 43 | Further invocations move it to the top of the window or toggle the |
| 44 | visibility of comments that precede it. | 44 | visibility of comments that precede it. |
| @@ -55,118 +55,124 @@ the comment lines. | |||
| 55 | visible (if only part could otherwise be made so), to make the defun line | 55 | visible (if only part could otherwise be made so), to make the defun line |
| 56 | visible (if point is in code and it could not be made so, or if only | 56 | visible (if point is in code and it could not be made so, or if only |
| 57 | comments, including the first comment line, are visible), or to make the | 57 | comments, including the first comment line, are visible), or to make the |
| 58 | first comment line visible (if point is in a comment)." | 58 | first comment line visible (if point is in a comment). |
| 59 | (interactive "P") | 59 | If INTERACTIVE is non-nil, as it is interactively, |
| 60 | (let* (;; (here (line-beginning-position)) | 60 | report errors as appropriate for this kind of usage." |
| 61 | (here (point)) | 61 | (interactive "P\nd") |
| 62 | ;; change this name once I've gotten rid of references to ht. | 62 | (if interactive |
| 63 | ;; this is actually the number of the last screen line | 63 | (condition-case e |
| 64 | (ht (- (window-height) 2)) | 64 | (reposition-window arg nil) |
| 65 | (line (repos-count-screen-lines (window-start) (point))) | 65 | (scan-error (user-error (cadr e)))) |
| 66 | (comment-height | 66 | (let* (;; (here (line-beginning-position)) |
| 67 | ;; The call to max deals with the case of cursor between defuns. | 67 | (here (point)) |
| 68 | (max 0 | 68 | ;; change this name once I've gotten rid of references to ht. |
| 69 | (repos-count-screen-lines-signed | 69 | ;; this is actually the number of the last screen line |
| 70 | ;; the beginning of the preceding comment | 70 | (ht (- (window-height) 2)) |
| 71 | (save-excursion | 71 | (line (repos-count-screen-lines (window-start) (point))) |
| 72 | (if (not (eobp)) (forward-char 1)) | 72 | (comment-height |
| 73 | (end-of-defun -1) | 73 | ;; The call to max deals with the case of cursor between defuns. |
| 74 | ;; Skip whitespace, newlines, and form feeds. | 74 | (max 0 |
| 75 | (if (re-search-forward "[^ \t\n\f]" nil t) | 75 | (repos-count-screen-lines-signed |
| 76 | (backward-char 1)) | 76 | ;; the beginning of the preceding comment |
| 77 | (point)) | 77 | (save-excursion |
| 78 | here))) | 78 | (if (not (eobp)) (forward-char 1)) |
| 79 | (defun-height | 79 | (end-of-defun -1) |
| 80 | (repos-count-screen-lines-signed | 80 | ;; Skip whitespace, newlines, and form feeds. |
| 81 | (save-excursion | 81 | (if (re-search-forward "[^ \t\n\f]" nil t) |
| 82 | (end-of-defun 1) ; so comments associate with following defuns | 82 | (backward-char 1)) |
| 83 | (beginning-of-defun 1) | 83 | (point)) |
| 84 | (point)) | 84 | here))) |
| 85 | here)) | 85 | (defun-height |
| 86 | ;; This must be positive, so don't use the signed version. | 86 | (repos-count-screen-lines-signed |
| 87 | (defun-depth (repos-count-screen-lines here | 87 | (save-excursion |
| 88 | (save-excursion | 88 | (end-of-defun 1) ; so comments associate with following defuns |
| 89 | (end-of-defun 1) | 89 | (beginning-of-defun 1) |
| 90 | (point)))) | 90 | (point)) |
| 91 | (defun-line-onscreen-p | 91 | here)) |
| 92 | (and (<= defun-height line) | 92 | ;; This must be positive, so don't use the signed version. |
| 93 | (<= (- line defun-height) ht)))) | 93 | (defun-depth (repos-count-screen-lines here |
| 94 | (cond ((or (= comment-height line) | 94 | (save-excursion |
| 95 | (and (= line ht) | 95 | (end-of-defun 1) |
| 96 | (> comment-height line) | 96 | (point)))) |
| 97 | ;; if defun line offscreen, we should be in case 4 | 97 | (defun-line-onscreen-p |
| 98 | defun-line-onscreen-p)) | 98 | (and (<= defun-height line) |
| 99 | ;; Either first comment line is at top of screen or (point at | 99 | (<= (- line defun-height) ht)))) |
| 100 | ;; bottom of screen, defun line onscreen, and first comment line | 100 | (cond ((or (= comment-height line) |
| 101 | ;; off top of screen). That is, it looks like we just did | 101 | (and (= line ht) |
| 102 | ;; recenter-definition, trying to fit as much of the comment | 102 | (> comment-height line) |
| 103 | ;; onscreen as possible. Put defun line at top of screen; that | 103 | ;; if defun line offscreen, we should be in case 4 |
| 104 | ;; is, show as much code, and as few comments, as possible. | 104 | defun-line-onscreen-p)) |
| 105 | 105 | ;; Either first comment line is at top of screen or (point at | |
| 106 | (if (and arg (> defun-depth (1+ ht))) | 106 | ;; bottom of screen, defun line onscreen, and first comment line |
| 107 | ;; Can't fit whole defun onscreen without moving point. | 107 | ;; off top of screen). That is, it looks like we just did |
| 108 | (progn (end-of-defun) (beginning-of-defun) (recenter 0)) | 108 | ;; recenter-definition, trying to fit as much of the comment |
| 109 | (recenter (max defun-height 0))) | 109 | ;; onscreen as possible. Put defun line at top of screen; that |
| 110 | ;;(repos-debug-macro "1") | 110 | ;; is, show as much code, and as few comments, as possible. |
| 111 | ) | 111 | |
| 112 | 112 | (if (and arg (> defun-depth (1+ ht))) | |
| 113 | ((or (= defun-height line) | 113 | ;; Can't fit whole defun onscreen without moving point. |
| 114 | (= line 0) | 114 | (progn (end-of-defun) (beginning-of-defun) (recenter 0)) |
| 115 | (and (< line comment-height) | 115 | (recenter (max defun-height 0))) |
| 116 | (< defun-height 0))) | 116 | ;;(repos-debug-macro "1") |
| 117 | ;; Defun line or cursor at top of screen, OR cursor in comment | 117 | ) |
| 118 | ;; whose first line is offscreen. | 118 | |
| 119 | ;; Avoid moving definition up even if defun runs offscreen; | 119 | ((or (= defun-height line) |
| 120 | ;; we care more about getting the comment onscreen. | 120 | (= line 0) |
| 121 | 121 | (and (< line comment-height) | |
| 122 | (cond ((= line ht) | 122 | (< defun-height 0))) |
| 123 | ;; cursor on last screen line (and so in a comment) | 123 | ;; Defun line or cursor at top of screen, OR cursor in comment |
| 124 | (if arg (progn (end-of-defun) (beginning-of-defun))) | 124 | ;; whose first line is offscreen. |
| 125 | (recenter 0) | 125 | ;; Avoid moving definition up even if defun runs offscreen; |
| 126 | ;;(repos-debug-macro "2a") | 126 | ;; we care more about getting the comment onscreen. |
| 127 | ) | 127 | |
| 128 | 128 | (cond ((= line ht) | |
| 129 | ;; This condition, copied from case 4, may not be quite right | 129 | ;; cursor on last screen line (and so in a comment) |
| 130 | 130 | (if arg (progn (end-of-defun) (beginning-of-defun))) | |
| 131 | ((and arg (< ht comment-height)) | 131 | (recenter 0) |
| 132 | ;; Can't get first comment line onscreen. | 132 | ;;(repos-debug-macro "2a") |
| 133 | ;; Go there and try again. | 133 | ) |
| 134 | (forward-line (- comment-height)) | 134 | |
| 135 | (beginning-of-line) | 135 | ;; This condition, copied from case 4, may not be quite right |
| 136 | ;; was (reposition-window) | 136 | |
| 137 | (recenter 0) | 137 | ((and arg (< ht comment-height)) |
| 138 | ;;(repos-debug-macro "2b") | 138 | ;; Can't get first comment line onscreen. |
| 139 | ) | 139 | ;; Go there and try again. |
| 140 | (t | 140 | (forward-line (- comment-height)) |
| 141 | (recenter (min ht comment-height)) | 141 | (beginning-of-line) |
| 142 | ;;(repos-debug-macro "2c") | 142 | ;; was (reposition-window) |
| 143 | )) | 143 | (recenter 0) |
| 144 | ;; (recenter (min ht comment-height)) | 144 | ;;(repos-debug-macro "2b") |
| 145 | ) | 145 | ) |
| 146 | 146 | (t | |
| 147 | ((and (> (+ line defun-depth -1) ht) | 147 | (recenter (min ht comment-height)) |
| 148 | defun-line-onscreen-p) | 148 | ;;(repos-debug-macro "2c") |
| 149 | ;; Defun runs off the bottom of the screen and the defun line | 149 | )) |
| 150 | ;; is onscreen. | 150 | ;; (recenter (min ht comment-height)) |
| 151 | ;; Move the defun up. | 151 | ) |
| 152 | (recenter (max 0 (1+ (- ht defun-depth)) defun-height)) | 152 | |
| 153 | ;;(repos-debug-macro "3") | 153 | ((and (> (+ line defun-depth -1) ht) |
| 154 | ) | 154 | defun-line-onscreen-p) |
| 155 | 155 | ;; Defun runs off the bottom of the screen and the defun line | |
| 156 | (t | 156 | ;; is onscreen. |
| 157 | ;; If on the bottom line and comment start is offscreen | 157 | ;; Move the defun up. |
| 158 | ;; then just move all comments offscreen, or at least as | 158 | (recenter (max 0 (1+ (- ht defun-depth)) defun-height)) |
| 159 | ;; far as they'll go. | 159 | ;;(repos-debug-macro "3") |
| 160 | 160 | ) | |
| 161 | ;; Try to get as much of the comments onscreen as possible. | 161 | |
| 162 | (if (and arg (< ht comment-height)) | 162 | (t |
| 163 | ;; Can't get defun line onscreen; go there and try again. | 163 | ;; If on the bottom line and comment start is offscreen |
| 164 | (progn (forward-line (- defun-height)) | 164 | ;; then just move all comments offscreen, or at least as |
| 165 | (beginning-of-line) | 165 | ;; far as they'll go. |
| 166 | (reposition-window)) | 166 | |
| 167 | (recenter (min ht comment-height))) | 167 | ;; Try to get as much of the comments onscreen as possible. |
| 168 | ;;(repos-debug-macro "4") | 168 | (if (and arg (< ht comment-height)) |
| 169 | )))) | 169 | ;; Can't get defun line onscreen; go there and try again. |
| 170 | (progn (forward-line (- defun-height)) | ||
| 171 | (beginning-of-line) | ||
| 172 | (reposition-window)) | ||
| 173 | (recenter (min ht comment-height))) | ||
| 174 | ;;(repos-debug-macro "4") | ||
| 175 | ))))) | ||
| 170 | 176 | ||
| 171 | ;;; Auxiliary functions | 177 | ;;; Auxiliary functions |
| 172 | 178 | ||
diff --git a/lisp/simple.el b/lisp/simple.el index 26eb8cad7f8..6c51553690d 100644 --- a/lisp/simple.el +++ b/lisp/simple.el | |||
| @@ -7691,44 +7691,53 @@ are interchanged." | |||
| 7691 | (interactive "*p") | 7691 | (interactive "*p") |
| 7692 | (transpose-subr 'forward-word arg)) | 7692 | (transpose-subr 'forward-word arg)) |
| 7693 | 7693 | ||
| 7694 | (defun transpose-sexps (arg) | 7694 | (defun transpose-sexps (arg &optional interactive) |
| 7695 | "Like \\[transpose-chars] (`transpose-chars'), but applies to sexps. | 7695 | "Like \\[transpose-chars] (`transpose-chars'), but applies to sexps. |
| 7696 | Unlike `transpose-words', point must be between the two sexps and not | 7696 | Unlike `transpose-words', point must be between the two sexps and not |
| 7697 | in the middle of a sexp to be transposed. | 7697 | in the middle of a sexp to be transposed. |
| 7698 | With non-zero prefix arg ARG, effect is to take the sexp before point | 7698 | With non-zero prefix arg ARG, effect is to take the sexp before point |
| 7699 | and drag it forward past ARG other sexps (backward if ARG is negative). | 7699 | and drag it forward past ARG other sexps (backward if ARG is negative). |
| 7700 | If ARG is zero, the sexps ending at or after point and at or after mark | 7700 | If ARG is zero, the sexps ending at or after point and at or after mark |
| 7701 | are interchanged." | 7701 | are interchanged. |
| 7702 | (interactive "*p") | 7702 | If INTERACTIVE is non-nil, as it is interactively, |
| 7703 | (transpose-subr | 7703 | report errors as appropriate for this kind of usage." |
| 7704 | (lambda (arg) | 7704 | (interactive "*p\nd") |
| 7705 | ;; Here we should try to simulate the behavior of | 7705 | (if interactive |
| 7706 | ;; (cons (progn (forward-sexp x) (point)) | 7706 | (condition-case nil |
| 7707 | ;; (progn (forward-sexp (- x)) (point))) | 7707 | (transpose-sexps arg nil) |
| 7708 | ;; Except that we don't want to rely on the second forward-sexp | 7708 | (scan-error (user-error "Not between two complete sexps"))) |
| 7709 | ;; putting us back to where we want to be, since forward-sexp-function | 7709 | (transpose-subr |
| 7710 | ;; might do funny things like infix-precedence. | 7710 | (lambda (arg) |
| 7711 | (if (if (> arg 0) | 7711 | ;; Here we should try to simulate the behavior of |
| 7712 | (looking-at "\\sw\\|\\s_") | 7712 | ;; (cons (progn (forward-sexp x) (point)) |
| 7713 | (and (not (bobp)) | 7713 | ;; (progn (forward-sexp (- x)) (point))) |
| 7714 | (save-excursion (forward-char -1) (looking-at "\\sw\\|\\s_")))) | 7714 | ;; Except that we don't want to rely on the second forward-sexp |
| 7715 | ;; Jumping over a symbol. We might be inside it, mind you. | 7715 | ;; putting us back to where we want to be, since forward-sexp-function |
| 7716 | (progn (funcall (if (> arg 0) | 7716 | ;; might do funny things like infix-precedence. |
| 7717 | 'skip-syntax-backward 'skip-syntax-forward) | 7717 | (if (if (> arg 0) |
| 7718 | "w_") | 7718 | (looking-at "\\sw\\|\\s_") |
| 7719 | (cons (save-excursion (forward-sexp arg) (point)) (point))) | 7719 | (and (not (bobp)) |
| 7720 | ;; Otherwise, we're between sexps. Take a step back before jumping | 7720 | (save-excursion |
| 7721 | ;; to make sure we'll obey the same precedence no matter which direction | 7721 | (forward-char -1) |
| 7722 | ;; we're going. | 7722 | (looking-at "\\sw\\|\\s_")))) |
| 7723 | (funcall (if (> arg 0) 'skip-syntax-backward 'skip-syntax-forward) " .") | 7723 | ;; Jumping over a symbol. We might be inside it, mind you. |
| 7724 | (cons (save-excursion (forward-sexp arg) (point)) | 7724 | (progn (funcall (if (> arg 0) |
| 7725 | (progn (while (or (forward-comment (if (> arg 0) 1 -1)) | 7725 | 'skip-syntax-backward 'skip-syntax-forward) |
| 7726 | (not (zerop (funcall (if (> arg 0) | 7726 | "w_") |
| 7727 | 'skip-syntax-forward | 7727 | (cons (save-excursion (forward-sexp arg) (point)) (point))) |
| 7728 | 'skip-syntax-backward) | 7728 | ;; Otherwise, we're between sexps. Take a step back before jumping |
| 7729 | "."))))) | 7729 | ;; to make sure we'll obey the same precedence no matter which |
| 7730 | (point))))) | 7730 | ;; direction we're going. |
| 7731 | arg 'special)) | 7731 | (funcall (if (> arg 0) 'skip-syntax-backward 'skip-syntax-forward) |
| 7732 | " .") | ||
| 7733 | (cons (save-excursion (forward-sexp arg) (point)) | ||
| 7734 | (progn (while (or (forward-comment (if (> arg 0) 1 -1)) | ||
| 7735 | (not (zerop (funcall (if (> arg 0) | ||
| 7736 | 'skip-syntax-forward | ||
| 7737 | 'skip-syntax-backward) | ||
| 7738 | "."))))) | ||
| 7739 | (point))))) | ||
| 7740 | arg 'special))) | ||
| 7732 | 7741 | ||
| 7733 | (defun transpose-lines (arg) | 7742 | (defun transpose-lines (arg) |
| 7734 | "Exchange current line and previous line, leaving point after both. | 7743 | "Exchange current line and previous line, leaving point after both. |