##// END OF EJS Templates
Merge pull request #1955 from ivanov/vim-ipython...
Min RK -
r7568:69f93d47 merge
parent child Browse files
Show More
@@ -1,189 +1,253
1 ###########
1 ###########
2 vim-ipython
2 vim-ipython
3 ###########
3 ###########
4
4
5 A two-way integration between Vim and IPython 0.11+
5 A two-way integration between Vim and IPython 0.11+
6
6
7 * author: Paul Ivanov (http://pirsquared.org)
7 * author: Paul Ivanov (http://pirsquared.org)
8 * github: http://github.com/ivanov/vim-ipython
8 * github: http://github.com/ivanov/vim-ipython
9 * demos: http://pirsquared.org/vim-ipython/
9 * demos: http://pirsquared.org/vim-ipython/
10 * blogpost: http://pirsquared.org/blog/2011/07/28/vim-ipython/
10 * blogpost: http://pirsquared.org/blog/2011/07/28/vim-ipython/
11
11
12 Using this plugin, you can send lines or whole files for IPython to
12 Using this plugin, you can send lines or whole files for IPython to
13 execute, and also get back object introspection and word completions in
13 execute, and also get back object introspection and word completions in
14 Vim, like what you get with: ``object?<enter>`` and ``object.<tab>`` in
14 Vim, like what you get with: ``object?<enter>`` and ``object.<tab>`` in
15 IPython.
15 IPython.
16
16
17 The big change from previous versions of ``ipy.vim`` is that it no longer
17 The big change from previous versions of ``ipy.vim`` is that it no longer
18 requires the old brittle ``ipy_vimserver.py`` instantiation, and since
18 requires the old brittle ``ipy_vimserver.py`` instantiation, and since
19 it uses just vim and python, it is platform independent (i.e. should work
19 it uses just vim and python, it is platform independent (i.e. works
20 even on windows, unlike the previous \*nix only solution). The requirements
20 even on windows, unlike the previous \*nix only solution). The requirements
21 are IPython 0.11+ with zeromq capabilities, vim compiled with +python.
21 are IPython 0.11+ with zeromq capabilities, vim compiled with +python.
22
22
23 If you can launch ``ipython qtconsole`` or ``ipython kernel``, and
23 If you can launch ``ipython qtconsole`` or ``ipython kernel``, and
24 ``:echo has('python')`` returns 1 in vim, you should be good to go.
24 ``:echo has('python')`` returns 1 in vim, you should be good to go.
25
25
26 -----------------
26 -----------------
27 Quickstart Guide:
27 Quickstart Guide:
28 -----------------
28 -----------------
29 Start ``ipython qtconsole`` [*]_ and copy the connection string.
29 Start ``ipython qtconsole`` [*]_ and copy the connection string.
30 Source ``ipy.vim`` file, which provides new IPython command::
30 Source ``ipy.vim`` file, which provides new IPython command::
31
31
32 :source ipy.vim
32 :source ipy.vim
33 (or copy it to ~/.vim/ftplugin/python to load automatically)
33 (or copy it to ~/.vim/ftplugin/python to load automatically)
34
34
35 :IPythonClipboard
35 :IPythonClipboard
36 (or :IPythonXSelection if you're using X11 without having to copy)
36 (or :IPythonXSelection if you're using X11 without having to copy)
37
37
38 The :IPython command allows you to put the full connection string. For IPython
38 The :IPython command allows you to put the full connection string. For IPython
39 0.11, it would look like this::
39 0.11, it would look like this::
40
40
41 :IPython --existing --shell=41882 --iopub=43286 --stdin=34987 --hb=36697
41 :IPython --existing --shell=41882 --iopub=43286 --stdin=34987 --hb=36697
42
42
43 and for IPython 0.12, like this::
43 and for IPython 0.12, like this::
44
44
45 :IPython --existing kernel-85997.json
45 :IPython --existing kernel-85997.json
46
46
47 The ``:IPythonClipboard`` command just uses the ``+`` register to get the
47 The ``:IPythonClipboard`` command just uses the ``+`` register to get the
48 connection string, whereas ``:IPythonXSelection`` uses the ``*`` register
48 connection string, whereas ``:IPythonXSelection`` uses the ``*`` register.
49
50 **NEW in IPython 0.12**!
51 Since IPython 0.12, you can simply use::
52
53 :IPython
54
55 without arguments to connect to the most recent IPython session (this is the
56 same as passing just the ``--existing`` flag to ``ipython qtconsole`` and
57 ``ipython console``.
49
58
50 .. [*] Though the demos above use ``qtconsole``, it is not required
59 .. [*] Though the demos above use ``qtconsole``, it is not required
51 for this workflow, it's just that it was the easiest way to show how to
60 for this workflow, it's just that it was the easiest way to show how to
52 make use of the new functionality in 0.11 release. In the current git
61 make use of the new functionality in 0.11 release. Since IPython 0.12, you
53 trunk of IPython, you can use ``ipython kernel`` to create a kernel and
62 can use ``ipython kernel`` to create a kernel and get the connection
54 get the connection string to use for any frontend (including vim-ipython).
63 string to use for any frontend (including vim-ipython), or use ``ipython
55 If you are still using 0.11, you can launch a regular kernel using
64 console`` to create a kernel and immediately connect to it using a
56 ``python -c "from IPython.zmq.ipkernel import main; main()"``
65 terminal-based client. You can even connect to an active IPython Notebook
66 kernel - just watch for the connection string that gets printed when you
67 open the notebook, or use the ``%connect_info`` magic to get the
68 connection string. If you are still using 0.11, you can launch a regular
69 kernel using ``python -c "from IPython.zmq.ipkernel import main; main()"``
57
70
58 ------------------------
71 ------------------------
59 Sending lines to IPython
72 Sending lines to IPython
60 ------------------------
73 ------------------------
61 Now type out a line and send it to IPython using ``<Ctrl-S>`` from Command mode::
74 Now type out a line and send it to IPython using ``<Ctrl-S>`` from Command mode::
62
75
63 import os
76 import os
64
77
65 You should see a notification message confirming the line was sent, along
78 You should see a notification message confirming the line was sent, along
66 with the input number for the line, like so ``In[1]: import os``.
79 with the input number for the line, like so ``In[1]: import os``.
67
80
68 ``<Ctrl-S>`` also works from insert mode, but doesn't show notification,
81 ``<Ctrl-S>`` also works from insert mode, but doesn't show notification,
69 unless ``monitor_subchannel`` is set to ``True`` (see `vim-ipython 'shell'`_,
82 unless ``monitor_subchannel`` is set to ``True`` (see `vim-ipython 'shell'`_,
70 below)
83 below)
71
84
72 It also works blockwise in Visual Mode. Select and send these lines using
85 It also works blockwise in Visual Mode. Select and send these lines using
73 ``<Ctrl-S>``::
86 ``<Ctrl-S>``::
74
87
75 import this,math # secret decoder ring
88 import this,math # secret decoder ring
76 a,b,c,d,e,f,g,h,i = range(1,10)
89 a,b,c,d,e,f,g,h,i = range(1,10)
77 code =(c,a,d,a,e,i,)
90 code =(c,a,d,a,e,i,)
78 msg = '...jrer nyy frag sebz Ivz.\nIvz+VClguba=%fyl '+this.s.split()[g]
91 msg = '...jrer nyy frag sebz Ivz.\nIvz+VClguba=%fyl '+this.s.split()[g]
79 decode=lambda x:"\n"+"".join([this.d.get(c,c) for c in x])+"!"
92 decode=lambda x:"\n"+"".join([this.d.get(c,c) for c in x])+"!"
80 format=lambda x:'These lines:\n '+'\n '.join([l for l in x.splitlines()])
93 format=lambda x:'These lines:\n '+'\n '.join([l for l in x.splitlines()])
81 secret_decoder = lambda a,b: format(a)+decode(msg)%str(b)[:-1]
94 secret_decoder = lambda a,b: format(a)+decode(msg)%str(b)[:-1]
82 '%d'*len(code)%code == str(int(math.pi*1e5))
95 '%d'*len(code)%code == str(int(math.pi*1e5))
83
96
84 Then, go to the qtconsole and run this line::
97 Then, go to the qtconsole and run this line::
85
98
86 print secret_decoder(_i,_)
99 print secret_decoder(_i,_)
87
100
88 You can also send whole files to IPython's ``%run`` magic using ``<F5>``.
101 You can also send whole files to IPython's ``%run`` magic using ``<F5>``.
89
102
103 **NEW in IPython 0.12**!
104 If you're trying to do run code fragments that have leading whitespace, use
105 ``<Alt-S>`` instead - it will dedent a single line, and remove the leading
106 whitespace of the first line from all lines in a visual mode selection.
107
90 -------------------------------
108 -------------------------------
91 IPython's object? Functionality
109 IPython's object? Functionality
92 -------------------------------
110 -------------------------------
93
111
94 If you're using gvim, mouse-over a variable to see IPython's ? equivalent. If
112 If you're using gvim, mouse-over a variable to see IPython's ``?`` equivalent.
95 you're using vim from a terminal, or want to copy something from the
113 If you're using vim from a terminal, or want to copy something from the
96 docstring, type ``<leader>d``. ``<leader>`` is usually ``\`` (the backslash
114 docstring, type ``<leader>d``. ``<leader>`` is usually ``\`` (the backslash
97 key). This will open a quickpreview window, which can be closed by hitting
115 key). This will open a quickpreview window, which can be closed by hitting
98 ``q`` or ``<escape>``.
116 ``q`` or ``<escape>``.
99
117
100 --------------------------------------
118 --------------------------------------
101 IPython's tab-completion Functionality
119 IPython's tab-completion Functionality
102 --------------------------------------
120 --------------------------------------
103 vim-ipython activates a 'completefunc' that queries IPython.
121 vim-ipython activates a 'completefunc' that queries IPython.
104 A completefunc is activated using ``Ctrl-X Ctrl-U`` in Insert Mode (vim
122 A completefunc is activated using ``Ctrl-X Ctrl-U`` in Insert Mode (vim
105 default). You can combine this functionality with SuperTab to get tab
123 default). You can combine this functionality with SuperTab to get tab
106 completion.
124 completion.
107
125
108 -------------------
126 -------------------
109 vim-ipython 'shell'
127 vim-ipython 'shell'
110 -------------------
128 -------------------
111 **NEW since IPython 0.11**!
112
129
113 By monitoring km.sub_channel, we can recreate what messages were sent to
130 By monitoring km.sub_channel, we can recreate what messages were sent to
114 IPython, and what IPython sends back in response.
131 IPython, and what IPython sends back in response.
115
132
116 ``monitor_subchannel`` is a parameter that sets whether this 'shell' should
133 ``monitor_subchannel`` is a parameter that sets whether this 'shell' should
117 updated on every sent command (default: True).
134 updated on every sent command (default: True).
118
135
119 If at any later time you wish to bring this shell up, including if you've set
136 If at any later time you wish to bring this shell up, including if you've set
120 ``monitor_subchannel=False``, hit ``<leader>s``.
137 ``monitor_subchannel=False``, hit ``<leader>s``.
121
138
139 **NEW since IPython 0.12**
140 For local kernels (kernels running on the same machine as vim), `Ctrl-C` in
141 the vim-ipython 'shell' sends an keyboard interrupt. (Note: this feature may
142 not work on Windows, please report the issue to ).
143
122 -------
144 -------
123 Options
145 Options
124 -------
146 -------
125 You can change these at the top of the ipy.vim::
147 You can change these at the top of the ipy.vim::
126
148
127 reselect = False # reselect lines after sending from Visual mode
149 reselect = False # reselect lines after sending from Visual mode
128 show_execution_count = True # wait to get numbers for In[43]: feedback?
150 show_execution_count = True # wait to get numbers for In[43]: feedback?
129 monitor_subchannel = True # update vim-ipython 'shell' on every send?
151 monitor_subchannel = True # update vim-ipython 'shell' on every send?
130 run_flags= "-i" # flags to for IPython's run magic when using <F5>
152 run_flags= "-i" # flags to for IPython's run magic when using <F5>
131
153
132 **Disabling default mappings**
154 **Disabling default mappings**
133 In your own ``.vimrc``, if you don't like the mappings provided by default,
155 In your own ``.vimrc``, if you don't like the mappings provided by default,
134 you can define a variable ``let g:ipy_perform_mappings=0`` which will prevent
156 you can define a variable ``let g:ipy_perform_mappings=0`` which will prevent
135 vim-ipython from defining any of the default mappings.
157 vim-ipython from defining any of the default mappings.
136
158
159 **NEW since IPython 0.12**
160 **Making completefunc local to a buffer, or disabling it**
161 By default, vim-ipython activates the custom completefunc globally.
162 Sometimes, having a completefunc breaks other plugins' completions. Putting
163 the line ``let g:ipy_completefunc = 'local'`` in one's vimrc will activate the
164 IPython-based completion only for current buffer. Setting `g:ipy_completefunc`
165 to anything other than `'local'` or `'global'` disables it altogether.
166
137 ---------------
167 ---------------
138 Current issues:
168 Current issues:
139 ---------------
169 ---------------
140 - For now, vim-ipython only connects to an ipython session in progress.
170 - For now, vim-ipython only connects to an ipython session in progress.
141 - The ipdb integration is not yet re-implemented.
171 - The ipdb integration is not yet re-implemented.
142 - If you're running inside ``screen``, read about the ``<CTRL-S>`` issue `here
172 - If you're running inside ``screen``, read about the ``<CTRL-S>`` issue `here
143 <http://munkymorgy.blogspot.com/2008/07/screen-ctrl-s-bug.html>`_, and add
173 <http://munkymorgy.blogspot.com/2008/07/screen-ctrl-s-bug.html>`_, and add
144 this line to your ``.bashrc`` to fix it::
174 this line to your ``.bashrc`` to fix it::
145
175
146 stty stop undef # to unmap ctrl-s
176 stty stop undef # to unmap ctrl-s
147
177
148 - In vim, if you're getting ``ImportError: No module named
178 - In vim, if you're getting ``ImportError: No module named
149 IPython.zmq.blockingkernelmanager`` but are able to import it in regular
179 IPython.zmq.blockingkernelmanager`` but are able to import it in regular
150 python, **either**
180 python, **either**
151
181
152 1. your ``sys.path`` in vim differs from the ``sys.path`` in regular python.
182 1. your ``sys.path`` in vim differs from the ``sys.path`` in regular python.
153 Try running these two lines, and comparing their output files::
183 Try running these two lines, and comparing their output files::
154
184
155 $ vim -c 'py import vim, sys; vim.current.buffer.append(sys.path)' -c ':wq vim_syspath'
185 $ vim -c 'py import vim, sys; vim.current.buffer.append(sys.path)' -c ':wq vim_syspath'
156 $ python -c "import sys; f=file('python_syspath','w'); f.write('\n'.join(sys.path)); f.close()"
186 $ python -c "import sys; f=file('python_syspath','w'); f.write('\n'.join(sys.path)); f.close()"
157
187
158 **or**
188 **or**
159
189
160 2. your vim is compiled against a different python than you are launching. See
190 2. your vim is compiled against a different python than you are launching. See
161 if there's a difference between ::
191 if there's a difference between ::
162
192
163 $ vim -c ':py import os; print os.__file__' -c ':q'
193 $ vim -c ':py import os; print os.__file__' -c ':q'
164 $ python -c ':py import os; print os.__file__'
194 $ python -c 'import os; print os.__file__'
165
195
166 - For vim inside a terminal, using the arrow keys won't work inside a
196 - For vim inside a terminal, using the arrow keys won't work inside a
167 documentation buffer, because the mapping for ``<Esc>`` overlaps with
197 documentation buffer, because the mapping for ``<Esc>`` overlaps with
168 ``^[OA`` and so on, and we use ``<Esc>`` as a quick way of closing the
198 ``^[OA`` and so on, and we use ``<Esc>`` as a quick way of closing the
169 documentation preview window. If you want go without this quick close
199 documentation preview window. If you want go without this quick close
170 functionality and want to use the arrow keys instead, look for instructions
200 functionality and want to use the arrow keys instead, look for instructions
171 starting with "Known issue: to enable the use of arrow keys..." in the
201 starting with "Known issue: to enable the use of arrow keys..." in the
172 ``get_doc_buffer`` function.
202 ``get_doc_buffer`` function.
173
203
174 - @fholgado's update to ``minibufexpl.vim`` that is up on GitHub will always
204 - @fholgado's update to ``minibufexpl.vim`` that is up on GitHub will always
175 put the cursor in the minibuf after sending a command when
205 put the cursor in the minibuf after sending a command when
176 ``monitor_subchannel`` is set. This is a bug in minibufexpl.vim and the workaround
206 ``monitor_subchannel`` is set. This is a bug in minibufexpl.vim and the workaround
177 is described in vim-ipython issue #7.
207 is described in vim-ipython issue #7.
178
208
179 ----------------------------
209 ----------------------------
180 Thanks and Bug Participation
210 Thanks and Bug Participation
181 ----------------------------
211 ----------------------------
182 * @MinRK for guiding me through the IPython kernel manager protocol.
212 Here's a brief acknowledgment of the folks who have graciously pitched in. If
183 * @nakamuray and @tcheneau for reporting and providing a fix for when vim is compiled without a gui (#1)
213 you've been missed, don't hesitate to contact me, or better yet, submit a
184 * @unpingco for reporting Windows bugs (#3,#4)
214 pull request with your attribution.
215
216 * @minrk for guiding me through the IPython kernel manager protocol, and
217 support of connection_file-based IPython connection (#13)
218 * @nakamuray and @tcheneau for reporting and providing a fix for when vim is
219 compiled without a gui (#1)
220 * @unpingco for reporting Windows bugs (#3,#4), providing better multiline
221 dedenting (#15), and suggesting that a resized vim-ipython shell stays
222 resized (#16).
185 * @simon-b for terminal vim arrow key issue (#5)
223 * @simon-b for terminal vim arrow key issue (#5)
186 * @jorgesca and @kwgoodman for shell (#6)
224 * @jorgesca and @kwgoodman for shell update problems (#6)
225 * @xowlinx and @vladimiroff for Ctrl-S issues in Konsole (#8)
187 * @zeekay for easily allowing custom mappings (#9)
226 * @zeekay for easily allowing custom mappings (#9)
188 * @minrk for support of connection_file-based IPython connection (#13)
227 * @jorgesca for reporting the lack of profile handling capability (#14),
189 * @jorgesca for reporting the lack of profile handling capability (#14)
228 only open updating 'shell' if it is open (#29)
229 * @enzbang for removing mapping that's not currently functional (#17)
230 * @ogrisel for fixing documentation typo (#19)
231 * @koepsell for gracefully exiting in case python is not available (#23)
232 * @mrterry for activating completefunc only after a connection is made (#25),
233 Ctrl-C implementation in vim-ipython 'shell' (#28)
234 * @nonameentername for completion on import statements (#26)
235 * @dstahlke for setting syntax of doc window to ReST
236 * @jtratner for docs with quotes (#30)
237 * @pielgrzym for setting completefunc locally to a buffer (#32)
238
239 Similar Projects
240 ----------------
241 * `vim-slime`_ - Grab some text and "send" it to a GNU Screen / tmux session
242 (Jonathan Palardy)
243 * `screen.vba`_ - Simulate a split shell, using GNU Screen / tmux, that you
244 can send commands to (Eric Van Dewoestine)
245 * conque_ - terminal emulator which uses a Vim buffer to display the program
246 output (Nico Raffo)
247 * `ipyqtmacvim`_ - plugin to send commands from MacVim to IPython Qt console
248 (Justin Kitzes)
249
250 .. _vim-slime: https://github.com/jpalardy/vim-slime
251 .. _screen.vba: https://github.com/ervandew/screen
252 .. _conque: http://code.google.com/p/conque/
253 .. _ipyqtmacvim: https://github.com/jkitzes/ipyqtmacvim/
@@ -1,521 +1,665
1 " Vim integration with IPython 0.11+
1 " Vim integration with IPython 0.11+
2 "
2 "
3 " A two-way integration between Vim and IPython.
3 " A two-way integration between Vim and IPython.
4 "
4 "
5 " Using this plugin, you can send lines or whole files for IPython to execute,
5 " Using this plugin, you can send lines or whole files for IPython to execute,
6 " and also get back object introspection and word completions in Vim, like
6 " and also get back object introspection and word completions in Vim, like
7 " what you get with: object?<enter> object.<tab> in IPython
7 " what you get with: object?<enter> object.<tab> in IPython
8 "
8 "
9 " -----------------
9 " -----------------
10 " Quickstart Guide:
10 " Quickstart Guide:
11 " -----------------
11 " -----------------
12 " Start ipython qtconsole and copy the connection string.
12 " Start ipython qtconsole and copy the connection string.
13 " Source this file, which provides new IPython command
13 " Source this file, which provides new IPython command
14 " :source ipy.vim
14 " :source ipy.vim
15 " :IPythonClipboard
15 " :IPythonClipboard
16 " (or :IPythonXSelection if you're using X11 without having to copy)
16 " (or :IPythonXSelection if you're using X11 without having to copy)
17 "
17 "
18 " written by Paul Ivanov (http://pirsquared.org)
18 " written by Paul Ivanov (http://pirsquared.org)
19 "
20 if !has('python')
21 " exit if python is not available.
22 finish
23 endif
24
25 " Allow custom mappings.
26 if !exists('g:ipy_perform_mappings')
27 let g:ipy_perform_mappings = 1
28 endif
29
30 " Register IPython completefunc
31 " 'global' -- for all of vim (default).
32 " 'local' -- only for the current buffer.
33 " otherwise -- don't register it at all.
34 "
35 " you can later set it using ':set completefunc=CompleteIPython', which will
36 " correspond to the 'global' behavior, or with ':setl ...' to get the 'local'
37 " behavior
38 if !exists('g:ipy_completefunc')
39 let g:ipy_completefunc = 'global'
40 endif
41
19 python << EOF
42 python << EOF
20 reselect = False # reselect lines after sending from Visual mode
43 reselect = False # reselect lines after sending from Visual mode
21 show_execution_count = True # wait to get numbers for In[43]: feedback?
44 show_execution_count = True # wait to get numbers for In[43]: feedback?
22 monitor_subchannel = True # update vim-ipython 'shell' on every send?
45 monitor_subchannel = True # update vim-ipython 'shell' on every send?
23 run_flags= "-i" # flags to for IPython's run magic when using <F5>
46 run_flags= "-i" # flags to for IPython's run magic when using <F5>
47 current_line = ''
24
48
25 import vim
49 import vim
26 import sys
50 import sys
27
51
28 # get around unicode problems when interfacing with vim
52 # get around unicode problems when interfacing with vim
29 vim_encoding=vim.eval('&encoding') or 'utf-8'
53 vim_encoding=vim.eval('&encoding') or 'utf-8'
30
54
31 try:
55 try:
32 sys.stdout.flush
56 sys.stdout.flush
33 except AttributeError:
57 except AttributeError:
34 # IPython complains if stderr and stdout don't have flush
58 # IPython complains if stderr and stdout don't have flush
35 # this is fixed in newer version of Vim
59 # this is fixed in newer version of Vim
36 class WithFlush(object):
60 class WithFlush(object):
37 def __init__(self,noflush):
61 def __init__(self,noflush):
38 self.write=noflush.write
62 self.write=noflush.write
39 self.writelines=noflush.writelines
63 self.writelines=noflush.writelines
40 def flush(self):pass
64 def flush(self):pass
41 sys.stdout = WithFlush(sys.stdout)
65 sys.stdout = WithFlush(sys.stdout)
42 sys.stderr = WithFlush(sys.stderr)
66 sys.stderr = WithFlush(sys.stderr)
43
67
44
68
45
69
46 ip = '127.0.0.1'
70 ip = '127.0.0.1'
47 try:
71 try:
48 km
72 km
49 except NameError:
73 except NameError:
50 km = None
74 km = None
75 try:
76 pid
77 except NameError:
78 pid = None
51
79
52 def km_from_string(s=''):
80 def km_from_string(s=''):
53 """create kernel manager from IPKernelApp string
81 """create kernel manager from IPKernelApp string
54 such as '--shell=47378 --iopub=39859 --stdin=36778 --hb=52668' for IPython 0.11
82 such as '--shell=47378 --iopub=39859 --stdin=36778 --hb=52668' for IPython 0.11
55 or just 'kernel-12345.json' for IPython 0.12
83 or just 'kernel-12345.json' for IPython 0.12
56 """
84 """
57 from os.path import join as pjoin
85 from os.path import join as pjoin
58 from IPython.zmq.blockingkernelmanager import BlockingKernelManager, Empty
86 from IPython.zmq.blockingkernelmanager import BlockingKernelManager, Empty
59 from IPython.config.loader import KeyValueConfigLoader
87 from IPython.config.loader import KeyValueConfigLoader
60 from IPython.zmq.kernelapp import kernel_aliases
88 from IPython.zmq.kernelapp import kernel_aliases
61 global km,send,Empty
89 global km,send,Empty
62
90
63 s = s.replace('--existing', '')
91 s = s.replace('--existing', '')
64 if 'connection_file' in BlockingKernelManager.class_trait_names():
92 if 'connection_file' in BlockingKernelManager.class_trait_names():
65 from IPython.lib.kernel import find_connection_file
93 from IPython.lib.kernel import find_connection_file
66 # 0.12 uses files instead of a collection of ports
94 # 0.12 uses files instead of a collection of ports
67 # include default IPython search path
95 # include default IPython search path
68 # filefind also allows for absolute paths, in which case the search
96 # filefind also allows for absolute paths, in which case the search
69 # is ignored
97 # is ignored
70 try:
98 try:
71 # XXX: the following approach will be brittle, depending on what
99 # XXX: the following approach will be brittle, depending on what
72 # connection strings will end up looking like in the future, and
100 # connection strings will end up looking like in the future, and
73 # whether or not they are allowed to have spaces. I'll have to sync
101 # whether or not they are allowed to have spaces. I'll have to sync
74 # up with the IPython team to address these issues -pi
102 # up with the IPython team to address these issues -pi
75 if '--profile' in s:
103 if '--profile' in s:
76 k,p = s.split('--profile')
104 k,p = s.split('--profile')
77 k = k.lstrip().rstrip() # kernel part of the string
105 k = k.lstrip().rstrip() # kernel part of the string
78 p = p.lstrip().rstrip() # profile part of the string
106 p = p.lstrip().rstrip() # profile part of the string
79 fullpath = find_connection_file(k,p)
107 fullpath = find_connection_file(k,p)
80 else:
108 else:
81 fullpath = find_connection_file(s.lstrip().rstrip())
109 fullpath = find_connection_file(s.lstrip().rstrip())
82 except IOError,e:
110 except IOError,e:
83 echo(":IPython " + s + " failed", "Info")
111 echo(":IPython " + s + " failed", "Info")
84 echo("^-- failed '" + s + "' not found", "Error")
112 echo("^-- failed '" + s + "' not found", "Error")
85 return
113 return
86 km = BlockingKernelManager(connection_file = fullpath)
114 km = BlockingKernelManager(connection_file = fullpath)
87 km.load_connection_file()
115 km.load_connection_file()
88 else:
116 else:
89 if s == '':
117 if s == '':
90 echo(":IPython 0.11 requires the full connection string")
118 echo(":IPython 0.11 requires the full connection string")
91 return
119 return
92 loader = KeyValueConfigLoader(s.split(), aliases=kernel_aliases)
120 loader = KeyValueConfigLoader(s.split(), aliases=kernel_aliases)
93 cfg = loader.load_config()['KernelApp']
121 cfg = loader.load_config()['KernelApp']
94 try:
122 try:
95 km = BlockingKernelManager(
123 km = BlockingKernelManager(
96 shell_address=(ip, cfg['shell_port']),
124 shell_address=(ip, cfg['shell_port']),
97 sub_address=(ip, cfg['iopub_port']),
125 sub_address=(ip, cfg['iopub_port']),
98 stdin_address=(ip, cfg['stdin_port']),
126 stdin_address=(ip, cfg['stdin_port']),
99 hb_address=(ip, cfg['hb_port']))
127 hb_address=(ip, cfg['hb_port']))
100 except KeyError,e:
128 except KeyError,e:
101 echo(":IPython " +s + " failed", "Info")
129 echo(":IPython " +s + " failed", "Info")
102 echo("^-- failed --"+e.message.replace('_port','')+" not specified", "Error")
130 echo("^-- failed --"+e.message.replace('_port','')+" not specified", "Error")
103 return
131 return
104 km.start_channels()
132 km.start_channels()
105 send = km.shell_channel.execute
133 send = km.shell_channel.execute
134
135 # now that we're connect to an ipython kernel, activate completion
136 # machinery, but do so only for the local buffer if the user added the
137 # following line the vimrc:
138 # let g:ipy_completefunc = 'local'
139 vim.command("""
140 if g:ipy_completefunc == 'global'
141 set completefunc=CompleteIPython
142 elseif g:ipy_completefunc == 'local'
143 setl completefunc=CompleteIPython
144 endif
145 """)
146 # also activate GUI doc balloons if in gvim
147 vim.command("""
148 if has('balloon_eval')
149 set bexpr=IPythonBalloonExpr()
150 set ballooneval
151 endif
152 """)
153 set_pid()
106 return km
154 return km
107
155
108 def echo(arg,style="Question"):
156 def echo(arg,style="Question"):
109 try:
157 try:
110 vim.command("echohl %s" % style)
158 vim.command("echohl %s" % style)
111 vim.command("echom \"%s\"" % arg.replace('\"','\\\"'))
159 vim.command("echom \"%s\"" % arg.replace('\"','\\\"'))
112 vim.command("echohl None")
160 vim.command("echohl None")
113 except vim.error:
161 except vim.error:
114 print "-- %s" % arg
162 print "-- %s" % arg
115
163
116 def disconnect():
164 def disconnect():
117 "disconnect kernel manager"
165 "disconnect kernel manager"
118 # XXX: make a prompt here if this km owns the kernel
166 # XXX: make a prompt here if this km owns the kernel
119 pass
167 pass
120
168
121 def get_doc(word):
169 def get_doc(word):
122 if km is None:
170 if km is None:
123 return ["Not connected to IPython, cannot query \"%s\"" %word]
171 return ["Not connected to IPython, cannot query: %s" % word]
124 msg_id = km.shell_channel.object_info(word)
172 msg_id = km.shell_channel.object_info(word)
125 doc = get_doc_msg(msg_id)
173 doc = get_doc_msg(msg_id)
126 # get around unicode problems when interfacing with vim
174 # get around unicode problems when interfacing with vim
127 return [d.encode(vim_encoding) for d in doc]
175 return [d.encode(vim_encoding) for d in doc]
128
176
129 import re
177 import re
130 # from http://serverfault.com/questions/71285/in-centos-4-4-how-can-i-strip-escape-sequences-from-a-text-file
178 # from http://serverfault.com/questions/71285/in-centos-4-4-how-can-i-strip-escape-sequences-from-a-text-file
131 strip = re.compile('\x1B\[([0-9]{1,2}(;[0-9]{1,2})?)?[m|K]')
179 strip = re.compile('\x1B\[([0-9]{1,2}(;[0-9]{1,2})?)?[m|K]')
132 def strip_color_escapes(s):
180 def strip_color_escapes(s):
133 return strip.sub('',s)
181 return strip.sub('',s)
134
182
135 def get_doc_msg(msg_id):
183 def get_doc_msg(msg_id):
136 n = 13 # longest field name (empirically)
184 n = 13 # longest field name (empirically)
137 b=[]
185 b=[]
138 try:
186 try:
139 content = get_child_msg(msg_id)['content']
187 content = get_child_msg(msg_id)['content']
140 except Empty:
188 except Empty:
141 # timeout occurred
189 # timeout occurred
142 return ["no reply from IPython kernel"]
190 return ["no reply from IPython kernel"]
143
191
144 if not content['found']:
192 if not content['found']:
145 return b
193 return b
146
194
147 for field in ['type_name','base_class','string_form','namespace',
195 for field in ['type_name','base_class','string_form','namespace',
148 'file','length','definition','source','docstring']:
196 'file','length','definition','source','docstring']:
149 c = content.get(field,None)
197 c = content.get(field,None)
150 if c:
198 if c:
151 if field in ['definition']:
199 if field in ['definition']:
152 c = strip_color_escapes(c).rstrip()
200 c = strip_color_escapes(c).rstrip()
153 s = field.replace('_',' ').title()+':'
201 s = field.replace('_',' ').title()+':'
154 s = s.ljust(n)
202 s = s.ljust(n)
155 if c.find('\n')==-1:
203 if c.find('\n')==-1:
156 b.append(s+c)
204 b.append(s+c)
157 else:
205 else:
158 b.append(s)
206 b.append(s)
159 b.extend(c.splitlines())
207 b.extend(c.splitlines())
160 return b
208 return b
161
209
162 def get_doc_buffer(level=0):
210 def get_doc_buffer(level=0):
163 # empty string in case vim.eval return None
211 # empty string in case vim.eval return None
164 word = vim.eval('expand("<cfile>")') or ''
212 word = vim.eval('expand("<cfile>")') or ''
165 doc = get_doc(word)
213 doc = get_doc(word)
166 if len(doc) ==0:
214 if len(doc) ==0:
167 echo(word+" not found","Error")
215 echo(repr(word)+" not found","Error")
168 return
216 return
169 # close any currently open preview windows
170 vim.command('pcl')
171 # documentation buffer name is same as the query made to ipython
217 # documentation buffer name is same as the query made to ipython
172 vim.command('new '+word)
218 vim.command('new '+word)
173 vim.command('setlocal pvw modifiable noro')
219 vim.command('setlocal modifiable noro')
174 # doc window quick quit keys: 'q' and 'escape'
220 # doc window quick quit keys: 'q' and 'escape'
175 vim.command('map <buffer> q :q<CR>')
221 vim.command('map <buffer> q :q<CR>')
176 # Known issue: to enable the use of arrow keys inside the terminal when
222 # Known issue: to enable the use of arrow keys inside the terminal when
177 # viewing the documentation, comment out the next line
223 # viewing the documentation, comment out the next line
178 vim.command('map <buffer> <Esc> :q<CR>')
224 vim.command('map <buffer> <Esc> :q<CR>')
179 # and uncomment this line (which will work if you have a timoutlen set)
225 # and uncomment this line (which will work if you have a timoutlen set)
180 #vim.command('map <buffer> <Esc><Esc> :q<CR>')
226 #vim.command('map <buffer> <Esc><Esc> :q<CR>')
181 b = vim.current.buffer
227 b = vim.current.buffer
182 b[:] = None
228 b[:] = None
183 b[:] = doc
229 b[:] = doc
184 vim.command('setlocal nomodified bufhidden=wipe')
230 vim.command('setlocal nomodified bufhidden=wipe')
185 #vim.command('setlocal previewwindow nomodifiable nomodified ro')
231 #vim.command('setlocal previewwindow nomodifiable nomodified ro')
186 #vim.command('set previewheight=%d'%len(b))# go to previous window
232 #vim.command('set previewheight=%d'%len(b))# go to previous window
187 vim.command('resize %d'%len(b))
233 vim.command('resize %d'%len(b))
188 #vim.command('pcl')
234 #vim.command('pcl')
189 #vim.command('pedit doc')
235 #vim.command('pedit doc')
190 #vim.command('normal ') # go to previous window
236 #vim.command('normal ') # go to previous window
237 # use the ReST formatting that ships with stock vim
238 vim.command('setlocal syntax=rst')
239
240 def vim_ipython_is_open():
241 """
242 Helper function to let us know if the vim-ipython shell is currently
243 visible
244 """
245 for w in vim.windows:
246 if w.buffer.name is not None and w.buffer.name.endswith("vim-ipython"):
247 return True
248 return False
191
249
192 def update_subchannel_msgs(debug=False):
250 def update_subchannel_msgs(debug=False, force=False):
251 """
252 Grab any pending messages and place them inside the vim-ipython shell.
253 This function will do nothing if the vim-ipython shell is not visible,
254 unless force=True argument is passed.
255 """
256 if km is None or (not vim_ipython_is_open() and not force):
257 return False
193 msgs = km.sub_channel.get_msgs()
258 msgs = km.sub_channel.get_msgs()
194 if debug:
259 if debug:
195 #try:
260 #try:
196 # vim.command("b debug_msgs")
261 # vim.command("b debug_msgs")
197 #except vim.error:
262 #except vim.error:
198 # vim.command("new debug_msgs")
263 # vim.command("new debug_msgs")
199 #finally:
264 #finally:
200 db = vim.current.buffer
265 db = vim.current.buffer
201 else:
266 else:
202 db = []
267 db = []
203 b = vim.current.buffer
268 b = vim.current.buffer
204 startedin_vimipython = vim.eval('@%')=='vim-ipython'
269 startedin_vimipython = vim.eval('@%')=='vim-ipython'
205 if not startedin_vimipython:
270 if not startedin_vimipython:
206 # switch to preview window
271 # switch to preview window
207 vim.command(
272 vim.command(
208 "try"
273 "try"
209 "|silent! wincmd P"
274 "|silent! wincmd P"
210 "|catch /^Vim\%((\a\+)\)\=:E441/"
275 "|catch /^Vim\%((\a\+)\)\=:E441/"
211 "|silent pedit +set\ ma vim-ipython"
276 "|silent pedit +set\ ma vim-ipython"
212 "|silent! wincmd P"
277 "|silent! wincmd P"
213 "|endtry")
278 "|endtry")
214 # if the current window is called 'vim-ipython'
279 # if the current window is called 'vim-ipython'
215 if vim.eval('@%')=='vim-ipython':
280 if vim.eval('@%')=='vim-ipython':
216 # set the preview window height to the current height
281 # set the preview window height to the current height
217 vim.command("set pvh=" + vim.eval('winheight(0)'))
282 vim.command("set pvh=" + vim.eval('winheight(0)'))
218 else:
283 else:
219 # close preview window, it was something other than 'vim-ipython'
284 # close preview window, it was something other than 'vim-ipython'
220 vim.command("pcl")
285 vim.command("pcl")
221 vim.command("silent pedit +set\ ma vim-ipython")
286 vim.command("silent pedit +set\ ma vim-ipython")
222 vim.command("wincmd P") #switch to preview window
287 vim.command("wincmd P") #switch to preview window
223 # subchannel window quick quit key 'q'
288 # subchannel window quick quit key 'q'
224 vim.command('map <buffer> q :q<CR>')
289 vim.command('map <buffer> q :q<CR>')
225 vim.command("set bufhidden=hide buftype=nofile ft=python")
290 vim.command("set bufhidden=hide buftype=nofile ft=python")
291 # make shift-enter and control-enter in insert mode behave same as in ipython notebook
292 # shift-enter send the current line, control-enter send the line
293 # but keeps it around for further editing.
294 vim.command("imap <buffer> <s-Enter> <esc>dd:python run_command('''<C-r>\"''')<CR>i")
295 # pkddA: paste, go up one line which is blank after run_command,
296 # delete it, and then back to insert mode
297 vim.command("imap <buffer> <c-Enter> <esc>dd:python run_command('''<C-r>\"''')<CR>pkddA")
298 # ctrl-C gets sent to the IPython process as a signal on POSIX
299 vim.command("map <buffer>  :IPythonInterrupt<cr>")
226
300
227 #syntax highlighting for python prompt
301 #syntax highlighting for python prompt
228 # QtConsole In[] is blue, but I prefer the oldschool green
302 # QtConsole In[] is blue, but I prefer the oldschool green
229 # since it makes the vim-ipython 'shell' look like the holidays!
303 # since it makes the vim-ipython 'shell' look like the holidays!
230 #vim.command("hi Blue ctermfg=Blue guifg=Blue")
304 #vim.command("hi Blue ctermfg=Blue guifg=Blue")
231 vim.command("hi Green ctermfg=Green guifg=Green")
305 vim.command("hi Green ctermfg=Green guifg=Green")
232 vim.command("hi Red ctermfg=Red guifg=Red")
306 vim.command("hi Red ctermfg=Red guifg=Red")
233 vim.command("syn keyword Green 'In\ []:'")
307 vim.command("syn keyword Green 'In\ []:'")
234 vim.command("syn match Green /^In \[[0-9]*\]\:/")
308 vim.command("syn match Green /^In \[[0-9]*\]\:/")
235 vim.command("syn match Red /^Out\[[0-9]*\]\:/")
309 vim.command("syn match Red /^Out\[[0-9]*\]\:/")
236 b = vim.current.buffer
310 b = vim.current.buffer
311 update_occured = False
237 for m in msgs:
312 for m in msgs:
238 #db.append(str(m).splitlines())
313 #db.append(str(m).splitlines())
239 s = ''
314 s = ''
240 if 'msg_type' not in m['header']:
315 if 'msg_type' not in m['header']:
241 # debug information
316 # debug information
242 #echo('skipping a message on sub_channel','WarningMsg')
317 #echo('skipping a message on sub_channel','WarningMsg')
243 #echo(str(m))
318 #echo(str(m))
244 continue
319 continue
245 elif m['header']['msg_type'] == 'status':
320 elif m['header']['msg_type'] == 'status':
246 continue
321 continue
247 elif m['header']['msg_type'] == 'stream':
322 elif m['header']['msg_type'] == 'stream':
248 s = strip_color_escapes(m['content']['data'])
323 s = strip_color_escapes(m['content']['data'])
249 elif m['header']['msg_type'] == 'pyout':
324 elif m['header']['msg_type'] == 'pyout':
250 s = "Out[%d]: " % m['content']['execution_count']
325 s = "Out[%d]: " % m['content']['execution_count']
251 s += m['content']['data']['text/plain']
326 s += m['content']['data']['text/plain']
252 elif m['header']['msg_type'] == 'pyin':
327 elif m['header']['msg_type'] == 'pyin':
253 # TODO: the next line allows us to resend a line to ipython if
328 # TODO: the next line allows us to resend a line to ipython if
254 # %doctest_mode is on. In the future, IPython will send the
329 # %doctest_mode is on. In the future, IPython will send the
255 # execution_count on subchannel, so this will need to be updated
330 # execution_count on subchannel, so this will need to be updated
256 # once that happens
331 # once that happens
257 if 'execution_count' in m['content']:
332 if 'execution_count' in m['content']:
258 s = "\nIn [%d]: "% m['content']['execution_count']
333 s = "\nIn [%d]: "% m['content']['execution_count']
259 else:
334 else:
260 s = "\nIn [00]: "
335 s = "\nIn [00]: "
261 s += m['content']['code'].strip()
336 s += m['content']['code'].strip()
262 elif m['header']['msg_type'] == 'pyerr':
337 elif m['header']['msg_type'] == 'pyerr':
263 c = m['content']
338 c = m['content']
264 s = "\n".join(map(strip_color_escapes,c['traceback']))
339 s = "\n".join(map(strip_color_escapes,c['traceback']))
265 s += c['ename'] + ":" + c['evalue']
340 s += c['ename'] + ":" + c['evalue']
266 if s.find('\n') == -1:
341 if s.find('\n') == -1:
267 # somewhat ugly unicode workaround from
342 # somewhat ugly unicode workaround from
268 # http://vim.1045645.n5.nabble.com/Limitations-of-vim-python-interface-with-respect-to-character-encodings-td1223881.html
343 # http://vim.1045645.n5.nabble.com/Limitations-of-vim-python-interface-with-respect-to-character-encodings-td1223881.html
269 if isinstance(s,unicode):
344 if isinstance(s,unicode):
270 s=s.encode(vim_encoding)
345 s=s.encode(vim_encoding)
271 b.append(s)
346 b.append(s)
272 else:
347 else:
273 try:
348 try:
274 b.append(s.splitlines())
349 b.append(s.splitlines())
275 except:
350 except:
276 b.append([l.encode(vim_encoding) for l in s.splitlines()])
351 b.append([l.encode(vim_encoding) for l in s.splitlines()])
352 update_occured = True
277 # make a newline so we can just start typing there
353 # make a newline so we can just start typing there
278 if b[-1] != '':
354 if b[-1] != '':
279 b.append([''])
355 b.append([''])
280 vim.command('normal G') # go to the end of the file
356 vim.command('normal G') # go to the end of the file
281 if not startedin_vimipython:
357 if not startedin_vimipython:
282 vim.command('normal p') # go back to where you were
358 vim.command('normal p') # go back to where you were
359 return update_occured
283
360
284 def get_child_msg(msg_id):
361 def get_child_msg(msg_id):
285 # XXX: message handling should be split into its own process in the future
362 # XXX: message handling should be split into its own process in the future
286 while True:
363 while True:
287 # get_msg will raise with Empty exception if no messages arrive in 1 second
364 # get_msg will raise with Empty exception if no messages arrive in 1 second
288 m= km.shell_channel.get_msg(timeout=1)
365 m= km.shell_channel.get_msg(timeout=1)
289 if m['parent_header']['msg_id'] == msg_id:
366 if m['parent_header']['msg_id'] == msg_id:
290 break
367 break
291 else:
368 else:
292 #got a message, but not the one we were looking for
369 #got a message, but not the one we were looking for
293 echo('skipping a message on shell_channel','WarningMsg')
370 echo('skipping a message on shell_channel','WarningMsg')
294 return m
371 return m
295
372
296 def print_prompt(prompt,msg_id=None):
373 def print_prompt(prompt,msg_id=None):
297 """Print In[] or In[42] style messages"""
374 """Print In[] or In[42] style messages"""
298 global show_execution_count
375 global show_execution_count
299 if show_execution_count and msg_id:
376 if show_execution_count and msg_id:
300 # wait to get message back from kernel
377 # wait to get message back from kernel
301 try:
378 try:
302 child = get_child_msg(msg_id)
379 child = get_child_msg(msg_id)
303 count = child['content']['execution_count']
380 count = child['content']['execution_count']
304 echo("In[%d]: %s" %(count,prompt))
381 echo("In[%d]: %s" %(count,prompt))
305 except Empty:
382 except Empty:
306 echo("In[]: %s (no reply from IPython kernel)" % prompt)
383 echo("In[]: %s (no reply from IPython kernel)" % prompt)
307 else:
384 else:
308 echo("In[]: %s" % prompt)
385 echo("In[]: %s" % prompt)
309
386
310 def with_subchannel(f,*args):
387 def with_subchannel(f,*args):
311 "conditionally monitor subchannel"
388 "conditionally monitor subchannel"
312 def f_with_update(*args):
389 def f_with_update(*args):
313 try:
390 try:
314 f(*args)
391 f(*args)
315 if monitor_subchannel:
392 if monitor_subchannel:
316 update_subchannel_msgs()
393 update_subchannel_msgs()
317 except AttributeError: #if km is None
394 except AttributeError: #if km is None
318 echo("not connected to IPython", 'Error')
395 echo("not connected to IPython", 'Error')
319 return f_with_update
396 return f_with_update
320
397
321 @with_subchannel
398 @with_subchannel
322 def run_this_file():
399 def run_this_file():
323 msg_id = send('run %s %s' % (run_flags, repr(vim.current.buffer.name),))
400 msg_id = send('run %s %s' % (run_flags, repr(vim.current.buffer.name),))
324 print_prompt("In[]: run %s %s" % (run_flags, repr(vim.current.buffer.name)),msg_id)
401 print_prompt("In[]: run %s %s" % (run_flags, repr(vim.current.buffer.name)),msg_id)
325
402
326 @with_subchannel
403 @with_subchannel
327 def run_this_line():
404 def run_this_line():
328 msg_id = send(vim.current.line)
405 msg_id = send(vim.current.line)
329 print_prompt(vim.current.line, msg_id)
406 print_prompt(vim.current.line, msg_id)
330
407
331 @with_subchannel
408 @with_subchannel
332 def run_command(cmd):
409 def run_command(cmd):
333 msg_id = send(cmd)
410 msg_id = send(cmd)
334 print_prompt(cmd, msg_id)
411 print_prompt(cmd, msg_id)
335 if monitor_subchannel:
336 update_subchannel_msgs()
337
412
338 @with_subchannel
413 @with_subchannel
339 def run_these_lines():
414 def run_these_lines():
340 r = vim.current.range
415 r = vim.current.range
341 lines = "\n".join(vim.current.buffer[r.start:r.end+1])
416 lines = "\n".join(vim.current.buffer[r.start:r.end+1])
342 msg_id = send(lines)
417 msg_id = send(lines)
343 #alternative way of doing this in more recent versions of ipython
418 #alternative way of doing this in more recent versions of ipython
344 #but %paste only works on the local machine
419 #but %paste only works on the local machine
345 #vim.command("\"*yy")
420 #vim.command("\"*yy")
346 #send("'%paste')")
421 #send("'%paste')")
347 #reselect the previously highlighted block
422 #reselect the previously highlighted block
348 vim.command("normal gv")
423 vim.command("normal gv")
349 if not reselect:
424 if not reselect:
350 vim.command("normal ")
425 vim.command("normal ")
351
426
352 #vim lines start with 1
427 #vim lines start with 1
353 #print "lines %d-%d sent to ipython"% (r.start+1,r.end+1)
428 #print "lines %d-%d sent to ipython"% (r.start+1,r.end+1)
354 prompt = "lines %d-%d "% (r.start+1,r.end+1)
429 prompt = "lines %d-%d "% (r.start+1,r.end+1)
355 print_prompt(prompt,msg_id)
430 print_prompt(prompt,msg_id)
356
431
432
433 def set_pid():
434 """
435 Explicitly ask the ipython kernel for its pid
436 """
437 global km, pid
438 lines = '\n'.join(['import os', '_pid = os.getpid()'])
439 msg_id = send(lines, silent=True, user_variables=['_pid'])
440
441 # wait to get message back from kernel
442 try:
443 child = get_child_msg(msg_id)
444 except Empty:
445 echo("no reply from IPython kernel")
446 return
447
448 pid = int(child['content']['user_variables']['_pid'])
449 return pid
450
451
452 def interrupt_kernel_hack():
453 """
454 Sends the interrupt signal to the remote kernel. This side steps the
455 (non-functional) ipython interrupt mechanisms.
456 Only works on posix.
457 """
458 global pid
459 import signal
460 import os
461 if pid is None:
462 # Avoid errors if we couldn't get pid originally,
463 # by trying to obtain it now
464 pid = set_pid()
465
466 if pid is None:
467 echo("cannot get kernel PID, Ctrl-C will not be supported")
468 return
469 echo("KeyboardInterrupt (sent to ipython: pid " +
470 "%i with signal %i)" % (pid, signal.SIGINT),"Operator")
471 try:
472 os.kill(pid, signal.SIGINT)
473 except OSError:
474 echo("unable to kill pid %d" % pid)
475 pid = None
476
357 def dedent_run_this_line():
477 def dedent_run_this_line():
358 vim.command("left")
478 vim.command("left")
359 run_this_line()
479 run_this_line()
360 vim.command("silent undo")
480 vim.command("silent undo")
361
481
362 def dedent_run_these_lines():
482 def dedent_run_these_lines():
363 r = vim.current.range
483 r = vim.current.range
364 shiftwidth = vim.eval('&shiftwidth')
484 shiftwidth = vim.eval('&shiftwidth')
365 count = int(vim.eval('indent(%d+1)/%s' % (r.start,shiftwidth)))
485 count = int(vim.eval('indent(%d+1)/%s' % (r.start,shiftwidth)))
366 vim.command("'<,'>" + "<"*count)
486 vim.command("'<,'>" + "<"*count)
367 run_these_lines()
487 run_these_lines()
368 vim.command("silent undo")
488 vim.command("silent undo")
369
489
370 #def set_this_line():
490 #def set_this_line():
371 # # not sure if there's a way to do this, since we have multiple clients
491 # # not sure if there's a way to do this, since we have multiple clients
372 # send("get_ipython().shell.set_next_input(\'%s\')" % vim.current.line.replace("\'","\\\'"))
492 # send("get_ipython().shell.set_next_input(\'%s\')" % vim.current.line.replace("\'","\\\'"))
373 # #print "line \'%s\' set at ipython prompt"% vim.current.line
493 # #print "line \'%s\' set at ipython prompt"% vim.current.line
374 # echo("line \'%s\' set at ipython prompt"% vim.current.line,'Statement')
494 # echo("line \'%s\' set at ipython prompt"% vim.current.line,'Statement')
375
495
376
496
377 def toggle_reselect():
497 def toggle_reselect():
378 global reselect
498 global reselect
379 reselect=not reselect
499 reselect=not reselect
380 print "F9 will%sreselect lines after sending to ipython"% (reselect and " " or " not ")
500 print "F9 will%sreselect lines after sending to ipython"% (reselect and " " or " not ")
381
501
382 #def set_breakpoint():
502 #def set_breakpoint():
383 # send("__IP.InteractiveTB.pdb.set_break('%s',%d)" % (vim.current.buffer.name,
503 # send("__IP.InteractiveTB.pdb.set_break('%s',%d)" % (vim.current.buffer.name,
384 # vim.current.window.cursor[0]))
504 # vim.current.window.cursor[0]))
385 # print "set breakpoint in %s:%d"% (vim.current.buffer.name,
505 # print "set breakpoint in %s:%d"% (vim.current.buffer.name,
386 # vim.current.window.cursor[0])
506 # vim.current.window.cursor[0])
387 #
507 #
388 #def clear_breakpoint():
508 #def clear_breakpoint():
389 # send("__IP.InteractiveTB.pdb.clear_break('%s',%d)" % (vim.current.buffer.name,
509 # send("__IP.InteractiveTB.pdb.clear_break('%s',%d)" % (vim.current.buffer.name,
390 # vim.current.window.cursor[0]))
510 # vim.current.window.cursor[0]))
391 # print "clearing breakpoint in %s:%d" % (vim.current.buffer.name,
511 # print "clearing breakpoint in %s:%d" % (vim.current.buffer.name,
392 # vim.current.window.cursor[0])
512 # vim.current.window.cursor[0])
393 #
513 #
394 #def clear_all_breakpoints():
514 #def clear_all_breakpoints():
395 # send("__IP.InteractiveTB.pdb.clear_all_breaks()");
515 # send("__IP.InteractiveTB.pdb.clear_all_breaks()");
396 # print "clearing all breakpoints"
516 # print "clearing all breakpoints"
397 #
517 #
398 #def run_this_file_pdb():
518 #def run_this_file_pdb():
399 # send(' __IP.InteractiveTB.pdb.run(\'execfile("%s")\')' % (vim.current.buffer.name,))
519 # send(' __IP.InteractiveTB.pdb.run(\'execfile("%s")\')' % (vim.current.buffer.name,))
400 # #send('run -d %s' % (vim.current.buffer.name,))
520 # #send('run -d %s' % (vim.current.buffer.name,))
401 # echo("In[]: run -d %s (using pdb)" % vim.current.buffer.name)
521 # echo("In[]: run -d %s (using pdb)" % vim.current.buffer.name)
402
522
403 EOF
523 EOF
404
524
405 fun! <SID>toggle_send_on_save()
525 fun! <SID>toggle_send_on_save()
406 if exists("s:ssos") && s:ssos == 0
526 if exists("s:ssos") && s:ssos == 0
407 let s:ssos = 1
527 let s:ssos = 1
408 au BufWritePost *.py :py run_this_file()
528 au BufWritePost *.py :py run_this_file()
409 echo "Autosend On"
529 echo "Autosend On"
410 else
530 else
411 let s:ssos = 0
531 let s:ssos = 0
412 au! BufWritePost *.py
532 au! BufWritePost *.py
413 echo "Autosend Off"
533 echo "Autosend Off"
414 endif
534 endif
415 endfun
535 endfun
416
536
417 " Allow custom mappings
537 " Update the vim-ipython shell when the cursor is not moving.
418 if !exists('g:ipy_perform_mappings')
538 " You can change how quickly this happens after you stop moving the cursor by
419 let g:ipy_perform_mappings = 1
539 " setting 'updatetime' (in milliseconds). For example, to have this event
420 endif
540 " trigger after 1 second:
541 "
542 " :set updatetime 1000
543 "
544 " NOTE: This will only be triggered once, after the first 'updatetime'
545 " milliseconds, *not* every 'updatetime' milliseconds. see :help CursorHold
546 " for more info.
547 "
548 " TODO: Make this easily configurable on the fly, so that an introspection
549 " buffer we may have opened up doesn't get closed just because of an idle
550 " event (i.e. user pressed \d and then left the buffer that popped up, but
551 " expects it to stay there).
552 au CursorHold *.*,vim-ipython :python if update_subchannel_msgs(): echo("vim-ipython shell updated (on idle)",'Operator')
553
554 " XXX: broken - cursor hold update for insert mode moves the cursor one
555 " character to the left of the last character (update_subchannel_msgs must be
556 " doing this)
557 "au CursorHoldI *.* :python if update_subchannel_msgs(): echo("vim-ipython shell updated (on idle)",'Operator')
558
559 " Same as above, but on regaining window focus (mostly for GUIs)
560 au FocusGained *.*,vim-ipython :python if update_subchannel_msgs(): echo("vim-ipython shell updated (on input focus)",'Operator')
561
562 " Update vim-ipython buffer when we move the cursor there. A message is only
563 " displayed if vim-ipython buffer has been updated.
564 au BufEnter vim-ipython :python if update_subchannel_msgs(): echo("vim-ipython shell updated (on buffer enter)",'Operator')
565
421 if g:ipy_perform_mappings != 0
566 if g:ipy_perform_mappings != 0
422 map <silent> <F5> :python run_this_file()<CR>
567 map <silent> <F5> :python run_this_file()<CR>
423 map <silent> <S-F5> :python run_this_line()<CR>
568 map <silent> <S-F5> :python run_this_line()<CR>
424 map <silent> <F9> :python run_these_lines()<CR>
569 map <silent> <F9> :python run_these_lines()<CR>
425 map <silent> <leader>d :py get_doc_buffer()<CR>
570 map <silent> <leader>d :py get_doc_buffer()<CR>
426 map <silent> <leader>s :py update_subchannel_msgs(); echo("vim-ipython shell updated",'Operator')<CR>
571 map <silent> <leader>s :py if update_subchannel_msgs(force=True): echo("vim-ipython shell updated",'Operator')<CR>
427 map <silent> <S-F9> :python toggle_reselect()<CR>
572 map <silent> <S-F9> :python toggle_reselect()<CR>
428 "map <silent> <C-F6> :python send('%pdb')<CR>
573 "map <silent> <C-F6> :python send('%pdb')<CR>
429 "map <silent> <F6> :python set_breakpoint()<CR>
574 "map <silent> <F6> :python set_breakpoint()<CR>
430 "map <silent> <s-F6> :python clear_breakpoint()<CR>
575 "map <silent> <s-F6> :python clear_breakpoint()<CR>
431 "map <silent> <F7> :python run_this_file_pdb()<CR>
576 "map <silent> <F7> :python run_this_file_pdb()<CR>
432 "map <silent> <s-F7> :python clear_all_breaks()<CR>
577 "map <silent> <s-F7> :python clear_all_breaks()<CR>
433 imap <C-F5> <C-O><F5>
578 imap <C-F5> <C-O><F5>
434 imap <S-F5> <C-O><S-F5>
579 imap <S-F5> <C-O><S-F5>
435 imap <silent> <F5> <C-O><F5>
580 imap <silent> <F5> <C-O><F5>
436 map <C-F5> :call <SID>toggle_send_on_save()<CR>
581 map <C-F5> :call <SID>toggle_send_on_save()<CR>
437 "" Example of how to quickly clear the current plot with a keystroke
582 "" Example of how to quickly clear the current plot with a keystroke
438 map <silent> <F12> :python run_command("plt.clf()")<cr>
583 "map <silent> <F12> :python run_command("plt.clf()")<cr>
439 "" Example of how to quickly close all figures with a keystroke
584 "" Example of how to quickly close all figures with a keystroke
440 map <silent> <F11> :python run_command("plt.close('all')")<cr>
585 "map <silent> <F11> :python run_command("plt.close('all')")<cr>
441
586
442 "pi custom
587 "pi custom
443 map <silent> <C-Return> :python run_this_file()<CR>
588 map <silent> <C-Return> :python run_this_file()<CR>
444 map <silent> <C-s> :python run_this_line()<CR>
589 map <silent> <C-s> :python run_this_line()<CR>
445 imap <silent> <C-s> <C-O>:python run_this_line()<CR>
590 imap <silent> <C-s> <C-O>:python run_this_line()<CR>
446 map <silent> <M-s> :python dedent_run_this_line()<CR>
591 map <silent> <M-s> :python dedent_run_this_line()<CR>
447 vmap <silent> <C-S> :python run_these_lines()<CR>
592 vmap <silent> <C-S> :python run_these_lines()<CR>
448 vmap <silent> <M-s> :python dedent_run_these_lines()<CR>
593 vmap <silent> <M-s> :python dedent_run_these_lines()<CR>
449 map <silent> <M-c> I#<ESC>
594 map <silent> <M-c> I#<ESC>
450 vmap <silent> <M-c> I#<ESC>
595 vmap <silent> <M-c> I#<ESC>
451 map <silent> <M-C> :s/^\([ \t]*\)#/\1/<CR>
596 map <silent> <M-C> :s/^\([ \t]*\)#/\1/<CR>
452 vmap <silent> <M-C> :s/^\([ \t]*\)#/\1/<CR>
597 vmap <silent> <M-C> :s/^\([ \t]*\)#/\1/<CR>
453 endif
598 endif
454
599
455 command! -nargs=* IPython :py km_from_string("<args>")
600 command! -nargs=* IPython :py km_from_string("<args>")
456 command! -nargs=0 IPythonClipboard :py km_from_string(vim.eval('@+'))
601 command! -nargs=0 IPythonClipboard :py km_from_string(vim.eval('@+'))
457 command! -nargs=0 IPythonXSelection :py km_from_string(vim.eval('@*'))
602 command! -nargs=0 IPythonXSelection :py km_from_string(vim.eval('@*'))
603 command! -nargs=0 IPythonInterrupt :py interrupt_kernel_hack()
458
604
459 function! IPythonBalloonExpr()
605 function! IPythonBalloonExpr()
460 python << endpython
606 python << endpython
461 word = vim.eval('v:beval_text')
607 word = vim.eval('v:beval_text')
462 reply = get_doc(word)
608 reply = get_doc(word)
463 vim.command("let l:doc = %s"% reply)
609 vim.command("let l:doc = %s"% reply)
464 endpython
610 endpython
465 return l:doc
611 return l:doc
466 endfunction
612 endfunction
467 if has('balloon_eval')
468 set bexpr=IPythonBalloonExpr()
469 set ballooneval
470 endif
471
613
472 fun! CompleteIPython(findstart, base)
614 fun! CompleteIPython(findstart, base)
473 if a:findstart
615 if a:findstart
474 " locate the start of the word
616 " locate the start of the word
475 let line = getline('.')
617 let line = getline('.')
476 let start = col('.') - 1
618 let start = col('.') - 1
477 while start > 0 && line[start-1] =~ '\k\|\.' "keyword
619 while start > 0 && line[start-1] =~ '\k\|\.' "keyword
478 let start -= 1
620 let start -= 1
479 endwhile
621 endwhile
480 echo start
622 echo start
623 python << endpython
624 current_line = vim.current.line
625 endpython
481 return start
626 return start
482 else
627 else
483 " find months matching with "a:base"
628 " find months matching with "a:base"
484 let res = []
629 let res = []
485 python << endpython
630 python << endpython
486 base = vim.eval("a:base")
631 base = vim.eval("a:base")
487 findstart = vim.eval("a:findstart")
632 findstart = vim.eval("a:findstart")
488 msg_id = km.shell_channel.complete(base, vim.current.line, vim.eval("col('.')"))
633 msg_id = km.shell_channel.complete(base, current_line, vim.eval("col('.')"))
489 try:
634 try:
490 m = get_child_msg(msg_id)
635 m = get_child_msg(msg_id)
491 matches = m['content']['matches']
636 matches = m['content']['matches']
492 matches.insert(0,base) # the "no completion" version
637 matches.insert(0,base) # the "no completion" version
493 # we need to be careful with unicode, because we can have unicode
638 # we need to be careful with unicode, because we can have unicode
494 # completions for filenames (for the %run magic, for example). So the next
639 # completions for filenames (for the %run magic, for example). So the next
495 # line will fail on those:
640 # line will fail on those:
496 #completions= [str(u) for u in matches]
641 #completions= [str(u) for u in matches]
497 # because str() won't work for non-ascii characters
642 # because str() won't work for non-ascii characters
498 # and we also have problems with unicode in vim, hence the following:
643 # and we also have problems with unicode in vim, hence the following:
499 completions = [s.encode(vim_encoding) for s in matches]
644 completions = [s.encode(vim_encoding) for s in matches]
500 except Empty:
645 except Empty:
501 echo("no reply from IPython kernel")
646 echo("no reply from IPython kernel")
502 completions=['']
647 completions=['']
503 ## Additionally, we have no good way of communicating lists to vim, so we have
648 ## Additionally, we have no good way of communicating lists to vim, so we have
504 ## to turn in into one long string, which can be problematic if e.g. the
649 ## to turn in into one long string, which can be problematic if e.g. the
505 ## completions contain quotes. The next line will not work if some filenames
650 ## completions contain quotes. The next line will not work if some filenames
506 ## contain quotes - but if that's the case, the user's just asking for
651 ## contain quotes - but if that's the case, the user's just asking for
507 ## it, right?
652 ## it, right?
508 #completions = '["'+ '", "'.join(completions)+'"]'
653 #completions = '["'+ '", "'.join(completions)+'"]'
509 #vim.command("let completions = %s" % completions)
654 #vim.command("let completions = %s" % completions)
510 ## An alternative for the above, which will insert matches one at a time, so
655 ## An alternative for the above, which will insert matches one at a time, so
511 ## if there's a problem with turning a match into a string, it'll just not
656 ## if there's a problem with turning a match into a string, it'll just not
512 ## include the problematic match, instead of not including anything. There's a
657 ## include the problematic match, instead of not including anything. There's a
513 ## bit more indirection here, but I think it's worth it
658 ## bit more indirection here, but I think it's worth it
514 for c in completions:
659 for c in completions:
515 vim.command('call add(res,"'+c+'")')
660 vim.command('call add(res,"'+c+'")')
516 endpython
661 endpython
517 "call extend(res,completions)
662 "call extend(res,completions)
518 return res
663 return res
519 endif
664 endif
520 endfun
665 endfun
521 set completefunc=CompleteIPython
General Comments 0
You need to be logged in to leave comments. Login now