##// END OF EJS Templates
Use lambda instead of operator.itemgetter
Thomas Kluyver -
Show More
@@ -1,231 +1,230 b''
1 """hooks for IPython.
1 """hooks for IPython.
2
2
3 In Python, it is possible to overwrite any method of any object if you really
3 In Python, it is possible to overwrite any method of any object if you really
4 want to. But IPython exposes a few 'hooks', methods which are _designed_ to
4 want to. But IPython exposes a few 'hooks', methods which are _designed_ to
5 be overwritten by users for customization purposes. This module defines the
5 be overwritten by users for customization purposes. This module defines the
6 default versions of all such hooks, which get used by IPython if not
6 default versions of all such hooks, which get used by IPython if not
7 overridden by the user.
7 overridden by the user.
8
8
9 hooks are simple functions, but they should be declared with 'self' as their
9 hooks are simple functions, but they should be declared with 'self' as their
10 first argument, because when activated they are registered into IPython as
10 first argument, because when activated they are registered into IPython as
11 instance methods. The self argument will be the IPython running instance
11 instance methods. The self argument will be the IPython running instance
12 itself, so hooks have full access to the entire IPython object.
12 itself, so hooks have full access to the entire IPython object.
13
13
14 If you wish to define a new hook and activate it, you need to put the
14 If you wish to define a new hook and activate it, you need to put the
15 necessary code into a python file which can be either imported or execfile()'d
15 necessary code into a python file which can be either imported or execfile()'d
16 from within your profile's ipython_config.py configuration.
16 from within your profile's ipython_config.py configuration.
17
17
18 For example, suppose that you have a module called 'myiphooks' in your
18 For example, suppose that you have a module called 'myiphooks' in your
19 PYTHONPATH, which contains the following definition:
19 PYTHONPATH, which contains the following definition:
20
20
21 import os
21 import os
22 from IPython.core import ipapi
22 from IPython.core import ipapi
23 ip = ipapi.get()
23 ip = ipapi.get()
24
24
25 def calljed(self,filename, linenum):
25 def calljed(self,filename, linenum):
26 "My editor hook calls the jed editor directly."
26 "My editor hook calls the jed editor directly."
27 print "Calling my own editor, jed ..."
27 print "Calling my own editor, jed ..."
28 if os.system('jed +%d %s' % (linenum,filename)) != 0:
28 if os.system('jed +%d %s' % (linenum,filename)) != 0:
29 raise TryNext()
29 raise TryNext()
30
30
31 ip.set_hook('editor', calljed)
31 ip.set_hook('editor', calljed)
32
32
33 You can then enable the functionality by doing 'import myiphooks'
33 You can then enable the functionality by doing 'import myiphooks'
34 somewhere in your configuration files or ipython command line.
34 somewhere in your configuration files or ipython command line.
35 """
35 """
36
36
37 #*****************************************************************************
37 #*****************************************************************************
38 # Copyright (C) 2005 Fernando Perez. <fperez@colorado.edu>
38 # Copyright (C) 2005 Fernando Perez. <fperez@colorado.edu>
39 #
39 #
40 # Distributed under the terms of the BSD License. The full license is in
40 # Distributed under the terms of the BSD License. The full license is in
41 # the file COPYING, distributed as part of this software.
41 # the file COPYING, distributed as part of this software.
42 #*****************************************************************************
42 #*****************************************************************************
43
43
44 import os
44 import os
45 import operator
46 import subprocess
45 import subprocess
47 import sys
46 import sys
48
47
49 from IPython.core.error import TryNext
48 from IPython.core.error import TryNext
50
49
51 # List here all the default hooks. For now it's just the editor functions
50 # List here all the default hooks. For now it's just the editor functions
52 # but over time we'll move here all the public API for user-accessible things.
51 # but over time we'll move here all the public API for user-accessible things.
53
52
54 __all__ = ['editor', 'fix_error_editor', 'synchronize_with_editor',
53 __all__ = ['editor', 'fix_error_editor', 'synchronize_with_editor',
55 'input_prefilter', 'shutdown_hook', 'late_startup_hook',
54 'input_prefilter', 'shutdown_hook', 'late_startup_hook',
56 'show_in_pager','pre_prompt_hook',
55 'show_in_pager','pre_prompt_hook',
57 'pre_run_code_hook', 'clipboard_get']
56 'pre_run_code_hook', 'clipboard_get']
58
57
59 def editor(self, filename, linenum=None, wait=True):
58 def editor(self, filename, linenum=None, wait=True):
60 """Open the default editor at the given filename and linenumber.
59 """Open the default editor at the given filename and linenumber.
61
60
62 This is IPython's default editor hook, you can use it as an example to
61 This is IPython's default editor hook, you can use it as an example to
63 write your own modified one. To set your own editor function as the
62 write your own modified one. To set your own editor function as the
64 new editor hook, call ip.set_hook('editor',yourfunc)."""
63 new editor hook, call ip.set_hook('editor',yourfunc)."""
65
64
66 # IPython configures a default editor at startup by reading $EDITOR from
65 # IPython configures a default editor at startup by reading $EDITOR from
67 # the environment, and falling back on vi (unix) or notepad (win32).
66 # the environment, and falling back on vi (unix) or notepad (win32).
68 editor = self.editor
67 editor = self.editor
69
68
70 # marker for at which line to open the file (for existing objects)
69 # marker for at which line to open the file (for existing objects)
71 if linenum is None or editor=='notepad':
70 if linenum is None or editor=='notepad':
72 linemark = ''
71 linemark = ''
73 else:
72 else:
74 linemark = '+%d' % int(linenum)
73 linemark = '+%d' % int(linenum)
75
74
76 # Enclose in quotes if necessary and legal
75 # Enclose in quotes if necessary and legal
77 if ' ' in editor and os.path.isfile(editor) and editor[0] != '"':
76 if ' ' in editor and os.path.isfile(editor) and editor[0] != '"':
78 editor = '"%s"' % editor
77 editor = '"%s"' % editor
79
78
80 # Call the actual editor
79 # Call the actual editor
81 proc = subprocess.Popen('%s %s %s' % (editor, linemark, filename),
80 proc = subprocess.Popen('%s %s %s' % (editor, linemark, filename),
82 shell=True)
81 shell=True)
83 if wait and proc.wait() != 0:
82 if wait and proc.wait() != 0:
84 raise TryNext()
83 raise TryNext()
85
84
86 import tempfile
85 import tempfile
87 def fix_error_editor(self,filename,linenum,column,msg):
86 def fix_error_editor(self,filename,linenum,column,msg):
88 """Open the editor at the given filename, linenumber, column and
87 """Open the editor at the given filename, linenumber, column and
89 show an error message. This is used for correcting syntax errors.
88 show an error message. This is used for correcting syntax errors.
90 The current implementation only has special support for the VIM editor,
89 The current implementation only has special support for the VIM editor,
91 and falls back on the 'editor' hook if VIM is not used.
90 and falls back on the 'editor' hook if VIM is not used.
92
91
93 Call ip.set_hook('fix_error_editor',youfunc) to use your own function,
92 Call ip.set_hook('fix_error_editor',youfunc) to use your own function,
94 """
93 """
95 def vim_quickfix_file():
94 def vim_quickfix_file():
96 t = tempfile.NamedTemporaryFile()
95 t = tempfile.NamedTemporaryFile()
97 t.write('%s:%d:%d:%s\n' % (filename,linenum,column,msg))
96 t.write('%s:%d:%d:%s\n' % (filename,linenum,column,msg))
98 t.flush()
97 t.flush()
99 return t
98 return t
100 if os.path.basename(self.editor) != 'vim':
99 if os.path.basename(self.editor) != 'vim':
101 self.hooks.editor(filename,linenum)
100 self.hooks.editor(filename,linenum)
102 return
101 return
103 t = vim_quickfix_file()
102 t = vim_quickfix_file()
104 try:
103 try:
105 if os.system('vim --cmd "set errorformat=%f:%l:%c:%m" -q ' + t.name):
104 if os.system('vim --cmd "set errorformat=%f:%l:%c:%m" -q ' + t.name):
106 raise TryNext()
105 raise TryNext()
107 finally:
106 finally:
108 t.close()
107 t.close()
109
108
110
109
111 def synchronize_with_editor(self, filename, linenum, column):
110 def synchronize_with_editor(self, filename, linenum, column):
112 pass
111 pass
113
112
114
113
115 class CommandChainDispatcher:
114 class CommandChainDispatcher:
116 """ Dispatch calls to a chain of commands until some func can handle it
115 """ Dispatch calls to a chain of commands until some func can handle it
117
116
118 Usage: instantiate, execute "add" to add commands (with optional
117 Usage: instantiate, execute "add" to add commands (with optional
119 priority), execute normally via f() calling mechanism.
118 priority), execute normally via f() calling mechanism.
120
119
121 """
120 """
122 def __init__(self,commands=None):
121 def __init__(self,commands=None):
123 if commands is None:
122 if commands is None:
124 self.chain = []
123 self.chain = []
125 else:
124 else:
126 self.chain = commands
125 self.chain = commands
127
126
128
127
129 def __call__(self,*args, **kw):
128 def __call__(self,*args, **kw):
130 """ Command chain is called just like normal func.
129 """ Command chain is called just like normal func.
131
130
132 This will call all funcs in chain with the same args as were given to
131 This will call all funcs in chain with the same args as were given to
133 this function, and return the result of first func that didn't raise
132 this function, and return the result of first func that didn't raise
134 TryNext"""
133 TryNext"""
135 last_exc = TryNext()
134 last_exc = TryNext()
136 for prio,cmd in self.chain:
135 for prio,cmd in self.chain:
137 #print "prio",prio,"cmd",cmd #dbg
136 #print "prio",prio,"cmd",cmd #dbg
138 try:
137 try:
139 return cmd(*args, **kw)
138 return cmd(*args, **kw)
140 except TryNext as exc:
139 except TryNext as exc:
141 last_exc = exc
140 last_exc = exc
142 # if no function will accept it, raise TryNext up to the caller
141 # if no function will accept it, raise TryNext up to the caller
143 raise last_exc
142 raise last_exc
144
143
145 def __str__(self):
144 def __str__(self):
146 return str(self.chain)
145 return str(self.chain)
147
146
148 def add(self, func, priority=0):
147 def add(self, func, priority=0):
149 """ Add a func to the cmd chain with given priority """
148 """ Add a func to the cmd chain with given priority """
150 self.chain.append((priority, func))
149 self.chain.append((priority, func))
151 self.chain.sort(key=operator.itemgetter(0))
150 self.chain.sort(key=lambda x: x[0])
152
151
153 def __iter__(self):
152 def __iter__(self):
154 """ Return all objects in chain.
153 """ Return all objects in chain.
155
154
156 Handy if the objects are not callable.
155 Handy if the objects are not callable.
157 """
156 """
158 return iter(self.chain)
157 return iter(self.chain)
159
158
160
159
161 def input_prefilter(self,line):
160 def input_prefilter(self,line):
162 """ Default input prefilter
161 """ Default input prefilter
163
162
164 This returns the line as unchanged, so that the interpreter
163 This returns the line as unchanged, so that the interpreter
165 knows that nothing was done and proceeds with "classic" prefiltering
164 knows that nothing was done and proceeds with "classic" prefiltering
166 (%magics, !shell commands etc.).
165 (%magics, !shell commands etc.).
167
166
168 Note that leading whitespace is not passed to this hook. Prefilter
167 Note that leading whitespace is not passed to this hook. Prefilter
169 can't alter indentation.
168 can't alter indentation.
170
169
171 """
170 """
172 #print "attempt to rewrite",line #dbg
171 #print "attempt to rewrite",line #dbg
173 return line
172 return line
174
173
175
174
176 def shutdown_hook(self):
175 def shutdown_hook(self):
177 """ default shutdown hook
176 """ default shutdown hook
178
177
179 Typically, shotdown hooks should raise TryNext so all shutdown ops are done
178 Typically, shotdown hooks should raise TryNext so all shutdown ops are done
180 """
179 """
181
180
182 #print "default shutdown hook ok" # dbg
181 #print "default shutdown hook ok" # dbg
183 return
182 return
184
183
185
184
186 def late_startup_hook(self):
185 def late_startup_hook(self):
187 """ Executed after ipython has been constructed and configured
186 """ Executed after ipython has been constructed and configured
188
187
189 """
188 """
190 #print "default startup hook ok" # dbg
189 #print "default startup hook ok" # dbg
191
190
192
191
193 def show_in_pager(self,s):
192 def show_in_pager(self,s):
194 """ Run a string through pager """
193 """ Run a string through pager """
195 # raising TryNext here will use the default paging functionality
194 # raising TryNext here will use the default paging functionality
196 raise TryNext
195 raise TryNext
197
196
198
197
199 def pre_prompt_hook(self):
198 def pre_prompt_hook(self):
200 """ Run before displaying the next prompt
199 """ Run before displaying the next prompt
201
200
202 Use this e.g. to display output from asynchronous operations (in order
201 Use this e.g. to display output from asynchronous operations (in order
203 to not mess up text entry)
202 to not mess up text entry)
204 """
203 """
205
204
206 return None
205 return None
207
206
208
207
209 def pre_run_code_hook(self):
208 def pre_run_code_hook(self):
210 """ Executed before running the (prefiltered) code in IPython """
209 """ Executed before running the (prefiltered) code in IPython """
211 return None
210 return None
212
211
213
212
214 def clipboard_get(self):
213 def clipboard_get(self):
215 """ Get text from the clipboard.
214 """ Get text from the clipboard.
216 """
215 """
217 from IPython.lib.clipboard import (
216 from IPython.lib.clipboard import (
218 osx_clipboard_get, tkinter_clipboard_get,
217 osx_clipboard_get, tkinter_clipboard_get,
219 win32_clipboard_get
218 win32_clipboard_get
220 )
219 )
221 if sys.platform == 'win32':
220 if sys.platform == 'win32':
222 chain = [win32_clipboard_get, tkinter_clipboard_get]
221 chain = [win32_clipboard_get, tkinter_clipboard_get]
223 elif sys.platform == 'darwin':
222 elif sys.platform == 'darwin':
224 chain = [osx_clipboard_get, tkinter_clipboard_get]
223 chain = [osx_clipboard_get, tkinter_clipboard_get]
225 else:
224 else:
226 chain = [tkinter_clipboard_get]
225 chain = [tkinter_clipboard_get]
227 dispatcher = CommandChainDispatcher()
226 dispatcher = CommandChainDispatcher()
228 for func in chain:
227 for func in chain:
229 dispatcher.add(func)
228 dispatcher.add(func)
230 text = dispatcher()
229 text = dispatcher()
231 return text
230 return text
General Comments 0
You need to be logged in to leave comments. Login now