diff --git a/README.md b/README.md
index 0d50fc1..8393846 100644
--- a/README.md
+++ b/README.md
@@ -9,4 +9,12 @@ This is plugin implementation of the following PyCharm [pull request](https://gi
JetBrains feature request: https://youtrack.jetbrains.com/issue/PY-38919
+New feature for 0.2.x:
+
+When editing Python code, execute a top level code block with "Execute cell in console".
+
+For IDEs with Jupyter notebook support, this executes a cell in the Python console.
+
+keyboard shortcut: alt shift E
.
+
![demonstration](demo.gif "demonstration")
diff --git a/src/main/java/com/jetbrains/python/actions/PyCellExecuteAction.java b/src/main/java/com/jetbrains/python/actions/PyCellExecuteAction.java
index a9a2c52..8778fb4 100644
--- a/src/main/java/com/jetbrains/python/actions/PyCellExecuteAction.java
+++ b/src/main/java/com/jetbrains/python/actions/PyCellExecuteAction.java
@@ -32,6 +32,76 @@
public class PyCellExecuteAction extends AnAction {
+ private static boolean inJupyterNotebookMode(final AnActionEvent e, final Editor editor) {
+ // by checking for `JupyterTokenType.CODE_MARKER`
+ // but Jupyter is a closed sourced component, to workaround check if it is not `PyElementType` or `PsiWhiteSpace`
+ final Document document = editor.getDocument();
+ final PsiDocumentManager psiDocumentManager = PsiDocumentManager.getInstance(e.getProject());
+ psiDocumentManager.commitDocument(document);
+ final PsiFile psiFile = psiDocumentManager.getPsiFile(document);
+
+ final LogicalPosition logicalPos = editor.getCaretModel().getLogicalPosition();
+ final int line = logicalPos.line;
+ int start = 6666, end = 6666;
+ for (int i = 0; ; --i) {
+ final int cline = line + i;
+ int offset;
+ try {
+ offset = DocumentUtil.getFirstNonSpaceCharOffset(document, cline);
+ start = offset;
+ } catch (IndexOutOfBoundsException ex) {
+ break;
+ }
+ final PsiElement psiElement = psiFile.findElementAt(offset);
+ // System.out.println("i = " + i);
+ // System.out.println("cline = " + cline);
+ // System.out.println("psiElement = " + psiElement);
+ // System.out.println("psiElement.getNode() = " + psiElement.getNode());
+ if (psiElement == null)
+ break;
+ final var elementType = psiElement.getNode().getElementType();
+ // System.out.println("elementType = " + elementType);
+ if (!((elementType instanceof PyElementType) || (psiElement.getNode() instanceof PsiWhiteSpace)))
+ return true;
+ }
+ return false;
+ }
+ static void moveCaretVertical(final Editor editor, final int numLines) {
+ final LogicalPosition pos = editor.getCaretModel().getLogicalPosition();
+ editor.getCaretModel().moveToOffset(
+ editor.logicalPositionToOffset(
+ new LogicalPosition(pos.line + numLines, pos.column)));
+ }
+
+ private static void submitTopLevelCodeBlock(final AnActionEvent e, final Editor editor) {
+ final Document document = editor.getDocument();
+ final PsiDocumentManager psiDocumentManager = PsiDocumentManager.getInstance(e.getProject());
+ psiDocumentManager.commitDocument(document);
+ final PsiFile psiFile = psiDocumentManager.getPsiFile(document);
+
+ for (; ; ) {
+ final LogicalPosition logicalPos = editor.getCaretModel().getLogicalPosition();
+ final int firstNonSpaceCharOffset = DocumentUtil.getFirstNonSpaceCharOffset(document, logicalPos.line);
+ // System.out.println("firstNonSpaceCharOffset = " + firstNonSpaceCharOffset);
+ final int lineStartOffset = DocumentUtil.getLineStartOffset(firstNonSpaceCharOffset,
+ document);
+// System.out.println("lineStartOffset = " + lineStartOffset);
+ if (lineStartOffset == firstNonSpaceCharOffset) {
+ final PsiElement pe = psiFile.findElementAt(lineStartOffset);
+// System.out.println("pe.getTextOffset() = " + pe.getTextOffset());
+ if (pe.getTextOffset() == lineStartOffset) {
+ PySmartExecuteSelectionAction.smartExecuteCode(e, editor);
+ return;
+ }
+ }
+ try {
+ moveCaretVertical(editor, -1);
+ }catch(Exception ex){
+// ex.printStackTrace();
+ throw ex;
+ }
+ }
+ }
private static void cellExecute(final AnActionEvent e, final Editor editor) {
final Document document = editor.getDocument();
final PsiDocumentManager psiDocumentManager = PsiDocumentManager.getInstance(e.getProject());
@@ -52,16 +122,18 @@ private static void cellExecute(final AnActionEvent e, final Editor editor) {
break;
}
final PsiElement psiElement = psiFile.findElementAt(offset);
+ // System.out.println("i = " + i);
+ // System.out.println("cline = " + cline);
+ // System.out.println("psiElement = " + psiElement);
+ // System.out.println("psiElement.getNode() = " + psiElement.getNode());
+ if (psiElement == null)
+ break;
final var elementType = psiElement.getNode().getElementType();
-// System.out.println("i = " + i);
-// System.out.println("cline = " + cline);
-// System.out.println("psiElement = " + psiElement);
-// System.out.println("psiElement.getNode() = " + psiElement.getNode());
-// System.out.println("elementType = " + elementType);
+ // System.out.println("elementType = " + elementType);
if (!((elementType instanceof PyElementType) || (psiElement.getNode() instanceof PsiWhiteSpace)))
break;
}
-// System.out.println("forward");
+ // System.out.println("forward==================");
for (int i = 0; ; ++i) {
final int cline = line + i;
int offset;
@@ -72,12 +144,14 @@ private static void cellExecute(final AnActionEvent e, final Editor editor) {
break;
}
final PsiElement psiElement = psiFile.findElementAt(offset);
+ // System.out.println("i = " + i);
+ // System.out.println("cline = " + cline);
+ // System.out.println("psiElement = " + psiElement);
+ if (psiElement == null)
+ break;
+ // System.out.println("psiElement.getNode() = " + psiElement.getNode());
final var elementType = psiElement.getNode().getElementType();
-// System.out.println("i = " + i);
-// System.out.println("cline = " + cline);
-// System.out.println("psiElement = " + psiElement);
-// System.out.println("psiElement.getNode() = " + psiElement.getNode());
-// System.out.println("elementType = " + elementType);
+ // System.out.println("elementType = " + elementType);
if (!((elementType instanceof PyElementType) || (psiElement.getNode() instanceof PsiWhiteSpace)))
break;
}
@@ -85,7 +159,7 @@ private static void cellExecute(final AnActionEvent e, final Editor editor) {
start = DocumentUtil.getLineEndOffset(start, document);
end = DocumentUtil.getLineEndOffset(end, document);
String codeToSend = editor.getDocument().getCharsSequence().subSequence(start, end).toString();
-// System.out.println("codeToSend = " + codeToSend);
+ // System.out.println("codeToSend = " + codeToSend);
PyExecuteInConsole.executeCodeInConsole(e.getProject(), codeToSend, null, true, true, false,
null);
}
@@ -100,7 +174,10 @@ public void actionPerformed(@NotNull AnActionEvent e) {
PyExecuteInConsole.executeCodeInConsole(e.getProject(), selectionText, null, true, true, false, null);
}
else {
- cellExecute(e, editor);
+ if (inJupyterNotebookMode(e, editor))
+ cellExecute(e, editor);
+ else
+ submitTopLevelCodeBlock(e, editor);
}
}
}
diff --git a/src/main/java/com/jetbrains/python/actions/PySmartExecuteSelectionAction.java b/src/main/java/com/jetbrains/python/actions/PySmartExecuteSelectionAction.java
index 6c9d533..989f3a3 100644
--- a/src/main/java/com/jetbrains/python/actions/PySmartExecuteSelectionAction.java
+++ b/src/main/java/com/jetbrains/python/actions/PySmartExecuteSelectionAction.java
@@ -104,7 +104,7 @@ static void moveCaretDown(final Editor editor, final int numLinesToSubmit) {
// editor.getScrollingModel().scrollToCaret(ScrollType.RELATIVE);
// }
}
- private static void smartExecuteCode(final AnActionEvent e, final Editor editor) {
+ static void smartExecuteCode(final AnActionEvent e, final Editor editor) {
final Document document = editor.getDocument();
final PsiDocumentManager psiDocumentManager = PsiDocumentManager.getInstance(e.getProject());
psiDocumentManager.commitDocument(document);
diff --git a/src/main/resources/META-INF/plugin.xml b/src/main/resources/META-INF/plugin.xml
index 7bbb7ae..53e14f3 100644
--- a/src/main/resources/META-INF/plugin.xml
+++ b/src/main/resources/META-INF/plugin.xml
@@ -6,7 +6,7 @@
python-smart-execute
Python Smart Execute
- 0.1.12
+ 0.2.0
Guo Ci Teo
https://youtrack.jetbrains.com/issue/PY-38919.
- For IDEs with Jupyter notebook support, there is also a execute cell command "Execute cell in console".
+ New feature for 0.2.x:
+
+ When editing Python code, execute a top level code block with "Execute cell in console".
+
+ For IDEs with Jupyter notebook support, this executes a cell in the Python console.
keyboard shortcut: alt shift E
.
]]>