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

Auto-detect code blocks around the cursor location. Shift-enter executes the entire block #1471

Open
ronglums opened this issue Mar 27, 2019 · 18 comments
Assignees
Labels
feature-request Request for new features or functionality interactive-window Impacts interactive window notebook-commands

Comments

@ronglums
Copy link

  1. Shift-enter moves to the next line after executing the current line
  2. Auto-detect code blocks around the cursor location. Shift-enter executes the entire block
@IanMatthewHuff
Copy link
Member

Just to say. This might be an improvement and we should totally consider it. But right now we had shift-enter match what the python extension does when sending code to the terminal. So if we have shift-enter move and advance we won't match the main python extension any more. Though maybe we can consider having both advance on shift-enter.

@greazer
Copy link
Contributor

greazer commented Mar 28, 2019

Do microsoft/vscode-python#1 for sure. Enter a new issue for microsoft/vscode-python#2 if we don't find an easy solution.

@daeh
Copy link

daeh commented Apr 27, 2019

No. 2 is on the top of my list of things that would improve VS-py for me, cf. microsoft/vscode-python#480

@aldanor
Copy link

aldanor commented May 19, 2019

So if we have shift-enter move and advance we won't match the main python extension any more. Though maybe we can consider having both advance on shift-enter.

@IanMatthewHuff You would match Jupyter Notebook/Lab behaviour though if Shift-Enter advanced after execution and Ctrl-Enter executed in place.

@IanMatthewHuff
Copy link
Member

@aldanor Thanks for the heads up on Ctrl-Enter. I'll look into that, at a minimum I could maybe just add a new Execution in place command and leave it unbound so that users could add it to the keybinding of their choice.

@aldanor
Copy link

aldanor commented May 20, 2019

@IanMatthewHuff That would be great, yea - at the very least to be able to remap it to user's liking without having to create macros manually.

@andycraig
Copy link
Contributor

andycraig commented Sep 29, 2019

This PR for the PyCharm editor shows a video of the sort of features that No. 2 could provide (automatically sending whole class and function definitions): JetBrains/intellij-community#711

