[climacs-cvs] CVS climacs
thenriksen
thenriksen at common-lisp.net
Mon Jun 5 16:13:33 UTC 2006
Update of /project/climacs/cvsroot/climacs
In directory clnet:/tmp/cvs-serv4125
Modified Files:
lisp-syntax.lisp
Log Message:
Fixed a bunch of structural Lisp movement commands/methods (from
elimination of infinite loops to proper handling of quote and
backquote forms).
--- /project/climacs/cvsroot/climacs/lisp-syntax.lisp 2006/06/04 22:19:56 1.84
+++ /project/climacs/cvsroot/climacs/lisp-syntax.lisp 2006/06/05 16:13:33 1.85
@@ -1791,6 +1791,38 @@
nil
(form-around-in-children (children stack-top) offset))))
+(defun find-list-parent-offset (form fn)
+ "Find a list parent of `token' and return `fn'
+applied to this parent token. `Fn' should be a function
+that returns an offset when applied to a
+token (eg. `start-offset' or `end-offset'). If a list
+parent cannot be found, return `fn' applied to `form'."
+ (when (not (typep form 'form*))
+ (let ((parent (parent form)))
+ (typecase parent
+ (form* (funcall fn form))
+ (list-form (funcall fn form))
+ (null (funcall fn form))
+ (t (find-list-parent-offset parent fn))))))
+
+(defun find-list-child-offset (form fn &optional (min-offset 0))
+ "Find a list child of `token' with a minimum start
+offset of `min-offset' and return `fn' applied to this child token.
+`Fn' should be a function that returns an offset when applied to a
+token (eg. `start-offset' or `end-offset'). If a list child cannot
+be found, return nil."
+ (labels ((has-list-child (form)
+ (some #'(lambda (child)
+ (if (and (typep child 'list-form)
+ (>= (start-offset child)
+ min-offset))
+ child
+ (has-list-child child)))
+ (children form))))
+ (let ((list-child (has-list-child form)))
+ (when (not (null list-child))
+ (funcall fn list-child)))))
+
(defmethod backward-expression (mark (syntax lisp-syntax))
(let ((potential-form (or (form-before syntax (offset mark))
(form-around syntax (offset mark)))))
@@ -1810,7 +1842,10 @@
then (end-offset potential-form)
for potential-form = (or (form-after syntax start)
(form-around syntax start))
- until (null potential-form)
+ until (or (null potential-form)
+ (and (= start
+ (end-offset potential-form))
+ (null (form-after syntax start))))
when (typep potential-form 'list-form)
do (setf (offset mark) (end-offset potential-form))
(return)
@@ -1821,55 +1856,52 @@
then (start-offset potential-form)
for potential-form = (or (form-before syntax start)
(form-around syntax start))
- until (null potential-form)
+ until (or (null potential-form)
+ (and (= start
+ (start-offset potential-form))
+ (null (form-before syntax start))))
when (typep potential-form 'list-form)
do (setf (offset mark) (start-offset potential-form))
(return)
finally (error 'no-expression)))
+(defun down-list-by-fn (mark syntax fn)
+ (let* ((offset (offset mark))
+ (potential-form (form-after syntax offset)))
+ (let ((new-offset (typecase potential-form
+ (list-form (start-offset potential-form))
+ (null nil)
+ (t (find-list-child-offset
+ (parent potential-form)
+ fn
+ offset)))))
+ (when new-offset
+ (setf (offset mark) (1+ new-offset))))))
+
(defmethod down-list (mark (syntax lisp-syntax))
- (loop for start = (offset mark)
- then (end-offset potential-form)
- for potential-form = (or (form-after syntax start)
- (form-around syntax start))
- until (null potential-form)
- when (typep potential-form 'list-form)
- do (setf (offset mark) (1+ (start-offset potential-form)))
- (return)
- finally (error 'no-expression)))
+ (down-list-by-fn mark syntax #'start-offset))
(defmethod backward-down-list (mark (syntax lisp-syntax))
- (loop for start = (offset mark)
- then (start-offset potential-form)
- for potential-form = (or (form-before syntax start)
- (form-around syntax start))
- until (null potential-form)
- when (typep potential-form 'list-form)
- do (setf (offset mark) (1- (end-offset potential-form)))
- (return)
- finally (error 'no-expression)))
+ (down-list-by-fn mark syntax #'end-offset)
+ (backward-object mark))
-(defmethod backward-up-list (mark (syntax lisp-syntax))
- (let ((form (or (form-around syntax (offset mark))
- (form-before syntax (offset mark))
- (form-after syntax (offset mark)))))
+(defun up-list-by-fn (mark syntax fn)
+ (let ((form (or (form-before syntax (offset mark))
+ (form-after syntax (offset mark))
+ (form-around syntax (offset mark)))))
(if form
- (let ((parent (parent form)))
- (if (typep parent 'list-form)
- (setf (offset mark) (start-offset parent))
- (error 'no-expression)))
- (error 'no-expression))))
+ (let ((parent (parent form)))
+ (when (not (null parent))
+ (let ((new-offset (find-list-parent-offset parent fn)))
+ (when new-offset
+ (setf (offset mark) new-offset)))))
+ (error 'no-expression))))
+
+(defmethod backward-up-list (mark (syntax lisp-syntax))
+ (up-list-by-fn mark syntax #'start-offset))
(defmethod up-list (mark (syntax lisp-syntax))
- (let ((form (or (form-around syntax (offset mark))
- (form-before syntax (offset mark))
- (form-after syntax (offset mark)))))
- (if form
- (let ((parent (parent form)))
- (if (typep parent 'list-form)
- (setf (offset mark) (end-offset parent))
- (error 'no-expression)))
- (error 'no-expression))))
+ (up-list-by-fn mark syntax #'end-offset))
(defmethod eval-defun (mark (syntax lisp-syntax))
(with-slots (stack-top) syntax
More information about the Climacs-cvs
mailing list