kassio/neoterm

[help needed] send code block that contains blank lines to python/ipython.

Closed this issue ยท 8 comments

Problem

Selecting

class MyClass:
    variable = "blah"

    def function(self):
        print("This is a message inside the class.")

myobjectx = MyClass()

and executing :TREPLSendSelection<CR>, give

>>> class MyClass:
...     variable = "blah"
...
>>>     def function(self):
  File "<stdin>", line 1
    def function(self):
    ^
IndentationError: unexpected indent
>>>         print("This is a message inside the class.")
  File "<stdin>", line 1
    print("This is a message inside the class.")
    ^
IndentationError: unexpected indent
>>>
>>> myobjectx = MyClass()
>>>

or

In [1]: class MyClass:
   ...:     variable = "blah"
   ...:

In [2]:     def function(self):
   ...:         print("This is a message inside the class.")
   ...:

In [3]: myobjectx = MyClass()

In [4]:

This problem appeared many times, e.g.,

  1. https://gitter.im/neovim/neovim/archives/2019/07/12?at=5d28a9013be99c478639f50a
  2. #127 (comment)
  3. #114

There were also some pull requests relating to this problem, e.g.

  1. #233
  2. #234
  3. #190 (this was for the indentation problem, which was solved via --no-autoindent flag)

The same approach as #234 is used in the plguin urbainvaes/vim-ripple:

https://github.com/urbainvaes/vim-ripple/blob/master/autoload/ripple.vim#L28


My question is,

  1. Will bracketed pasted be implemented in the future, or will #234 be merged?
  2. If no, are there any workaround for this problem?

Thanks a lot!

I had a similar problem. I also tested many other REPL for python programming in neovim and think that neoterm is best suited for my workflow. I just added these two functions:

" Paste Textblock between two marks to neoterm (like in matlab or spyder)
function! s:PasteCell()
        let l:pattern  = '^#%%'
        let l:start    = search(l:pattern, 'Wb') + 1
        let l:end      = search(l:pattern,'W') - 1
        if l:end == -1
            let l:end = line('$')
        end
        let lines = getline(start,end)
        call setreg('+', lines, 'l')
        1T %paste
endfunction
command! -nargs=* PasteCell call s:PasteCell()

" Start a python REPL within a venv and run the script
function! s:RunIPython()
    let l:file = expand('%')
    if g:neoterm.has_any()
        silent! 1T %reset -f
    else
        vert 1T conda activate py3conda
        silent! 1T python -c 'import subprocess; subprocess.call("ipython")' --no-banner --no-confirm-exit --quick --quiet
    endif
    silent! 1Tclear
    exec "1T %run " . l:file
endfunction
command! -nargs=* RunIPython call s:RunIPython()

I would like to integrate this directly into neoterm, but I don't know the programming language and the code base well enough. This code is not really stable or flexible. However, the cell mode can be adapted to suit your problem:

function! s:get_visual_selection()
    "cp https://stackoverflow.com/questions/1533565/how-to-get-visually-selected-text-in-vimscript
    let [line_start, column_start] = getpos("'<")[1:2]
    let [line_end, column_end] = getpos("'>")[1:2]
    let lines = getline(line_start, line_end)
    if len(lines) == 0
        return ''
    endif
    let lines[-1] = lines[-1][: column_end - (&selection == 'inclusive' ? 1 : 2)]
    let lines[0] = lines[0][column_start - 1:]
    call setreg('+', lines, 'l')
    1T %paste
endfunction
command! -nargs=* PasteVisualSel call s:get_visual_selection()

You can map the Commands like PasteVisualSel to any key.

I am currently working on a pull request on this topic. This is my first contact with github and vim scripting. I don't know the rules, but I think this is a good place to start. What do I have to consider?

Will bracketed pasted be implemented in the future, or will #234 be merged?

#234 got stale, is someone get it updated it can be merged.

If no, are there any workaround for this problem?

tbh, I don't know. I have almost no knowledge on python, so I'm expecting the community to contribute and fix/implement this.

@incoggnito,

What do I have to consider?

You can open the pull request with your initial ideas and we can go from that. The architecture of the plugin shouldn't be too complex. Vim/Neovim documentation is very thorough, so it can be very helpful.

You can open the pull request with your initial ideas and we can go from that. The architecture of the plugin shouldn't be too complex. Vim/Neovim documentation is very thorough, so it can be very helpful.

Yes that's true. Nevertheless, for me these are quite a few new topics. So far I'm only used to a little python programming on windows without using any git. The help files are awesome .... steep learning curve :)

can we close this one, now that #274 was merged?

@kassio

I think that a more complete solution is to support bracketed paste mode. We see a similar issue in the R console radian. I am also quite sure julia console would have a similar issue.

In my own opinion, #234 is in the right direction.

@kassio , @incoggnito
Thanks for your great effort, I've tested on my machine. And it works. However, personally I do not like this hack by filtering out all the blank lines. I would agree with @randy3k that bracketed paste mode would be a better solution: it may also solve similar problems for other interactive interpreter say for R and there would be no need to change the default ipython behavior by hardcoding the --no-autoindent flag.

For ipython only, the %paste magic command is nice.

Anyway, for now it meets my need. Thanks so much. If later I have time on this, I may try to contribute to it. I just close the issue for now.