ipy_synchronize_with.py
241 lines
| 7.4 KiB
| text/x-python
|
PythonLexer
Brian Granger
|
r2027 | from IPython.core import ipapi | |
ip = ipapi.get() | |||
vds
|
r1265 | ||
import win32api | |||
import win32ui | |||
import win32console | |||
import dde | |||
import os | |||
import scitedirector | |||
vds2212
|
r1394 | # test to write. | |
vds
|
r1265 | ||
vds
|
r1528 | def set_hook(synchronize_with_editor): | |
"""Set the synchronize with editor hook with a callable object. | |||
The callable object will be called with the following arguments when | |||
IPython wants to synchronize with you favorite editor: | |||
- ip: a running IPython instance. | |||
- filename: the path of the file the editor is supposed to display. | |||
- lineno : the line number of the line the editor is supposed to | |||
highlight. | |||
- columnno : the column number of the character the editor is supposed | |||
to highlight. | |||
""" | |||
vds
|
r1265 | ip.set_hook("synchronize_with_editor", synchronize_with_editor) | |
vds
|
r1528 | def find_filename(filename): | |
"""Return the filename to synchronize with based on """ | |||
vds
|
r1330 | filename = os.path.splitext(filename) | |
if filename[1] == ".pyc": | |||
filename = (filename[0], ".py") | |||
filename = "".join(filename) | |||
vds
|
r1265 | if not os.path.isabs(filename): | |
filename = os.path.join(os.getcwd(), filename) | |||
if os.path.isfile(filename): | |||
return filename | |||
return "" | |||
vds
|
r1528 | def run_command(path, command, arguments, asynchronous = True): | |
"""Run a shell command and return the exit code of the command""" | |||
# This is a thin wrapper around os.system that: | |||
# - Let you run command asynchronously. | |||
# - Accept spaces in command path. | |||
# - Dont throw exception if the command don't exist. | |||
vds
|
r1284 | line = '' | |
if asynchronous: | |||
line += 'start ' | |||
try: | |||
line += win32api.GetShortPathName(os.path.join(path, command) + ".exe") + " " | |||
except: | |||
print 'could not find: "%s"' % (os.path.join(path, command) + ".exe") | |||
return -1 | |||
line += arguments | |||
r = os.system(line) | |||
return r | |||
def sleep(milliseconds): | |||
vds
|
r1528 | """Wait some milliseconds.""" | |
# This is used to make sure the editor did its job before we reset the focus on the console. | |||
vds
|
r1284 | win32api.Sleep(milliseconds) | |
vds
|
r1528 | def restore_console_focus(): | |
"""Restore the focus to the IPython console.""" | |||
vds
|
r1265 | h = win32console.GetConsoleWindow() | |
console_window = win32ui.CreateWindowFromHandle(h) | |||
console_window.SetForegroundWindow() | |||
vds
|
r1284 | ||
vds
|
r1265 | ||
# This is the most simple example of hook: | |||
class GVimHook: | |||
def __init__(self, path, wakeup_duration): | |||
self.path = path | |||
self.wakeup_duration = wakeup_duration | |||
def __call__(self, ip, filename, lineno, columnno): | |||
vds
|
r1528 | filename = find_filename(filename) | |
vds
|
r1265 | ||
if not filename: | |||
return | |||
vds
|
r1528 | run_command(self.path, 'gvim', '--remote-silent +%d "%s"' % (lineno, filename)) | |
vds
|
r1265 | ||
vds
|
r1284 | sleep(self.wakeup_duration) | |
vds
|
r1265 | ||
vds
|
r1528 | restore_console_focus() | |
vds
|
r1265 | ||
def gvim(path = r"C:\Program Files\vim\vim71", wakeup_duration = 100): | |||
synchronize_with_editor = GVimHook(path, wakeup_duration) | |||
vds
|
r1528 | set_hook(synchronize_with_editor) | |
vds
|
r1265 | ||
class EmacsHook: | |||
def __init__(self, path, wakeup_duration, start_duration): | |||
self.path = path | |||
self.wakeup_duration = wakeup_duration | |||
self.start_duration = start_duration | |||
def __call__(self, ip, filename, lineno, columnno): | |||
vds
|
r1528 | filename = find_filename(filename) | |
vds
|
r1265 | ||
if not filename: | |||
return | |||
vds
|
r1528 | r = run_command(self.path, "emacsclient", '-n +%d:%d "%s" 2>nul' % (lineno, columnno, filename), False) | |
vds
|
r1265 | if r != 0: | |
vds
|
r1528 | run_command(self.path, 'runemacs', '--quick -f server-start +%d:%d "%s"' % (lineno, columnno, filename)) | |
vds
|
r1284 | sleep(self.start_duration) | |
vds
|
r1265 | else: | |
vds
|
r1284 | sleep(self.wakeup_duration) | |
vds
|
r1265 | ||
vds
|
r1528 | restore_console_focus() | |
vds
|
r1265 | ||
def emacs(path = r"C:\Program Files\emacs\bin", wakeup_duration = 100, start_duration = 2000): | |||
synchronize_with_editor = EmacsHook(path, wakeup_duration, start_duration) | |||
vds
|
r1528 | set_hook(synchronize_with_editor) | |
vds
|
r1265 | ||
class SciteHook: | |||
def __init__(self, path, wakeup_duration, start_duration): | |||
self.path = path | |||
self.wakeup_duration = wakeup_duration | |||
self.start_duration = start_duration | |||
def __call__(self, ip, filename, lineno, columnno): | |||
vds
|
r1528 | filename = find_filename(filename) | |
vds
|
r1265 | ||
if not filename: | |||
return | |||
scites = scitedirector.findWindows() | |||
if not scites: | |||
vds
|
r1528 | run_command(self.path, "scite", '"-open:%s" -goto:%d' % (filename.replace("\\", "/"), lineno)) | |
vds
|
r1265 | ||
vds
|
r1284 | sleep(self.start_duration) | |
vds
|
r1528 | restore_console_focus() | |
vds
|
r1265 | else: | |
scite = scites[0] | |||
scitedirector.sendCommand(scite, 'open:%s' % filename.replace("\\", "/")) | |||
scitedirector.sendCommand(scite, "goto:%d" % lineno) | |||
def scite(path = r"C:\Program Files\SciTE Source Code Editor", wakeup_duration = 100, start_duration = 500): | |||
synchronize_with_editor = SciteHook(path, wakeup_duration, start_duration) | |||
vds
|
r1528 | set_hook(synchronize_with_editor) | |
vds
|
r1265 | ||
class NodePadPlusPlusHook: | |||
def __init__(self, path, wakeup_duration): | |||
self.path = path | |||
self.wakeup_duration = wakeup_duration | |||
def __call__(self, ip, filename, lineno, columnno): | |||
vds
|
r1528 | filename = find_filename(filename) | |
vds
|
r1265 | ||
if not filename: | |||
return | |||
vds
|
r1528 | run_command(self.path, "notepad++", '"%s" -n%d' % (filename, lineno)) | |
vds
|
r1265 | ||
vds
|
r1284 | sleep(self.wakeup_duration) | |
vds
|
r1265 | ||
vds
|
r1528 | restore_console_focus() | |
vds
|
r1265 | ||
def notepadplusplus(path = r"C:\Program Files\Notepad++", wakeup_duration = 100): | |||
synchronize_with_editor = NodePadPlusPlusHook(path, wakeup_duration) | |||
vds
|
r1528 | set_hook(synchronize_with_editor) | |
vds
|
r1265 | ||
class PsPadHook: | |||
def __init__(self, path, wakeup_duration): | |||
self.path = path | |||
self.wakeup_duration = wakeup_duration | |||
def __call__(self, ip, filename, lineno, columnno): | |||
vds
|
r1528 | filename = find_filename(filename) | |
vds
|
r1265 | ||
if not filename: | |||
return | |||
vds
|
r1528 | run_command(self.path, "pspad", '"%s" -%d' % (filename, lineno)) | |
vds
|
r1265 | ||
vds
|
r1284 | sleep(self.wakeup_duration) | |
vds
|
r1265 | ||
vds
|
r1528 | restore_console_focus() | |
vds
|
r1265 | ||
def pspad(path = r"C:\Program Files\PSPad editor", wakeup_duration = 100): | |||
synchronize_with_editor = PsPadHook(path, wakeup_duration) | |||
vds
|
r1528 | set_hook(synchronize_with_editor) | |
vds
|
r1265 | ||
# This is an example of DDE hook: | |||
class UltraEditHook: | |||
def __init__(self, path, wakeup_duration, start_duration): | |||
self.path = path | |||
self.wakeup_duration = wakeup_duration | |||
self.start_duration = start_duration | |||
def __call__(self, ip, filename, lineno, columnno): | |||
vds
|
r1528 | filename = find_filename(filename) | |
vds
|
r1265 | ||
if not filename: | |||
return | |||
server = dde.CreateServer() | |||
server.Create("myddeserver") | |||
conversation = dde.CreateConversation(server) | |||
try: | |||
conversation.ConnectTo("uedit32", "System") | |||
conversation.Exec(r'[open("%s/%d"])' % (filename, lineno)) | |||
vds
|
r1284 | ||
sleep(self.wakeup_duration) | |||
vds
|
r1265 | except: | |
vds
|
r1528 | run_command(self.path, 'uedit32', '"%s/%d"' % (filename, lineno)) | |
vds
|
r1284 | ||
sleep(self.start_duration) | |||
vds
|
r1265 | ||
server.Shutdown() | |||
vds
|
r1528 | restore_console_focus() | |
vds
|
r1265 | ||
def ultraedit(path = r"C:\Program Files\IDM Computer Solutions\UltraEdit-32", wakeup_duration = 10, start_duration = 2000): | |||
synchronize_with_editor = UltraEditHook(path, wakeup_duration, start_duration) | |||
vds
|
r1528 | set_hook(synchronize_with_editor) | |
vds
|
r1284 |