From e04eb424b1ef1cea26f6abdd8637803839dddad6 Mon Sep 17 00:00:00 2001 From: Tomas Protivinsky Date: Thu, 2 Jan 2020 16:04:05 +0100 Subject: [PATCH] Fixing visual mode and bracketed paste (#23) * fixing visual mode and bracketed paste * keeping bracketed paste as default * Added marks to ensure correct cursor positioning * Changed register x to unnamed register * Made a global default and updated documentation Co-authored-by: Will Handley --- README.rst | 144 ++++++++++++++++++++++---------------- autoload/vimteractive.vim | 5 +- doc/vimteractive.txt | 76 +++++++++++--------- plugin/vimteractive.vim | 5 +- 4 files changed, 134 insertions(+), 96 deletions(-) diff --git a/README.rst b/README.rst index 065a2ef..ee9dea0 100644 --- a/README.rst +++ b/README.rst @@ -3,46 +3,49 @@ Vimteractive ============ :vimteractive: send commands from text files to interactive programs via vim :Author: Will Handley -:Version: 2.2.0 +:Version: 2.2.1 :Homepage: https://github.com/williamjameshandley/vimteractive :Documentation: ``:help vimteractive`` Vimteractive was inspired by the workflow of the `vim-ipython `__ plugin. -This plugin is designed to extend a subset of the functionality of -vim-ipython to other interpreters (including ipython). It is based -around the unix philosophy of `"do one thing and do it -well" `__. +This plugin is designed to extend a subset of the functionality of vim-ipython +to other interpreters (including ipython). It is based around the unix +philosophy of `"do one thing and do it well" `__. Vimteractive aims to provide a robust and simple link between text files and interactive interpreters. Vimteractive will never aim to do things like autocompletion, leaving that to other, more developed tools such as -`YouCompleteMe `__. +`YouCompleteMe `__ or +`TabNine ``. The activating commands are - ipython ``:Iipython`` -- python ``:Ipython`` - julia ``:Ijulia`` - maple ``:Imaple`` - bash ``:Ibash`` - zsh ``:Izsh`` +- python ``:Ipython`` - clojure ``:Iclojure`` - autodetect based on filetype ``:Iterm`` -Commands may be sent from a text file to the chosen terminal using -``CTRL-S``. If there is no terminal, ``CTRL-S`` will automatically -open one for you using ``:Iterm``. +Commands may be sent from a text file to the chosen terminal using ``CTRL-S``. +If there is no terminal, ``CTRL-S`` will automatically open one for you using +``:Iterm``. + +Note: it's highly recommended to use IPython as your default Python +interpreter. You can set it like this: + +.. code:: vim -It's highly recommended to set your default Python shell to IPython -(see "Extending functionality" section for instructions). If you prefer -not to do it, make sure, that every top-level block has at least one newline -after it. + let g:vimteractive_default_shells = { 'python': 'ipython' } Installation ------------ -Since this package leverages the native vim interactive terminal, vimteractive is only compatible with vim 8 or greater. +Since this package leverages the native vim interactive terminal, vimteractive +is only compatible with vim 8 or greater. To use the key-bindings, you should first disable the ``CTRL-S`` default, which is a terminal command to freeze the output. You can @@ -71,22 +74,21 @@ Motivation ---------- `IPython and Jupyter `__ are excellent tools for -exploratory analyses in python. They leverage the interactivity of the -python kernel to allow you to keep results of calculations in memory -whilst developing further code to process them. - -However, I can't stand typing into anything other than vim. Anywhere -else, my screen fills with hjklEB, or worse, I close the window with a -careless ````. I want a technique that allows me to operate on -plain text files, but still be able to work interactively with the -interpreter with minimal effort. - -`Many Projects <#similar-projects>`__ achieve this with a varying level -of functionality. Vimteractive aims to create the simplest tool for -sending things from text to interpreter, and making it easy to add -additional interpreters. In particular, my main aim in starting this was -to get a vim-ipython like interface to the command line -`maple `__. +exploratory analyses in python. They leverage the interactivity of the python +kernel to allow you to keep results of calculations in memory whilst developing +further code to process them. + +However, I can't stand typing into anything other than vim. Anywhere else, my +screen fills with hjklEB, or worse, I close the window with a careless +````. I want a technique that allows me to operate on plain text files, +but still be able to work interactively with the interpreter with minimal +effort. + +`Many Projects <#similar-projects>`__ achieve this with a varying level of +functionality. Vimteractive aims to create the simplest tool for sending things +from text to interpreter, and making it easy to add additional interpreters. In +particular, my main aim in starting this was to get a vim-ipython like +interface to the command line `maple `__. Usage ----- @@ -110,69 +112,91 @@ Create a python file ``test.py`` with the following content: ax.set_xlabel('$x$') ax.set_ylabel('$y$') -Now start an ipython interpreter in vim with ``:Iipython``. You should -see a preview window open above with your ipython prompt. Position your -cursor over the first line of ``test.py``, and press -``CTRL-S``. You should see this line now appear in the first prompt of -the preview window. Do the same with the second and fourth lines. At the -fourth line, you should see a figure appear once it's constructed with -``plt.subplots()``. Continue by sending lines to the interpreter. You -can send multiple lines by doing a visual selection and pressing -``CTRL-S``. - -If you switch windows with ``CTRL-W+k``, you will see the terminal -buffer switch to a more usual looking normal-mode buffer, from which you -can perform traditional normal mode commands. However, if you try to -insert, you will enter the terminal, and be able to enter commands -interactively into the prompt as if you had run it in the command line. -You can save this buffer if you wish to a new file if it contains -valuable output +Now start an ipython interpreter in vim with ``:Iipython``. You should see a +preview window open above with your ipython prompt. Position your cursor over +the first line of ``test.py``, and press ``CTRL-S``. You should see this line +now appear in the first prompt of the preview window. Do the same with the +second and fourth lines. At the fourth line, you should see a figure appear +once it's constructed with ``plt.subplots()``. Continue by sending lines to the +interpreter. You can send multiple lines by doing a visual selection and +pressing ``CTRL-S``. + +If you switch windows with ``CTRL-W+k``, you will see the terminal buffer +switch to a more usual looking normal-mode buffer, from which you can perform +traditional normal mode commands. However, if you try to insert, you will enter +the terminal, and be able to enter commands interactively into the prompt as if +you had run it in the command line. You can save this buffer if you wish to a +new file if it contains valuable output You may want to send lines to one terminal from two buffers. To achieve that, run ``:Iconn `` where ```` is a name of buffer -containing terminal. If there is only one terminal, you can use just ``:Iconn``. +containing terminal. If there is only one terminal, you can use just +``:Iconn``. Supported terminals ~~~~~~~~~~~~~~~~~~~ - ``:Iipython`` Activate an ipython terminal -- ``:Ipython`` Activate a python terminal - ``:Ijulia`` Activate a julia terminal - ``:Imaple`` Activate a maple terminal - ``:Ibash`` Activate a bash terminal - ``:Izsh`` Activate a zsh terminal +- ``:Ipython`` Activate a python terminal - ``:Iclojure`` Activate a clojure terminal - ``:Iterm`` Activate default terminal for this filetype Sending commands ~~~~~~~~~~~~~~~~ -``CTRL-S`` sends lines of text to the interpreter in a mode-dependent -manner: +``CTRL-S`` sends lines of text to the interpreter in a mode-dependent manner: -In Normal mode, ``CTRL-S`` sends the line currently occupied by the -cursor the terminal. +In Normal mode, ``CTRL-S`` sends the line currently occupied by the cursor the +terminal. -In Insert mode, ``CTRL-S`` sends the line currently being edited, and -then returns to insert mode at the same location. +In Insert mode, ``CTRL-S`` sends the line currently being edited, and then +returns to insert mode at the same location. In Visual mode, ``CTRL-S`` sends the current selection to the terminal. ``ALT-S`` sends all lines from the start to the current line. +Connecting to an existing terminal +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + +``:Iconn [{buffer]`` connects current buffer to REPL in ``{buffer}``. You can +connect any number of buffers to one REPL. ``{buffer}`` can be omitted if there +is only one terminal. + + +Common issues +------------- + +Bracketed paste +~~~~~~~~~~~~~~~ + +If you see strange symbols like ``^[[200~`` when sending lines to your new +interpreter, you may be on an older system which does not have bracketed paste +enabled, or have other shell misbehaviour issues. You can change the default +setting with + +.. code:: vim + + let g:vimteractive_bracketed_paste_default = 0 + + Options -~~~~~~~ +------- These options can be put in your ``.vimrc``, or run manually as desired: .. code:: vim - let g:vimteractive_vertical = 1 " Vertically split terminals - let g:vimteractive_autostart = 0 " Don't start terminals by default + let g:vimteractive_vertical = 1 " Vertically split terminals + let g:vimteractive_autostart = 0 " Don't start terminals by default Extending functionality ----------------------- -This project is very much in an alpha phase, so if you have any issues +This project is very much in an beta phase, so if you have any issues that arise on your system, feel free to `leave an issue `__ or create a `fork and pull request `__ with your proposed changes diff --git a/autoload/vimteractive.vim b/autoload/vimteractive.vim index 8f2da8c..7f3e974 100644 --- a/autoload/vimteractive.vim +++ b/autoload/vimteractive.vim @@ -85,10 +85,9 @@ function! vimteractive#sendlines(lines) call s:show_term() - let l:term_type = getbufvar(b:vimteractive_connected_term, "term_type") + let l:term_type = getbufvar(b:vimteractive_connected_term, "vimteractive_term_type") - mark` - if get(g:vimteractive_bracketed_paste, l:term_type, 1) + if get(g:vimteractive_bracketed_paste, l:term_type, g:vimteractive_bracketed_paste_default) call term_sendkeys(b:vimteractive_connected_term,"[200~" . a:lines . "[201~\n") else call term_sendkeys(b:vimteractive_connected_term, a:lines . "\n") diff --git a/doc/vimteractive.txt b/doc/vimteractive.txt index 27aa09f..0aca52e 100644 --- a/doc/vimteractive.txt +++ b/doc/vimteractive.txt @@ -8,9 +8,10 @@ CONTENTS *vimteractive-contents* 1.Intro........................................|vimteractive-intro| 2.Usage........................................|vimteractive-usage| - 3.Extending functionality......................|vimteractive-extending| - 4.About........................................|vimteractive-about| - 5.License......................................|vimteractive-license| + 3.Common issues................................|vimteractive-issues| + 4.Extending functionality......................|vimteractive-extending| + 5.About........................................|vimteractive-about| + 6.License......................................|vimteractive-license| ============================================================================== 1. Intro *vimteractive-intro* @@ -24,35 +25,30 @@ to other interpreters (including ipython). It is based around the unix philosophy of "do one thing and do it well". It aims to provide a robust and simple link between text files and interactive interpreters. Vimteractive will never aim to do things like autocompletion, leaving that to other, more -developed tools such as YouCompleteMe. +developed tools such as YouCompleteMe or TabNine. The activating commands are - ipython |:Iipython| -- python |:Ipython| - julia |:Ijulia| - maple |:Imaple| - bash |:Ibash| -- clojure |:Iclojure| - zsh |:Izsh| +- python |:Ipython| +- clojure |:Iclojure| +- autodetect based on filetype |:Iterm| -You can also let Vimteractive detect interpreter using |:Iterm| or just send -some lines: Vimteractive will create terminal if needed. Note: it's highly -recommended to use IPython as your default Python interpreter. You can set it -like this: - - let g:vimteractive_default_shells = { 'python': 'ipython' } +Commands may be sent from a text file to the chosen terminal using CTRL-S. If +there is no terminal, CTRL-S will automatically open one for you using +|:Iterm|. See |v_CTRL_S| for more details. -Default Python REPL support for pasting is really bad and you should use -IPython whenever possible. If you need to use default Python REPL, you must -put newline after every top-level block. +Note: it's highly recommended to use IPython as your default Python +interpreter. You can set it like this: -Commands may be sent from a text file to the chosen terminal using CTRL-S. -See |v_CTRL_S| for more details. + let g:vimteractive_default_shells = { 'python': 'ipython' } Since this package leverages the native vim interactive terminal, it is only compatible with vim 8 or greater. - ============================================================================== 2. Usage *vimteractive-usage* @@ -64,7 +60,7 @@ stty -ixon into your .bashrc (or equivalent shell profile file) ------------------------------------------------------------------------------ -Example usage: +Example usage *vimteractive-usage* Create a python file "test.py" with the following content: @@ -97,18 +93,19 @@ you wish to a new file if it contains valuable output By default every buffer is connected to separate terminal. If you want to connect two buffers to one terminal, use |:Iconn| command. - +------------------------------------------------------------------------------ Supported terminals *vimteractive-terminals* *:Iipython* Activate an ipython terminal -*:Ipython* Activate a python terminal *:Ijulia* Activate a julia terminal *:Imaple* Activate a maple terminal *:Ibash* Activate a bash terminal *:Izsh* Activate a zsh terminal +*:Ipython* Activate a python terminal *:Iclojure* Activate a clojure terminal *:Iterm* Activate a terminal based on current filetype +------------------------------------------------------------------------------ Sending commands *v_CTRL_S* CTRL-S sends lines of text to the interpreter in a mode-dependent manner: @@ -126,23 +123,38 @@ ALT-S sends all lines from the start to the current line. If there is no active terminal for current buffer, CTRL-S will automatically create one for you using |:Iterm|. +------------------------------------------------------------------------------ +Connecting to existing REPLs *:Iconn* *vimteractive-connecting* + +:Iconn [{buffer}] connects current buffer to REPL in {buffer}. You can connect +any number of buffers to one REPL. {buffer} can be omitted if there is only one +terminal. + ============================================================================== -3. Connecting to existing REPLs *:Iconn* *vimteractive-connecting* -:Iconn [{buffer}] Connect current buffer to REPL in {buffer}. You can - connect any number of buffers to one REPL. {buffer} - can be omitted if there is only one terminal. +3. Common issues *vimteractive-issues* + +------------------------------------------------------------------------------ +Bracketed paste *vimteractive-issues-bracketed-paste* + +If you see strange symbols like ^[[200~ when sending lines to your new +interpreter, you may be on an older system which does not have bracketed paste +enabled, or have other shell misbehaviour issues. You can change the default +setting with + + let g:vimteractive_bracketed_paste_default = 0 + ============================================================================== -3. Vimteractive options *vimteractive-options* +4. Vimteractive options *vimteractive-options* These options can be put in your |.vimrc|, or run manually as desired: - let g:vimteractive_vertical = 1 " Vertically split terminals - let g:vimteractive_autostart = 0 " Don't start terminals by default + let g:vimteractive_vertical = 1 " Vertically split terminals + let g:vimteractive_autostart = 0 " Don't start terminals by default ============================================================================== -4. Extending functionality *vimteractive-extending* +5. Extending functionality *vimteractive-extending* To add a new interpreter to Vimteractive, you should define g:vimteractive_commands variable. For example: @@ -165,13 +177,13 @@ milliseconds like this: let g:vimteractive_slow_prompt = { 'pythonasync': 200 } -This project is very much in an alpha phase, so if you have any issues that +This project is very much in an beta phase, so if you have any issues that arise on your system, feel free to contact me: williamjameshandley@gmail.com ============================================================================== -5. About *vimteractive-functionality* +6. About *vimteractive-functionality* The core maintainer of vimteractive is: @@ -182,6 +194,6 @@ Find the latest version of vimteractive at: http://github.com/williamjameshandley/vimteractive ============================================================================== -6. License *vimteractive-license* +7. License *vimteractive-license* Vimteractive is licensed under GPL 3.0 diff --git a/plugin/vimteractive.vim b/plugin/vimteractive.vim index 9666e66..45ed70b 100644 --- a/plugin/vimteractive.vim +++ b/plugin/vimteractive.vim @@ -43,6 +43,9 @@ if !has_key(g:, 'vimteractive_default_shells') endif " If 0, disable bracketed paste escape sequences +if !has_key(g:, 'vimteractive_bracketed_paste_default') + let g:vimteractive_bracketed_paste_default=1 +endif if !has_key(g:, 'vimteractive_bracketed_paste') let g:vimteractive_bracketed_paste = { } endif @@ -84,7 +87,7 @@ noremap :call vimteractive#sendlines(getline('.')) inoremap :call vimteractive#sendlines(getline('.'))a " Control-S in visual mode to send multiple lines -vnoremap :call vimteractive#sendlines(getreg('*')) +vnoremap m`""y:call vimteractive#sendlines(substitute(getreg('"'), "\n*$", "", ""))`` " Alt-S in normal mode to send all lines up to this point noremap :call vimteractive#sendlines(join(getline(1,'.'), "\n"))