emacs-diffs
[Top][All Lists]
Advanced

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

[Emacs-diffs] /srv/bzr/emacs/emacs-24 r110849: Fix end-of-defun misbehav


From: Fabián Ezequiel Gallina
Subject: [Emacs-diffs] /srv/bzr/emacs/emacs-24 r110849: Fix end-of-defun misbehavior.
Date: Mon, 12 Nov 2012 10:26:50 -0300
User-agent: Bazaar (2.5.0)

------------------------------------------------------------
revno: 110849
committer: Fabián Ezequiel Gallina <address@hidden>
branch nick: emacs-24
timestamp: Mon 2012-11-12 10:26:50 -0300
message:
  Fix end-of-defun misbehavior.
  * progmodes/python.el (python-nav-beginning-of-defun): Rename from
  python-beginning-of-defun-function.  Handle nested defuns
  correctly.
  (python-nav-end-of-defun): Rename from
  python-end-of-defun-function.  Ensure forward movement.
  (python-info-current-defun): Reimplemented to work as intended
  with new fixed python-nav-{end,beginning}-of-defun.  Stop scanning
  parent defuns as soon as possible.
modified:
  lisp/ChangeLog
  lisp/progmodes/python.el
=== modified file 'lisp/ChangeLog'
--- a/lisp/ChangeLog    2012-11-12 08:42:27 +0000
+++ b/lisp/ChangeLog    2012-11-12 13:26:50 +0000
@@ -1,3 +1,15 @@
+2012-11-12  Fabián Ezequiel Gallina  <address@hidden>
+
+       Fix end-of-defun misbehavior.
+       * progmodes/python.el (python-nav-beginning-of-defun): Rename from
+       python-beginning-of-defun-function.  Handle nested defuns
+       correctly.
+       (python-nav-end-of-defun): Rename from
+       python-end-of-defun-function.  Ensure forward movement.
+       (python-info-current-defun): Reimplemented to work as intended
+       with new fixed python-nav-{end,beginning}-of-defun.  Stop scanning
+       parent defuns as soon as possible.
+
 2012-11-12  Glenn Morris  <address@hidden>
 
        * progmodes/flymake.el (flymake-error-bitmap)

