emacs-diffs
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

[Emacs-diffs] /srv/bzr/emacs/trunk r110434: Enhancements on forward-sexp


From: Fabián Ezequiel Gallina
Subject: [Emacs-diffs] /srv/bzr/emacs/trunk r110434: Enhancements on forward-sexp movement.
Date: Mon, 08 Oct 2012 02:19:15 -0300
User-agent: Bazaar (2.5.0)

------------------------------------------------------------
revno: 110434
committer: Fabián Ezequiel Gallina <address@hidden>
branch nick: trunk
timestamp: Mon 2012-10-08 02:19:15 -0300
message:
  Enhancements on forward-sexp movement.
  * progmodes/python.el (python-nav-beginning-of-statement)
  (python-nav-end-of-statement): Return point-marker.
  (python-nav-forward-sexp): lisp-like forward-sexp behavior.
  (python-info-current-symbol)
  (python-info-statement-starts-block-p): Rename from
  python-info-beginning-of-block-p.
  (python-info-statement-ends-block-p): Rename from
  python-info-end-of-block-p.
  (python-info-beginning-of-statement-p)
  (python-info-end-of-statement-p)
  (python-info-beginning-of-block-p, python-info-end-of-block-p):
  New functions.
modified:
  lisp/ChangeLog
  lisp/progmodes/python.el
=== modified file 'lisp/ChangeLog'
--- a/lisp/ChangeLog    2012-10-08 00:12:26 +0000
+++ b/lisp/ChangeLog    2012-10-08 05:19:15 +0000
@@ -1,3 +1,19 @@
+2012-10-08  Fabián Ezequiel Gallina  <address@hidden>
+
+       Enhancements on forward-sexp movement.
+       * progmodes/python.el (python-nav-beginning-of-statement)
+       (python-nav-end-of-statement): Return point-marker.
+       (python-nav-forward-sexp): lisp-like forward-sexp behavior.
+       (python-info-current-symbol)
+       (python-info-statement-starts-block-p): Rename from
+       python-info-beginning-of-block-p.
+       (python-info-statement-ends-block-p): Rename from
+       python-info-end-of-block-p.
+       (python-info-beginning-of-statement-p)
+       (python-info-end-of-statement-p)
+       (python-info-beginning-of-block-p, python-info-end-of-block-p):
+       New functions.
+
 2012-10-08  Stefan Monnier  <address@hidden>
 
        * comint.el (comint-preinput-scroll-to-bottom): Preserve the

