changeset 110067:5cab4c4229ff

* lisp/emacs-lisp/smie.el (smie-down-list): New command.
author Stefan Monnier <monnier@iro.umontreal.ca>
date Tue, 31 Aug 2010 14:22:40 +0200
parents 5ef877197e04
children 2af503eb57ef
files lisp/ChangeLog lisp/emacs-lisp/smie.el
diffstat 2 files changed, 38 insertions(+), 0 deletions(-) [+]
line wrap: on
line diff
--- a/lisp/ChangeLog	Tue Aug 31 14:13:51 2010 +0200
+++ b/lisp/ChangeLog	Tue Aug 31 14:22:40 2010 +0200
@@ -1,5 +1,7 @@
 2010-08-31  Stefan Monnier  <monnier@iro.umontreal.ca>
 
+	* emacs-lisp/smie.el (smie-down-list): New command.
+
 	Remove old indentation and navigation code on octave-mode.
 	* progmodes/octave-mod.el (octave-mode-map): Remap down-list to
 	smie-down-list rather than add a binding for octave-down-block.
--- a/lisp/emacs-lisp/smie.el	Tue Aug 31 14:13:51 2010 +0200
+++ b/lisp/emacs-lisp/smie.el	Tue Aug 31 14:22:40 2010 +0200
@@ -560,6 +560,42 @@
         (indent-according-to-mode)
       (reindent-then-newline-and-indent))))
 
+(defun smie-down-list (&optional arg)
+  "Move forward down one level paren-like blocks.  Like `down-list'.
+With argument ARG, do this that many times.
+A negative argument means move backward but still go down a level.
+This command assumes point is not in a string or comment."
+  (interactive "p")
+  (let ((start (point))
+        (inc (if (< arg 0) -1 1))
+        (offset (if (< arg 0) 1 0))
+        (next-token (if (< arg 0)
+                        smie-backward-token-function
+                      smie-forward-token-function)))
+    (while (/= arg 0)
+      (setq arg (- arg inc))
+      (while
+          (let* ((pos (point))
+                 (token (funcall next-token))
+                 (levels (assoc token smie-op-levels)))
+            (cond
+             ((zerop (length token))
+              (if (if (< inc 0) (looking-back "\\s(\\|\\s)" (1- (point)))
+                    (looking-at "\\s(\\|\\s)"))
+                  ;; Go back to `start' in case of an error.  This presumes
+                  ;; none of the token we've found until now include a ( or ).
+                  (progn (goto-char start) (down-list inc) nil)
+                (forward-sexp inc)
+                (/= (point) pos)))
+             ((and levels (null (nth (+ 1 offset) levels))) nil)
+             ((and levels (null (nth (- 2 offset) levels)))
+              (let ((end (point)))
+                (goto-char start)
+                (signal 'scan-error
+                        (list "Containing expression ends prematurely"
+                              pos end))))
+             (t)))))))
+
 ;;; The indentation engine.
 
 (defcustom smie-indent-basic 4