|
"""Hooks for IPython. |
|
|
|
In Python, it is possible to overwrite any method of any object if you really |
|
want to. But IPython exposes a few 'hooks', methods which are *designed* to |
|
be overwritten by users for customization purposes. This module defines the |
|
default versions of all such hooks, which get used by IPython if not |
|
overridden by the user. |
|
|
|
Hooks are simple functions, but they should be declared with ``self`` as their |
|
first argument, because when activated they are registered into IPython as |
|
instance methods. The self argument will be the IPython running instance |
|
itself, so hooks have full access to the entire IPython object. |
|
|
|
If you wish to define a new hook and activate it, you can make an :doc:`extension |
|
</config/extensions/index>` or a :ref:`startup script <startup_files>`. For |
|
example, you could use a startup file like this:: |
|
|
|
import os |
|
|
|
def calljed(self,filename, linenum): |
|
"My editor hook calls the jed editor directly." |
|
print("Calling my own editor, jed ...") |
|
if os.system('jed +%d %s' % (linenum,filename)) != 0: |
|
raise TryNext() |
|
|
|
def load_ipython_extension(ip): |
|
ip.set_hook('editor', calljed) |
|
|
|
""" |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
import os |
|
import subprocess |
|
import sys |
|
|
|
from .error import TryNext |
|
|
|
|
|
|
|
|
|
__all__ = [ |
|
"editor", |
|
"synchronize_with_editor", |
|
"show_in_pager", |
|
"pre_prompt_hook", |
|
"clipboard_get", |
|
] |
|
|
|
deprecated = {'pre_run_code_hook': "a callback for the 'pre_execute' or 'pre_run_cell' event", |
|
'late_startup_hook': "a callback for the 'shell_initialized' event", |
|
'shutdown_hook': "the atexit module", |
|
} |
|
|
|
def editor(self, filename, linenum=None, wait=True): |
|
"""Open the default editor at the given filename and linenumber. |
|
|
|
This is IPython's default editor hook, you can use it as an example to |
|
write your own modified one. To set your own editor function as the |
|
new editor hook, call ip.set_hook('editor',yourfunc).""" |
|
|
|
|
|
|
|
editor = self.editor |
|
|
|
|
|
if linenum is None or editor=='notepad': |
|
linemark = '' |
|
else: |
|
linemark = '+%d' % int(linenum) |
|
|
|
|
|
if ' ' in editor and os.path.isfile(editor) and editor[0] != '"': |
|
editor = '"%s"' % editor |
|
|
|
|
|
proc = subprocess.Popen('%s %s %s' % (editor, linemark, filename), |
|
shell=True) |
|
if wait and proc.wait() != 0: |
|
raise TryNext() |
|
|
|
|
|
def synchronize_with_editor(self, filename, linenum, column): |
|
pass |
|
|
|
|
|
class CommandChainDispatcher: |
|
""" Dispatch calls to a chain of commands until some func can handle it |
|
|
|
Usage: instantiate, execute "add" to add commands (with optional |
|
priority), execute normally via f() calling mechanism. |
|
|
|
""" |
|
def __init__(self,commands=None): |
|
if commands is None: |
|
self.chain = [] |
|
else: |
|
self.chain = commands |
|
|
|
|
|
def __call__(self,*args, **kw): |
|
""" Command chain is called just like normal func. |
|
|
|
This will call all funcs in chain with the same args as were given to |
|
this function, and return the result of first func that didn't raise |
|
TryNext""" |
|
last_exc = TryNext() |
|
for prio,cmd in self.chain: |
|
|
|
try: |
|
return cmd(*args, **kw) |
|
except TryNext as exc: |
|
last_exc = exc |
|
|
|
raise last_exc |
|
|
|
def __str__(self): |
|
return str(self.chain) |
|
|
|
def add(self, func, priority=0): |
|
""" Add a func to the cmd chain with given priority """ |
|
self.chain.append((priority, func)) |
|
self.chain.sort(key=lambda x: x[0]) |
|
|
|
def __iter__(self): |
|
""" Return all objects in chain. |
|
|
|
Handy if the objects are not callable. |
|
""" |
|
return iter(self.chain) |
|
|
|
|
|
def show_in_pager(self, data, start, screen_lines): |
|
""" Run a string through pager """ |
|
|
|
raise TryNext |
|
|
|
|
|
def pre_prompt_hook(self): |
|
""" Run before displaying the next prompt |
|
|
|
Use this e.g. to display output from asynchronous operations (in order |
|
to not mess up text entry) |
|
""" |
|
|
|
return None |
|
|
|
|
|
def clipboard_get(self): |
|
""" Get text from the clipboard. |
|
""" |
|
from ..lib.clipboard import ( |
|
osx_clipboard_get, |
|
tkinter_clipboard_get, |
|
win32_clipboard_get, |
|
wayland_clipboard_get, |
|
) |
|
if sys.platform == 'win32': |
|
chain = [win32_clipboard_get, tkinter_clipboard_get] |
|
elif sys.platform == 'darwin': |
|
chain = [osx_clipboard_get, tkinter_clipboard_get] |
|
else: |
|
chain = [wayland_clipboard_get, tkinter_clipboard_get] |
|
dispatcher = CommandChainDispatcher() |
|
for func in chain: |
|
dispatcher.add(func) |
|
text = dispatcher() |
|
return text |
|
|