aboutsummaryrefslogtreecommitdiffstats
path: root/lisp/progmodes/python.el
diff options
context:
space:
mode:
Diffstat (limited to 'lisp/progmodes/python.el')
-rw-r--r--lisp/progmodes/python.el164
1 files changed, 64 insertions, 100 deletions
diff --git a/lisp/progmodes/python.el b/lisp/progmodes/python.el
index 0213a0ec8fb..bbf66f2033f 100644
--- a/lisp/progmodes/python.el
+++ b/lisp/progmodes/python.el
@@ -46,8 +46,7 @@
46;; causes the current line to be dedented automatically if needed. 46;; causes the current line to be dedented automatically if needed.
47 47
48;; Movement: `beginning-of-defun' and `end-of-defun' functions are 48;; Movement: `beginning-of-defun' and `end-of-defun' functions are
49;; properly implemented. A `beginning-of-innermost-defun' is defined 49;; properly implemented.
50;; to navigate nested defuns.
51 50
52;; Shell interaction: is provided and allows you easily execute any 51;; Shell interaction: is provided and allows you easily execute any
53;; block of code of your current buffer in an inferior Python process. 52;; block of code of your current buffer in an inferior Python process.
@@ -224,8 +223,6 @@
224 "-" 223 "-"
225 ["Start of def/class" beginning-of-defun 224 ["Start of def/class" beginning-of-defun
226 :help "Go to start of outermost definition around point"] 225 :help "Go to start of outermost definition around point"]
227 ["Start of def/class" python-beginning-of-innermost-defun
228 :help "Go to start of innermost definition around point"]
229 ["End of def/class" end-of-defun 226 ["End of def/class" end-of-defun
230 :help "Go to end of definition around point"] 227 :help "Go to end of definition around point"]
231 "-" 228 "-"
@@ -266,7 +263,10 @@
266 (or "def" "class" "if" "elif" "else" "try" 263 (or "def" "class" "if" "elif" "else" "try"
267 "except" "finally" "for" "while" "with") 264 "except" "finally" "for" "while" "with")
268 symbol-end)) 265 symbol-end))
266 `(decorator . ,(rx line-start (* space) ?@ (any letter ?_)
267 (* (any word ?_))))
269 `(defun . ,(rx symbol-start (or "def" "class") symbol-end)) 268 `(defun . ,(rx symbol-start (or "def" "class") symbol-end))
269 `(symbol-name . ,(rx (any letter ?_) (* (any word ?_))))
270 `(open-paren . ,(rx (or "{" "[" "("))) 270 `(open-paren . ,(rx (or "{" "[" "(")))
271 `(close-paren . ,(rx (or "}" "]" ")"))) 271 `(close-paren . ,(rx (or "}" "]" ")")))
272 `(simple-operator . ,(rx (any ?+ ?- ?/ ?& ?^ ?~ ?| ?* ?< ?> ?= ?%))) 272 `(simple-operator . ,(rx (any ?+ ?- ?/ ?& ?^ ?~ ?| ?* ?< ?> ?= ?%)))
@@ -870,109 +870,73 @@ With numeric ARG, just insert that many colons. With
870 870
871;;; Navigation 871;;; Navigation
872 872
873(defcustom python-use-beginning-of-innermost-defun nil 873(defvar python-nav-beginning-of-defun-regexp
874 "Set if `beginning-of-defun-function' should go to innermost defun." 874 (python-rx line-start (* space) defun (+ space) symbol-name)
875 :type 'string
876 :group 'python
877 :safe 'stringp)
878
879(defvar python-beginning-of-defun-regexp
880 "^\\(def\\|class\\)[[:space:]]+[[:word:]]+"
881 "Regular expresion matching beginning of outermost class or function.")
882
883(defvar python-beginning-of-innermost-defun-regexp
884 "^[[:space:]]*\\(def\\|class\\)[[:space:]]+[[:word:]]+"
885 "Regular expresion matching beginning of innermost class or function.") 875 "Regular expresion matching beginning of innermost class or function.")
886 876
887(defun python-beginning-of-defun (&optional innermost) 877(defun python-nav-beginning-of-defun ()
888 "Move point to the beginning of innermost/outermost def or class. 878 "Move point to beginning-of-defun.
889If INNERMOST is non-nil then move to the beginning of the 879This is the main part of`python-beginning-of-defun-function'
890innermost definition." 880implementation."
891 (let ((starting-point (point-marker)) 881 (let ((indent-pos (save-excursion
892 (nonblank-line-indent) 882 (back-to-indentation)
893 (defun-indent) 883 (point-marker)))
894 (defun-point) 884 (include-decorators
895 (regexp (if innermost 885 (lambda ()
896 python-beginning-of-innermost-defun-regexp 886 (when (save-excursion
897 python-beginning-of-defun-regexp))) 887 (forward-line -1)
898 (back-to-indentation) 888 (looking-at (python-rx decorator)))
899 (if (and (not (looking-at "@")) 889 (while (and (not (bobp))
900 (not (looking-at regexp))) 890 (forward-line -1)
901 (forward-comment -1) 891 (looking-at (python-rx decorator))))
902 (while (and (not (eobp)) 892 (when (not (bobp)) (forward-line 1))))))
903 (forward-line 1) 893 (if (and (> (point) indent-pos)
904 (not (back-to-indentation)) 894 (save-excursion
905 (looking-at "@")))) 895 (goto-char (line-beginning-position))
906 (when (not (looking-at regexp)) 896 (looking-at python-nav-beginning-of-defun-regexp)))
907 (re-search-backward regexp nil t))
908 (setq nonblank-line-indent (+ (current-indentation) python-indent-offset))
909 (setq defun-indent (current-indentation))
910 (setq defun-point (point-marker))
911 (if (> nonblank-line-indent defun-indent)
912 (progn 897 (progn
913 (goto-char defun-point) 898 (goto-char (line-beginning-position))
914 (forward-line -1) 899 (funcall include-decorators))
915 (while (and (looking-at "@") 900 (goto-char (line-beginning-position))
916 (forward-line -1) 901 (re-search-backward python-nav-beginning-of-defun-regexp nil t)
917 (not (bobp)) 902 (goto-char (or (python-info-ppss-context 'string) (point)))
918 (not (back-to-indentation)))) 903 (funcall include-decorators))))
919 (unless (bobp) 904
920 (forward-line 1)) 905(defun python-beginning-of-defun-function (&optional arg)
921 (point-marker)) 906 "Move point to the beginning of def or class.
922 (if innermost 907With positive ARG move that number of functions forward. With
923 (python-beginning-of-defun) 908negative do the same but backwards."
924 (goto-char starting-point) 909 (when (or (null arg) (= arg 0)) (setq arg 1))
925 nil)))) 910 (if (> arg 0)
926 911 (dotimes (i arg)
927(defun python-beginning-of-defun-function () 912 (python-nav-beginning-of-defun))
928 "Move point to the beginning of \(inner|outer)most def or class. 913 (dotimes (i (- arg))
929The point is moved to the beginning of innermost or outermost def 914 (python-end-of-defun-function)
930or class given the value of 915 (forward-comment 1)
931`python-use-beginning-of-innermost-defun'. Returns nil if point 916 (goto-char (line-end-position))
932is not in a def or class." 917 (when (not (eobp))
933 (python-beginning-of-defun python-use-beginning-of-innermost-defun)) 918 (python-nav-beginning-of-defun)))))
934
935(defun python-beginning-of-outermost-defun ()
936 "Move point to the beginning of outermost def or class.
937Returns nil if point is not in a def or class."
938 (interactive)
939 (python-beginning-of-defun nil))
940
941(defun python-beginning-of-innermost-defun ()
942 "Move point to the beginning of innermost def or class.
943Returns nil if point is not in a def or class."
944 (interactive)
945 (python-beginning-of-defun t))
946 919
947(defun python-end-of-defun-function () 920(defun python-end-of-defun-function ()
948 "Move point to the end of def or class. 921 "Move point to the end of def or class.
949Returns nil if point is not in a def or class." 922Returns nil if point is not in a def or class."
950 (let ((starting-point (point-marker)) 923 (interactive)
951 (defun-regexp (python-rx defun)) 924 (let ((beg-defun-indent)
952 (beg-defun-indent)) 925 (decorator-regexp "[[:space:]]*@"))
953 (back-to-indentation) 926 (when (looking-at decorator-regexp)
954 (if (looking-at "@") 927 (while (and (not (eobp))
955 (while (and (not (eobp)) 928 (forward-line 1)
956 (forward-line 1) 929 (looking-at decorator-regexp))))
957 (not (back-to-indentation)) 930 (when (not (looking-at python-nav-beginning-of-defun-regexp))
958 (looking-at "@"))) 931 (python-beginning-of-defun-function))
959 (while (and (not (bobp)) 932 (setq beg-defun-indent (current-indentation))
960 (not (progn (back-to-indentation) (current-word))) 933 (forward-line 1)
961 (forward-line -1)))) 934 (while (and (forward-line 1)
962 (when (or (not (equal (current-indentation) 0)) 935 (not (eobp))
963 (string-match defun-regexp (current-word))) 936 (or (not (current-word))
964 (setq beg-defun-indent (save-excursion 937 (> (current-indentation) beg-defun-indent))))
965 (or (looking-at defun-regexp) 938 (forward-comment 1)
966 (python-beginning-of-innermost-defun)) 939 (goto-char (line-beginning-position))))
967 (current-indentation)))
968 (while (and (forward-line 1)
969 (not (eobp))
970 (or (not (current-word))
971 (> (current-indentation) beg-defun-indent))))
972 (while (and (forward-comment -1)
973 (not (bobp))))
974 (forward-line 1)
975 (point-marker))))
976 940
977 941
978;;; Shell integration 942;;; Shell integration