=== modified file 'lisp/progmodes/python.el'
--- a/lisp/progmodes/python.el  2012-10-07 19:37:37 +0000
+++ b/lisp/progmodes/python.el  2012-10-08 05:19:15 +0000
@@ -1169,7 +1169,8 @@
                        (python-info-line-ends-backslash-p))
                      (python-syntax-context 'string)
                      (python-syntax-context 'paren))
-                (forward-line -1)))))
+                (forward-line -1))))
+  (point-marker))
 
 (defun python-nav-end-of-statement ()
   "Move to end of current statement."
@@ -1180,7 +1181,8 @@
                      (python-info-line-ends-backslash-p)
                      (python-syntax-context 'string)
                      (python-syntax-context 'paren))
-                (forward-line 1)))))
+                (forward-line 1))))
+  (point-marker))
 
 (defun python-nav-backward-statement (&optional arg)
   "Move backward to previous statement.
@@ -1295,151 +1297,104 @@
        (while (and (funcall search-fn paren-regexp nil t)
                    (python-syntax-context 'paren)))))))
 
-(defun python-nav--forward-sexp ()
-  "Move to forward sexp."
-  (case (python-syntax-context-type)
-    (string
-     ;; Inside of a string, get out of it.
-     (while (and (re-search-forward "[\"']" nil t)
-                 (python-syntax-context 'string))))
-    (comment
-     ;; Inside of a comment, just move forward.
-     (python-util-forward-comment))
-    (paren
-     (python-nav-lisp-forward-sexp-safe 1))
-    (t
-     (if (and (not (eobp))
-              (= (syntax-class (syntax-after (point))) 4))
-         ;; Looking an open-paren
-         (python-nav-lisp-forward-sexp-safe 1)
-       (let ((block-starting-pos
-              (save-excursion (python-nav-beginning-of-block)))
-             (block-ending-pos
-              (save-excursion (python-nav-end-of-block)))
-             (next-block-starting-pos
-              (save-excursion (python-nav-forward-block))))
-         (cond
-          ((not block-starting-pos)
-           ;; Not inside a block, move to closest one.
-           (and next-block-starting-pos
-                (goto-char next-block-starting-pos)))
-          ((= (point) block-starting-pos)
-           ;; Point is at beginning of block
-           (if (and next-block-starting-pos
-                    (< next-block-starting-pos block-ending-pos))
-               ;; Beginning of next block is closer than current's
-               ;; end, move to it.
-               (goto-char next-block-starting-pos)
-             (goto-char block-ending-pos)))
-          ((= block-ending-pos (point))
-           ;; Point is at end of current block
-           (let ((parent-block-end-pos
-                  (save-excursion
-                    (python-util-forward-comment)
-                    (python-nav-beginning-of-block)
-                    (python-nav-end-of-block))))
-             (if (and parent-block-end-pos
-                      (or (not next-block-starting-pos)
-                          (> next-block-starting-pos parent-block-end-pos)))
-                 ;; If the parent block ends before next block
-                 ;; starts move to it.
-                 (goto-char parent-block-end-pos)
-               (and next-block-starting-pos
-                    (goto-char next-block-starting-pos)))))
-          (t (python-nav-end-of-block))))))))
+(defun python-nav--forward-sexp (&optional dir)
+  "Move to forward sexp.
+With positive Optional argument DIR direction move forward, else
+backwards."
+  (setq dir (or dir 1))
+  (unless (= dir 0)
+    (let* ((forward-p (if (> dir 0)
+                          (and (setq dir 1) t)
+                        (and (setq dir -1) nil)))
+           (re-search-fn (if forward-p
+                             're-search-forward
+                           're-search-backward))
+           (context-type (python-syntax-context-type)))
+      (cond
+       ((eq context-type 'string)
+        ;; Inside of a string, get out of it.
+        (while (and (funcall re-search-fn "[\"']" nil t)
+                    (python-syntax-context 'string))))
+       ((eq context-type 'comment)
+        ;; Inside of a comment, just move forward.
+        (python-util-forward-comment dir))
+       ((or (eq context-type 'paren)
+            (and forward-p (looking-at (python-rx open-paren)))
+            (and (not forward-p)
+                 (eq (syntax-class (syntax-after (1- (point))))
+                     (car (string-to-syntax ")")))))
+        ;; Inside a paren or looking at it, lisp knows what to do.
+        (python-nav-lisp-forward-sexp-safe dir))
+       (t
+        ;; This part handles the lispy feel of
+        ;; `python-nav-forward-sexp'.  Knowing everything about the
+        ;; current context and the context of the next sexp tries to
+        ;; follow the lisp sexp motion commands in a symmetric manner.
+        (let* ((context
+                (cond
+                 ((python-info-beginning-of-block-p) 'block-start)
+                 ((python-info-end-of-block-p) 'block-end)
+                 ((python-info-beginning-of-statement-p) 'statement-start)
+                 ((python-info-end-of-statement-p) 'statement-end)))
+               (next-sexp-pos
+                (save-excursion
+                  (python-nav-lisp-forward-sexp-safe dir)
+                  (point)))
+              (next-sexp-context
+               (save-excursion
+                 (goto-char next-sexp-pos)
+                 (cond
+                  ((python-info-beginning-of-block-p) 'block-start)
+                  ((python-info-end-of-block-p) 'block-end)
+                  ((python-info-beginning-of-statement-p) 'statement-start)
+                  ((python-info-end-of-statement-p) 'statement-end)
+                  ((python-info-statement-starts-block-p) 'starts-block)
+                  ((python-info-statement-ends-block-p) 'ends-block)))))
+          (if forward-p
+              (cond ((and (not (eobp))
+                          (python-info-current-line-empty-p))
+                     (python-util-forward-comment dir)
+                     (python-nav--forward-sexp dir))
+                    ((eq context 'block-start)
+                     (python-nav-end-of-block))
+                    ((eq context 'statement-start)
+                     (python-nav-end-of-statement))
+                    ((and (memq context '(statement-end block-end))
+                          (eq next-sexp-context 'ends-block))
+                     (goto-char next-sexp-pos)
+                     (python-nav-end-of-block))
+                    ((and (memq context '(statement-end block-end))
+                          (eq next-sexp-context 'starts-block))
+                     (goto-char next-sexp-pos)
+                     (python-nav-end-of-block))
+                    ((memq context '(statement-end block-end))
+                     (goto-char next-sexp-pos)
+                     (python-nav-end-of-statement))
+                    (t (goto-char next-sexp-pos)))
+            (cond ((and (not (bobp))
+                        (python-info-current-line-empty-p))
+                     (python-util-forward-comment dir)
+                     (python-nav--forward-sexp dir))
+                  ((eq context 'block-end)
+                   (python-nav-beginning-of-block))
+                  ((eq context 'statement-end)
+                   (python-nav-beginning-of-statement))
+                  ((and (memq context '(statement-start block-start))
+                        (eq next-sexp-context 'starts-block))
+                   (goto-char next-sexp-pos)
+                   (python-nav-beginning-of-block))
+                  ((and (memq context '(statement-start block-start))
+                        (eq next-sexp-context 'ends-block))
+                   (goto-char next-sexp-pos)
+                   (python-nav-beginning-of-block))
+                  ((memq context '(statement-start block-start))
+                   (goto-char next-sexp-pos)
+                   (python-nav-beginning-of-statement))
+                  (t (goto-char next-sexp-pos))))))))))
 
 (defun python-nav--backward-sexp ()
   "Move to backward sexp."
-  (case (python-syntax-context-type)
-    (string
-     ;; Inside of a string, get out of it.
-     (while (and (re-search-backward "[\"']" nil t)
-                 (python-syntax-context 'string))))
-    (comment
-     ;; Inside of a comment, just move backward.
-     (python-util-forward-comment -1))
-    (paren
-     ;; Handle parens like we are lisp.
-     (python-nav-lisp-forward-sexp-safe -1))
-    (t
-     (let* ((block-starting-pos
-             (save-excursion (python-nav-beginning-of-block)))
-            (block-ending-pos
-             (save-excursion (python-nav-end-of-block)))
-            (prev-block-ending-pos
-             (save-excursion (when (python-nav-backward-block)
-                               (python-nav-end-of-block))))
-            (prev-block-parent-ending-pos
-             (save-excursion
-               (when prev-block-ending-pos
-                 (goto-char prev-block-ending-pos)
-                 (python-util-forward-comment)
-                 (python-nav-beginning-of-block)
-                 (python-nav-end-of-block)))))
-       (if (and (not (bobp))
-                (= (syntax-class (syntax-after (1- (point)))) 5))
-           ;; Char before point is a paren closing char, handle it
-           ;; like we are lisp.
-           (python-nav-lisp-forward-sexp-safe -1)
-         (cond
-          ((not block-ending-pos)
-           ;; Not in and ending pos, move to end of previous block.
-           (and (python-nav-backward-block)
-                (python-nav-end-of-block)))
-          ((= (point) block-ending-pos)
-           ;; In ending pos, we need to search backwards for the
-           ;; closest point looking the list of candidates from here.
-           (let ((candidates))
-             (dolist (name
-                      '(prev-block-parent-ending-pos
-                        prev-block-ending-pos
-                        block-ending-pos
-                        block-starting-pos))
-               (when (and (symbol-value name)
-                          (< (symbol-value name) (point)))
-                 (add-to-list 'candidates (symbol-value name))))
-             (goto-char (apply 'max candidates))))
-          ((> (point) block-ending-pos)
-           ;; After an ending position, move to it.
-           (goto-char block-ending-pos))
-          ((= (point) block-starting-pos)
-           ;; On a block starting position.
-           (if (not (> (point) (or prev-block-ending-pos (point))))
-               ;; Point is after the end position of the block that
-               ;; wraps the current one, just move a block backward.
-               (python-nav-backward-block)
-             ;; If we got here we are facing a case like this one:
-             ;;
-             ;;     try:
-             ;;         return here()
-             ;;     except Exception as e:
-             ;;
-             ;; Where point is on the "except" and must move to the
-             ;; end of "here()".
-             (goto-char prev-block-ending-pos)
-             (let ((parent-block-ending-pos
-                    (save-excursion
-                      (python-nav-forward-sexp)
-                      (and (not (looking-at (python-rx block-start)))
-                           (point)))))
-               (when (and parent-block-ending-pos
-                          (> parent-block-ending-pos prev-block-ending-pos))
-                 ;; If we got here we are facing a case like this one:
-                 ;;
-                 ;;     except ImportError:
-                 ;;         if predicate():
-                 ;;             processing()
-                 ;;         here()
-                 ;;     except AttributeError:
-                 ;;
-                 ;; Where point is on the "except" and must move to
-                 ;; the end of "here()". Without this extra step we'd
-                 ;; just get to the end of processing().
-                 (goto-char parent-block-ending-pos)))))
-          (t
-           (if (and prev-block-ending-pos (< prev-block-ending-pos (point)))
-               (goto-char prev-block-ending-pos)
-             (python-nav-beginning-of-block)))))))))
+  (python-nav--forward-sexp -1))
 
 (defun python-nav-forward-sexp (&optional arg)
   "Move forward across one block of code.
@@ -2891,12 +2846,43 @@
                          ".") ".")
              name)))))))
 
-(defsubst python-info-beginning-of-block-statement-p ()
+(defun python-info-statement-starts-block-p ()
   "Return non-nil if current statement opens a block."
   (save-excursion
     (python-nav-beginning-of-statement)
     (looking-at (python-rx block-start))))
 
+(defun python-info-statement-ends-block-p ()
+  "Return non-nil if point is at end of block."
+  (let ((end-of-block-pos (save-excursion
+                            (python-nav-end-of-block)))
+        (end-of-statement-pos (save-excursion
+                                (python-nav-end-of-statement))))
+    (and end-of-block-pos end-of-statement-pos
+         (= end-of-block-pos end-of-statement-pos))))
+
+(defun python-info-beginning-of-statement-p ()
+  "Return non-nil if point is at beginning of statement."
+  (= (point) (save-excursion
+               (python-nav-beginning-of-statement)
+               (point))))
+
+(defun python-info-end-of-statement-p ()
+  "Return non-nil if point is at end of statement."
+  (= (point) (save-excursion
+               (python-nav-end-of-statement)
+               (point))))
+
+(defun python-info-beginning-of-block-p ()
+  "Return non-nil if point is at beginning of block."
+  (and (python-info-beginning-of-statement-p)
+       (python-info-statement-starts-block-p)))
+
+(defun python-info-end-of-block-p ()
+  "Return non-nil if point is at end of block."
+  (and (python-info-end-of-statement-p)
+       (python-info-statement-ends-block-p)))
+
 (defun python-info-closing-block ()
   "Return the point of the block the current line closes."
   (let ((closing-word (save-excursion


reply via email to

[Prev in Thread] Current Thread [Next in Thread]