diff options
| author | Stefan Monnier | 2006-08-20 17:54:48 +0000 |
|---|---|---|
| committer | Stefan Monnier | 2006-08-20 17:54:48 +0000 |
| commit | 67b595a2904e477aa06913ebf46e7ce7130801f9 (patch) | |
| tree | ded039d731c0000d3e436c1b9890979d13b03cba | |
| parent | c7bb83bdeb37144192a4924535a11daa8d57535a (diff) | |
| download | emacs-67b595a2904e477aa06913ebf46e7ce7130801f9.tar.gz emacs-67b595a2904e477aa06913ebf46e7ce7130801f9.zip | |
Update to Dave Love's latest version.
(__all__): Fix args -> eargs. Add new `modpath' fun.
(eargs): Add `imports' arg.
(all_names): New fun.
(complete): Rewrite without using rlcompleter.
Remove `namespace' arg, add `imports' arg.
(ehelp): Replace g and l args with `imports'.
(eimport): Use __main__ rather than `emacs' namespace.
(modpath): New fun.
| -rw-r--r-- | etc/ChangeLog | 12 | ||||
| -rw-r--r-- | etc/emacs.py | 140 |
2 files changed, 122 insertions, 30 deletions
diff --git a/etc/ChangeLog b/etc/ChangeLog index ec2b017c25c..6f177e3b890 100644 --- a/etc/ChangeLog +++ b/etc/ChangeLog | |||
| @@ -1,3 +1,15 @@ | |||
| 1 | 2006-08-20 Dave Love <fx@gnu.org> | ||
| 2 | |||
| 3 | * emacs.py: Update to Dave Love's latest version. | ||
| 4 | (__all__): Fix args -> eargs. Add new `modpath' fun. | ||
| 5 | (eargs): Add `imports' arg. | ||
| 6 | (all_names): New fun. | ||
| 7 | (complete): Rewrite without using rlcompleter. | ||
| 8 | Remove `namespace' arg, add `imports' arg. | ||
| 9 | (ehelp): Replace g and l args with `imports'. | ||
| 10 | (eimport): Use __main__ rather than `emacs' namespace. | ||
| 11 | (modpath): New fun. | ||
| 12 | |||
| 1 | 2006-08-20 Slawomir Nowaczyk <slawomir.nowaczyk.847@student.lu.se> (tiny change) | 13 | 2006-08-20 Slawomir Nowaczyk <slawomir.nowaczyk.847@student.lu.se> (tiny change) |
| 2 | 14 | ||
| 3 | * emacs.py (eexecfile): Use the __main__ rather than `emacs' namespace. | 15 | * emacs.py (eexecfile): Use the __main__ rather than `emacs' namespace. |
diff --git a/etc/emacs.py b/etc/emacs.py index bc6c5bb034d..7614f0927df 100644 --- a/etc/emacs.py +++ b/etc/emacs.py | |||
| @@ -1,7 +1,7 @@ | |||
| 1 | """Definitions used by commands sent to inferior Python in python.el.""" | 1 | """Definitions used by commands sent to inferior Python in python.el.""" |
| 2 | 2 | ||
| 3 | # Copyright (C) 2004, 2005, 2006 Free Software Foundation, Inc. | 3 | # Copyright (C) 2004, 2005, 2006 Free Software Foundation, Inc. |
| 4 | # Author: Dave Love <d.love@dl.ac.uk> | 4 | # Author: Dave Love <fx@gnu.org> |
| 5 | 5 | ||
| 6 | # This file is part of GNU Emacs. | 6 | # This file is part of GNU Emacs. |
| 7 | 7 | ||
| @@ -20,9 +20,10 @@ | |||
| 20 | # Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, | 20 | # Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, |
| 21 | # Boston, MA 02110-1301, USA. | 21 | # Boston, MA 02110-1301, USA. |
| 22 | 22 | ||
| 23 | import os, sys, traceback, inspect, rlcompleter, __main__ | 23 | import os, sys, traceback, inspect, __main__ |
| 24 | from sets import Set | ||
| 24 | 25 | ||
| 25 | __all__ = ["eexecfile", "args", "complete", "ehelp", "eimport"] | 26 | __all__ = ["eexecfile", "eargs", "complete", "ehelp", "eimport", "modpath"] |
| 26 | 27 | ||
| 27 | def eexecfile (file): | 28 | def eexecfile (file): |
| 28 | """Execute FILE and then remove it. | 29 | """Execute FILE and then remove it. |
| @@ -32,8 +33,8 @@ def eexecfile (file): | |||
| 32 | try: | 33 | try: |
| 33 | try: execfile (file, __main__.__dict__) | 34 | try: execfile (file, __main__.__dict__) |
| 34 | except: | 35 | except: |
| 35 | (type, value, tb) = sys.exc_info () | 36 | (type, value, tb) = sys.exc_info () |
| 36 | # Lose the stack frame for this location. | 37 | # Lose the stack frame for this location. |
| 37 | tb = tb.tb_next | 38 | tb = tb.tb_next |
| 38 | if tb is None: # print_exception won't do it | 39 | if tb is None: # print_exception won't do it |
| 39 | print "Traceback (most recent call last):" | 40 | print "Traceback (most recent call last):" |
| @@ -41,9 +42,10 @@ def eexecfile (file): | |||
| 41 | finally: | 42 | finally: |
| 42 | os.remove (file) | 43 | os.remove (file) |
| 43 | 44 | ||
| 44 | def eargs (name): | 45 | def eargs (name, imports): |
| 45 | "Get arglist of NAME for Eldoc &c." | 46 | "Get arglist of NAME for Eldoc &c." |
| 46 | try: | 47 | try: |
| 48 | if imports: exec imports | ||
| 47 | parts = name.split ('.') | 49 | parts = name.split ('.') |
| 48 | if len (parts) > 1: | 50 | if len (parts) > 1: |
| 49 | exec 'import ' + parts[0] # might fail | 51 | exec 'import ' + parts[0] # might fail |
| @@ -57,8 +59,7 @@ def eargs (name): | |||
| 57 | return | 59 | return |
| 58 | if inspect.ismethod (func): | 60 | if inspect.ismethod (func): |
| 59 | func = func.im_func | 61 | func = func.im_func |
| 60 | if not inspect.isfunction (func): | 62 | if not inspect.isfunction (func): return |
| 61 | return | ||
| 62 | (args, varargs, varkw, defaults) = inspect.getargspec (func) | 63 | (args, varargs, varkw, defaults) = inspect.getargspec (func) |
| 63 | # No space between name and arglist for consistency with builtins. | 64 | # No space between name and arglist for consistency with builtins. |
| 64 | print '_emacs_out', \ | 65 | print '_emacs_out', \ |
| @@ -66,41 +67,109 @@ def eargs (name): | |||
| 66 | defaults) | 67 | defaults) |
| 67 | except: pass | 68 | except: pass |
| 68 | 69 | ||
| 69 | def complete (text, namespace = None): | 70 | def all_names (object): |
| 71 | """Return (an approximation to) a list of all possible attribute | ||
| 72 | names reachable via the attributes of OBJECT, i.e. roughly the | ||
| 73 | leaves of the dictionary tree under it.""" | ||
| 74 | |||
| 75 | def do_object (object, names): | ||
| 76 | if inspect.ismodule (object): | ||
| 77 | do_module (object, names) | ||
| 78 | elif inspect.isclass (object): | ||
| 79 | do_class (object, names) | ||
| 80 | # Might have an object without its class in scope. | ||
| 81 | elif hasattr (object, '__class__'): | ||
| 82 | names.add ('__class__') | ||
| 83 | do_class (object.__class__, names) | ||
| 84 | # Probably not a good idea to try to enumerate arbitrary | ||
| 85 | # dictionaries... | ||
| 86 | return names | ||
| 87 | |||
| 88 | def do_module (module, names): | ||
| 89 | if hasattr (module, '__all__'): # limited export list | ||
| 90 | names.union_update (module.__all__) | ||
| 91 | for i in module.__all__: | ||
| 92 | do_object (getattr (module, i), names) | ||
| 93 | else: # use all names | ||
| 94 | names.union_update (dir (module)) | ||
| 95 | for i in dir (module): | ||
| 96 | do_object (getattr (module, i), names) | ||
| 97 | return names | ||
| 98 | |||
| 99 | def do_class (object, names): | ||
| 100 | ns = dir (object) | ||
| 101 | names.union_update (ns) | ||
| 102 | if hasattr (object, '__bases__'): # superclasses | ||
| 103 | for i in object.__bases__: do_object (i, names) | ||
| 104 | return names | ||
| 105 | |||
| 106 | return do_object (object, Set ([])) | ||
| 107 | |||
| 108 | def complete (name, imports): | ||
| 70 | """Complete TEXT in NAMESPACE and print a Lisp list of completions. | 109 | """Complete TEXT in NAMESPACE and print a Lisp list of completions. |
| 71 | NAMESPACE is currently not used.""" | 110 | Exec IMPORTS first.""" |
| 72 | if namespace is None: namespace = __main__.__dict__ | 111 | import __main__, keyword |
| 73 | c = rlcompleter.Completer (namespace) | 112 | |
| 113 | def class_members(object): | ||
| 114 | names = dir (object) | ||
| 115 | if hasattr (object, '__bases__'): | ||
| 116 | for super in object.__bases__: | ||
| 117 | names = class_members (super) | ||
| 118 | return names | ||
| 119 | |||
| 120 | names = Set ([]) | ||
| 121 | base = None | ||
| 74 | try: | 122 | try: |
| 75 | if '.' in text: | 123 | dict = __main__.__dict__.copy() |
| 76 | matches = c.attr_matches (text) | 124 | if imports: exec imports in dict |
| 77 | else: | 125 | l = len (name) |
| 78 | matches = c.global_matches (text) | 126 | if not "." in name: |
| 79 | print '_emacs_out (', | 127 | for list in [dir (__builtins__), keyword.kwlist, dict.keys()]: |
| 80 | for elt in matches: | 128 | for elt in list: |
| 81 | print '"%s"' % elt, | 129 | if elt[:l] == name: names.add(elt) |
| 82 | print ')' | 130 | else: |
| 83 | except: | 131 | base = name[:name.rfind ('.')] |
| 84 | print '_emacs_out ()' | 132 | name = name[name.rfind('.')+1:] |
| 133 | try: | ||
| 134 | object = eval (base, dict) | ||
| 135 | names = Set (dir (object)) | ||
| 136 | if hasattr (object, '__class__'): | ||
| 137 | names.add('__class__') | ||
| 138 | names.union_update (class_members (object)) | ||
| 139 | except: names = all_names (dict) | ||
| 140 | except: return [] | ||
| 141 | l = len(name) | ||
| 142 | print '_emacs_out (', | ||
| 143 | for n in names: | ||
| 144 | if name == n[:l]: | ||
| 145 | if base: print '"%s.%s"' % (base, n), | ||
| 146 | else: print '"%s"' % n, | ||
| 147 | print ')' | ||
| 85 | 148 | ||
| 86 | def ehelp (name, g, l): | 149 | def ehelp (name, imports): |
| 87 | """Get help on string NAME using globals G and locals L. | 150 | """Get help on string NAME. |
| 88 | First try to eval name for, e.g. user definitions where we need | 151 | First try to eval name for, e.g. user definitions where we need |
| 89 | the object. Otherwise try the string form.""" | 152 | the object. Otherwise try the string form.""" |
| 90 | try: help (eval (name, g, l)) | 153 | locls = {} |
| 154 | if imports: | ||
| 155 | try: exec imports in locls | ||
| 156 | except: pass | ||
| 157 | try: help (eval (name, globals(), locls)) | ||
| 91 | except: help (name) | 158 | except: help (name) |
| 92 | 159 | ||
| 93 | def eimport (mod, dir): | 160 | def eimport (mod, dir): |
| 94 | """Import module MOD with directory DIR at the head of the search path. | 161 | """Import module MOD with directory DIR at the head of the search path. |
| 95 | NB doesn't load from DIR if MOD shadows a system module.""" | 162 | NB doesn't load from DIR if MOD shadows a system module.""" |
| 163 | from __main__ import __dict__ | ||
| 164 | |||
| 96 | path0 = sys.path[0] | 165 | path0 = sys.path[0] |
| 97 | sys.path[0] = dir | 166 | sys.path[0] = dir |
| 98 | try: | 167 | try: |
| 99 | try: | 168 | try: |
| 100 | if globals().has_key(mod) and inspect.ismodule (eval (mod)): | 169 | if __dict__.has_key(mod) and inspect.ismodule (__dict__[mod]): |
| 101 | reload(eval (mod)) | 170 | reload (__dict__[mod]) |
| 102 | else: | 171 | else: |
| 103 | globals ()[mod] = __import__ (mod) | 172 | __dict__[mod] = __import__ (mod) |
| 104 | except: | 173 | except: |
| 105 | (type, value, tb) = sys.exc_info () | 174 | (type, value, tb) = sys.exc_info () |
| 106 | print "Traceback (most recent call last):" | 175 | print "Traceback (most recent call last):" |
| @@ -108,6 +177,17 @@ def eimport (mod, dir): | |||
| 108 | finally: | 177 | finally: |
| 109 | sys.path[0] = path0 | 178 | sys.path[0] = path0 |
| 110 | 179 | ||
| 111 | print '_emacs_ok' # ready for input and can call continuation | 180 | def modpath (module): |
| 181 | """Return the source file for the given MODULE (or None). | ||
| 182 | Assumes that MODULE.py and MODULE.pyc are in the same directory.""" | ||
| 183 | try: | ||
| 184 | path = __import__ (module).__file__ | ||
| 185 | if path[-4:] == '.pyc' and os.path.exists (path[0:-1]): | ||
| 186 | path = path[:-1] | ||
| 187 | print "_emacs_out", path | ||
| 188 | except: | ||
| 189 | print "_emacs_out ()" | ||
| 190 | |||
| 191 | # print '_emacs_ok' # ready for input and can call continuation | ||
| 112 | 192 | ||
| 113 | # arch-tag: d90408f3-90e2-4de4-99c2-6eb9c7b9ca46 | 193 | # arch-tag: d90408f3-90e2-4de4-99c2-6eb9c7b9ca46 |