-- Matt Tucker <tuck(a)whistlingfish.net> spake thusly:
-- Hrvoje Niksic <hniksic(a)arsdigita.com> spake thusly:
> The problem is pretty much described in the subject: an open
> parenthesis in the first column makes XEmacs syntax analyzer think
> that it's the beginning of defun. This fools the indentation
> functions, font-lock, etc.
I can research this a bit further and try to fix it. I suspect that
there are at least a couple solutions. One of them would be to apply
custom syntax tables to all strings to mark opening parentheses as
punctuation, but that seems overkill. It might also be possible to fix
`beginning-of-defun' to use `parse-partial-sexp' instead of just doing
a regex search.
I've got a solution for this. The primary issue is that
beginning-of-defun was using regexp's instead of syntax parsing to find
the beginning of functions. I have a patch that exhibits the correct
behavior and fixes the "paren in column 1" bug. Since this is such a
long-standing issue and beginning-of-defun is such a basic function, I
thought it might be better to commit this to 21.5 rather than 21.2, to
give us more time to debug it.
Stephen, is 21.5 ready for commits? Should I apply this?
I also was hoping someone who was a bit more lisp-savvy than I am might
take a look at the code and make some suggestions. It works fine, but
I'm not totally happy with the result. It just doesn't feel quite clean
to me.
The patch is attached, and the new defun is as follows:
(defun beginning-of-defun-raw (&optional arg)
"Move point to the character that starts a defun.
This is identical to beginning-of-defun, except that point does not move
to the beginning of the line when `defun-prompt-regexp' is non-nil."
(interactive "p")
(and arg (< arg 0) (not (eobp)) (forward-char 1))
(if (eq arg 0)
t
(let* ((arg (or arg 1))
(state (parse-partial-sexp (point-min) (point)))
(depth (nth 0 state))
(pt (if (or (nth 3 state) (nth 4 state))
(nth 8 state)
(point)))
(dir (if (> arg 0)
-1
1))
p)
(cond ((> depth 0)
(setq pt (scan-lists pt dir depth)))
((eq dir -1)
(if (setq p (scan-lists pt dir 0))
(setq pt p)
(setq pt (buffer-end dir)))))
(while (not (or (eq arg 0)
(eq pt (buffer-end dir))))
(when (eq dir 1)
(setq state (parse-partial-sexp pt (point-max) 1))
(setq pt (if (eq 1 (nth 0 state))
(1- (point))
(point))))
(goto-char pt)
(beginning-of-line)
(if (and (looking-at (if defun-prompt-regexp
(concat "^\\s(\\|"
"\\("
defun-prompt-regexp
"\\)\\s(")
"^\\s("))
(eq pt (1- (match-end 0))))
(setq arg (+ arg dir)))
(if (not (eq arg 0))
(if (setq p (scan-lists pt dir 0))
(setq pt p)
(setq pt (buffer-end dir)))))
(goto-char pt)
(eq arg 0))))