Skip to content
Projects
Groups
Snippets
Help
Loading...
Help
Support
Keyboard shortcuts
?
Submit feedback
Contribute to GitLab
Sign in / Register
Toggle navigation
C
cpython
Project overview
Project overview
Details
Activity
Releases
Repository
Repository
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Issues
0
Issues
0
List
Boards
Labels
Milestones
Merge Requests
0
Merge Requests
0
Analytics
Analytics
Repository
Value Stream
Wiki
Wiki
Members
Members
Collapse sidebar
Close sidebar
Activity
Graph
Create a new issue
Commits
Issue Boards
Open sidebar
Kirill Smelkov
cpython
Commits
3ec97e5d
Commit
3ec97e5d
authored
Oct 09, 1995
by
Guido van Rossum
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
interface for Emacs imenu
parent
288527a1
Changes
1
Hide whitespace changes
Inline
Side-by-side
Showing
1 changed file
with
305 additions
and
0 deletions
+305
-0
Misc/pyimenu.el
Misc/pyimenu.el
+305
-0
No files found.
Misc/pyimenu.el
0 → 100755
View file @
3ec97e5d
;;; PYIMENU.EL ---
;; Copyright (C) 1995 Perry A. Stoll
;; Author: Perry A. Stoll <stoll@atr-sw.atr.co.jp>
;; Created: 12 May 1995
;; Version: 1.0
;; Keywords: tools python imenu
;; This program is free software; you can redistribute it and/or modify
;; it under the terms of the GNU General Public License as published by
;; the Free Software Foundation; either version 2, or (at your option)
;; any later version.
;; This program is distributed in the hope that it will be useful,
;; but WITHOUT ANY WARRANTY; without even the implied warranty of
;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
;; GNU General Public License for more details.
;; A copy of the GNU General Public License can be obtained from the
;; Free Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139,
;; USA.
;;;; COMMENTS
;; I use the imenu package a lot for looking at Lisp and C/C++
;; code. When I started using Python, I was dismayed that I couldn't
;; use it to look at Python source. So here's a rough go at it.
;;;; USAGE
;; This program is used in conjunction with the imenu package. When
;; you call imenu in python-mode in a python buffer, a list of
;; functions and classes is built. The top level menu has a list of
;; all functions and classes defined at the top indentation
;; level. Classes which have methods defined in them have a submenu
;; which contains all definitions contained in them. Selecting any
;; item will bring you to that point in the file.
;;;; INSTALLATION
;; You know the routine:
;; 1) Save this file as pyimenu.el,
;; 2) Place that file somewhere in your emacs load path (maybe ~/emacs
;; or ~/emacs/lisp),
;; 3) Byte compile it (M-x byte-compile-file),
;; 4) Add the following (between "cut here" and "end here") to your
;; ~/.emacs file,
;; 5) Reboot. (joke: DON'T do that, although you'll probably have to
;; either reload your ~/.emacs file or start a new emacs)
;;--------------cut here-------------------------------------------
;;;; Load the pyimenu index function
;;(autoload 'imenu "imenu" nil t)
;;(autoload 'imenu-example--create-python-index "pyimenu")
;;;; Add the index creation function to the python-mode-hook
;;(add-hook 'python-mode-hook
;; (function
;; (lambda ()
;; (setq imenu-create-index-function
;; (function imenu-example--create-python-index)))))
;;----------------end here--------------------------------------------
;;
;; That is all you need. Of course, the following provides a more
;; useful interface. i.e. this is how I have it set up ;-)
;;
;;----------------optionally cut here----------------------------------
;;(autoload 'imenu-add-to-menubar "imenu" nil t)
;;(defun my-imenu-install-hook ()
;; (imenu-add-to-menubar (format "%s-%s" "IM" mode-name)))
;;(add-hook 'python-mode-hook (function my-imenu-install-hook))
;;;; Bind imenu to some convenient (?) mouse key. This really lets you
;;;; fly around the buffer. Here it is set to Meta-Shift-Mouse3Click.
;;(global-set-key [M-S-down-mouse-3] (function imenu))
;;-----------------optionaly end here-----------------------------------
;;;; CAVEATS/NOTES
;; 0) I'm not a professional elisp programmer and it shows in the code
;; below. If anyone there has suggestions/changes, I'd love to
;; hear them. I've tried the code out on a bunch of python files
;; from the python-1.1.1 Demo distribution and it worked with
;; them - your mileage may very.
;;
;; 1) You must have the imenu package to use this file. This file
;; works with imenu version 1.11 (the version included with emacs
;; 19.28) and imenu version 1.14; if you have a later version, this
;; may not work with it.
;;
;; 2) This setup assumes you also have python-mode.el, so that it can
;; use the python-mode-hook. It comes with the python distribution.
;;
;; 3) I don't have the Python 1.2 distribution yet, so again, this may
;; not work with that.
;;
(
require
'imenu
)
;;;
;;; VARIABLES: customizable in your .emacs file.
;;;
(
defvar
imenu-example--python-show-method-args-p
nil
"*When using imenu package with python-mode, whether the arguments of
the function/methods should be printed in the imenu buffer in addition
to the function/method name. If non-nil, args are printed."
)
;;;
;;; VARIABLES: internal use.
;;;
(
defvar
imenu-example--python-class-regexp
(
concat
; <<classes>>
"\\("
;
"^[ \t]*"
; newline and maybe whitespace
"\\(class[ \t]+[a-zA-Z0-9_]+\\)"
; class name
; possibly multiple superclasses
"\\([ \t]*\\((\\([a-zA-Z0-9_, \t\n]\\)*)\\)?\\)"
"[ \t]*:"
; and the final :
"\\)"
; >>classes<<
)
"Regexp for Python classes for use with the imenu package."
)
(
defvar
imenu-example--python-method-regexp
(
concat
; <<methods and functions>>
"\\("
;
"^[ \t]*"
; new line and maybe whitespace
"\\(def[ \t]+"
; function definitions start with def
"\\([a-zA-Z0-9_]+\\)"
; name is here
; function arguments...
"[ \t]*(\\([a-zA-Z0-9_=,\* \t\n]*\\))"
"\\)"
; end of def
"[ \t]*:"
; and then the :
"\\)"
; >>methods and functions<<
)
"Regexp for Python methods/functions for use with the imenu package."
)
(
defvar
imenu-example--python-method-no-arg-parens
'
(
2
8
)
"Indicies into the parenthesis list of the regular expression for
python for use with imenu. Using these values will result in smaller
imenu lists, as arguments to functions are not listed.
See the variable imenu-example--python-show-method-args-p to for
information"
)
(
defvar
imenu-example--python-method-arg-parens
'
(
2
7
)
"Indicies into the parenthesis list of the regular expression for
python for use with imenu. Using these values will result in large
imenu lists, as arguments to functions are listed.
See the variable imenu-example--python-show-method-args-p to for
information"
)
;; Note that in this format, this variable can still be used with the
;; imenu--generic-function. Otherwise, there is no real reason to have
;; it.
(
defvar
imenu-example--generic-python-expression
(
cons
(
concat
imenu-example--python-class-regexp
"\\|"
; or...
imenu-example--python-method-regexp
)
imenu-example--python-method-no-arg-parens
)
"Generic Python expression which may be used directly with imenu by
setting the variable imenu-generic-expression to this value. Also, see
the function \\[imenu-example--create-python-index] for an alternate
way of finding the index."
)
;; These next two variables are used when searching for the python
;; class/definitions. Just saving some time in accessing the
;; generic-python-expression, really.
(
defvar
imenu-example--python-generic-regexp
)
(
defvar
imenu-example--python-generic-parens
)
;;;
;;; CODE:
;;;
;; Note:
;; At first, I tried using some of the functions supplied by
;; python-mode to navigate through functions and classes, but after a
;; while, I decided dump it. This file is relatively self contained
;; and I liked it that.
;;;###autoload
(
defun
imenu-example--create-python-index
()
"Interface function for imenu package to find all python classes and
functions/methods. Calls function
\\[imenu-example--create-python-index-engine]. See that function for
the details of how this works."
(
setq
imenu-example--python-generic-regexp
(
car
imenu-example--generic-python-expression
))
(
setq
imenu-example--python-generic-parens
(
if
imenu-example--python-show-method-args-p
imenu-example--python-method-arg-parens
imenu-example--python-method-no-arg-parens
))
(
goto-char
(
point-min
))
(
imenu-example--create-python-index-engine
nil
))
(
defun
imenu-example--create-python-index-engine
(
&optional
start-indent
)
"Function for finding all definitions (classes, methods, or functions)
in a python file for the imenu package.
Retuns a possibly nested alist of the form \(INDEX-NAME
INDEX-POSITION). The second element of the alist may be an alist,
producing a nested list as in \(INDEX-NAME . INDEX-ALIST).
This function should not be called directly, as it calls itself
recursively and requires some setup. Rather this is the engine for the
function \\[imenu-example--create-python-index].
It works recursively by looking for all definitions at the current
indention level. When it finds one, it adds it to the alist. If it
finds a definition at a greater indentation level, it removes the
previous definition from the alist. In it's place it adds all
definitions found at the next indentation level. When it finds a
definition that is less indented then the current level, it retuns the
alist it has created thus far.
The optional argument START-INDENT indicates the starting indentation
at which to continue looking for python classes, methods, or
functions. If this is not supplied, the function uses the indentation
of the first definition found. "
(
let
((
index-alist
'
())
(
sub-method-alist
'
())
looking-p
def-name
prev-name
cur-indent
def-pos
(
class-paren
(
first
imenu-example--python-generic-parens
))
(
def-paren
(
second
imenu-example--python-generic-parens
)))
(
setq
looking-p
(
re-search-forward
imenu-example--python-generic-regexp
(
point-max
)
t
))
(
while
looking-p
(
save-excursion
;; used to set def-name to this value but generic-extract-name is
;; new to imenu-1.14. this way it still works with imenu-1.11
;;(imenu--generic-extract-name imenu-example--python-generic-parens))
(
let
((
cur-paren
(
if
(
match-beginning
class-paren
)
class-paren
def-paren
)))
(
setq
def-name
(
buffer-substring
(
match-beginning
cur-paren
)
(
match-end
cur-paren
))))
(
beginning-of-line
)
(
setq
cur-indent
(
current-indentation
)))
;; HACK: want to go to the correct definition location. Assuming
;; here that there are only two..which is true for python.
(
setq
def-pos
(
or
(
match-beginning
class-paren
)
(
match-beginning
def-paren
)))
; if we don't have a starting indent level, take this one
(
or
start-indent
(
setq
start-indent
cur-indent
))
; if we don't have class name yet, take this one
(
or
prev-name
(
setq
prev-name
def-name
))
;; what level is the next definition on?
;; must be same, deeper or shallower indentation
(
cond
;; at the same indent level, add it to the list...
((
=
start-indent
cur-indent
)
(
push
(
cons
def-name
def-pos
)
index-alist
))
;; deeper indented expression, recur...
((
<
start-indent
cur-indent
)
;; the point is currently on the expression we're supposed to
;; start on, so go back to the last expression. The recursive
;; call will find this place again and add it to the correct
;; list
(
re-search-backward
imenu-example--python-generic-regexp
(
point-min
)
'move
)
(
setq
sub-method-alist
(
imenu-example--create-python-index-engine
cur-indent
))
(
if
sub-method-alist
;; we put the last element on the index-alist on the start
;; of the submethod alist so the user can still get to it.
(
let
((
save-elmt
(
pop
index-alist
)))
(
push
(
cons
(
imenu-create-submenu-name
prev-name
)
(
cons
save-elmt
sub-method-alist
))
index-alist
))))
;; found less indented expression, we're done.
(
t
(
setq
looking-p
nil
)
(
re-search-backward
imenu-example--python-generic-regexp
(
point-min
)
t
)))
(
setq
prev-name
def-name
)
(
and
looking-p
(
setq
looking-p
(
re-search-forward
imenu-example--python-generic-regexp
(
point-max
)
'move
))))
(
nreverse
index-alist
)))
(
provide
'pyimenu
)
;;; PyImenu.EL ends here
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment