diff options
| author | Fabián Ezequiel Gallina | 2012-05-17 00:03:25 -0300 |
|---|---|---|
| committer | Fabián Ezequiel Gallina | 2012-05-17 00:03:25 -0300 |
| commit | fc6c545e4c61b341fd433f994c193ec6f61abbdd (patch) | |
| tree | d6332bc5521691b64bb008fa83a0deb9beea363b | |
| parent | 1faf2911d613ac1c208e7ffca52e484804d3b0bb (diff) | |
| download | emacs-fc6c545e4c61b341fd433f994c193ec6f61abbdd.tar.gz emacs-fc6c545e4c61b341fd433f994c193ec6f61abbdd.zip | |
Added simple way of jumping to current buffer's class/function definitions
The new `python-nav-jump-to-defun' function allows a user to jump fast
and easy to a function or class definition in the current buffer. For
this a entry in the menu and the C-c C-j keybinding have been
introduced.
New functions:
+ `python-nav-list-defun-positions'
+ `python-nav-read-defun'
+ `python-nav-jump-to-defun'
The new function `python-nav-list-defun-positions' does the same as a
relevant part of the `python-imenu-create-index' so the latter has
been refactored to use it.
| -rw-r--r-- | lisp/progmodes/python.el | 89 |
1 files changed, 67 insertions, 22 deletions
diff --git a/lisp/progmodes/python.el b/lisp/progmodes/python.el index fe026a8da1a..05e999a6bef 100644 --- a/lisp/progmodes/python.el +++ b/lisp/progmodes/python.el | |||
| @@ -49,14 +49,16 @@ | |||
| 49 | ;; causes the current line to be dedented automatically if needed. | 49 | ;; causes the current line to be dedented automatically if needed. |
| 50 | 50 | ||
| 51 | ;; Movement: `beginning-of-defun' and `end-of-defun' functions are | 51 | ;; Movement: `beginning-of-defun' and `end-of-defun' functions are |
| 52 | ;; properly implemented. Also there are specialized | 52 | ;; properly implemented. There are also specialized |
| 53 | ;; `forward-sentence' and `backward-sentence' replacements | 53 | ;; `forward-sentence' and `backward-sentence' replacements |
| 54 | ;; (`python-nav-forward-sentence', `python-nav-backward-sentence' | 54 | ;; (`python-nav-forward-sentence', `python-nav-backward-sentence' |
| 55 | ;; respectively). Extra functions `python-nav-sentence-start' and | 55 | ;; respectively). Extra functions `python-nav-sentence-start' and |
| 56 | ;; `python-nav-sentence-end' are included to move to the beginning and | 56 | ;; `python-nav-sentence-end' are included to move to the beginning and |
| 57 | ;; to the end of a setence while taking care of multiline definitions. | 57 | ;; to the end of a setence while taking care of multiline definitions. |
| 58 | ;; `python-nav-jump-to-defun' is provided and allows jumping to a | ||
| 59 | ;; function or class definition quickly in the current buffer. | ||
| 58 | 60 | ||
| 59 | ;; Shell interaction: is provided and allows you easily execute any | 61 | ;; Shell interaction: is provided and allows you to execute easily any |
| 60 | ;; block of code of your current buffer in an inferior Python process. | 62 | ;; block of code of your current buffer in an inferior Python process. |
| 61 | 63 | ||
| 62 | ;; Shell completion: hitting tab will try to complete the current | 64 | ;; Shell completion: hitting tab will try to complete the current |
| @@ -213,6 +215,7 @@ | |||
| 213 | (substitute-key-definition 'forward-sentence | 215 | (substitute-key-definition 'forward-sentence |
| 214 | 'python-nav-forward-sentence | 216 | 'python-nav-forward-sentence |
| 215 | map global-map) | 217 | map global-map) |
| 218 | (define-key map "\C-c\C-j" 'python-nav-jump-to-defun) | ||
| 216 | ;; Indent specific | 219 | ;; Indent specific |
| 217 | (define-key map "\177" 'python-indent-dedent-line-backspace) | 220 | (define-key map "\177" 'python-indent-dedent-line-backspace) |
| 218 | (define-key map (kbd "<backtab>") 'python-indent-dedent-line) | 221 | (define-key map (kbd "<backtab>") 'python-indent-dedent-line) |
| @@ -247,16 +250,17 @@ | |||
| 247 | ["Shift region right" python-indent-shift-right :active mark-active | 250 | ["Shift region right" python-indent-shift-right :active mark-active |
| 248 | :help "Shift region right by a single indentation step"] | 251 | :help "Shift region right by a single indentation step"] |
| 249 | "-" | 252 | "-" |
| 250 | ["Mark def/class" mark-defun | ||
| 251 | :help "Mark outermost definition around point"] | ||
| 252 | "-" | ||
| 253 | ["Start of def/class" beginning-of-defun | 253 | ["Start of def/class" beginning-of-defun |
| 254 | :help "Go to start of outermost definition around point"] | 254 | :help "Go to start of outermost definition around point"] |
| 255 | ["End of def/class" end-of-defun | 255 | ["End of def/class" end-of-defun |
| 256 | :help "Go to end of definition around point"] | 256 | :help "Go to end of definition around point"] |
| 257 | "-" | 257 | ["Mark def/class" mark-defun |
| 258 | :help "Mark outermost definition around point"] | ||
| 259 | ["Jump to def/class" python-nav-jump-to-defun | ||
| 260 | :help "Jump to a class or function definition"] | ||
| 261 | "--" | ||
| 258 | ("Skeletons") | 262 | ("Skeletons") |
| 259 | "-" | 263 | "---" |
| 260 | ["Start interpreter" run-python | 264 | ["Start interpreter" run-python |
| 261 | :help "Run inferior Python process in a separate buffer"] | 265 | :help "Run inferior Python process in a separate buffer"] |
| 262 | ["Switch to shell" python-shell-switch-to-shell | 266 | ["Switch to shell" python-shell-switch-to-shell |
| @@ -272,7 +276,7 @@ | |||
| 272 | ["Eval file" python-shell-send-file | 276 | ["Eval file" python-shell-send-file |
| 273 | :help "Eval file in inferior Python session"] | 277 | :help "Eval file in inferior Python session"] |
| 274 | ["Debugger" pdb :help "Run pdb under GUD"] | 278 | ["Debugger" pdb :help "Run pdb under GUD"] |
| 275 | "-" | 279 | "----" |
| 276 | ["Check file" python-check | 280 | ["Check file" python-check |
| 277 | :help "Check file for errors"] | 281 | :help "Check file for errors"] |
| 278 | ["Help on symbol" python-eldoc-at-point | 282 | ["Help on symbol" python-eldoc-at-point |
| @@ -898,7 +902,7 @@ With numeric ARG, just insert that many colons. With | |||
| 898 | 902 | ||
| 899 | (defvar python-nav-beginning-of-defun-regexp | 903 | (defvar python-nav-beginning-of-defun-regexp |
| 900 | (python-rx line-start (* space) defun (+ space) (group symbol-name)) | 904 | (python-rx line-start (* space) defun (+ space) (group symbol-name)) |
| 901 | "Regular expresion matching beginning of class or function. | 905 | "Regexp matching class or function definition. |
| 902 | The name of the defun should be grouped so it can be retrieved | 906 | The name of the defun should be grouped so it can be retrieved |
| 903 | via `match-string'.") | 907 | via `match-string'.") |
| 904 | 908 | ||
| @@ -1024,6 +1028,51 @@ With negative argument, move backward repeatedly to start of sentence." | |||
| 1024 | (forward-line -1) | 1028 | (forward-line -1) |
| 1025 | (setq arg (1+ arg)))) | 1029 | (setq arg (1+ arg)))) |
| 1026 | 1030 | ||
| 1031 | (defun python-nav-list-defun-positions (&optional include-type) | ||
| 1032 | "Make an Alist of defun names and point markers for current buffer. | ||
| 1033 | When optional argument INCLUDE-TYPE is non-nil the type is | ||
| 1034 | included the defun name." | ||
| 1035 | (let ((defs)) | ||
| 1036 | (save-restriction | ||
| 1037 | (widen) | ||
| 1038 | (save-excursion | ||
| 1039 | (goto-char (point-max)) | ||
| 1040 | (while (re-search-backward python-nav-beginning-of-defun-regexp nil t) | ||
| 1041 | (when (and (not (python-info-ppss-context 'string)) | ||
| 1042 | (not (python-info-ppss-context 'comment)) | ||
| 1043 | (not (python-info-ppss-context 'parent))) | ||
| 1044 | (add-to-list | ||
| 1045 | 'defs (cons | ||
| 1046 | (python-info-current-defun include-type) | ||
| 1047 | (point-marker))))) | ||
| 1048 | defs)))) | ||
| 1049 | |||
| 1050 | (defun python-nav-read-defun () | ||
| 1051 | "Read a defun name of current buffer and return its point marker. | ||
| 1052 | A cons cell with the form (DEFUN-NAME . POINT-MARKER) is returned | ||
| 1053 | when defun is completed, else nil." | ||
| 1054 | (let ((defs (python-nav-list-defun-positions))) | ||
| 1055 | (minibuffer-with-setup-hook | ||
| 1056 | (lambda () | ||
| 1057 | (setq minibuffer-completion-table (mapcar 'car defs))) | ||
| 1058 | (let ((stringdef | ||
| 1059 | (read-from-minibuffer | ||
| 1060 | "Jump to definition: " nil | ||
| 1061 | minibuffer-local-must-match-map))) | ||
| 1062 | (when (not (string= stringdef "")) | ||
| 1063 | (assoc-string stringdef defs)))))) | ||
| 1064 | |||
| 1065 | (defun python-nav-jump-to-defun (def) | ||
| 1066 | "Jump to the definition of DEF in current file." | ||
| 1067 | (interactive | ||
| 1068 | (list (python-nav-read-defun))) | ||
| 1069 | (when (not (called-interactively-p 'interactive)) | ||
| 1070 | (setq def (assoc-string def (python-nav-list-defun-positions)))) | ||
| 1071 | (let ((def-marker (cdr def))) | ||
| 1072 | (when (markerp def-marker) | ||
| 1073 | (goto-char (marker-position def-marker)) | ||
| 1074 | (back-to-indentation)))) | ||
| 1075 | |||
| 1027 | 1076 | ||
| 1028 | ;;; Shell integration | 1077 | ;;; Shell integration |
| 1029 | 1078 | ||
| @@ -2223,7 +2272,7 @@ Argument PLAIN-INDEX is the calculated plain index used to build the tree." | |||
| 2223 | full-element plain-index)))) | 2272 | full-element plain-index)))) |
| 2224 | 2273 | ||
| 2225 | (defun python-imenu-make-tree (index) | 2274 | (defun python-imenu-make-tree (index) |
| 2226 | "Build the imenu alist tree from plain INDEX. | 2275 | "Build the imenu alist tree from plain INDEX. |
| 2227 | 2276 | ||
| 2228 | The idea of this function is that given the alist: | 2277 | The idea of this function is that given the alist: |
| 2229 | 2278 | ||
| @@ -2249,21 +2298,17 @@ This tree gets built: | |||
| 2249 | 2298 | ||
| 2250 | Internally it uses `python-imenu-make-element-tree' to create all | 2299 | Internally it uses `python-imenu-make-element-tree' to create all |
| 2251 | branches for each element." | 2300 | branches for each element." |
| 2252 | (setq python-imenu-index-alist nil) | 2301 | (setq python-imenu-index-alist nil) |
| 2253 | (mapc (lambda (element) | 2302 | (mapc (lambda (element) |
| 2254 | (python-imenu-make-element-tree element element index)) | 2303 | (python-imenu-make-element-tree element element index)) |
| 2255 | (mapcar (lambda (element) | 2304 | (mapcar (lambda (element) |
| 2256 | (split-string (car element) "\\." t)) index)) | 2305 | (split-string (car element) "\\." t)) index)) |
| 2257 | python-imenu-index-alist) | 2306 | python-imenu-index-alist) |
| 2258 | 2307 | ||
| 2259 | (defun python-imenu-create-index () | 2308 | (defun python-imenu-create-index () |
| 2260 | "`imenu-create-index-function' for Python." | 2309 | "`imenu-create-index-function' for Python." |
| 2261 | (let ((index)) | 2310 | (let ((index |
| 2262 | (goto-char (point-max)) | 2311 | (python-nav-list-defun-positions python-imenu-include-defun-type))) |
| 2263 | (while (python-beginning-of-defun-function 1 t) | ||
| 2264 | (let ((defun-dotted-name | ||
| 2265 | (python-info-current-defun python-imenu-include-defun-type))) | ||
| 2266 | (push (cons defun-dotted-name (point)) index))) | ||
| 2267 | (if python-imenu-make-tree | 2312 | (if python-imenu-make-tree |
| 2268 | (python-imenu-make-tree index) | 2313 | (python-imenu-make-tree index) |
| 2269 | index))) | 2314 | index))) |