intellij-community icon indicating copy to clipboard operation
intellij-community copied to clipboard

Improvements to “Execute Line in Console” feature in PyCharm.

Open guoci opened this issue 7 years ago • 33 comments

This PR suggests some improvements to the “Execute Line in Console” feature in PyCharm. Currently, that feature submits a line to the Python console, even when the line is an incomplete input. A screencast demonstrating the new feature in this PR is shown below. demo pycharm_pull_request_demo

In this PR, the following changes are implemented:

When the cursor is on a line and that line is an incomplete input, submit a minimum amount of lines to produce a complete input.

After that, the cursor in the editor is advanced accordingly.

Because of my unfamiliarity with the source code, I have used some code that is clearly not acceptable. I would appreciate if the reviewers can help with improving the code.

guoci avatar Jan 18 '18 00:01 guoci

I have attached a video clip above to help visualize the feature.

guoci avatar Feb 02 '18 19:02 guoci

Has this been implemented? If not, when? This is a great addition that I have been hoping for for quite some time. Thank you!

Jmarks199 avatar Aug 30 '18 19:08 Jmarks199

@Jmarks199 I compile from source to use this feature. Hope this will get looked at by the PyCharm developers.

guoci avatar Sep 01 '18 19:09 guoci

Hi @guoci! Sorry for the late response.

This is really interesting feature, but I think it's worth creating a separate action (for example "Smart Execute Line"), because it changes the original action significantly.

Your implementation need some improvements as well. It isn't a good idea to create a separate Python process for every action run just to check it's syntax correctness. You can look into checkComplete method in PyConsoleEnterHandler class. We use this class to handle "Enter" pressed in Python Console to check whether we should execute current command or not. I think it would be better to use it instead of passing code to a Python process.

This new action is a nice idea, but I think it need some investigation and testing before including it into PyCharm release. I would like to suggest you to implement it as a PyCharm plugin. So you (and some other users) will be able to use it without manual compiling PyCharm from sources, and you won't depend on our approval.

You can learn about plugin development here: https://www.jetbrains.com/help/idea/plugin-development-guidelines.html. All you need is to create and register a new action (similar to PyExecuteSelectionAction) and rewrite syntax checking.

Please let me know whether you want to implement this feature as a plugin or you want to continue work on the pull request.

Thank you very much for your interest and for your pull request!

Elizaveta239 avatar Sep 03 '18 09:09 Elizaveta239

@Elizaveta239 thanks for your reply. Agreed, the action should have a new name.

The checkComplete method doesn't replicate the behavior of the python code. It only checks if some code is valid. If we have compound statements with blank lines, e.g.

class C:
   def f():pass


   def g():pass

checking for syntax validity will not work here. Code ending at line 2 and line 5 are both valid.

For my own implementation (not in this PR), I start a single Python process once and communicate with it repeatedly through PyCharm to reduce overhead. I haven’t figured out how to implement that within PyCharm yet.

I will prefer it to be a builtin feature, but I will look into working on a plugin if the PyCharm developers don't approve the feature.

guoci avatar Sep 09 '18 20:09 guoci

@guoci It's still unclear for me, how you decide which piece of code should be executed. Is it a syntactically correct piece of code, which beginning is on the line with cursor and it's surrounded by empty lines?

Elizaveta239 avatar Sep 18 '18 12:09 Elizaveta239

@Elizaveta239 It is the maximum number of lines starting from the current line (line the cursor is at) such that the number of top-level statements=1. If the cursor is at the beginning of

if 0:
    print(1)

else:
    print(2)
print(3)

then submitted code is

if 0:
    print(1)

else:
    print(2)

. The else part will not be left out, as would happen if you type that code in a python shell. We stop at print(3) because it is another top-level statement. In short, we submit lines until we reach a new top-level statement or when the file ends, consistent with how code will behave in a script. Blank lines in a compound statement do not matter.

guoci avatar Sep 18 '18 16:09 guoci

@guoci I got it, thank you! But on the first screen cast you're sending together 3 lines on the top level:

%%time
import time
time.sleep(1)

