I'm getting up-list: Scan error: "Unbalanced parentheses"
from this position:
(foo "bar|")
Snippet from up-list
doc:
This command assumes point is not in a string or comment.
So this is the expected behavior.
But I don't care. I just want to go upwards from a list.
Could someone suggest an up-list
clone that does the proper thing?
I'm looking for something better than this naive code:
(defun up-list-naive ()
(interactive)
(while (not (ignore-errors (up-list) t))
(forward-char)))
EDIT: incorporated Andreas Rohler's suggestion:
This works for me in your test case:
(defun my-up-list ()
(interactive)
(let ((s (syntax-ppss)))
(when (nth 3 s)
(goto-char (nth 8 s))))
(ignore-errors (up-list)))
syntax-ppss
returns a list, the third element of which exists if you're inside a string, and the 8th element is the beginning of the string (if you're in one, otherwise nil).
In extension of answers given: deal with comments also, send "nil" when no further list found. When interactively called, message result.
(defun ar-up-list (arg)
"Move forward out of one level of parentheses.
With ARG, do this that many times.
A negative argument means move backward but still to a less deep spot."
(interactive "p")
(let ((orig (point))
(pps (syntax-ppss))
erg)
(and (nth 8 pps) (goto-char (nth 8 pps)))
(ignore-errors (up-list arg))
(and (< orig (point)) (setq erg (point)))
(when (interactive-p) (message "%s" erg))
erg))
And it's complement:
(defun ar-down-list (arg)
"Move forward down one level of parentheses.
With ARG, do this that many times.
A negative argument means move backward but still go down a level. "
(interactive "p")
(let ((orig (point))
(pps (syntax-ppss))
erg)
(and (nth 8 pps) (goto-char (nth 8 pps)))
(ignore-errors (down-list arg))
(and (< orig (point)) (setq erg (point)))
(when (interactive-p) (message "%s" erg))
erg))