It would be nice if the following blocks were supported:

  1. Compound statement blocks (class, def, with, async, for/else, while/else, if/elif/else, try/except/finally), if the cursor is on the first line with the colon (suggested here https://github.com/microsoft/vscode-python/issues/480#issuecomment-479140136)
  2. Long lines split with \
  3. Multi-line bracketed blocks, as is common when using pandas, e.g.:
(pd.DataFrame({'a':[1,1,2,2], 'b':[1,2,3,4]})
 .groupby('a')
 .agg(sum))
  1. Function calls:
print('hello ' +
    'world')
  1. Multi-line lists and dictionaries:
x =[1,
    2,
    3]

d = {'a':1,
    'b':2,
    'c':3}

EDIT: The cursor would ideally go to the next code block after running the current code block.

@greazer greazer changed the title Python Interactive shift-enter execution workflow improvement Auto-detect code blocks around the cursor location. Shift-enter executes the entire block Oct 18, 2019
@arencambre
Copy link

arencambre commented Aug 18, 2020

This relates to microsoft/vscode-python#13495. Would make a lot of sense to implement them together.

@andycraig
Copy link
Contributor

Auto-detection of code blocks is still the feature that would make the biggest difference to my VS Code Python experience. We added something like this to one of the VS Code R extensions. I was thinking of putting my hand up to do an external contributor PR for the case of detecting blocks like def, if/else etc., but realised that to 'only' handle them you still need to consider some complicated cases.

  1. Simple case example:
if True: # Cursor on this line
    print("hello world")
  1. Complicated case example:
# Cursor on any line
if all([
    True,
    'a' in {
        'a',
        'b',
    },
    len(")") > 0,
]):
    print("hello world")

If the extension is already parsing the file and maintaining an AST with line numbers, these two cases can be handled just as easily. If the extension isn't doing that, then handling the complicated case is a fair amount of work. This file is how we handle it for R: https://github.com/Ikuyadeu/vscode-R/blob/master/src/selection.ts Most of the code is dedicated to handling nested parentheses/brackets/braces over multiple lines.

As a simpler first step that would probably handle most real-world cases, you could use this heuristic:

Proposed heuristic

If the cursor is on a line ending in a colon :, check whether all its parentheses/brackets/braces are matched WITHIN THAT LINE (ignoring parentheses/brackets/braces in strings). If so, use indendation to detect the rest of the block, and send the whole block. If not, show an error message like 'Could not identify block'. If the cursor is on a line that does NOT end in a colon, send just that line.

Would you be interested in an external contributor PR for this proposed heuristic method?

@leifwalsh
Copy link

I'm also interested in this feature. I think @andycraig's heuristics sound reasonable, and I think this would be a huge improvement for workflows that include use of the Interactive Window.

I also filed #8658 which I think people interested in this might also want to see.

@andycraig
Copy link
Contributor

Hi @rebornix - messaging you since you're assigned to this issue currently. This is still the feature that would improve the VS Code Python experience the most for me. Is there any interest in the heuristic approach I proposed above? If so I could work on a PR. If not I could create an extension to provide this functionality.

Note that there are two feature requests in this issue:

  1. Shift-enter moves to the next line after executing the current line
  2. Auto-detect code blocks around the cursor location. Shift-enter executes the entire block

I'm mainly talking about 2.

Thanks!

@GitHunter0
Copy link

GitHunter0 commented Sep 3, 2022

microsoft/vscode-python#18105 similar issue which I think is better described

@andycraig
Copy link
Contributor

I'd love this block-detection functionality so I'm going to have a try at creating an extension to provide it. My plan is to use the Python Extension Template and make it compatible with both the VS Code Jupyter and VS Code Python extensions.

In the meantime, if there's any move towards providing this functionality within the VS Code Jupyter or VS Code Python extensions themselves, please let me know as I'd very happily leave it to the pros!

@kylebarron
Copy link

kylebarron commented Dec 1, 2022

I used this functionality in Atom + Hydrogen every day, and now that Atom is dying in more places, I got so frustrated without this functionality in vscode that I made my own vscode extension for this. In this screencast, the only keyboard shortcut used is Shift+Enter, which runs a block and moves down to the start of the next block (Ctrl+Enter/Cmd+Enter are currently mapped to "run the current block but don't move the cursor)

Screen.Recording.2022-11-28.at.10.27.28.PM.mov

Implementation

  • The github repo for this is here: https://github.com/kylebarron/vscode-jupyter-python

  • This is based off of https://github.com/nteract/hydrogen and https://github.com/nikitakit/hydrogen-python, specifically the code here. The idea is pretty simple:

    1. Include the current line plus any additional lines that have a greater initial indent

    2. Define a (user-editable) list of keywords that should be marked as "include this line even if it's at the same indent as the start line". So for example the default list includes elif and else, so that if your cursor is at the initial if line, the if plus elif plus else blocks all get evaluated at the same time.

      The default setting for this is: else, elif, except, finally, }, ], ).

    This heuristic generally works on most "clean" code; maybe the complicated case above would break it.

  • Using the block of text inferred by the above heuristic, call the jupyter.execSelectionInteractive command in the jupyter package

Caveats

  • My plan is to use the Python Extension Template and make it compatible with both the VS Code Jupyter and VS Code Python extensions

    I personally really love IPython and find the rich outputs (like dataframe rendering) useful, so the extension I wrote only supports the jupyter extension and not the bare python extension.

  • I wrote this extension super fast, so it probably has bugs and I don't want to make any promises about my maintenance of it going forward.

(Thanks @andycraig for linking to this issue from #12176.)

@Lauler
Copy link

Lauler commented Nov 14, 2023

This should now be supported in VSCode since October 2023. See: https://code.visualstudio.com/updates/v1_84#_python

@kylebarron
Copy link

kylebarron commented Nov 14, 2023

That's really exciting! The screenshot in that link shows it working in the Python terminal; does it also work for Python inside Jupyter, not just in the REPL?

@amunger
Copy link
Contributor

amunger commented Nov 14, 2023

That feature is just for the python REPL at this point.

@GitHunter0
Copy link

The cursor will also be automatically moved to the next executable line, to provide a smooth experience when executing multiple chunks iteratively.

I just don't like that part, I want the option to leave the cursor where it is, because frequently I need to run the same block over and over again

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
feature-request Request for new features or functionality interactive-window Impacts interactive window notebook-commands
Projects
None yet
Development

No branches or pull requests