Anyway, I believe any of this rules can be implemented using static analysis, without sending commands to Python. For example, you can get cursor position, find its PsiElement by offset:

    PsiDocumentManager psiDocumentManager = PsiDocumentManager.getInstance(project);
    psiDocumentManager.commitDocument(editor.getDocument());
    PsiFile psiFile = psiDocumentManager.getPsiFile(editor.getDocument());

    VisualPosition caretPos = editor.getCaretModel().getVisualPosition();
    int line = caretPos.getLine();

    int offset = DocumentUtil.getFirstNonSpaceCharOffset(editor.getDocument(), line);
    PsiElement psiElement = psiFile.findElementAt(offset);

And after that you can inspect elements in file, get elements of the same level or on top level (psiElement.getChildren() and psiElement.getParent()). There many useful functions in PsiTreeUtil class as well.

Elizaveta239 avatar Sep 19 '18 14:09 Elizaveta239

@Elizaveta239 thanks for your time on this and your code examples. I will try reimplementing it with intellij's code. For that 3 lines of code, it is a IPython cell magic code block and so it makes sense to execute all of it. IPython shell translates it to a single statement as standard python code.

guoci avatar Sep 19 '18 16:09 guoci

@Elizaveta239 I have reimplemented the feature with Intellij's parsing code.

guoci avatar Sep 21 '18 18:09 guoci

Hi @guoci! Thank you very much! It looks much better now! But it still changes "Execute Selection" action behavior. I think it would be better to create a separate action, so there will be two different actions in a context menu: Execute Selection and Smart Execute Selection. You can read more about new custom actions here: http://www.jetbrains.org/intellij/sdk/docs/tutorials/action_system/working_with_custom_actions.html

I can do it on my own but later, because I'm busy with other tasks at the moment.

Elizaveta239 avatar Sep 24 '18 09:09 Elizaveta239

Hi @Elizaveta239, I have separated the actions, binding the new action to alt shift A When there is a code selection, both of the actions behave the same.

But I was thinking if it would be better to replace the original behavior when no code is selected. Although both actions are different when no code is selected, I believe the average user would prefer this new action.

guoci avatar Sep 24 '18 18:09 guoci

@Elizaveta239 is this PR ok? Let me know if I need to do more.

guoci avatar Jan 17 '19 18:01 guoci

Hi @guoci! Yes, the PR is ok, thank you! The feature looks interesting, but we still can't estimate its usefulness. Why don't you want to publish it as a separate plugin and share it within JetBrains plugin repository? If it's popular, we'll merge it into PyCharm code base.

Elizaveta239 avatar Jan 23 '19 16:01 Elizaveta239

@Elizaveta239 thanks! I will need some time to get that done.

guoci avatar Jan 23 '19 17:01 guoci

@Elizaveta239 where are the instructions for creating a PyCharm plugin? I can find one for creating a Intellij plugin https://www.jetbrains.org/intellij/sdk/docs/, but not for a PyCharm plugin.

guoci avatar Jan 31 '19 17:01 guoci

@guoci In fact all PyCharm plugins are Intellij IDEA plugins. So you should develop it as IDEA plugin, and mention in settings, that your plugin is compatible only with PyCharm, not with other Intellij-based IDEs.

We even had a webinar about plugin development recently: https://blog.jetbrains.com/pycharm/2019/01/webinar-recording-live-development-of-a-pycharm-plugin-with-joachim-ansorg/ So you can follow steps from it: https://github.com/jansorg/pycharm-webinar-base

Elizaveta239 avatar Feb 01 '19 14:02 Elizaveta239

Now published as PyCharm plugin. https://plugins.jetbrains.com/plugin/11945-python-smart-execute

guoci avatar Feb 03 '19 22:02 guoci

Great news! Usually plugin approval takes a few days, I'll ask to make it faster. Thank you very much for your contribution!

Elizaveta239 avatar Feb 04 '19 14:02 Elizaveta239

Hi @guoci. I just wanted to thank you for he creation of this plugin. For those of us who are learning Python after a background in R, this comes very very handy. Thanks!

