Corrected implementations for python-{beginning,end}-of-defun functions.

When point is at beginning-of-defun, end-of-defun moves to the end of
the defun, even if it contains nested defuns. When point is at any
inner defun end-of-defun moves to the end of it, if another inner
defun exists at the same level point is moved to it.

For beginning-of-defun things are funkier, it would move backwards
following nested defuns in order. This will be fixed soon.

Note: Decorators are considered part of defuns.

Removed:
    * python-use-beginning-of-innermost-defun
    * python-beginning-of-innermost-defun-regexp

Renamed:
    * python-beginning-of-defun => python-nav-beginning-of-defun
    * python-beginning-of-defun-regexp => python-nav-beginning-of-defun-regexp
This commit is contained in:
Fabián Ezequiel Gallina 2012-05-17 00:03:11 -03:00 committed by Fabián Ezequiel Gallina
parent c806ea6e87
commit 0567effbae

View file

@ -46,8 +46,7 @@
;; causes the current line to be dedented automatically if needed. ;; causes the current line to be dedented automatically if needed.
;; Movement: `beginning-of-defun' and `end-of-defun' functions are ;; Movement: `beginning-of-defun' and `end-of-defun' functions are
;; properly implemented. A `beginning-of-innermost-defun' is defined ;; properly implemented.
;; to navigate nested defuns.
;; Shell interaction: is provided and allows you easily execute any ;; Shell interaction: is provided and allows you easily execute any
;; block of code of your current buffer in an inferior Python process. ;; block of code of your current buffer in an inferior Python process.
@ -224,8 +223,6 @@
"-" "-"
["Start of def/class" beginning-of-defun ["Start of def/class" beginning-of-defun
:help "Go to start of outermost definition around point"] :help "Go to start of outermost definition around point"]
["Start of def/class" python-beginning-of-innermost-defun
:help "Go to start of innermost definition around point"]
["End of def/class" end-of-defun ["End of def/class" end-of-defun
:help "Go to end of definition around point"] :help "Go to end of definition around point"]
"-" "-"
@ -266,7 +263,10 @@
(or "def" "class" "if" "elif" "else" "try" (or "def" "class" "if" "elif" "else" "try"
"except" "finally" "for" "while" "with") "except" "finally" "for" "while" "with")
symbol-end)) symbol-end))
`(decorator . ,(rx line-start (* space) ?@ (any letter ?_)
(* (any word ?_))))
`(defun . ,(rx symbol-start (or "def" "class") symbol-end)) `(defun . ,(rx symbol-start (or "def" "class") symbol-end))
`(symbol-name . ,(rx (any letter ?_) (* (any word ?_))))
`(open-paren . ,(rx (or "{" "[" "("))) `(open-paren . ,(rx (or "{" "[" "(")))
`(close-paren . ,(rx (or "}" "]" ")"))) `(close-paren . ,(rx (or "}" "]" ")")))
`(simple-operator . ,(rx (any ?+ ?- ?/ ?& ?^ ?~ ?| ?* ?< ?> ?= ?%))) `(simple-operator . ,(rx (any ?+ ?- ?/ ?& ?^ ?~ ?| ?* ?< ?> ?= ?%)))
@ -870,109 +870,73 @@ With numeric ARG, just insert that many colons. With
;;; Navigation ;;; Navigation
(defcustom python-use-beginning-of-innermost-defun nil (defvar python-nav-beginning-of-defun-regexp
"Set if `beginning-of-defun-function' should go to innermost defun." (python-rx line-start (* space) defun (+ space) symbol-name)
:type 'string
:group 'python
:safe 'stringp)
(defvar python-beginning-of-defun-regexp
"^\\(def\\|class\\)[[:space:]]+[[:word:]]+"
"Regular expresion matching beginning of outermost class or function.")
(defvar python-beginning-of-innermost-defun-regexp
"^[[:space:]]*\\(def\\|class\\)[[:space:]]+[[:word:]]+"
"Regular expresion matching beginning of innermost class or function.") "Regular expresion matching beginning of innermost class or function.")
(defun python-beginning-of-defun (&optional innermost) (defun python-nav-beginning-of-defun ()
"Move point to the beginning of innermost/outermost def or class. "Move point to beginning-of-defun.
If INNERMOST is non-nil then move to the beginning of the This is the main part of`python-beginning-of-defun-function'
innermost definition." implementation."
(let ((starting-point (point-marker)) (let ((indent-pos (save-excursion
(nonblank-line-indent) (back-to-indentation)
(defun-indent) (point-marker)))
(defun-point) (include-decorators
(regexp (if innermost (lambda ()
python-beginning-of-innermost-defun-regexp (when (save-excursion
python-beginning-of-defun-regexp))) (forward-line -1)
(back-to-indentation) (looking-at (python-rx decorator)))
(if (and (not (looking-at "@")) (while (and (not (bobp))
(not (looking-at regexp))) (forward-line -1)
(forward-comment -1) (looking-at (python-rx decorator))))
(while (and (not (eobp)) (when (not (bobp)) (forward-line 1))))))
(forward-line 1) (if (and (> (point) indent-pos)
(not (back-to-indentation)) (save-excursion
(looking-at "@")))) (goto-char (line-beginning-position))
(when (not (looking-at regexp)) (looking-at python-nav-beginning-of-defun-regexp)))
(re-search-backward regexp nil t))
(setq nonblank-line-indent (+ (current-indentation) python-indent-offset))
(setq defun-indent (current-indentation))
(setq defun-point (point-marker))
(if (> nonblank-line-indent defun-indent)
(progn (progn
(goto-char defun-point) (goto-char (line-beginning-position))
(forward-line -1) (funcall include-decorators))
(while (and (looking-at "@") (goto-char (line-beginning-position))
(forward-line -1) (re-search-backward python-nav-beginning-of-defun-regexp nil t)
(not (bobp)) (goto-char (or (python-info-ppss-context 'string) (point)))
(not (back-to-indentation)))) (funcall include-decorators))))
(unless (bobp)
(forward-line 1))
(point-marker))
(if innermost
(python-beginning-of-defun)
(goto-char starting-point)
nil))))
(defun python-beginning-of-defun-function () (defun python-beginning-of-defun-function (&optional arg)
"Move point to the beginning of \(inner|outer)most def or class. "Move point to the beginning of def or class.
The point is moved to the beginning of innermost or outermost def With positive ARG move that number of functions forward. With
or class given the value of negative do the same but backwards."
`python-use-beginning-of-innermost-defun'. Returns nil if point (when (or (null arg) (= arg 0)) (setq arg 1))
is not in a def or class." (if (> arg 0)
(python-beginning-of-defun python-use-beginning-of-innermost-defun)) (dotimes (i arg)
(python-nav-beginning-of-defun))
(defun python-beginning-of-outermost-defun () (dotimes (i (- arg))
"Move point to the beginning of outermost def or class. (python-end-of-defun-function)
Returns nil if point is not in a def or class." (forward-comment 1)
(interactive) (goto-char (line-end-position))
(python-beginning-of-defun nil)) (when (not (eobp))
(python-nav-beginning-of-defun)))))
(defun python-beginning-of-innermost-defun ()
"Move point to the beginning of innermost def or class.
Returns nil if point is not in a def or class."
(interactive)
(python-beginning-of-defun t))
(defun python-end-of-defun-function () (defun python-end-of-defun-function ()
"Move point to the end of def or class. "Move point to the end of def or class.
Returns nil if point is not in a def or class." Returns nil if point is not in a def or class."
(let ((starting-point (point-marker)) (interactive)
(defun-regexp (python-rx defun)) (let ((beg-defun-indent)
(beg-defun-indent)) (decorator-regexp "[[:space:]]*@"))
(back-to-indentation) (when (looking-at decorator-regexp)
(if (looking-at "@") (while (and (not (eobp))
(while (and (not (eobp)) (forward-line 1)
(forward-line 1) (looking-at decorator-regexp))))
(not (back-to-indentation)) (when (not (looking-at python-nav-beginning-of-defun-regexp))
(looking-at "@"))) (python-beginning-of-defun-function))
(while (and (not (bobp)) (setq beg-defun-indent (current-indentation))
(not (progn (back-to-indentation) (current-word))) (forward-line 1)
(forward-line -1)))) (while (and (forward-line 1)
(when (or (not (equal (current-indentation) 0)) (not (eobp))
(string-match defun-regexp (current-word))) (or (not (current-word))
(setq beg-defun-indent (save-excursion (> (current-indentation) beg-defun-indent))))
(or (looking-at defun-regexp) (forward-comment 1)
(python-beginning-of-innermost-defun)) (goto-char (line-beginning-position))))
(current-indentation)))
(while (and (forward-line 1)
(not (eobp))
(or (not (current-word))
(> (current-indentation) beg-defun-indent))))
(while (and (forward-comment -1)
(not (bobp))))
(forward-line 1)
(point-marker))))
;;; Shell integration ;;; Shell integration