=== modified file 'lisp/progmodes/python.el'
--- a/lisp/progmodes/python.el  2012-11-03 12:20:02 +0000
+++ b/lisp/progmodes/python.el  2012-11-12 13:26:50 +0000
@@ -1074,12 +1074,9 @@
 The name of the defun should be grouped so it can be retrieved
 via `match-string'.")
 
-(defun python-nav-beginning-of-defun (&optional arg)
-  "Move point to `beginning-of-defun'.
-With positive ARG move search backwards.  With negative do the
-same but forward.  When ARG is nil or 0 defaults to 1.  This is
-the main part of `python-beginning-of-defun-function'.  Return
-non-nil if point is moved to `beginning-of-defun'."
+(defun python-nav--beginning-of-defun (&optional arg)
+  "Internal implementation of `python-nav-beginning-of-defun'.
+With positive ARG search backwards, else search forwards."
   (when (or (null arg) (= arg 0)) (setq arg 1))
   (let* ((re-search-fn (if (> arg 0)
                            #'re-search-backward
@@ -1087,6 +1084,15 @@
          (line-beg-pos (line-beginning-position))
          (line-content-start (+ line-beg-pos (current-indentation)))
          (pos (point-marker))
+         (beg-indentation
+          (and (> arg 0)
+               (save-excursion
+                 (and (python-info-current-line-empty-p)
+                      (python-util-forward-comment -1))
+                 (python-nav-beginning-of-statement)
+                 (if (python-info-looking-at-beginning-of-defun)
+                     (+ (current-indentation) python-indent-offset)
+                   (current-indentation)))))
          (found
           (progn
             (when (and (< arg 0)
@@ -1094,7 +1100,12 @@
               (end-of-line 1))
             (while (and (funcall re-search-fn
                                  python-nav-beginning-of-defun-regexp nil t)
-                        (python-syntax-context-type)))
+                        (or (python-syntax-context-type)
+                            ;; Handle nested defuns when moving
+                            ;; backwards by checking indentation.
+                            (and (> arg 0)
+                                 (not (= (current-indentation) 0))
+                                 (>= (current-indentation) beg-indentation)))))
             (and (python-info-looking-at-beginning-of-defun)
                  (or (not (= (line-number-at-pos pos)
                              (line-number-at-pos)))
@@ -1105,55 +1116,43 @@
         (or (beginning-of-line 1) t)
       (and (goto-char pos) nil))))
 
-(defun python-beginning-of-defun-function (&optional arg)
-  "Move point to the beginning of def or class.
-With positive ARG move that number of functions backwards.  With
-negative do the same but forward.  When ARG is nil or 0 defaults
-to 1.  Return non-nil if point is moved to `beginning-of-defun'."
+(defun python-nav-beginning-of-defun (&optional arg)
+  "Move point to `beginning-of-defun'.
+With positive ARG search backwards else search forward.  When ARG
+is nil or 0 defaults to 1.  When searching backwards nested
+defuns are handled with care depending on current point
+position.  Return non-nil if point is moved to
+`beginning-of-defun'."
   (when (or (null arg) (= arg 0)) (setq arg 1))
   (let ((found))
     (cond ((and (eq this-command 'mark-defun)
                 (python-info-looking-at-beginning-of-defun)))
           (t
            (dotimes (i (if (> arg 0) arg (- arg)))
-             (when (and (python-nav-beginning-of-defun arg)
+             (when (and (python-nav--beginning-of-defun arg)
                         (not found))
                (setq found t)))))
     found))
 
-(defun python-end-of-defun-function ()
+(defun python-nav-end-of-defun ()
   "Move point to the end of def or class.
 Returns nil if point is not in a def or class."
   (interactive)
-  (let ((beg-defun-indent))
+  (let ((beg-defun-indent)
+        (beg-pos (point)))
     (when (or (python-info-looking-at-beginning-of-defun)
-              (python-beginning-of-defun-function 1)
-              (python-beginning-of-defun-function -1))
+              (python-nav-beginning-of-defun 1)
+              (python-nav-beginning-of-defun -1))
       (setq beg-defun-indent (current-indentation))
-      (forward-line 1)
-      ;; Go as forward as possible
-      (while (and (or
-                   (python-nav-beginning-of-defun -1)
-                   (and (goto-char (point-max)) nil))
-                  (> (current-indentation) beg-defun-indent)))
-      (beginning-of-line 1)
-      ;; Go as backwards as possible
-      (while (and (forward-line -1)
-                  (not (bobp))
-                  (or (not (current-word))
-                      (equal (char-after (+ (point) (current-indentation))) ?#)
-                      (<= (current-indentation) beg-defun-indent)
-                      (looking-at (python-rx decorator))
-                      (python-syntax-context-type))))
-      (forward-line 1)
-      ;; If point falls inside a paren or string context the point is
-      ;; forwarded at the end of it (or end of buffer if its not closed)
-      (let ((context-type (python-syntax-context-type)))
-        (when (memq context-type '(paren string))
-          ;; Slow but safe.
-          (while (and (not (eobp))
-                      (python-syntax-context-type))
-            (forward-line 1)))))))
+      (while (progn
+               (python-nav-end-of-statement)
+               (python-util-forward-comment 1)
+               (and (> (current-indentation) beg-defun-indent)
+                    (not (eobp)))))
+      (python-util-forward-comment -1)
+      (forward-line 1)
+      ;; Ensure point moves forward.
+      (and (> beg-pos (point)) (goto-char beg-pos)))))
 
 (defun python-nav-beginning-of-statement ()
   "Move to start of current statement."
@@ -2022,7 +2021,7 @@
     (python-shell-send-region
      (progn
        (end-of-line 1)
-       (while (and (or (python-beginning-of-defun-function)
+       (while (and (or (python-nav-beginning-of-defun)
                        (beginning-of-line 1))
                    (> (current-indentation) 0)))
        (when (not arg)
@@ -2031,7 +2030,7 @@
          (forward-line 1))
        (point-marker))
      (progn
-       (or (python-end-of-defun-function)
+       (or (python-nav-end-of-defun)
            (end-of-line 1))
        (point-marker)))))
 
@@ -2879,38 +2878,40 @@
 This function is compatible to be used as
 `add-log-current-defun-function' since it returns nil if point is
 not inside a defun."
-  (let ((names '())
-        (starting-indentation)
-        (starting-point)
-        (first-run t))
     (save-restriction
       (widen)
       (save-excursion
-        (setq starting-point (point-marker))
-        (setq starting-indentation (save-excursion
-                                     (python-nav-beginning-of-statement)
-                                     (current-indentation)))
         (end-of-line 1)
-        (while (python-beginning-of-defun-function 1)
-          (when (or (< (current-indentation) starting-indentation)
-                    (and first-run
-                         (<
-                          starting-point
-                          (save-excursion
-                            (python-end-of-defun-function)
-                            (point-marker)))))
-            (setq first-run nil)
-            (setq starting-indentation (current-indentation))
-            (looking-at python-nav-beginning-of-defun-regexp)
-            (setq names (cons
+        (let ((names)
+              (starting-indentation
+               (save-excursion
+                 (and
+                  (python-nav-beginning-of-defun 1)
+                  ;; This extra number is just for checking code
+                  ;; against indentation to work well on first run.
+                  (+ (current-indentation) 4))))
+              (starting-point (point)))
+          ;; Check point is inside a defun.
+          (when (and starting-indentation
+                     (< starting-point
+                         (save-excursion
+                           (python-nav-end-of-defun)
+                           (point))))
+            (catch 'exit
+              (while (python-nav-beginning-of-defun 1)
+                (when (< (current-indentation) starting-indentation)
+                  (setq starting-indentation (current-indentation))
+                  (setq names
+                        (cons
                          (if (not include-type)
                              (match-string-no-properties 1)
                            (mapconcat 'identity
                                       (split-string
                                        (match-string-no-properties 0)) " "))
-                         names))))))
-    (when names
-      (mapconcat (lambda (string) string) names "."))))
+                         names)))
+                (and (= (current-indentation) 0) (throw 'exit t)))))
+          (and names
+               (mapconcat (lambda (string) string) names "."))))))
 
 (defun python-info-current-symbol (&optional replace-self)
   "Return current symbol using dotty syntax.
@@ -3200,9 +3201,9 @@
        'python-fill-paragraph)
 
   (set (make-local-variable 'beginning-of-defun-function)
-       #'python-beginning-of-defun-function)
+       #'python-nav-beginning-of-defun)
   (set (make-local-variable 'end-of-defun-function)
-       #'python-end-of-defun-function)
+       #'python-nav-end-of-defun)
 
   (add-hook 'completion-at-point-functions
             'python-completion-complete-at-point nil 'local)
@@ -3230,7 +3231,7 @@
   (add-to-list 'hs-special-modes-alist
                `(python-mode "^\\s-*\\(?:def\\|class\\)\\>" nil "#"
                              ,(lambda (arg)
-                                (python-end-of-defun-function)) nil))
+                                (python-nav-end-of-defun)) nil))
 
   (set (make-local-variable 'mode-require-final-newline) t)
 


reply via email to

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