summaryrefslogtreecommitdiff
path: root/lisp/progmodes/python.el
diff options
context:
space:
mode:
authorFabián Ezequiel Gallina <fgallina@cuca>2012-05-17 00:03:25 -0300
committerFabián Ezequiel Gallina <fgallina@gnu.org>2012-05-17 00:03:25 -0300
commitfc6c545e4c61b341fd433f994c193ec6f61abbdd (patch)
treed6332bc5521691b64bb008fa83a0deb9beea363b /lisp/progmodes/python.el
parent1faf2911d613ac1c208e7ffca52e484804d3b0bb (diff)
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.
Diffstat (limited to 'lisp/progmodes/python.el')
-rw-r--r--lisp/progmodes/python.el89
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 @@
;; causes the current line to be dedented automatically if needed.
;; Movement: `beginning-of-defun' and `end-of-defun' functions are
-;; properly implemented. Also there are specialized
+;; properly implemented. There are also specialized
;; `forward-sentence' and `backward-sentence' replacements
;; (`python-nav-forward-sentence', `python-nav-backward-sentence'
;; respectively). Extra functions `python-nav-sentence-start' and
;; `python-nav-sentence-end' are included to move to the beginning and
;; to the end of a setence while taking care of multiline definitions.
+;; `python-nav-jump-to-defun' is provided and allows jumping to a
+;; function or class definition quickly in the current buffer.
-;; Shell interaction: is provided and allows you easily execute any
+;; Shell interaction: is provided and allows you to execute easily any
;; block of code of your current buffer in an inferior Python process.
;; Shell completion: hitting tab will try to complete the current
@@ -213,6 +215,7 @@
(substitute-key-definition 'forward-sentence
'python-nav-forward-sentence
map global-map)
+ (define-key map "\C-c\C-j" 'python-nav-jump-to-defun)
;; Indent specific
(define-key map "\177" 'python-indent-dedent-line-backspace)
(define-key map (kbd "<backtab>") 'python-indent-dedent-line)
@@ -247,16 +250,17 @@
["Shift region right" python-indent-shift-right :active mark-active
:help "Shift region right by a single indentation step"]
"-"
- ["Mark def/class" mark-defun
- :help "Mark outermost definition around point"]
- "-"
["Start of def/class" beginning-of-defun
:help "Go to start of outermost definition around point"]
["End of def/class" end-of-defun
:help "Go to end of definition around point"]
- "-"
+ ["Mark def/class" mark-defun
+ :help "Mark outermost definition around point"]
+ ["Jump to def/class" python-nav-jump-to-defun
+ :help "Jump to a class or function definition"]
+ "--"
("Skeletons")
- "-"
+ "---"
["Start interpreter" run-python
:help "Run inferior Python process in a separate buffer"]
["Switch to shell" python-shell-switch-to-shell
@@ -272,7 +276,7 @@
["Eval file" python-shell-send-file
:help "Eval file in inferior Python session"]
["Debugger" pdb :help "Run pdb under GUD"]
- "-"
+ "----"
["Check file" python-check
:help "Check file for errors"]
["Help on symbol" python-eldoc-at-point
@@ -898,7 +902,7 @@ With numeric ARG, just insert that many colons. With
(defvar python-nav-beginning-of-defun-regexp
(python-rx line-start (* space) defun (+ space) (group symbol-name))
- "Regular expresion matching beginning of class or function.
+ "Regexp matching class or function definition.
The name of the defun should be grouped so it can be retrieved
via `match-string'.")
@@ -1024,6 +1028,51 @@ With negative argument, move backward repeatedly to start of sentence."
(forward-line -1)
(setq arg (1+ arg))))
+(defun python-nav-list-defun-positions (&optional include-type)
+ "Make an Alist of defun names and point markers for current buffer.
+When optional argument INCLUDE-TYPE is non-nil the type is
+included the defun name."
+ (let ((defs))
+ (save-restriction
+ (widen)
+ (save-excursion
+ (goto-char (point-max))
+ (while (re-search-backward python-nav-beginning-of-defun-regexp nil t)
+ (when (and (not (python-info-ppss-context 'string))
+ (not (python-info-ppss-context 'comment))
+ (not (python-info-ppss-context 'parent)))
+ (add-to-list
+ 'defs (cons
+ (python-info-current-defun include-type)
+ (point-marker)))))
+ defs))))
+
+(defun python-nav-read-defun ()
+ "Read a defun name of current buffer and return its point marker.
+A cons cell with the form (DEFUN-NAME . POINT-MARKER) is returned
+when defun is completed, else nil."
+ (let ((defs (python-nav-list-defun-positions)))
+ (minibuffer-with-setup-hook
+ (lambda ()
+ (setq minibuffer-completion-table (mapcar 'car defs)))
+ (let ((stringdef
+ (read-from-minibuffer
+ "Jump to definition: " nil
+ minibuffer-local-must-match-map)))
+ (when (not (string= stringdef ""))
+ (assoc-string stringdef defs))))))
+
+(defun python-nav-jump-to-defun (def)
+ "Jump to the definition of DEF in current file."
+ (interactive
+ (list (python-nav-read-defun)))
+ (when (not (called-interactively-p 'interactive))
+ (setq def (assoc-string def (python-nav-list-defun-positions))))
+ (let ((def-marker (cdr def)))
+ (when (markerp def-marker)
+ (goto-char (marker-position def-marker))
+ (back-to-indentation))))
+
;;; Shell integration
@@ -2223,7 +2272,7 @@ Argument PLAIN-INDEX is the calculated plain index used to build the tree."
full-element plain-index))))
(defun python-imenu-make-tree (index)
-"Build the imenu alist tree from plain INDEX.
+ "Build the imenu alist tree from plain INDEX.
The idea of this function is that given the alist:
@@ -2249,21 +2298,17 @@ This tree gets built:
Internally it uses `python-imenu-make-element-tree' to create all
branches for each element."
-(setq python-imenu-index-alist nil)
-(mapc (lambda (element)
- (python-imenu-make-element-tree element element index))
- (mapcar (lambda (element)
- (split-string (car element) "\\." t)) index))
-python-imenu-index-alist)
+ (setq python-imenu-index-alist nil)
+ (mapc (lambda (element)
+ (python-imenu-make-element-tree element element index))
+ (mapcar (lambda (element)
+ (split-string (car element) "\\." t)) index))
+ python-imenu-index-alist)
(defun python-imenu-create-index ()
"`imenu-create-index-function' for Python."
- (let ((index))
- (goto-char (point-max))
- (while (python-beginning-of-defun-function 1 t)
- (let ((defun-dotted-name
- (python-info-current-defun python-imenu-include-defun-type)))
- (push (cons defun-dotted-name (point)) index)))
+ (let ((index
+ (python-nav-list-defun-positions python-imenu-include-defun-type)))
(if python-imenu-make-tree
(python-imenu-make-tree index)
index)))