##// END OF EJS Templates
BUG: Fix incorrect argument signature for show_in_pager dummy hook.
Scott Sanderson -
Show More
@@ -1,214 +1,214 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 can make an :doc:`extension
14 If you wish to define a new hook and activate it, you can make an :doc:`extension
15 </config/extensions/index>` or a :ref:`startup script <startup_files>`. For
15 </config/extensions/index>` or a :ref:`startup script <startup_files>`. For
16 example, you could use a startup file like this::
16 example, you could use a startup file like this::
17
17
18 import os
18 import os
19
19
20 def calljed(self,filename, linenum):
20 def calljed(self,filename, linenum):
21 "My editor hook calls the jed editor directly."
21 "My editor hook calls the jed editor directly."
22 print "Calling my own editor, jed ..."
22 print "Calling my own editor, jed ..."
23 if os.system('jed +%d %s' % (linenum,filename)) != 0:
23 if os.system('jed +%d %s' % (linenum,filename)) != 0:
24 raise TryNext()
24 raise TryNext()
25
25
26 def load_ipython_extension(ip):
26 def load_ipython_extension(ip):
27 ip.set_hook('editor', calljed)
27 ip.set_hook('editor', calljed)
28
28
29 """
29 """
30
30
31 #*****************************************************************************
31 #*****************************************************************************
32 # Copyright (C) 2005 Fernando Perez. <fperez@colorado.edu>
32 # Copyright (C) 2005 Fernando Perez. <fperez@colorado.edu>
33 #
33 #
34 # Distributed under the terms of the BSD License. The full license is in
34 # Distributed under the terms of the BSD License. The full license is in
35 # the file COPYING, distributed as part of this software.
35 # the file COPYING, distributed as part of this software.
36 #*****************************************************************************
36 #*****************************************************************************
37
37
38 import os
38 import os
39 import subprocess
39 import subprocess
40 import sys
40 import sys
41
41
42 from IPython.core.error import TryNext
42 from IPython.core.error import TryNext
43
43
44 # List here all the default hooks. For now it's just the editor functions
44 # List here all the default hooks. For now it's just the editor functions
45 # but over time we'll move here all the public API for user-accessible things.
45 # but over time we'll move here all the public API for user-accessible things.
46
46
47 __all__ = ['editor', 'fix_error_editor', 'synchronize_with_editor',
47 __all__ = ['editor', 'fix_error_editor', 'synchronize_with_editor',
48 'shutdown_hook', 'late_startup_hook',
48 'shutdown_hook', 'late_startup_hook',
49 'show_in_pager','pre_prompt_hook',
49 'show_in_pager','pre_prompt_hook',
50 'pre_run_code_hook', 'clipboard_get']
50 'pre_run_code_hook', 'clipboard_get']
51
51
52 deprecated = {'pre_run_code_hook': "a callback for the 'pre_execute' or 'pre_run_cell' event",
52 deprecated = {'pre_run_code_hook': "a callback for the 'pre_execute' or 'pre_run_cell' event",
53 'late_startup_hook': "a callback for the 'shell_initialized' event",
53 'late_startup_hook': "a callback for the 'shell_initialized' event",
54 'shutdown_hook': "the atexit module",
54 'shutdown_hook': "the atexit module",
55 }
55 }
56
56
57 def editor(self, filename, linenum=None, wait=True):
57 def editor(self, filename, linenum=None, wait=True):
58 """Open the default editor at the given filename and linenumber.
58 """Open the default editor at the given filename and linenumber.
59
59
60 This is IPython's default editor hook, you can use it as an example to
60 This is IPython's default editor hook, you can use it as an example to
61 write your own modified one. To set your own editor function as the
61 write your own modified one. To set your own editor function as the
62 new editor hook, call ip.set_hook('editor',yourfunc)."""
62 new editor hook, call ip.set_hook('editor',yourfunc)."""
63
63
64 # IPython configures a default editor at startup by reading $EDITOR from
64 # IPython configures a default editor at startup by reading $EDITOR from
65 # the environment, and falling back on vi (unix) or notepad (win32).
65 # the environment, and falling back on vi (unix) or notepad (win32).
66 editor = self.editor
66 editor = self.editor
67
67
68 # marker for at which line to open the file (for existing objects)
68 # marker for at which line to open the file (for existing objects)
69 if linenum is None or editor=='notepad':
69 if linenum is None or editor=='notepad':
70 linemark = ''
70 linemark = ''
71 else:
71 else:
72 linemark = '+%d' % int(linenum)
72 linemark = '+%d' % int(linenum)
73
73
74 # Enclose in quotes if necessary and legal
74 # Enclose in quotes if necessary and legal
75 if ' ' in editor and os.path.isfile(editor) and editor[0] != '"':
75 if ' ' in editor and os.path.isfile(editor) and editor[0] != '"':
76 editor = '"%s"' % editor
76 editor = '"%s"' % editor
77
77
78 # Call the actual editor
78 # Call the actual editor
79 proc = subprocess.Popen('%s %s %s' % (editor, linemark, filename),
79 proc = subprocess.Popen('%s %s %s' % (editor, linemark, filename),
80 shell=True)
80 shell=True)
81 if wait and proc.wait() != 0:
81 if wait and proc.wait() != 0:
82 raise TryNext()
82 raise TryNext()
83
83
84 import tempfile
84 import tempfile
85 def fix_error_editor(self,filename,linenum,column,msg):
85 def fix_error_editor(self,filename,linenum,column,msg):
86 """Open the editor at the given filename, linenumber, column and
86 """Open the editor at the given filename, linenumber, column and
87 show an error message. This is used for correcting syntax errors.
87 show an error message. This is used for correcting syntax errors.
88 The current implementation only has special support for the VIM editor,
88 The current implementation only has special support for the VIM editor,
89 and falls back on the 'editor' hook if VIM is not used.
89 and falls back on the 'editor' hook if VIM is not used.
90
90
91 Call ip.set_hook('fix_error_editor',youfunc) to use your own function,
91 Call ip.set_hook('fix_error_editor',youfunc) to use your own function,
92 """
92 """
93 def vim_quickfix_file():
93 def vim_quickfix_file():
94 t = tempfile.NamedTemporaryFile()
94 t = tempfile.NamedTemporaryFile()
95 t.write('%s:%d:%d:%s\n' % (filename,linenum,column,msg))
95 t.write('%s:%d:%d:%s\n' % (filename,linenum,column,msg))
96 t.flush()
96 t.flush()
97 return t
97 return t
98 if os.path.basename(self.editor) != 'vim':
98 if os.path.basename(self.editor) != 'vim':
99 self.hooks.editor(filename,linenum)
99 self.hooks.editor(filename,linenum)
100 return
100 return
101 t = vim_quickfix_file()
101 t = vim_quickfix_file()
102 try:
102 try:
103 if os.system('vim --cmd "set errorformat=%f:%l:%c:%m" -q ' + t.name):
103 if os.system('vim --cmd "set errorformat=%f:%l:%c:%m" -q ' + t.name):
104 raise TryNext()
104 raise TryNext()
105 finally:
105 finally:
106 t.close()
106 t.close()
107
107
108
108
109 def synchronize_with_editor(self, filename, linenum, column):
109 def synchronize_with_editor(self, filename, linenum, column):
110 pass
110 pass
111
111
112
112
113 class CommandChainDispatcher:
113 class CommandChainDispatcher:
114 """ Dispatch calls to a chain of commands until some func can handle it
114 """ Dispatch calls to a chain of commands until some func can handle it
115
115
116 Usage: instantiate, execute "add" to add commands (with optional
116 Usage: instantiate, execute "add" to add commands (with optional
117 priority), execute normally via f() calling mechanism.
117 priority), execute normally via f() calling mechanism.
118
118
119 """
119 """
120 def __init__(self,commands=None):
120 def __init__(self,commands=None):
121 if commands is None:
121 if commands is None:
122 self.chain = []
122 self.chain = []
123 else:
123 else:
124 self.chain = commands
124 self.chain = commands
125
125
126
126
127 def __call__(self,*args, **kw):
127 def __call__(self,*args, **kw):
128 """ Command chain is called just like normal func.
128 """ Command chain is called just like normal func.
129
129
130 This will call all funcs in chain with the same args as were given to
130 This will call all funcs in chain with the same args as were given to
131 this function, and return the result of first func that didn't raise
131 this function, and return the result of first func that didn't raise
132 TryNext"""
132 TryNext"""
133 last_exc = TryNext()
133 last_exc = TryNext()
134 for prio,cmd in self.chain:
134 for prio,cmd in self.chain:
135 #print "prio",prio,"cmd",cmd #dbg
135 #print "prio",prio,"cmd",cmd #dbg
136 try:
136 try:
137 return cmd(*args, **kw)
137 return cmd(*args, **kw)
138 except TryNext as exc:
138 except TryNext as exc:
139 last_exc = exc
139 last_exc = exc
140 # if no function will accept it, raise TryNext up to the caller
140 # if no function will accept it, raise TryNext up to the caller
141 raise last_exc
141 raise last_exc
142
142
143 def __str__(self):
143 def __str__(self):
144 return str(self.chain)
144 return str(self.chain)
145
145
146 def add(self, func, priority=0):
146 def add(self, func, priority=0):
147 """ Add a func to the cmd chain with given priority """
147 """ Add a func to the cmd chain with given priority """
148 self.chain.append((priority, func))
148 self.chain.append((priority, func))
149 self.chain.sort(key=lambda x: x[0])
149 self.chain.sort(key=lambda x: x[0])
150
150
151 def __iter__(self):
151 def __iter__(self):
152 """ Return all objects in chain.
152 """ Return all objects in chain.
153
153
154 Handy if the objects are not callable.
154 Handy if the objects are not callable.
155 """
155 """
156 return iter(self.chain)
156 return iter(self.chain)
157
157
158
158
159 def shutdown_hook(self):
159 def shutdown_hook(self):
160 """ default shutdown hook
160 """ default shutdown hook
161
161
162 Typically, shotdown hooks should raise TryNext so all shutdown ops are done
162 Typically, shotdown hooks should raise TryNext so all shutdown ops are done
163 """
163 """
164
164
165 #print "default shutdown hook ok" # dbg
165 #print "default shutdown hook ok" # dbg
166 return
166 return
167
167
168
168
169 def late_startup_hook(self):
169 def late_startup_hook(self):
170 """ Executed after ipython has been constructed and configured
170 """ Executed after ipython has been constructed and configured
171
171
172 """
172 """
173 #print "default startup hook ok" # dbg
173 #print "default startup hook ok" # dbg
174
174
175
175
176 def show_in_pager(self,s):
176 def show_in_pager(self, data, start, screen_lines):
177 """ Run a string through pager """
177 """ Run a string through pager """
178 # raising TryNext here will use the default paging functionality
178 # raising TryNext here will use the default paging functionality
179 raise TryNext
179 raise TryNext
180
180
181
181
182 def pre_prompt_hook(self):
182 def pre_prompt_hook(self):
183 """ Run before displaying the next prompt
183 """ Run before displaying the next prompt
184
184
185 Use this e.g. to display output from asynchronous operations (in order
185 Use this e.g. to display output from asynchronous operations (in order
186 to not mess up text entry)
186 to not mess up text entry)
187 """
187 """
188
188
189 return None
189 return None
190
190
191
191
192 def pre_run_code_hook(self):
192 def pre_run_code_hook(self):
193 """ Executed before running the (prefiltered) code in IPython """
193 """ Executed before running the (prefiltered) code in IPython """
194 return None
194 return None
195
195
196
196
197 def clipboard_get(self):
197 def clipboard_get(self):
198 """ Get text from the clipboard.
198 """ Get text from the clipboard.
199 """
199 """
200 from IPython.lib.clipboard import (
200 from IPython.lib.clipboard import (
201 osx_clipboard_get, tkinter_clipboard_get,
201 osx_clipboard_get, tkinter_clipboard_get,
202 win32_clipboard_get
202 win32_clipboard_get
203 )
203 )
204 if sys.platform == 'win32':
204 if sys.platform == 'win32':
205 chain = [win32_clipboard_get, tkinter_clipboard_get]
205 chain = [win32_clipboard_get, tkinter_clipboard_get]
206 elif sys.platform == 'darwin':
206 elif sys.platform == 'darwin':
207 chain = [osx_clipboard_get, tkinter_clipboard_get]
207 chain = [osx_clipboard_get, tkinter_clipboard_get]
208 else:
208 else:
209 chain = [tkinter_clipboard_get]
209 chain = [tkinter_clipboard_get]
210 dispatcher = CommandChainDispatcher()
210 dispatcher = CommandChainDispatcher()
211 for func in chain:
211 for func in chain:
212 dispatcher.add(func)
212 dispatcher.add(func)
213 text = dispatcher()
213 text = dispatcher()
214 return text
214 return text
General Comments 0
You need to be logged in to leave comments. Login now