aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorMattias EngdegÄrd2021-04-30 17:09:21 +0200
committerMattias EngdegÄrd2021-04-30 17:31:20 +0200
commit1167253f75badf9e7df1bf983c2ebeb2d37d3881 (patch)
tree8e8b97591a7298fa63bd17d2f50a43d514e4256f
parentab7a61e0efd0684bc37a556d12f36521f9f61782 (diff)
downloademacs-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.el246
-rw-r--r--lisp/reposition.el232
-rw-r--r--lisp/simple.el73
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.
503Otherwise, that's the beginning of the buffer." 503Otherwise, 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.
508With argument, do it that many times. 508With argument, do it that many times.
509Negative argument -N means move back to Nth preceding end of defun. 509Negative 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
515If variable `end-of-defun-function' is non-nil, its value 515If variable `end-of-defun-function' is non-nil, its value
516is called as a function to find the defun's end." 516is called as a function to find the defun's end.
517 (interactive "^p") 517
518 (or (not (eq this-command 'end-of-defun)) 518If INTERACTIVE is non-nil, as it is interactively,
519 (eq last-command 'end-of-defun) 519report 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.
575The defun marked is the one that contains point or follows point. 582The defun marked is the one that contains point or follows point.
576With positive ARG, mark this and that many next defuns; with negative 583With positive ARG, mark this and that many next defuns; with negative
577ARG, change the direction of marking. 584ARG, change the direction of marking.
578 585
579If the mark is active, it marks the next or previous defun(s) after 586If the mark is active, it marks the next or previous defun(s) after
580the one(s) already marked." 587the one(s) already marked.
581 (interactive "p") 588
582 (setq arg (or arg 1)) 589If INTERACTIVE is non-nil, as it is interactively,
583 ;; There is no `mark-defun-back' function - see 590report 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.
43Further invocations move it to the top of the window or toggle the 43Further invocations move it to the top of the window or toggle the
44visibility of comments that precede it. 44visibility of comments that precede it.
@@ -55,118 +55,124 @@ the comment lines.
55visible (if only part could otherwise be made so), to make the defun line 55visible (if only part could otherwise be made so), to make the defun line
56visible (if point is in code and it could not be made so, or if only 56visible (if point is in code and it could not be made so, or if only
57comments, including the first comment line, are visible), or to make the 57comments, including the first comment line, are visible), or to make the
58first comment line visible (if point is in a comment)." 58first comment line visible (if point is in a comment).
59 (interactive "P") 59If INTERACTIVE is non-nil, as it is interactively,
60 (let* (;; (here (line-beginning-position)) 60report 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.
7696Unlike `transpose-words', point must be between the two sexps and not 7696Unlike `transpose-words', point must be between the two sexps and not
7697in the middle of a sexp to be transposed. 7697in the middle of a sexp to be transposed.
7698With non-zero prefix arg ARG, effect is to take the sexp before point 7698With non-zero prefix arg ARG, effect is to take the sexp before point
7699and drag it forward past ARG other sexps (backward if ARG is negative). 7699and drag it forward past ARG other sexps (backward if ARG is negative).
7700If ARG is zero, the sexps ending at or after point and at or after mark 7700If ARG is zero, the sexps ending at or after point and at or after mark
7701are interchanged." 7701are interchanged.
7702 (interactive "*p") 7702If INTERACTIVE is non-nil, as it is interactively,
7703 (transpose-subr 7703report 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.