At 7:29 PM +0200 9/17/04, Arjan Bos wrote:
I already had something similar. Looking
at the current bracket under point, finding its opposite and start
counting the brackets you encounter. Another of the same bracket ups
the ante, the opposite pops one from the ante. When the ante is empty,
all bets are off, and the bracket is found.
My code isn't perfect, so I will borrow heavily from
yours.
Thanks!
Arjan,
I cleaned up my code to the point that it will also work in place
of the regular forward-sexp and backward-sexp for everyday use.
Here is a copy, if you're interested. Please let me know if you
try it and find any problems. I will be using it myself as a
permenant replacement for forward-sexp and backward-sexp. If you
are interested in being notified of any problems I may find, please
let me know.
(defun skip-string-forward (&optional
limit)
(if (eq (char-after)
?\")
(catch
'done
(forward-char 1)
(while t
(skip-chars-forward "^\\\\\""
limit)
(cond ((eq (point) limit)
(throw 'done nil) )
((eq
(char-after) ?\")
(forward-char 1)
(throw 'done nil) )
(t
(forward-char 1)
(if
(eq (point) limit)
(throw 'done nil)
(forward-char 1) ) ) ) ) ) ) )
(defun skip-string-backward (&optional
limit)
(if (eq (char-before)
?\")
(catch
'done
(forward-char -1)
(while t
(skip-chars-backward "^\""
limit)
(if (eq (point) limit)
(throw 'done nil)
)
(forward-char -1)
(if (eq (point) limit)
(throw 'done nil)
)
(if (not (eq (char-before) ?\\))
(throw 'done nil) ) ) ) )
)
(defun forward-pexp (&optional
arg)
(interactive
"p")
(or arg (setq arg 1))
(let (open close next notstrc notstro
notstre depth pair)
(catch 'done
(cond ((>
arg 0)
(skip-chars-forward "
\t\n")
(if (not (memq (char-after) '(?\( ?\[
?\{ ?\<)))
(goto-char (or (scan-sexps (point) arg) (buffer-end
arg)))
(skip-chars-forward
"^([{<\"")
(while (eq (char-after)
?\")
(skip-string-forward)
(skip-chars-forward "^([{<\"") )
(setq open
(char-after))
(if (setq close (cadr
(assq open '( (?\( ?\))
(?\[ ?\])
(?\{ ?\})
(?\< ?\>) ) ) ) )
(progn
(setq notstro (string ?^ open
?\")
notstre (string ?^ open close ?\")
)
(while (and (> arg 0) (not
(eobp)))
(skip-chars-forward
notstro)
(while (eq (char-after)
?\")
(if
(eq (char-before) ?\\)
(forward-char 1)
(skip-string-forward) )
(skip-chars-forward notstro) )
(forward-char
1)
(setq depth
1)
(while (and (> depth
0) (not (eobp)))
(skip-chars-forward notstre)
(while (eq (char-after) ?\")
(if (eq (char-before) ?\\)
(forward-char
1)
(skip-string-forward) )
(skip-chars-forward notstre) )
(setq next (char-after))
(cond ((eq next open)
(setq depth (1+ depth)) )
((eq next
close)
(setq depth (1- depth)) )
(t
(throw 'done nil) ) )
(forward-char 1) )
(setq arg (1- arg) ) ) )
) ) )
((< arg 0)
(skip-chars-backward "
\t\t")
(if (not (memq (char-before) '(?\)
?\] ?\} ?\>)))
(progn
(goto-char (or (scan-sexps (point) arg)
(buffer-end arg)))
(backward-prefix-chars) )
(skip-chars-backward
"^)]}>\"")
(while (eq (char-before)
?\")
(skip-string-backward)
(skip-chars-backward "^)]}>\"") )
(setq close
(char-before))
(if (setq open (cadr
(assq close '( (?\) ?\()
(?\] ?\[)
(?\} ?\{)
(?\> ?\<) ) ) ) )
(progn
(setq notstrc (string ?^ close
?\")
notstre (string ?^ close open ?\")
)
(while (and (< arg 0) (not
(bobp)))
(skip-chars-backward
notstrc)
(while (eq (char-before)
?\")
(if
(eq (char-before (1- (point))) ?\\)
(forward-char -1)
(skip-string-backward) )
(skip-chars-backward notstrc) )
(forward-char
-1)
(setq depth
1)
(while (and (> depth
0) (not (bobp)))
(skip-chars-backward notstre)
(while (eq (char-before) ?\")
(if (eq (char-before (1- (point)))
?\\)
(forward-char
-1)
(skip-string-backward) )
(skip-chars-backward notstre) )
(setq next (char-before))
(cond ((eq next close)
(setq depth (1+ depth)) )
((eq next
open)
(setq depth (1- depth)) )
(t
(throw 'done nil) ) )
(forward-char -1) )
(setq arg (1+ arg)) ) ) )
) ) ) ) ))
--Greg