carlosahumada89 avatar Jul 19 '19 15:07 carlosahumada89

@carlosahumada89 Thanks. Me too, I tried to implement this feature to emulate RStudio's Run Selected Line(s) Crtl+Enter feature. Since Python is not a curly-brace language, the implementation is more complicated.

AFAIK, no Python IDE has this feature.

guoci avatar Aug 30 '19 15:08 guoci

Actually there is a relatively new pycharm plug-in that works perfectly. Not sure the name at the moment.

Sent from my iPhone

On Aug 30, 2019, at 11:31 AM, guoci <[email protected]mailto:[email protected]> wrote:

@carlosahumada89https://github.com/carlosahumada89 Thanks. Me too, I tried to implement this feature to emulate RStudio's Run Selected Line(s) Crtl+Enter feature. Since Python is not a curly-brace language, the implementation is more complicated.

AFAIK, no Python IDE has this feature.

— You are receiving this because you were mentioned. Reply to this email directly, view it on GitHubhttps://github.com/JetBrains/intellij-community/pull/711?email_source=notifications&email_token=AH2CEGBO5IL6ZXD2VMJQ7TDQHE4MJA5CNFSM4EMIWYUKYY3PNVWWK3TUL52HS4DFVREXG43VMVBW63LNMVXHJKTDN5WW2ZLOORPWSZGOD5R7S6Y#issuecomment-526645627, or mute the threadhttps://github.com/notifications/unsubscribe-auth/AH2CEGC5ILTKUW2U64O5B4LQHE4MJANCNFSM4EMIWYUA.

Jmarks199 avatar Aug 30 '19 15:08 Jmarks199

@Jmarks199 yes, I am the author of that plugin, link below. The code is based on this PR. https://plugins.jetbrains.com/plugin/11945-python-smart-execute

guoci avatar Aug 30 '19 15:08 guoci

@guoci @Elizaveta239 @traff Maybe it's time to merge it? I've just implemented pretty the same feature for R plugin. Looks like that's really useful for DataScience mode.

vladimir-koshelev avatar Nov 01 '19 20:11 vladimir-koshelev

@vedun-z Sure, but at the moment it requires some steps from one of the JetBrains team members. We need to:

  • find a shortcut, which doesn't overlap any other action from Intellij IDEA Ultimate (currently Alt + Shift + A overlaps "Show all affected files" action)
  • create a build from this branch and pass it to QA team
  • make fixes after testing
  • review code and find possible issues there

Unfortunately, I'm currently busy with other tasks. @vedun-z You're welcome to do these steps.

Elizaveta239 avatar Nov 05 '19 13:11 Elizaveta239

@Elizaveta239 Thank you for great opportunity, but as long as this feature are not going to 2019.3 anyway, there's no reason to rush. We could schedule it to 2020.1, what do you think?

vladimir-koshelev avatar Nov 05 '19 18:11 vladimir-koshelev

Sure! I've created a feature request for it: https://youtrack.jetbrains.com/issue/PY-38919

Elizaveta239 avatar Nov 06 '19 11:11 Elizaveta239

@vedun-z @Elizaveta239 it would be nice to get this going again. It's really surprising this hasn't been added as a feature. The real question is, why would anyone ever want to use the default execute in console functionality? Personally, I can't imagine using Pycharm without this feature and the plugin seems to be broken in version 2021.3.

java.lang.NoSuchMethodError: 'void com.jetbrains.python.actions.PyExecuteSelectionAction.showConsoleAndExecuteCode(com.intellij.openapi.actionSystem.AnActionEvent, java.lang.String)'

Jmarks199 avatar Dec 04 '21 16:12 Jmarks199

I have just uploaded an update, currently pending approval from JetBrains. @Jmarks199 Thanks for reporting, you can download it here before the approval.

guoci avatar Dec 05 '21 20:12 guoci

For code to the plugin, see https://github.com/guoci/pycharm-smart-execute. The code in this PR is no longer working due to API changes.

guoci avatar Dec 07 '21 20:12 guoci