Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Use ipython 5's new paste functionality to fix long lines issue #123

Closed
alok opened this issue Jan 3, 2017 · 16 comments
Closed

Use ipython 5's new paste functionality to fix long lines issue #123

alok opened this issue Jan 3, 2017 · 16 comments
Labels

Comments

@alok
Copy link

alok commented Jan 3, 2017

I figured I'd make this a separate issue. I'll quote the text I added to another issue:

ipython 5 removed the %cpaste magic function and apparently just works with pasting long input directly. You may want to either add detection for ipython 5.x+, or require users to use it if they use ipython (it has been out for months now). Then, you can use something other than cpaste (I'm not sure how they made it work, but it apparently does).

@jpalardy
Copy link
Owner

jpalardy commented Jan 3, 2017

Hmmmm… does that just mean not turning on ipython mode? Or is there more to it?

@alok
Copy link
Author

alok commented Jan 3, 2017

I took a 200 line python script, copied it to the system clipboard, and then just hit Cmd-V to paste it and it pasted with the correct indentation. I'm not sure how they implement it. I'd try not turning it on and see if that works.

@aicherc
Copy link

aicherc commented May 6, 2017

I was able to get this to partially work by turning on "bracked paste mode" (https://cirw.in/blog/bracketed-paste), instead of using %cpaste. Specifically in ftplugin/python/slime.vim I changed

if exists('g:slime_python_ipython') && len(split(a:text,"\n")) > 1
   return ["%cpaste -q\n", a:text, "--\n"]

to

if exists('g:slime_python_ipython') && len(split(a:text,"\n")) > 1
   return ["\e[200~", a:text, "\e[201~\n"]

where \e[200~ and \e[201~ are the bracketed paste escape sequences.
As far as I can tell, this prevents ipython 5.0+ from only reading the first line.
See also (ipython/ipython#9948)

I don't know enough about vimscript to make it check the current version of ipython (as multi-line pasting is version 5.0+).

@dlovell
Copy link

dlovell commented Jul 4, 2017

@jpalardy , "not turning on ipython mode" doesn't work because you need to send something special for "non-executing-newline"

We need to bind a shortcut that adds a new line without executing, if you are scripting you can use C-o Down to force a newline and Escape Enter to force execution.

See also: ENH: enable multiline send for ipython
(I think I like "bracketed paste mode" better)

@jpalardy
Copy link
Owner

jpalardy commented Jul 5, 2017

Based on what I'm reading, this is related to #142 ?

@NedWestern
Copy link
Contributor

For IPython 7.2, I managed to get it working with the following changes:

if exists('g:slime_python_ipython') && len(split(a:text,"\n")) > 1
  return ["%cpaste -q\n", g:slime_dispatch_ipython_pause, a:text, "--\n"]

to

if exists('g:slime_python_ipython')
  return [a:text, g:slime_dispatch_ipython_pause, "\n"]

when vim-slime pastes the text, IPython 5.0+ will run the code with no problems, but it will not auto-execute. Adding the pause and the newline character makes IPython execute the code after pasting.

Note that for large blocks of code with empty lines, there is still a problem with IPython executing at some of these empty lines, which seems to occur randomly, indicating a timing issue. This will be a problem for indented code. I'm not sure how to address this.

@jpalardy
Copy link
Owner

jpalardy commented May 6, 2019

I'll have to defer to an iPython user for a solution.

@NedWestern
Copy link
Contributor

If I replace empty lines with a comment character, it suppresses early execution and somewhat preserves the layout of the code. A bit hacky, but it seems to work.

@NedWestern
Copy link
Contributor

So... should I submit a pull request for testing perhaps? Or no?

@jpalardy
Copy link
Owner

jpalardy commented May 8, 2019

I'm up for it.

If you send a PR, I'll merge it. If it doesn't work, we'll revert?

@NedWestern
Copy link
Contributor

New to this... hopefully it's OK.

@aicherc
Copy link

aicherc commented May 8, 2019

@NedWestern
For the problem with IPython executing at empty lines somewhat randomly (treating one code chunk as multiple chunks), have you tried adding the "bracketed paste mode" characters around a.text? (see #123 (comment))

I've been using it (for the last two years) to send code from vim to ipython using tmux and it's removed the issue of ipython thinking I'm sending multiple chunks (as far as I can tell).

Specifically replacing

if exists('g:slime_python_ipython')
  return [a:text, g:slime_dispatch_ipython_pause, "\n"]

with

if exists('g:slime_python_ipython')
  return ["\e[200~", a:text, "\e[201~", g:slime_dispatch_ipython_pause, "\n"]

It might let you avoid having to suppress empty lines with comment characters.

@NedWestern
Copy link
Contributor

@aicherc
Hi Christopher, yes I read your blog post. Sounds interesting, but I can not get it to work for my setup (IPython 7.2 in vimterminal in gVim). It sends the escape sequence, minus the "\e", and does not execute.

In [1]: [200~print('foo')
        : ^[[201~
        :

Does it require specific settings in vim?

@aicherc
Copy link

aicherc commented May 8, 2019

@NedWestern
Thanks for trying it out.
After re-reading the blog post, it sounds like "bracketed paste mode" is only intended to work in terminals that support it (my setup is gnome-terminal + tmux). I'm not very familiar with vimterminal (or terminal emulation in vim/neovim) to know if they support it.

Based on this, I like your current solution (empty lines -> #), since it works more generally.

@NedWestern
Copy link
Contributor

True, but it seems to break for some people... ugh.

@stale
Copy link

stale bot commented Nov 1, 2019

This issue has been automatically marked as stale because it has not had recent activity. It will be closed if no further activity occurs. Thank you for your contributions.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Projects
None yet
Development

No branches or pull requests

5 participants