Make up-list and backward-up-list get out of more spots
This commit is contained in:
parent
6c971fb0f4
commit
3f63a9f7de
7 changed files with 220 additions and 32 deletions
|
@ -57,10 +57,14 @@ Should take the same arguments and behave similarly to `forward-sexp'.")
|
|||
|
||||
(defun forward-sexp (&optional arg)
|
||||
"Move forward across one balanced expression (sexp).
|
||||
With ARG, do it that many times. Negative arg -N means
|
||||
move backward across N balanced expressions.
|
||||
This command assumes point is not in a string or comment.
|
||||
Calls `forward-sexp-function' to do the work, if that is non-nil."
|
||||
With ARG, do it that many times. Negative arg -N means move
|
||||
backward across N balanced expressions. This command assumes
|
||||
point is not in a string or comment. Calls
|
||||
`forward-sexp-function' to do the work, if that is non-nil. If
|
||||
unable to move over a sexp, signal `scan-error' with three
|
||||
arguments: a message, the start of the obstacle (usually a
|
||||
parenthesis or list marker of some kind), and end of the
|
||||
obstacle."
|
||||
(interactive "^p")
|
||||
(or arg (setq arg 1))
|
||||
(if forward-sexp-function
|
||||
|
@ -140,38 +144,92 @@ This command assumes point is not in a string or comment."
|
|||
(goto-char (or (scan-lists (point) inc -1) (buffer-end arg)))
|
||||
(setq arg (- arg inc)))))
|
||||
|
||||
(defun backward-up-list (&optional arg)
|
||||
(defun backward-up-list (&optional arg escape-strings no-syntax-crossing)
|
||||
"Move backward out of one level of parentheses.
|
||||
This command will also work on other parentheses-like expressions
|
||||
defined by the current language mode.
|
||||
With ARG, do this that many times.
|
||||
A negative argument means move forward but still to a less deep spot.
|
||||
This command assumes point is not in a string or comment."
|
||||
(interactive "^p")
|
||||
(up-list (- (or arg 1))))
|
||||
defined by the current language mode. With ARG, do this that
|
||||
many times. A negative argument means move forward but still to
|
||||
a less deep spot. If ESCAPE-STRINGS is non-nil (as it is
|
||||
interactively), move out of enclosing strings as well. If
|
||||
NO-SYNTAX-CROSSING is non-nil (as it is interactively), prefer to
|
||||
break out of any enclosing string instead of moving to the start
|
||||
of a list broken across multiple strings. On error, location of
|
||||
point is unspecified."
|
||||
(interactive "^p\nd\nd")
|
||||
(up-list (- (or arg 1)) escape-strings no-syntax-crossing))
|
||||
|
||||
(defun up-list (&optional arg)
|
||||
(defun up-list (&optional arg escape-strings no-syntax-crossing)
|
||||
"Move forward out of one level of parentheses.
|
||||
This command will also work on other parentheses-like expressions
|
||||
defined by the current language mode.
|
||||
With ARG, do this that many times.
|
||||
A negative argument means move backward but still to a less deep spot.
|
||||
This command assumes point is not in a string or comment."
|
||||
(interactive "^p")
|
||||
defined by the current language mode. With ARG, do this that
|
||||
many times. A negative argument means move backward but still to
|
||||
a less deep spot. If ESCAPE-STRINGS is non-nil (as it is
|
||||
interactively), move out of enclosing strings as well. If
|
||||
NO-SYNTAX-CROSSING is non-nil (as it is interactively), prefer to
|
||||
break out of any enclosing string instead of moving to the start
|
||||
of a list broken across multiple strings. On error, location of
|
||||
point is unspecified."
|
||||
(interactive "^p\nd\nd")
|
||||
(or arg (setq arg 1))
|
||||
(let ((inc (if (> arg 0) 1 -1))
|
||||
pos)
|
||||
(pos nil))
|
||||
(while (/= arg 0)
|
||||
(if (null forward-sexp-function)
|
||||
(goto-char (or (scan-lists (point) inc 1) (buffer-end arg)))
|
||||
(condition-case err
|
||||
(while (progn (setq pos (point))
|
||||
(forward-sexp inc)
|
||||
(/= (point) pos)))
|
||||
(scan-error (goto-char (nth (if (> arg 0) 3 2) err))))
|
||||
(if (= (point) pos)
|
||||
(signal 'scan-error
|
||||
(list "Unbalanced parentheses" (point) (point)))))
|
||||
(condition-case err
|
||||
(save-restriction
|
||||
;; If we've been asked not to cross string boundaries
|
||||
;; and we're inside a string, narrow to that string so
|
||||
;; that scan-lists doesn't find a match in a different
|
||||
;; string.
|
||||
(when no-syntax-crossing
|
||||
(let* ((syntax (syntax-ppss))
|
||||
(string-comment-start (nth 8 syntax)))
|
||||
(when string-comment-start
|
||||
(save-excursion
|
||||
(goto-char string-comment-start)
|
||||
(narrow-to-region
|
||||
(point)
|
||||
(if (nth 3 syntax) ; in string
|
||||
(condition-case nil
|
||||
(progn (forward-sexp) (point))
|
||||
(scan-error (point-max)))
|
||||
(forward-comment 1)
|
||||
(point)))))))
|
||||
(if (null forward-sexp-function)
|
||||
(goto-char (or (scan-lists (point) inc 1)
|
||||
(buffer-end arg)))
|
||||
(condition-case err
|
||||
(while (progn (setq pos (point))
|
||||
(forward-sexp inc)
|
||||
(/= (point) pos)))
|
||||
(scan-error (goto-char (nth (if (> arg 0) 3 2) err))))
|
||||
(if (= (point) pos)
|
||||
(signal 'scan-error
|
||||
(list "Unbalanced parentheses" (point) (point))))))
|
||||
(scan-error
|
||||
(let ((syntax nil))
|
||||
(or
|
||||
;; If we bumped up against the end of a list, see whether
|
||||
;; we're inside a string: if so, just go to the beginning
|
||||
;; or end of that string.
|
||||
(and escape-strings
|
||||
(or syntax (setf syntax (syntax-ppss)))
|
||||
(nth 3 syntax)
|
||||
(goto-char (nth 8 syntax))
|
||||
(progn (when (> inc 0)
|
||||
(forward-sexp))
|
||||
t))
|
||||
;; If we narrowed to a comment above and failed to escape
|
||||
;; it, the error might be our fault, not an indication
|
||||
;; that we're out of syntax. Try again from beginning or
|
||||
;; end of the comment.
|
||||
(and no-syntax-crossing
|
||||
(or syntax (setf syntax (syntax-ppss)))
|
||||
(nth 4 syntax)
|
||||
(goto-char (nth 8 syntax))
|
||||
(or (< inc 0)
|
||||
(forward-comment 1))
|
||||
(setf arg (+ arg inc)))
|
||||
(signal (car err) (cdr err))))))
|
||||
(setq arg (- arg inc)))))
|
||||
|
||||
(defun kill-sexp (&optional arg)
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue