From 2a026e4cceb6b2da7f1d5c387148789503df1ec6 Mon Sep 17 00:00:00 2001 From: "Gregory.Shrago" Date: Fri, 29 Jul 2016 01:55:52 +0300 Subject: [PATCH] scripting: take PSI into consideration on command detection --- .../console/RunIdeConsoleAction.java | 32 ++++++++++++++++--- 1 file changed, 27 insertions(+), 5 deletions(-) diff --git a/platform/lang-impl/src/com/intellij/execution/console/RunIdeConsoleAction.java b/platform/lang-impl/src/com/intellij/execution/console/RunIdeConsoleAction.java index 22f63cfcaa7f..9a65d66ee746 100644 --- a/platform/lang-impl/src/com/intellij/execution/console/RunIdeConsoleAction.java +++ b/platform/lang-impl/src/com/intellij/execution/console/RunIdeConsoleAction.java @@ -42,8 +42,9 @@ import com.intellij.openapi.util.TextRange; import com.intellij.openapi.util.text.StringUtil; import com.intellij.openapi.vfs.VfsUtilCore; import com.intellij.openapi.vfs.VirtualFile; -import com.intellij.psi.PsiFile; -import com.intellij.psi.PsiManager; +import com.intellij.psi.*; +import com.intellij.psi.impl.source.tree.LeafPsiElement; +import com.intellij.psi.util.PsiTreeUtil; import com.intellij.util.ExceptionUtil; import com.intellij.util.NotNullFunction; import com.intellij.util.ObjectUtils; @@ -127,7 +128,8 @@ public class RunIdeConsoleAction extends DumbAwareAction { @NotNull VirtualFile file, @NotNull Editor editor, @NotNull IdeScriptEngine engine) { - String command = getCommandText(editor); + String command = getCommandText(project, editor); + if (StringUtil.isEmptyOrSpaces(command)) return; String profile = getProfileText(file); RunContentDescriptor descriptor = getConsoleView(project, file); ConsoleViewImpl consoleView = (ConsoleViewImpl)descriptor.getExecutionConsole(); @@ -171,12 +173,31 @@ public class RunIdeConsoleAction extends DumbAwareAction { } @NotNull - private static String getCommandText(@NotNull Editor editor) { + private static String getCommandText(@NotNull Project project, @NotNull Editor editor) { TextRange selectedRange = EditorUtil.getSelectionInAnyMode(editor); Document document = editor.getDocument(); - if (selectedRange.getLength() == 0) { + if (selectedRange.isEmpty()) { int line = document.getLineNumber(selectedRange.getStartOffset()); selectedRange = TextRange.create(document.getLineStartOffset(line), document.getLineEndOffset(line)); + + // try detect a non-trivial composite PSI element if there's a PSI file + PsiFile file = PsiDocumentManager.getInstance(project).getPsiFile(editor.getDocument()); + if (file != null && file.getFirstChild() != null && file.getFirstChild() != file.getLastChild()) { + PsiElement e1 = file.findElementAt(selectedRange.getStartOffset()); + PsiElement e2 = file.findElementAt(selectedRange.getEndOffset()); + while (e1 != e2 && (e1 instanceof PsiWhiteSpace || e1 != null && StringUtil.isEmptyOrSpaces(e1.getText()))) { + e1 = ObjectUtils.chooseNotNull(e1.getNextSibling(), PsiTreeUtil.getDeepestFirst(e1.getParent())); + } + while (e1 != e2 && (e2 instanceof PsiWhiteSpace || e2 != null && StringUtil.isEmptyOrSpaces(e2.getText()))) { + e2 = ObjectUtils.chooseNotNull(e2.getPrevSibling(), PsiTreeUtil.getDeepestLast(e2.getParent())); + } + if (e1 instanceof LeafPsiElement) e1 = e1.getParent(); + if (e2 instanceof LeafPsiElement) e2 = e2.getParent(); + PsiElement parent = e1 == null ? e2 : e2 == null ? e1 : PsiTreeUtil.findCommonParent(e1, e2); + if (parent != null && parent != file) { + selectedRange = parent.getTextRange(); + } + } } return document.getText(selectedRange); } @@ -242,6 +263,7 @@ public class RunIdeConsoleAction extends DumbAwareAction { Editor editor = CommonDataKeys.EDITOR.getData(e.getDataContext()); VirtualFile virtualFile = CommonDataKeys.VIRTUAL_FILE.getData(e.getDataContext()); if (project == null || editor == null || virtualFile == null) return; + PsiDocumentManager.getInstance(project).commitAllDocuments(); String extension = virtualFile.getExtension(); if (extension != null && (engine == null || !engine.getFileExtensions().contains(extension))) {