From 7f2d56b239e5b29349f6bc233df4a5c08215c533 Mon Sep 17 00:00:00 2001 From: Ekaterina Tuzova Date: Fri, 15 Apr 2011 11:20:11 +0400 Subject: [PATCH] added simple documentation stub generation for python functions --- .../PythonDocumentationProvider.java | 31 ++++++++++++++++ .../python/editor/PythonEnterHandler.java | 37 +++++++++++++++++++ 2 files changed, 68 insertions(+) diff --git a/python/src/com/jetbrains/python/documentation/PythonDocumentationProvider.java b/python/src/com/jetbrains/python/documentation/PythonDocumentationProvider.java index e670efa51696..a65bf1bfbe5f 100644 --- a/python/src/com/jetbrains/python/documentation/PythonDocumentationProvider.java +++ b/python/src/com/jetbrains/python/documentation/PythonDocumentationProvider.java @@ -53,12 +53,16 @@ import java.util.regex.Pattern; /** * Provides quick docs for classes, methods, and functions. + * Generates documentation stub */ public class PythonDocumentationProvider extends AbstractDocumentationProvider implements ExternalDocumentationProvider { @NonNls private static final String LINK_TYPE_CLASS = "#class#"; @NonNls private static final String LINK_TYPE_PARENT = "#parent#"; + @NonNls private static final String RST_PREFIX = ":"; + @NonNls private static final String EPYDOC_PREFIX = "@"; + // provides ctrl+hover info public String getQuickNavigateInfo(final PsiElement element, PsiElement originalElement) { if (element instanceof PyFunction) { @@ -799,4 +803,31 @@ public class PythonDocumentationProvider extends AbstractDocumentationProvider i } return ret; } + + public String generateDocumentationContentStub(PyFunction element, String substring, String offset) { + Project project = element.getProject(); + PyDocumentationSettings documentationSettings = PyDocumentationSettings.getInstance(project); + String result = ""; + if (documentationSettings.isEpydocFormat()) + result += generateContent(element, offset, EPYDOC_PREFIX); + else if (documentationSettings.isReSTFormat()) + result += generateContent(element, offset, RST_PREFIX); + result += substring; + return result; + } + + private String generateContent(PyFunction element, String offset, String prefix) { + PyParameter[] list = element.getParameterList().getParameters(); + StringBuilder builder = new StringBuilder(); + for(PyParameter p : list) { + builder.append(prefix); + builder.append("param "); + builder.append(p.getName()); + builder.append(": "); + builder.append(offset); + } + builder.append(prefix).append("return:").append(offset); + return builder.toString(); + } + } diff --git a/python/src/com/jetbrains/python/editor/PythonEnterHandler.java b/python/src/com/jetbrains/python/editor/PythonEnterHandler.java index e13480e7cfbe..17ff790b3664 100644 --- a/python/src/com/jetbrains/python/editor/PythonEnterHandler.java +++ b/python/src/com/jetbrains/python/editor/PythonEnterHandler.java @@ -1,5 +1,6 @@ package com.jetbrains.python.editor; +import com.intellij.codeInsight.CodeInsightSettings; import com.intellij.codeInsight.editorActions.AutoHardWrapHandler; import com.intellij.codeInsight.editorActions.enter.EnterHandlerDelegate; import com.intellij.ide.DataManager; @@ -12,6 +13,7 @@ import com.intellij.openapi.util.Ref; import com.intellij.psi.*; import com.intellij.psi.util.PsiTreeUtil; import com.jetbrains.python.PyTokenTypes; +import com.jetbrains.python.documentation.PythonDocumentationProvider; import com.jetbrains.python.psi.*; import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.Nullable; @@ -58,6 +60,20 @@ public class PythonEnterHandler implements EnterHandlerDelegate { if (element == null) { return Result.Continue; } + CodeInsightSettings codeInsightSettings = CodeInsightSettings.getInstance(); + if (codeInsightSettings.JAVADOC_STUB_ON_ENTER && inDocComment(element)) { + PythonDocumentationProvider provider = new PythonDocumentationProvider(); + PyFunction fun = PsiTreeUtil.getParentOfType(element, PyFunction.class); + if (fun != null) { + PsiWhiteSpace whitespace = PsiTreeUtil.getPrevSiblingOfType(fun.getStatementList(), PsiWhiteSpace.class); + String docStub = provider.generateDocumentationContentStub(fun, element.getParent().getText().substring(0,3), whitespace.getText()); + if (docStub != null && docStub.length() != 0) { + editor.getDocument().insertString(editor.getCaretModel().getOffset(), docStub); + return Result.Continue; + } + } + } + if (offset > 0) { final PsiElement beforeCaret = file.findElementAt(offset-1); if (beforeCaret instanceof PsiWhiteSpace && beforeCaret.getText().indexOf('\\') > 0) { @@ -117,6 +133,27 @@ public class PythonEnterHandler implements EnterHandlerDelegate { return Result.Continue; } + private boolean inDocComment(PsiElement element) { + PyStringLiteralExpression string = PsiTreeUtil.getParentOfType(element, PyStringLiteralExpression.class); + if (string != null) { + PyFunction func = PsiTreeUtil.getParentOfType(element, PyFunction.class); + if (func != null) { + String text = string.getText(); + if (text.startsWith("\"\"\"") || text.startsWith("'''")) { + if (!text.endsWith("\"\"\"") && !text.endsWith("'''")) + return true; + PsiErrorElement error = PsiTreeUtil.getNextSiblingOfType(string, PsiErrorElement.class); + if (error != null) + return true; + error = PsiTreeUtil.getNextSiblingOfType(string.getParent(), PsiErrorElement.class); + if (error != null) + return true; + } + } + } + return false; + } + @Nullable private static PsiElement findWrappable(PsiFile file, int offset, boolean before) { PsiElement wrappable = before