##// END OF EJS Templates
use shlex.split on editor hooks on Windows...
Min RK -
Show More
@@ -1,124 +1,128 b''
1 """ 'editor' hooks for common editors that work well with ipython
1 """ 'editor' hooks for common editors that work well with ipython
2
2
3 They should honor the line number argument, at least.
3 They should honor the line number argument, at least.
4
4
5 Contributions are *very* welcome.
5 Contributions are *very* welcome.
6 """
6 """
7 from __future__ import print_function
7 from __future__ import print_function
8
8
9 import os
9 import os
10 import pipes
10 import pipes
11 import shlex
11 import subprocess
12 import subprocess
12
13
13 from IPython import get_ipython
14 from IPython import get_ipython
14 from IPython.core.error import TryNext
15 from IPython.core.error import TryNext
15 from IPython.utils import py3compat
16 from IPython.utils import py3compat
16
17
17
18
18 def install_editor(template, wait=False):
19 def install_editor(template_list, wait=False):
19 """Installs the editor that is called by IPython for the %edit magic.
20 """Installs the editor that is called by IPython for the %edit magic.
20
21
21 This overrides the default editor, which is generally set by your EDITOR
22 This overrides the default editor, which is generally set by your EDITOR
22 environment variable or is notepad (windows) or vi (linux). By supplying a
23 environment variable or is notepad (windows) or vi (linux). By supplying a
23 template string `run_template`, you can control how the editor is invoked
24 template string `run_template`, you can control how the editor is invoked
24 by IPython -- (e.g. the format in which it accepts command line options)
25 by IPython -- (e.g. the format in which it accepts command line options)
25
26
26 Parameters
27 Parameters
27 ----------
28 ----------
28 template : basestring
29 template : basestring
29 run_template acts as a template for how your editor is invoked by
30 run_template acts as a template for how your editor is invoked by
30 the shell. It should contain '{filename}', which will be replaced on
31 the shell. It should contain '{filename}', which will be replaced on
31 invokation with the file name, and '{line}', $line by line number
32 invokation with the file name, and '{line}', $line by line number
32 (or 0) to invoke the file with.
33 (or 0) to invoke the file with.
33 wait : bool
34 wait : bool
34 If `wait` is true, wait until the user presses enter before returning,
35 If `wait` is true, wait until the user presses enter before returning,
35 to facilitate non-blocking editors that exit immediately after
36 to facilitate non-blocking editors that exit immediately after
36 the call.
37 the call.
37 """
38 """
38
39
39 # not all editors support $line, so we'll leave out this check
40 # not all editors support $line, so we'll leave out this check
40 # for substitution in ['$file', '$line']:
41 # for substitution in ['$file', '$line']:
41 # if not substitution in run_template:
42 # if not substitution in run_template:
42 # raise ValueError(('run_template should contain %s'
43 # raise ValueError(('run_template should contain %s'
43 # ' for string substitution. You supplied "%s"' % (substitution,
44 # ' for string substitution. You supplied "%s"' % (substitution,
44 # run_template)))
45 # run_template)))
45
46
46 def call_editor(self, filename, line=0):
47 def call_editor(self, filename, line=0):
47 if line is None:
48 if line is None:
48 line = 0
49 line = 0
49 cmd = template.format(filename=pipes.quote(filename), line=line)
50 cmd = template.format(filename=pipes.quote(filename), line=line)
50 print(">", cmd)
51 print(">", cmd)
52 # pipes.quote doesn't work right on Windows, but it does after splitting
53 if sys.platform.startswith('win'):
54 cmd = shlex.split(cmd)
51 proc = subprocess.Popen(cmd, shell=True)
55 proc = subprocess.Popen(cmd, shell=True)
52 if wait and proc.wait() != 0:
56 if wait and proc.wait() != 0:
53 raise TryNext()
57 raise TryNext()
54 if wait:
58 if wait:
55 py3compat.input("Press Enter when done editing:")
59 py3compat.input("Press Enter when done editing:")
56
60
57 get_ipython().set_hook('editor', call_editor)
61 get_ipython().set_hook('editor', call_editor)
58 get_ipython().editor = template
62 get_ipython().editor = template
59
63
60
64
61 # in these, exe is always the path/name of the executable. Useful
65 # in these, exe is always the path/name of the executable. Useful
62 # if you don't have the editor directory in your path
66 # if you don't have the editor directory in your path
63 def komodo(exe=u'komodo'):
67 def komodo(exe=u'komodo'):
64 """ Activestate Komodo [Edit] """
68 """ Activestate Komodo [Edit] """
65 install_editor(exe + u' -l {line} {filename}', wait=True)
69 install_editor(exe + u' -l {line} {filename}', wait=True)
66
70
67
71
68 def scite(exe=u"scite"):
72 def scite(exe=u"scite"):
69 """ SciTE or Sc1 """
73 """ SciTE or Sc1 """
70 install_editor(exe + u' {filename} -goto:{line}')
74 install_editor(exe + u' {filename} -goto:{line}')
71
75
72
76
73 def notepadplusplus(exe=u'notepad++'):
77 def notepadplusplus(exe=u'notepad++'):
74 """ Notepad++ http://notepad-plus.sourceforge.net """
78 """ Notepad++ http://notepad-plus.sourceforge.net """
75 install_editor(exe + u' -n{line} {filename}')
79 install_editor(exe + u' -n{line} {filename}')
76
80
77
81
78 def jed(exe=u'jed'):
82 def jed(exe=u'jed'):
79 """ JED, the lightweight emacsish editor """
83 """ JED, the lightweight emacsish editor """
80 install_editor(exe + u' +{line} {filename}')
84 install_editor(exe + u' +{line} {filename}')
81
85
82
86
83 def idle(exe=u'idle'):
87 def idle(exe=u'idle'):
84 """ Idle, the editor bundled with python
88 """ Idle, the editor bundled with python
85
89
86 Parameters
90 Parameters
87 ----------
91 ----------
88 exe : str, None
92 exe : str, None
89 If none, should be pretty smart about finding the executable.
93 If none, should be pretty smart about finding the executable.
90 """
94 """
91 if exe is None:
95 if exe is None:
92 import idlelib
96 import idlelib
93 p = os.path.dirname(idlelib.__filename__)
97 p = os.path.dirname(idlelib.__filename__)
94 # i'm not sure if this actually works. Is this idle.py script
98 # i'm not sure if this actually works. Is this idle.py script
95 # guarenteed to be executable?
99 # guarenteed to be executable?
96 exe = os.path.join(p, 'idle.py')
100 exe = os.path.join(p, 'idle.py')
97 install_editor(exe + u' {filename}')
101 install_editor(exe + u' {filename}')
98
102
99
103
100 def mate(exe=u'mate'):
104 def mate(exe=u'mate'):
101 """ TextMate, the missing editor"""
105 """ TextMate, the missing editor"""
102 # wait=True is not required since we're using the -w flag to mate
106 # wait=True is not required since we're using the -w flag to mate
103 install_editor(exe + u' -w -l {line} {filename}')
107 install_editor(exe + u' -w -l {line} {filename}')
104
108
105
109
106 # ##########################################
110 # ##########################################
107 # these are untested, report any problems
111 # these are untested, report any problems
108 # ##########################################
112 # ##########################################
109
113
110
114
111 def emacs(exe=u'emacs'):
115 def emacs(exe=u'emacs'):
112 install_editor(exe + u' +{line} {filename}')
116 install_editor(exe + u' +{line} {filename}')
113
117
114
118
115 def gnuclient(exe=u'gnuclient'):
119 def gnuclient(exe=u'gnuclient'):
116 install_editor(exe + u' -nw +{line} {filename}')
120 install_editor(exe + u' -nw +{line} {filename}')
117
121
118
122
119 def crimson_editor(exe=u'cedt.exe'):
123 def crimson_editor(exe=u'cedt.exe'):
120 install_editor(exe + u' /L:{line} {filename}')
124 install_editor(exe + u' /L:{line} {filename}')
121
125
122
126
123 def kate(exe=u'kate'):
127 def kate(exe=u'kate'):
124 install_editor(exe + u' -u -l {line} {filename}')
128 install_editor(exe + u' -u -l {line} {filename}')
General Comments 0
You need to be logged in to leave comments. Login now