From d9820fa279bf9643ad8dfe0763a6f04d6688f657 Mon Sep 17 00:00:00 2001 From: Nathan Heijermans Date: Tue, 2 Dec 2014 13:48:53 -0500 Subject: [PATCH 01/24] Some pedantic typographical/grammatical changes. --- ftplugin/python/vim_ipython.py | 24 ++++++++++++------------ 1 file changed, 12 insertions(+), 12 deletions(-) diff --git a/ftplugin/python/vim_ipython.py b/ftplugin/python/vim_ipython.py index 202925c..3afda49 100644 --- a/ftplugin/python/vim_ipython.py +++ b/ftplugin/python/vim_ipython.py @@ -20,14 +20,14 @@ def __getattribute__(self, key): import sys -# get around unicode problems when interfacing with vim +# Get around unicode problems when interfacing with Vim. vim_encoding=vim.eval('&encoding') or 'utf-8' try: sys.stdout.flush except AttributeError: # IPython complains if stderr and stdout don't have flush - # this is fixed in newer version of Vim + # This is fixed in newer version of Vim. class WithFlush(object): def __init__(self,noflush): self.write=noflush.write @@ -62,7 +62,7 @@ def vim_regex_escape(x): ip = '127.0.0.1' -# this allows us to load vim_ipython multiple times +# This allows us to load vim_ipython multiple times. try: km kc @@ -73,8 +73,8 @@ def vim_regex_escape(x): pid = None _install_instructions = """You *must* install IPython into the Python that -your vim is linked against. If you are seeing this message, this usually means -either (1) installing IPython using the system Python that vim is using, or +your Vim is linked against. If you are seeing this message, this usually means +either (1) installing IPython using the system Python that Vim is using, or (2) recompiling Vim against the Python where you already have IPython installed. This is only a requirement to allow Vim to speak with an IPython instance using IPython's own machinery. It does *not* mean that the IPython @@ -226,7 +226,7 @@ def get_doc(word, level=0): return ["Not connected to IPython, cannot query: %s" % word] msg_id = kc.shell_channel.object_info(word, level) doc = get_doc_msg(msg_id) - # get around unicode problems when interfacing with vim + # Get around unicode problems when interfacing with Vim. return [d.encode(vim_encoding) for d in doc] import re @@ -293,10 +293,10 @@ def get_doc_buffer(level=0): #vim.command('pedit doc') #vim.command('normal! ') # go to previous window if level == 0: - # use the ReST formatting that ships with stock vim + # Use the ReST formatting that ships with stock Vim vim.command('setlocal syntax=rst') else: - # use Python syntax highlighting + # Use Python syntax highlighting. vim.command('setlocal syntax=python') def ipy_complete(base, current_line, pos): @@ -305,12 +305,12 @@ def ipy_complete(base, current_line, pos): m = get_child_msg(msg_id) matches = m['content']['matches'] matches.insert(0,base) # the "no completion" version - # we need to be careful with unicode, because we can have unicode + # We need to be careful with unicode, because we can have unicode # completions for filenames (for the %run magic, for example). So the next # line will fail on those: #completions= [str(u) for u in matches] # because str() won't work for non-ascii characters - # and we also have problems with unicode in vim, hence the following: + # we also have problems with unicode in Vim, hence the following: return matches except Empty: echo("no reply from IPython kernel") @@ -396,7 +396,7 @@ def update_subchannel_msgs(debug=False, force=False): if header == 'status': continue elif header == 'stream': - # TODO: alllow for distinguishing between stdout and stderr (using + # TODO: allow for distinguishing between stdout and stderr (using # custom syntax markers in the vim-ipython buffer perhaps), or by # also echoing the message to the status bar s = strip_color_escapes(m['content']['data']) @@ -541,7 +541,7 @@ def run_these_lines(dedent=False): if not reselect: vim.command("normal! ") - #vim lines start with 1 + # Vim line numbering starts at 1. #print("lines %d-%d sent to ipython"% (r.start+1,r.end+1)) prompt = "lines %d-%d "% (r.start+1,r.end+1) print_prompt(prompt,msg_id) From a89c9cffe3f612fe8a3c7be848b3eba6f9976c85 Mon Sep 17 00:00:00 2001 From: Nathan Heijermans Date: Tue, 2 Dec 2014 13:53:54 -0500 Subject: [PATCH 02/24] Move imports to the beginning of the file. --- ftplugin/python/vim_ipython.py | 54 ++++++++++++++++++---------------- 1 file changed, 28 insertions(+), 26 deletions(-) diff --git a/ftplugin/python/vim_ipython.py b/ftplugin/python/vim_ipython.py index 3afda49..6e082cd 100644 --- a/ftplugin/python/vim_ipython.py +++ b/ftplugin/python/vim_ipython.py @@ -1,14 +1,31 @@ -reselect = False # reselect lines after sending from Visual mode -show_execution_count = True # wait to get numbers for In[43]: feedback? -monitor_subchannel = True # update vim-ipython 'shell' on every send? -run_flags= "-i" # flags to for IPython's run magic when using -current_line = '' +import inspect +import os +import re +import signal +import sys +import textwrap try: - from queue import Empty # python3 convention + # Python3 compatibility. + from queue import Empty except ImportError: from Queue import Empty +try: + import IPython +except ImportError: + install_instructions = textwrap.dedent("""\ + You *must* install IPython into the Python that your Vim is linked + against. If you are seeing this message, this usually means either (1) + installing IPython using the system Python that Vim is using, or (2) + recompiling Vim against the Python where you already have IPython + installed. This is only a requirement to allow Vim to speak with an + IPython instance using IPython's own machinery. It does *not* mean that + the IPython instance with which you communicate via vim-ipython needs to + be running the same version of Python. + """).strip() + raise ImportError("Could not find IPython.\n" + install_instructions) + try: import vim except ImportError: @@ -18,7 +35,11 @@ def __getattribute__(self, key): vim = NoOp() print("uh oh, not running inside vim") -import sys +reselect = False # reselect lines after sending from Visual mode +show_execution_count = True # wait to get numbers for In[43]: feedback? +monitor_subchannel = True # update vim-ipython 'shell' on every send? +run_flags= "-i" # flags to for IPython's run magic when using +current_line = '' # Get around unicode problems when interfacing with Vim. vim_encoding=vim.eval('&encoding') or 'utf-8' @@ -72,16 +93,6 @@ def vim_regex_escape(x): kc = None pid = None -_install_instructions = """You *must* install IPython into the Python that -your Vim is linked against. If you are seeing this message, this usually means -either (1) installing IPython using the system Python that Vim is using, or -(2) recompiling Vim against the Python where you already have IPython -installed. This is only a requirement to allow Vim to speak with an IPython -instance using IPython's own machinery. It does *not* mean that the IPython -instance with which you communicate via vim-ipython needs to be running the -same version of Python. -""" - def new_ipy(s=''): """Create a new IPython kernel (optionally with extra arguments) @@ -103,10 +114,6 @@ def km_from_string(s=''): such as '--shell=47378 --iopub=39859 --stdin=36778 --hb=52668' for IPython 0.11 or just 'kernel-12345.json' for IPython 0.12 """ - try: - import IPython - except ImportError: - raise ImportError("Could not find IPython. " + _install_instructions) from IPython.config.loader import KeyValueConfigLoader try: from IPython.kernel import ( @@ -175,7 +182,6 @@ def km_from_string(s=''): send = kc.shell_channel.execute #XXX: backwards compatibility for IPython < 0.13 - import inspect sc = kc.shell_channel num_oinfo_args = len(inspect.getargspec(sc.object_info).args) if num_oinfo_args == 2: @@ -229,7 +235,6 @@ def get_doc(word, level=0): # Get around unicode problems when interfacing with Vim. return [d.encode(vim_encoding) for d in doc] -import re # from http://serverfault.com/questions/71285/in-centos-4-4-how-can-i-strip-escape-sequences-from-a-text-file strip = re.compile('\x1B\[([0-9]{1,2}(;[0-9]{1,2})?)?[m|K]') def strip_color_escapes(s): @@ -572,7 +577,6 @@ def set_pid(): def terminate_kernel_hack(): "Send SIGTERM to our the IPython kernel" - import signal interrupt_kernel_hack(signal.SIGTERM) def interrupt_kernel_hack(signal_to_send=None): @@ -582,8 +586,6 @@ def interrupt_kernel_hack(signal_to_send=None): Only works on posix. """ global pid - import signal - import os if pid is None: # Avoid errors if we couldn't get pid originally, # by trying to obtain it now From 4e61c4df3dc500bb7b41e42372091838d49c43d4 Mon Sep 17 00:00:00 2001 From: Nathan Heijermans Date: Tue, 2 Dec 2014 14:17:45 -0500 Subject: [PATCH 03/24] Cleaned up wrapping of stout/sterr's flush. --- ftplugin/python/vim_ipython.py | 17 +++++++++-------- 1 file changed, 9 insertions(+), 8 deletions(-) diff --git a/ftplugin/python/vim_ipython.py b/ftplugin/python/vim_ipython.py index 6e082cd..a61dbfd 100644 --- a/ftplugin/python/vim_ipython.py +++ b/ftplugin/python/vim_ipython.py @@ -44,16 +44,17 @@ def __getattribute__(self, key): # Get around unicode problems when interfacing with Vim. vim_encoding=vim.eval('&encoding') or 'utf-8' -try: - sys.stdout.flush -except AttributeError: - # IPython complains if stderr and stdout don't have flush - # This is fixed in newer version of Vim. +# IPython complains if stderr and stdout don't have flush. This is fixed in +# newer version of Vim. +if not hasattr(sys.stdout, 'flush'): class WithFlush(object): def __init__(self,noflush): - self.write=noflush.write - self.writelines=noflush.writelines - def flush(self):pass + self.write = noflush.write + self.writelines = noflush.writelines + + def flush(self): + pass + sys.stdout = WithFlush(sys.stdout) sys.stderr = WithFlush(sys.stderr) From cfaa1f7ce653b4da61a0afce4d24adc93cfe7230 Mon Sep 17 00:00:00 2001 From: Nathan Heijermans Date: Tue, 2 Dec 2014 14:22:20 -0500 Subject: [PATCH 04/24] Replaced s.lstrip().rstrip() with s.strip(). --- ftplugin/python/vim_ipython.py | 8 +++----- 1 file changed, 3 insertions(+), 5 deletions(-) diff --git a/ftplugin/python/vim_ipython.py b/ftplugin/python/vim_ipython.py index a61dbfd..3243b6c 100644 --- a/ftplugin/python/vim_ipython.py +++ b/ftplugin/python/vim_ipython.py @@ -145,12 +145,10 @@ def km_from_string(s=''): # whether or not they are allowed to have spaces. I'll have to sync # up with the IPython team to address these issues -pi if '--profile' in s: - k,p = s.split('--profile') - k = k.lstrip().rstrip() # kernel part of the string - p = p.lstrip().rstrip() # profile part of the string - fullpath = find_connection_file(k,p) + k, p = s.split('--profile', 1) + fullpath = find_connection_file(k.strip(), p.strip()) else: - fullpath = find_connection_file(s.lstrip().rstrip()) + fullpath = find_connection_file(s.strip()) except IOError as e: echo(":IPython " + s + " failed", "Info") echo("^-- failed '" + s + "' not found", "Error") From 8d5f2e8e610ca0010c997bb2733ac92e341b3b0c Mon Sep 17 00:00:00 2001 From: Nathan Heijermans Date: Tue, 2 Dec 2014 14:38:35 -0500 Subject: [PATCH 05/24] Support for IPython 3. - IPython's shell_channel doesn't have the ``object_info`` attribute any more. - ``user_variables`` are going away. ``user_expressions`` remain, and provide the same type of interface back to the client. --- ftplugin/python/vim_ipython.py | 24 +++++++++++++----------- 1 file changed, 13 insertions(+), 11 deletions(-) diff --git a/ftplugin/python/vim_ipython.py b/ftplugin/python/vim_ipython.py index 3243b6c..9f386e6 100644 --- a/ftplugin/python/vim_ipython.py +++ b/ftplugin/python/vim_ipython.py @@ -180,15 +180,17 @@ def km_from_string(s=''): kc.start_channels() send = kc.shell_channel.execute - #XXX: backwards compatibility for IPython < 0.13 sc = kc.shell_channel - num_oinfo_args = len(inspect.getargspec(sc.object_info).args) - if num_oinfo_args == 2: - # patch the object_info method which used to only take one argument - klass = sc.__class__ - klass._oinfo_orig = klass.object_info - klass.object_info = lambda s,x,y: s._oinfo_orig(x) - + + # XXX: backwards compatibility for IPython < 0.13 + if hasattr(sc, 'object_info'): + num_oinfo_args = len(inspect.getargspec(sc.object_info).args) + if num_oinfo_args == 2: + # Patch the object_info method which used to only take one argument. + klass = sc.__class__ + klass._oinfo_orig = klass.object_info + klass.object_info = lambda s,x,y: s._oinfo_orig(x) + #XXX: backwards compatibility for IPython < 1.0 if not hasattr(kc, 'iopub_channel'): kc.iopub_channel = kc.sub_channel @@ -557,7 +559,7 @@ def set_pid(): """ global pid lines = '\n'.join(['import os', '_pid = os.getpid()']) - msg_id = send(lines, silent=True, user_variables=['_pid']) + msg_id = send(lines, silent=True, user_expressions={'_pid': '_pid'}) # wait to get message back from kernel try: @@ -566,9 +568,9 @@ def set_pid(): echo("no reply from IPython kernel") return try: - pid = int(child['content']['user_variables']['_pid']) + pid = int(child['content']['user_expressions']['_pid']) except TypeError: # change in IPython 1.0.dev moved this out - pid = int(child['content']['user_variables']['_pid']['data']['text/plain']) + pid = int(child['content']['user_expressions']['_pid']['data']['text/plain']) except KeyError: # change in IPython 1.0.dev moved this out echo("Could not get PID information, kernel not running Python?") return pid From 66d2ba70874728d9f511346d8e0f92eca460c09b Mon Sep 17 00:00:00 2001 From: Nathan Heijermans Date: Tue, 2 Dec 2014 14:51:32 -0500 Subject: [PATCH 06/24] More pedantic typographical/whitespace tweaks. --- ftplugin/python/vim_ipython.py | 10 ++++++---- 1 file changed, 6 insertions(+), 4 deletions(-) diff --git a/ftplugin/python/vim_ipython.py b/ftplugin/python/vim_ipython.py index 9f386e6..efc6776 100644 --- a/ftplugin/python/vim_ipython.py +++ b/ftplugin/python/vim_ipython.py @@ -33,7 +33,7 @@ class NoOp(object): def __getattribute__(self, key): return lambda *args: '0' vim = NoOp() - print("uh oh, not running inside vim") + print("Uh oh, not running inside Vim.") reselect = False # reselect lines after sending from Visual mode show_execution_count = True # wait to get numbers for In[43]: feedback? @@ -82,7 +82,6 @@ def vim_regex_escape(x): status_blank_lines = int(vim_variable('g:ipy_status_blank_lines', '1')) - ip = '127.0.0.1' # This allows us to load vim_ipython multiple times. try: @@ -110,6 +109,7 @@ def new_ipy(s=''): km.start_kernel() return km_from_string(km.connection_file) + def km_from_string(s=''): """create kernel manager from IPKernelApp string such as '--shell=47378 --iopub=39859 --stdin=36778 --hb=52668' for IPython 0.11 @@ -195,7 +195,7 @@ def km_from_string(s=''): if not hasattr(kc, 'iopub_channel'): kc.iopub_channel = kc.sub_channel - # now that we're connect to an ipython kernel, activate completion + # Now that we're connected to an IPython kernel, activate the completion # machinery, but do so only for the local buffer if the user added the # following line the vimrc: # let g:ipy_completefunc = 'local' @@ -206,7 +206,8 @@ def km_from_string(s=''): setl completefunc=CompleteIPython endif """) - # also activate GUI doc balloons if in gvim + + # Also activate GUI doc balloons if in gvim. vim.command(""" if has('balloon_eval') set bexpr=IPythonBalloonExpr() @@ -398,6 +399,7 @@ def update_subchannel_msgs(debug=False, force=False): #echo('skipping a message on sub_channel','WarningMsg') #echo(str(m)) continue + header = m['header']['msg_type'] if header == 'status': continue From 8e4e42d57b86b1fd772a2dccdb758a30e7a45d1c Mon Sep 17 00:00:00 2001 From: Nathan Heijermans Date: Tue, 2 Dec 2014 15:47:53 -0500 Subject: [PATCH 07/24] Add support dynamically enabling debug output messages. --- ftplugin/python/vim_ipython.py | 32 ++++++++++++++++++++------------ 1 file changed, 20 insertions(+), 12 deletions(-) diff --git a/ftplugin/python/vim_ipython.py b/ftplugin/python/vim_ipython.py index efc6776..d9a61e1 100644 --- a/ftplugin/python/vim_ipython.py +++ b/ftplugin/python/vim_ipython.py @@ -93,6 +93,22 @@ def vim_regex_escape(x): kc = None pid = None + +def echo(arg,style="Question"): + try: + vim.command("echohl %s" % style) + vim.command("echom \"%s\"" % arg.replace('\"','\\\"')) + vim.command("echohl None") + except vim.error: + print("-- %s" % arg) + + +def debug(s, style='Info'): + debug_enabled = vim_variable('g:ipy_enable_debug_output', False) + if bool(debug_enabled): + echo(s, style) + + def new_ipy(s=''): """Create a new IPython kernel (optionally with extra arguments) @@ -153,6 +169,7 @@ def km_from_string(s=''): echo(":IPython " + s + " failed", "Info") echo("^-- failed '" + s + "' not found", "Error") return + debug("Using connection File: {0}".format(fullpath)) km = KernelManager(connection_file = fullpath) km.load_connection_file() else: @@ -216,14 +233,6 @@ def km_from_string(s=''): set_pid() return km -def echo(arg,style="Question"): - try: - vim.command("echohl %s" % style) - vim.command("echom \"%s\"" % arg.replace('\"','\\\"')) - vim.command("echohl None") - except vim.error: - print("-- %s" % arg) - def disconnect(): "disconnect kernel manager" # XXX: make a prompt here if this km owns the kernel @@ -333,7 +342,7 @@ def vim_ipython_is_open(): return True return False -def update_subchannel_msgs(debug=False, force=False): +def update_subchannel_msgs(force=False): """ Grab any pending messages and place them inside the vim-ipython shell. This function will do nothing if the vim-ipython shell is not visible, @@ -395,9 +404,8 @@ def update_subchannel_msgs(debug=False, force=False): for m in msgs: s = '' if 'msg_type' not in m['header']: - # debug information - #echo('skipping a message on sub_channel','WarningMsg') - #echo(str(m)) + debug('skipping a message on sub_channel', 'WarningMsg') + debug(str(m)) continue header = m['header']['msg_type'] From 45fba4af31524a608fdd389306a4c3eaa0d7ebe2 Mon Sep 17 00:00:00 2001 From: Nathan Heijermans Date: Tue, 2 Dec 2014 15:54:42 -0500 Subject: [PATCH 08/24] Corrected more typographical errors. --- ftplugin/python/vim_ipython.py | 18 +++++++++--------- 1 file changed, 9 insertions(+), 9 deletions(-) diff --git a/ftplugin/python/vim_ipython.py b/ftplugin/python/vim_ipython.py index d9a61e1..3f7af68 100644 --- a/ftplugin/python/vim_ipython.py +++ b/ftplugin/python/vim_ipython.py @@ -41,11 +41,11 @@ def __getattribute__(self, key): run_flags= "-i" # flags to for IPython's run magic when using current_line = '' -# Get around unicode problems when interfacing with Vim. +# Get around Unicode problems when interfacing with Vim. vim_encoding=vim.eval('&encoding') or 'utf-8' # IPython complains if stderr and stdout don't have flush. This is fixed in -# newer version of Vim. +# newer versions of Vim. if not hasattr(sys.stdout, 'flush'): class WithFlush(object): def __init__(self,noflush): @@ -243,7 +243,7 @@ def get_doc(word, level=0): return ["Not connected to IPython, cannot query: %s" % word] msg_id = kc.shell_channel.object_info(word, level) doc = get_doc_msg(msg_id) - # Get around unicode problems when interfacing with Vim. + # Get around Unicode problems when interfacing with Vim. return [d.encode(vim_encoding) for d in doc] # from http://serverfault.com/questions/71285/in-centos-4-4-how-can-i-strip-escape-sequences-from-a-text-file @@ -321,12 +321,12 @@ def ipy_complete(base, current_line, pos): m = get_child_msg(msg_id) matches = m['content']['matches'] matches.insert(0,base) # the "no completion" version - # We need to be careful with unicode, because we can have unicode + # We need to be careful with Unicode, because we can have Unicode # completions for filenames (for the %run magic, for example). So the next # line will fail on those: #completions= [str(u) for u in matches] # because str() won't work for non-ascii characters - # we also have problems with unicode in Vim, hence the following: + # we also have problems with Unicode in Vim, hence the following: return matches except Empty: echo("no reply from IPython kernel") @@ -420,13 +420,13 @@ def update_subchannel_msgs(force=False): s = status_prompt_out % {'line': m['content']['execution_count']} s += m['content']['data']['text/plain'] elif header == 'display_data': - # TODO: handle other display data types (HMTL? images?) + # TODO: handle other display data types (HTML? images?) s += m['content']['data']['text/plain'] elif header == 'pyin': - # TODO: the next line allows us to resend a line to ipython if + # TODO: the next line allows us to resend a line to IPython if # %doctest_mode is on. In the future, IPython will send the # execution_count on subchannel, so this will need to be updated - # once that happens + # once that happens. line_number = m['content'].get('execution_count', 0) prompt = status_prompt_in % {'line': line_number} s = prompt @@ -440,7 +440,7 @@ def update_subchannel_msgs(force=False): s += c['ename'] + ":" + c['evalue'] if s.find('\n') == -1: - # somewhat ugly unicode workaround from + # somewhat ugly Unicode workaround from # http://vim.1045645.n5.nabble.com/Limitations-of-vim-python-interface-with-respect-to-character-encodings-td1223881.html if isinstance(s,unicode): s=s.encode(vim_encoding) From 7dfe43a24dd3ce0e60e895a99c30020266f24292 Mon Sep 17 00:00:00 2001 From: Nathan Heijermans Date: Tue, 2 Dec 2014 16:06:42 -0500 Subject: [PATCH 09/24] Support for Python 3. - Adjusted update_channel_messages() to support changes to the message types and contents. - Added debug output to help catch unhandled messages. --- ftplugin/python/vim_ipython.py | 14 +++++++++++--- 1 file changed, 11 insertions(+), 3 deletions(-) diff --git a/ftplugin/python/vim_ipython.py b/ftplugin/python/vim_ipython.py index 3f7af68..ce7ba2f 100644 --- a/ftplugin/python/vim_ipython.py +++ b/ftplugin/python/vim_ipython.py @@ -409,20 +409,25 @@ def update_subchannel_msgs(force=False): continue header = m['header']['msg_type'] + if header == 'status': continue elif header == 'stream': # TODO: allow for distinguishing between stdout and stderr (using # custom syntax markers in the vim-ipython buffer perhaps), or by # also echoing the message to the status bar - s = strip_color_escapes(m['content']['data']) - elif header == 'pyout': + field_name = 'data' + if field_name not in m['content']: + field_name = 'text' + field_name = 'data' if 'data' in m['content'] else 'text' + s = strip_color_escapes(m['content'][field_name]) + elif header in ['pyout', 'execute_result']: s = status_prompt_out % {'line': m['content']['execution_count']} s += m['content']['data']['text/plain'] elif header == 'display_data': # TODO: handle other display data types (HTML? images?) s += m['content']['data']['text/plain'] - elif header == 'pyin': + elif header in ['pyin', 'execute_input']: # TODO: the next line allows us to resend a line to IPython if # %doctest_mode is on. In the future, IPython will send the # execution_count on subchannel, so this will need to be updated @@ -438,6 +443,9 @@ def update_subchannel_msgs(force=False): c = m['content'] s = "\n".join(map(strip_color_escapes,c['traceback'])) s += c['ename'] + ":" + c['evalue'] + else: + debug('Unexpected message type {0}'.format(header)) + debug(str(m)) if s.find('\n') == -1: # somewhat ugly Unicode workaround from From 194b0c0b316af8e42ca0cfa713fe896f9ca455bd Mon Sep 17 00:00:00 2001 From: Nathan Heijermans Date: Tue, 2 Dec 2014 16:08:38 -0500 Subject: [PATCH 10/24] Renamed variable for clarification. --- ftplugin/python/vim_ipython.py | 16 ++++++++-------- 1 file changed, 8 insertions(+), 8 deletions(-) diff --git a/ftplugin/python/vim_ipython.py b/ftplugin/python/vim_ipython.py index ce7ba2f..6bd9455 100644 --- a/ftplugin/python/vim_ipython.py +++ b/ftplugin/python/vim_ipython.py @@ -408,11 +408,11 @@ def update_subchannel_msgs(force=False): debug(str(m)) continue - header = m['header']['msg_type'] + msg_type = m['header']['msg_type'] - if header == 'status': + if msg_type == 'status': continue - elif header == 'stream': + elif msg_type == 'stream': # TODO: allow for distinguishing between stdout and stderr (using # custom syntax markers in the vim-ipython buffer perhaps), or by # also echoing the message to the status bar @@ -421,13 +421,13 @@ def update_subchannel_msgs(force=False): field_name = 'text' field_name = 'data' if 'data' in m['content'] else 'text' s = strip_color_escapes(m['content'][field_name]) - elif header in ['pyout', 'execute_result']: + elif msg_type in ['pyout', 'execute_result']: s = status_prompt_out % {'line': m['content']['execution_count']} s += m['content']['data']['text/plain'] - elif header == 'display_data': + elif msg_type == 'display_data': # TODO: handle other display data types (HTML? images?) s += m['content']['data']['text/plain'] - elif header in ['pyin', 'execute_input']: + elif msg_type in ['pyin', 'execute_input']: # TODO: the next line allows us to resend a line to IPython if # %doctest_mode is on. In the future, IPython will send the # execution_count on subchannel, so this will need to be updated @@ -439,12 +439,12 @@ def update_subchannel_msgs(force=False): dots = '.' * len(prompt.rstrip()) dots += prompt[len(prompt.rstrip()):] s += m['content']['code'].rstrip().replace('\n', '\n' + dots) - elif header == 'pyerr': + elif msg_type == 'pyerr': c = m['content'] s = "\n".join(map(strip_color_escapes,c['traceback'])) s += c['ename'] + ":" + c['evalue'] else: - debug('Unexpected message type {0}'.format(header)) + debug('Unexpected message type {0}'.format(msg_type)) debug(str(m)) if s.find('\n') == -1: From ddb7cb5e5463515f6716950b8e51671a7bfc86e3 Mon Sep 17 00:00:00 2001 From: Nathan Heijermans Date: Tue, 2 Dec 2014 18:35:12 -0500 Subject: [PATCH 11/24] Updated README.rst to use proper names when appropriate. --- README.rst | 34 +++++++++++++++++----------------- 1 file changed, 17 insertions(+), 17 deletions(-) diff --git a/README.rst b/README.rst index c7ff5f2..086260a 100644 --- a/README.rst +++ b/README.rst @@ -18,12 +18,12 @@ IPython. The big change from previous versions of ``ipy.vim`` is that it no longer requires the old brittle ``ipy_vimserver.py`` instantiation, and since -it uses just vim and python, it is platform independent (i.e. works -even on windows, unlike the previous \*nix only solution). The requirements -are IPython 0.11 or newer with zeromq capabilities, vim compiled with +python. +it uses just Vim and Python, it is platform independent (i.e. works +even on Windows, unlike the previous \*nix only solution). The requirements +are IPython 0.11 or newer with ZeroMQ capabilities, Vim compiled with +python. If you can launch ``ipython qtconsole`` or ``ipython kernel``, and -``:echo has('python')`` returns 1 in vim, you should be good to go. +``:echo has('python')`` returns 1 in Vim, you should be good to go. ----------------- Quickstart Guide: @@ -119,7 +119,7 @@ IPython's object? Functionality ------------------------------- If you're using gvim, mouse-over a variable to see IPython's ``?`` equivalent. -If you're using vim from a terminal, or want to copy something from the +If you're using Vim from a terminal, or want to copy something from the docstring, type ``d``. ```` is usually ``\`` (the backslash key). This will open a quickpreview window, which can be closed by hitting ``q`` or ````. @@ -128,7 +128,7 @@ key). This will open a quickpreview window, which can be closed by hitting IPython's tab-completion Functionality -------------------------------------- vim-ipython activates a 'completefunc' that queries IPython. -A completefunc is activated using ``Ctrl-X Ctrl-U`` in Insert Mode (vim +A completefunc is activated using ``Ctrl-X Ctrl-U`` in Insert Mode (Vim default). You can combine this functionality with SuperTab to get tab completion. @@ -146,7 +146,7 @@ If at any later time you wish to bring this shell up, including if you've set ``monitor_subchannel=False``, hit ``s``. **NEW since IPython 0.12** -For local kernels (kernels running on the same machine as vim), `Ctrl-C` in +For local kernels (kernels running on the same machine as Vim), `Ctrl-C` in the vim-ipython 'shell' sends an keyboard interrupt. (Note: this feature may not work on Windows, please report the issue to ). @@ -208,7 +208,7 @@ Known issues: - For now, vim-ipython only connects to an ipython session in progress. - The standard ipython clients (console, qtconsole, notebook) do not currently display the result of computation which they did not initialize. This means - that if you send print statements for execution from within vim, they will + that if you send print statements for execution from within Vim, they will only be shown inside the vim-ipython shell buffer, but **not** within any of the standard clients. This is not a limitation of vim-ipython, but a limitation of those built-in clients, see `ipython/ipython#1873 @@ -217,16 +217,16 @@ Known issues: [IPython PR #3089](https://github.com/ipython/ipython/pull/3089) - If ```` does not work inside your terminal, but you are able to run some of the other commands successfully (````, for example), try running - this command before launching vim in the terminal (add it to your + this command before launching Vim in the terminal (add it to your ``.bashrc`` if it fixes the issue):: stty stop undef # to unmap ctrl-s -- In vim, if you're getting ``ImportError: No module named +- In Vim, if you're getting ``ImportError: No module named IPython.zmq.blockingkernelmanager`` but are able to import it in regular - python, **either** + Python, **either** - 1. your ``sys.path`` in vim differs from the ``sys.path`` in regular python. + 1. your ``sys.path`` in Vim differs from the ``sys.path`` in regular Python. Try running these two lines, and comparing their output files:: $ vim -c 'py import vim, sys; vim.current.buffer.append(sys.path)' -c ':wq vim_syspath' @@ -234,13 +234,13 @@ Known issues: **or** - 2. your vim is compiled against a different python than you are launching. See + 2. your Vim is compiled against a different Python than you are launching. See if there's a difference between :: $ vim -c ':py import os; print os.__file__' -c ':q' $ python -c 'import os; print os.__file__' -- For vim inside a terminal, using the arrow keys won't work inside a +- For Vim inside a terminal, using the arrow keys won't work inside a documentation buffer, because the mapping for ```` overlaps with ``^[OA`` and so on, and we use ```` as a quick way of closing the documentation preview window. If you want go without this quick close @@ -269,12 +269,12 @@ pull request with your attribution. * @minrk for guiding me through the IPython kernel manager protocol, and support of connection_file-based IPython connection (#13), and keeping vim-ipython working across IPython API changes. -* @nakamuray and @tcheneau for reporting and providing a fix for when vim is +* @nakamuray and @tcheneau for reporting and providing a fix for when Vim is compiled without a gui (#1) * @unpingco for reporting Windows bugs (#3,#4), providing better multiline dedenting (#15), and suggesting that a resized vim-ipython shell stays resized (#16). -* @simon-b for terminal vim arrow key issue (#5) +* @simon-b for terminal Vim arrow key issue (#5) * @jorgesca and @kwgoodman for shell update problems (#6) * @xowlinx and @vladimiroff for Ctrl-S issues in Konsole (#8) * @zeekay for easily allowing custom mappings (#9) @@ -282,7 +282,7 @@ pull request with your attribution. only open updating 'shell' if it is open (#29) * @enzbang for removing mapping that's not currently functional (#17) * @ogrisel for fixing documentation typo (#19) -* @koepsell for gracefully exiting in case python is not available (#23) +* @koepsell for gracefully exiting in case Python is not available (#23) * @mrterry for activating completefunc only after a connection is made (#25), Ctrl-C implementation in vim-ipython 'shell' (#28) * @nonameentername for completion on import statements (#26) From b8b30160bf4fbca79f7200d13871835d24e2abd8 Mon Sep 17 00:00:00 2001 From: Nathan Heijermans Date: Tue, 2 Dec 2014 18:37:03 -0500 Subject: [PATCH 12/24] Support for Python 3.0. Tell folks that vim-ipython supports IPython 3.x too. --- README.rst | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.rst b/README.rst index 086260a..5478e36 100644 --- a/README.rst +++ b/README.rst @@ -4,7 +4,7 @@ vim-ipython A two-way integration between Vim and IPython. -IPython versions 0.11.x, 0.12.x, 0.13.x, 1.x and 2.x +Supports IPython versions 0.11.x, 0.12.x, 0.13.x, 1.x, 2.x and 3.x. * author: Paul Ivanov (http://pirsquared.org) * github: http://github.com/ivanov/vim-ipython From f51bdf279eff3f16bce3a9b05cc7065a31cb8519 Mon Sep 17 00:00:00 2001 From: Nathan Heijermans Date: Tue, 2 Dec 2014 18:40:51 -0500 Subject: [PATCH 13/24] Updated README.rst to use proper names when appropriate. --- README.rst | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/README.rst b/README.rst index 5478e36..daf0798 100644 --- a/README.rst +++ b/README.rst @@ -205,8 +205,8 @@ editor and REPL combination. --------------- Known issues: --------------- -- For now, vim-ipython only connects to an ipython session in progress. -- The standard ipython clients (console, qtconsole, notebook) do not currently +- For now, vim-ipython only connects to an IPython session in progress. +- The standard IPython clients (console, qtconsole, notebook) do not currently display the result of computation which they did not initialize. This means that if you send print statements for execution from within Vim, they will only be shown inside the vim-ipython shell buffer, but **not** within any of @@ -301,7 +301,7 @@ Similar Projects * `screen.vba`_ - Simulate a split shell, using GNU Screen / tmux, that you can send commands to (Eric Van Dewoestine) * `vimux`_ - vim plugin to interact with tmux (Ben Mills) -* `vimux-pyutils`_ - send code to tmux ipython session (Julien Rebetez) +* `vimux-pyutils`_ - send code to tmux IPython session (Julien Rebetez) * conque_ - terminal emulator which uses a Vim buffer to display the program output (Nico Raffo) * `ipyqtmacvim`_ - plugin to send commands from MacVim to IPython Qt console From bf567f9949489effe4b177563b5633d1dd8456b9 Mon Sep 17 00:00:00 2001 From: Nathan Heijermans Date: Tue, 2 Dec 2014 19:00:46 -0500 Subject: [PATCH 14/24] Support Python 3.0 error messages. --- ftplugin/python/vim_ipython.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/ftplugin/python/vim_ipython.py b/ftplugin/python/vim_ipython.py index 6bd9455..3c99238 100644 --- a/ftplugin/python/vim_ipython.py +++ b/ftplugin/python/vim_ipython.py @@ -439,7 +439,7 @@ def update_subchannel_msgs(force=False): dots = '.' * len(prompt.rstrip()) dots += prompt[len(prompt.rstrip()):] s += m['content']['code'].rstrip().replace('\n', '\n' + dots) - elif msg_type == 'pyerr': + elif msg_type in ['pyerr', 'error']: c = m['content'] s = "\n".join(map(strip_color_escapes,c['traceback'])) s += c['ename'] + ":" + c['evalue'] From a518b69f74fa60f146996cce317ddeccdecfcf90 Mon Sep 17 00:00:00 2001 From: Nathan Heijermans Date: Sat, 6 Dec 2014 17:27:29 -0500 Subject: [PATCH 15/24] Tweaks to try to pin-point travis CI failures. --- test/simple.vader | 14 +++++++++++--- 1 file changed, 11 insertions(+), 3 deletions(-) diff --git a/test/simple.vader b/test/simple.vader index dfc831f..0ed6036 100644 --- a/test/simple.vader +++ b/test/simple.vader @@ -25,13 +25,21 @@ Expect: Hello True -Execute python (check vim_ipython import): + +Before (set filetype to Python): + filetype plugin on + set ft=python + +Execute python (Ensure vim_python ftplugin loads): import vim - vim.command("set ft=python") + vim.current.buffer.append("filetype is " + vim.eval("&ft")) + vim.current.buffer.append("IPython command exists: " + vim.eval("exists(':IPython') != 0")) vim.command("IPython") import vim_ipython - current.buffer.append("vim_ipython loaded") + vim.current.buffer.append("vim_ipython loaded") Expect: Hello + filetype is python + IPython command exists: 1 vim_ipython loaded From 9a3add84ba4b1407bc0608afb13ef24de49182f5 Mon Sep 17 00:00:00 2001 From: Nathan Heijermans Date: Sun, 7 Dec 2014 15:51:55 -0500 Subject: [PATCH 16/24] Print out the Python version, too. --- .travis.yml | 1 + 1 file changed, 1 insertion(+) diff --git a/.travis.yml b/.travis.yml index 8a554ea..2ab440e 100644 --- a/.travis.yml +++ b/.travis.yml @@ -4,6 +4,7 @@ before_script: | git clone https://github.com/junegunn/vader.vim.git script: | + python -V vim -Nu <(cat << VIMRC filetype off set rtp+=vader.vim From f2d15a0a51cf4abba23b34bc569d967e66507d52 Mon Sep 17 00:00:00 2001 From: Nathan Heijermans Date: Sun, 7 Dec 2014 16:34:56 -0500 Subject: [PATCH 17/24] Added logging to Vader test script. --- test/simple.vader | 59 ++++++++++++++++++++++++++++++++--------------- 1 file changed, 41 insertions(+), 18 deletions(-) diff --git a/test/simple.vader b/test/simple.vader index 0ed6036..088b7af 100644 --- a/test/simple.vader +++ b/test/simple.vader @@ -1,12 +1,26 @@ Given (): Hello -Execute python ( check Python support ): - import os - import vim - from vim import current, vars - vim.command('normal! yy2p') - current.buffer.append(os.path.basename(vars['vader_file'])) +Execute (Make sure Vim actually works.): + Log "Run simple 'put' test." + let t="Vim is working." + put =t + Log "Done." + +Expect: + Hello + Vim is working. + + +Execute (Check Python support ): + Assert has('python') == 1, 'FAIL: Vim must have Python support.' + Log 'Import modules.' + python import os + python import vim + Log 'Yank/paste current line.' + python vim.command('normal! yy2p') + python vim.current.buffer.append(os.path.basename(vim.vars['vader_file'])) + Log 'Done.' Expect: Hello @@ -15,11 +29,14 @@ Expect: simple.vader -Execute python (check IPython import): - import vim - from vim import current, vars - import IPython - current.buffer.append(str(IPython.version_info[0] >= 1)) +Execute (Check IPython): + Assert has('python') == 1, 'FAIL: Vim must have Python support.' + python import vim + Log 'Import IPython.' + python import IPython + Log 'Check IPython version >= 1.' + python vim.current.buffer.append(str(IPython.version_info[0] >= 1)) + Log 'Done.' Expect: Hello @@ -27,16 +44,22 @@ Expect: Before (set filetype to Python): + Log 'Enable filetype plugin.' filetype plugin on + Log 'Set filetype=python.' set ft=python + Log '[before] done.' -Execute python (Ensure vim_python ftplugin loads): - import vim - vim.current.buffer.append("filetype is " + vim.eval("&ft")) - vim.current.buffer.append("IPython command exists: " + vim.eval("exists(':IPython') != 0")) - vim.command("IPython") - import vim_ipython - vim.current.buffer.append("vim_ipython loaded") +Execute (Ensure vim_python ftplugin loads): + Assert has('python') == 1, 'FAIL: Vim must have Python support.' + python import vim + python vim.current.buffer.append("filetype is " + vim.eval("&ft")) + AssertEqual 'python', &filetype + python vim.current.buffer.append("IPython command exists: " + vim.eval("exists(':IPython') != 0")) + python vim.command("IPython") + python import vim_ipython + python vim.current.buffer.append("vim_ipython loaded") + Log 'Done.' Expect: Hello From c33e5aaef92940360e2025d0c77060a933a8408b Mon Sep 17 00:00:00 2001 From: Nathan Heijermans Date: Sun, 7 Dec 2014 16:47:12 -0500 Subject: [PATCH 18/24] Debugging: Add list of Vim variables to output. --- test/simple.vader | 2 ++ 1 file changed, 2 insertions(+) diff --git a/test/simple.vader b/test/simple.vader index 088b7af..8830991 100644 --- a/test/simple.vader +++ b/test/simple.vader @@ -19,6 +19,8 @@ Execute (Check Python support ): python import vim Log 'Yank/paste current line.' python vim.command('normal! yy2p') + Log 'Add name of vader script to file' + python vim.current.buffer.append(["{}={}".format(k, v) for k, v in vim.vars.items()]) python vim.current.buffer.append(os.path.basename(vim.vars['vader_file'])) Log 'Done.' From f8da199741e5687bd02f2fbf283e1264d152c793 Mon Sep 17 00:00:00 2001 From: Nathan Heijermans Date: Sun, 7 Dec 2014 19:58:52 -0500 Subject: [PATCH 19/24] Add IPython to the mix. --- .travis.yml | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/.travis.yml b/.travis.yml index 2ab440e..335cbf5 100644 --- a/.travis.yml +++ b/.travis.yml @@ -2,13 +2,13 @@ language: vim before_script: | git clone https://github.com/junegunn/vader.vim.git + git clone https://github.com/ipython/ipython.git script: | - python -V - vim -Nu <(cat << VIMRC + PYTHONPATH=ipython python -m IPython console & + PYTHONPATH=../ipython vim -Nu <(cat << VIMRC filetype off set rtp+=vader.vim set rtp+=. - set rtp+=after filetype plugin indent on VIMRC) -c 'Vader! test/*' > /dev/null From c499d3178e63e6ffaaab58afb6e0cc62ea3d3f7b Mon Sep 17 00:00:00 2001 From: Nathan Heijermans Date: Sun, 7 Dec 2014 20:00:08 -0500 Subject: [PATCH 20/24] Noted: Python support test is broken in < Vim 7.4. --- test/simple.vader | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/test/simple.vader b/test/simple.vader index 8830991..9783342 100644 --- a/test/simple.vader +++ b/test/simple.vader @@ -12,7 +12,9 @@ Expect: Vim is working. -Execute (Check Python support ): +Execute (FIXME: Check Python support.): + " Note: vim.vars didn't make it into Vim until version 7.4. The commands + " below might not work. Assert has('python') == 1, 'FAIL: Vim must have Python support.' Log 'Import modules.' python import os @@ -20,7 +22,6 @@ Execute (Check Python support ): Log 'Yank/paste current line.' python vim.command('normal! yy2p') Log 'Add name of vader script to file' - python vim.current.buffer.append(["{}={}".format(k, v) for k, v in vim.vars.items()]) python vim.current.buffer.append(os.path.basename(vim.vars['vader_file'])) Log 'Done.' @@ -31,7 +32,7 @@ Expect: simple.vader -Execute (Check IPython): +Execute (Check IPython.): Assert has('python') == 1, 'FAIL: Vim must have Python support.' python import vim Log 'Import IPython.' From 8959cb51dffcd2c0e8044bf3e79734294e4fff3a Mon Sep 17 00:00:00 2001 From: Nathan Heijermans Date: Sun, 7 Dec 2014 20:04:28 -0500 Subject: [PATCH 21/24] Install python-zmq, fix PYTHONPATH used for Vim call. --- .travis.yml | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/.travis.yml b/.travis.yml index 335cbf5..b168d81 100644 --- a/.travis.yml +++ b/.travis.yml @@ -1,12 +1,16 @@ language: vim +before_install: | + sudo apt-get update -qq + sudo apt-get install python-zmq + before_script: | git clone https://github.com/junegunn/vader.vim.git git clone https://github.com/ipython/ipython.git script: | PYTHONPATH=ipython python -m IPython console & - PYTHONPATH=../ipython vim -Nu <(cat << VIMRC + PYTHONPATH=ipython vim -Nu <(cat << VIMRC filetype off set rtp+=vader.vim set rtp+=. From f4fcd8f3b629203cf581576d384c4c4c076d0f95 Mon Sep 17 00:00:00 2001 From: Nathan Heijermans Date: Sun, 7 Dec 2014 20:08:26 -0500 Subject: [PATCH 22/24] Try installing pyzmq another way. --- .travis.yml | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/.travis.yml b/.travis.yml index b168d81..436c56f 100644 --- a/.travis.yml +++ b/.travis.yml @@ -2,7 +2,8 @@ language: vim before_install: | sudo apt-get update -qq - sudo apt-get install python-zmq + sudo apt-get install python-pip + sudo pip install --upgrade pyzmq before_script: | git clone https://github.com/junegunn/vader.vim.git From 2e6208c7c6e4cc8cabeeaee21ce775495481dd41 Mon Sep 17 00:00:00 2001 From: Nathan Heijermans Date: Wed, 10 Dec 2014 22:38:47 -0500 Subject: [PATCH 23/24] Added Vader test to exercise IPython round trip. --- test/simple.vader | 33 +++++++++++++++++++++++++++++++++ 1 file changed, 33 insertions(+) diff --git a/test/simple.vader b/test/simple.vader index 9783342..e08e7a2 100644 --- a/test/simple.vader +++ b/test/simple.vader @@ -69,3 +69,36 @@ Expect: filetype is python IPython command exists: 1 vim_ipython loaded + + +Given (): + " ".join(["Vim", "+", "IPython", "==", "nifty"]) + +Before (set filetype to Python): + filetype plugin on + set ft=python + IPython + +Execute (Run a command and get its result from the preview window.): + python import vim_ipython + Log 'Restarting kernel to reset execution counter.' + python vim_ipython.kc.shutdown(True) + Log 'Running current line: `' . getline('.') .'`' + python vim_ipython.run_this_line() + Log 'Copying results from preview window.' + " Switch to the preview window, move to the line with the "In []" command, + " then delete all the output + wincmd P + normal gg + /^In \+\[ + normal VGd + " Switch back to the previous window, and paste the output. + wincmd p + normal p + Log 'Done.' + +Expect (): + " ".join(["Vim", "+", "IPython", "==", "nifty"]) + In [1]: " ".join(["Vim", "+", "IPython", "==", "nifty"]) + Out[1]: 'Vim + IPython == nifty' + From cb0a3caa9c2e93830ff403616cb172b8de3a2311 Mon Sep 17 00:00:00 2001 From: Nathan Heijermans Date: Wed, 10 Dec 2014 22:51:16 -0500 Subject: [PATCH 24/24] Run an IPython notebook instead of the console app. --- .travis.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.travis.yml b/.travis.yml index 436c56f..c4ee499 100644 --- a/.travis.yml +++ b/.travis.yml @@ -10,7 +10,7 @@ before_script: | git clone https://github.com/ipython/ipython.git script: | - PYTHONPATH=ipython python -m IPython console & + PYTHONPATH=ipython python -m IPython notebook --no-browser & PYTHONPATH=ipython vim -Nu <(cat << VIMRC filetype off set rtp+=vader.vim