summaryrefslogtreecommitdiff
path: root/python/edu/src/com/jetbrains/python/edu/PyExecuteFileLineMarkerProvider.java
diff options
context:
space:
mode:
Diffstat (limited to 'python/edu/src/com/jetbrains/python/edu/PyExecuteFileLineMarkerProvider.java')
-rw-r--r--python/edu/src/com/jetbrains/python/edu/PyExecuteFileLineMarkerProvider.java91
1 files changed, 91 insertions, 0 deletions
diff --git a/python/edu/src/com/jetbrains/python/edu/PyExecuteFileLineMarkerProvider.java b/python/edu/src/com/jetbrains/python/edu/PyExecuteFileLineMarkerProvider.java
new file mode 100644
index 000000000000..03522bb8cf8a
--- /dev/null
+++ b/python/edu/src/com/jetbrains/python/edu/PyExecuteFileLineMarkerProvider.java
@@ -0,0 +1,91 @@
+package com.jetbrains.python.edu;
+
+import com.intellij.codeHighlighting.Pass;
+import com.intellij.codeInsight.daemon.GutterIconNavigationHandler;
+import com.intellij.codeInsight.daemon.LineMarkerInfo;
+import com.intellij.codeInsight.daemon.LineMarkerProvider;
+import com.intellij.execution.actions.ConfigurationContext;
+import com.intellij.icons.AllIcons;
+import com.intellij.ide.DataManager;
+import com.intellij.openapi.editor.Editor;
+import com.intellij.openapi.editor.markup.GutterIconRenderer;
+import com.intellij.psi.PsiComment;
+import com.intellij.psi.PsiElement;
+import com.intellij.psi.PsiWhiteSpace;
+import com.intellij.psi.util.PsiUtilBase;
+import com.intellij.util.Function;
+import com.jetbrains.python.psi.PyFile;
+import com.jetbrains.python.psi.PyImportStatement;
+import com.jetbrains.python.psi.PyStatement;
+import org.jetbrains.annotations.NotNull;
+import org.jetbrains.annotations.Nullable;
+
+import java.awt.event.MouseEvent;
+import java.util.Collection;
+import java.util.List;
+
+/**
+ * @author traff
+ */
+public class PyExecuteFileLineMarkerProvider implements LineMarkerProvider {
+ @Nullable
+ @Override
+ public LineMarkerInfo getLineMarkerInfo(@NotNull PsiElement element) {
+ return null;
+ }
+
+ @Override
+ public void collectSlowLineMarkers(@NotNull List<PsiElement> elements, @NotNull Collection<LineMarkerInfo> result) {
+ for (PsiElement element : elements) {
+ if (isFirstCodeLine(element)) {
+ result.add(new LineMarkerInfo<PsiElement>(
+ element, element.getTextRange(), AllIcons.Actions.Execute, Pass.UPDATE_OVERRIDEN_MARKERS,
+ new Function<PsiElement, String>() {
+ @Override
+ public String fun(PsiElement e) {
+ return "Execute '" + e.getContainingFile().getName() + "'";
+ }
+ },
+ new GutterIconNavigationHandler<PsiElement>() {
+ @Override
+ public void navigate(MouseEvent e, PsiElement elt) {
+ executeCurrentScript(elt);
+ }
+ },
+ GutterIconRenderer.Alignment.RIGHT));
+ }
+ }
+ }
+
+ private static void executeCurrentScript(PsiElement elt) {
+ Editor editor = PsiUtilBase.findEditor(elt);
+ assert editor != null;
+
+ final ConfigurationContext context =
+ ConfigurationContext.getFromContext(DataManager.getInstance().getDataContext(editor.getComponent()));
+ PyRunCurrentFileAction.run(context);
+ }
+
+ private static boolean isFirstCodeLine(PsiElement element) {
+ return element instanceof PyStatement &&
+ element.getParent() instanceof PyFile &&
+ !isNothing(element) &&
+ nothingBefore(element);
+ }
+
+ private static boolean nothingBefore(PsiElement element) {
+ element = element.getPrevSibling();
+ while (element != null) {
+ if (!isNothing(element)) {
+ return false;
+ }
+ element = element.getPrevSibling();
+ }
+
+ return true;
+ }
+
+ private static boolean isNothing(PsiElement element) {
+ return (element instanceof PsiComment) || (element instanceof PyImportStatement) || (element instanceof PsiWhiteSpace);
+ }
+}