diff options
Diffstat (limited to 'python/edu/src/com/jetbrains/python/edu/PyExecuteFileLineMarkerProvider.java')
-rw-r--r-- | python/edu/src/com/jetbrains/python/edu/PyExecuteFileLineMarkerProvider.java | 91 |
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); + } +} |