mirror of
https://gitflic.ru/project/openide/openide.git
synced 2026-09-27 10:03:11 +07:00
load and render python stdlib in scientific mode
This commit is contained in:
@@ -26,6 +26,15 @@
|
||||
<orderEntry type="library" name="gson" level="project" />
|
||||
<orderEntry type="module" module-name="xml-openapi" />
|
||||
<orderEntry type="module" module-name="vcs-api" />
|
||||
<orderEntry type="module-library">
|
||||
<library name="org.jsoup:jsoup:1.10.3" type="repository">
|
||||
<properties maven-id="org.jsoup:jsoup:1.10.3" />
|
||||
<CLASSES>
|
||||
<root url="jar://$MAVEN_REPOSITORY$/org/jsoup/jsoup/1.10.3/jsoup-1.10.3.jar!/" />
|
||||
</CLASSES>
|
||||
<JAVADOC />
|
||||
<SOURCES />
|
||||
</library>
|
||||
</orderEntry>
|
||||
</component>
|
||||
</module>
|
||||
|
||||
</module>
|
||||
@@ -26,6 +26,8 @@ import com.intellij.openapi.actionSystem.Presentation;
|
||||
import com.intellij.openapi.actionSystem.ToggleAction;
|
||||
import com.intellij.openapi.editor.colors.EditorColorsManager;
|
||||
import com.intellij.openapi.editor.colors.EditorColorsScheme;
|
||||
import com.intellij.openapi.module.Module;
|
||||
import com.intellij.openapi.module.ModuleUtilCore;
|
||||
import com.intellij.openapi.options.FontSize;
|
||||
import com.intellij.openapi.project.DumbAware;
|
||||
import com.intellij.openapi.project.Project;
|
||||
@@ -35,6 +37,7 @@ import com.intellij.psi.PsiElement;
|
||||
import com.intellij.psi.PsiManager;
|
||||
import com.intellij.util.ui.UIUtil;
|
||||
import com.jetbrains.python.console.PythonConsoleToolWindow;
|
||||
import com.jetbrains.python.documentation.PyDocumentationSettings;
|
||||
import com.jetbrains.python.run.PythonConfigurationType;
|
||||
import com.jetbrains.python.run.PythonRunConfiguration;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
@@ -78,12 +81,21 @@ public class PySciViewAction extends ToggleAction implements DumbAware {
|
||||
showDocumentationToolwindow(project, element);
|
||||
showDataViewAsToolwindow(project);
|
||||
showCommandLineInRunConfiguration(project, true);
|
||||
renderExternalDocumentation(element, true);
|
||||
}
|
||||
else {
|
||||
hideConsoleToolwindow(project);
|
||||
restoreDocumentationPopup(project);
|
||||
hideDataViewer(project);
|
||||
showCommandLineInRunConfiguration(project, false);
|
||||
renderExternalDocumentation(element, false);
|
||||
}
|
||||
}
|
||||
|
||||
private static void renderExternalDocumentation(PsiElement element, boolean render) {
|
||||
final Module module = ModuleUtilCore.findModuleForPsiElement(element);
|
||||
if (module != null) {
|
||||
PyDocumentationSettings.getInstance(module).setRenderExternalDocumentation(render);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
+2
-1
@@ -22,6 +22,7 @@ import com.intellij.openapi.vfs.VirtualFile;
|
||||
import com.intellij.psi.PsiElement;
|
||||
import com.intellij.psi.PsiFileSystemItem;
|
||||
import com.intellij.psi.PsiNamedElement;
|
||||
import com.intellij.psi.util.QualifiedName;
|
||||
import com.jetbrains.python.PyNames;
|
||||
import com.jetbrains.python.documentation.PythonDocumentationLinkProvider;
|
||||
import com.jetbrains.python.documentation.PythonDocumentationProvider;
|
||||
@@ -29,7 +30,6 @@ import com.jetbrains.python.psi.PyClass;
|
||||
import com.jetbrains.python.psi.PyFile;
|
||||
import com.jetbrains.python.psi.PyFunction;
|
||||
import com.jetbrains.python.psi.impl.PyBuiltinCache;
|
||||
import com.intellij.psi.util.QualifiedName;
|
||||
import com.jetbrains.python.psi.resolve.QualifiedNameFinder;
|
||||
import com.jetbrains.python.sdk.PythonSdkType;
|
||||
|
||||
@@ -544,6 +544,7 @@ public class PyStdlibDocumentationLinkProvider implements PythonDocumentationLin
|
||||
|
||||
@Override
|
||||
public String getExternalDocumentationUrl(PsiElement element, PsiElement originalElement) {
|
||||
if (PyBuiltinCache.getInstance(element).isBuiltin(element)) return null;
|
||||
PsiFileSystemItem file = element instanceof PsiFileSystemItem ? (PsiFileSystemItem) element : element.getContainingFile();
|
||||
if (PyNames.INIT_DOT_PY.equals(file.getName())) {
|
||||
file = file.getParent();
|
||||
|
||||
@@ -49,7 +49,7 @@
|
||||
</constraints>
|
||||
<properties/>
|
||||
</component>
|
||||
<grid id="e7a5f" binding="myDocStringsPanel" layout-manager="GridLayoutManager" row-count="2" column-count="2" same-size-horizontally="false" same-size-vertically="false" hgap="-1" vgap="-1">
|
||||
<grid id="e7a5f" binding="myDocStringsPanel" layout-manager="GridLayoutManager" row-count="3" column-count="2" same-size-horizontally="false" same-size-vertically="false" hgap="-1" vgap="-1">
|
||||
<margin top="0" left="0" bottom="0" right="0"/>
|
||||
<constraints>
|
||||
<grid row="2" column="0" row-span="2" col-span="2" vsize-policy="3" hsize-policy="3" anchor="0" fill="3" indent="0" use-parent-layout="false"/>
|
||||
@@ -82,6 +82,14 @@
|
||||
<text value="Analyze Python code in docstrings"/>
|
||||
</properties>
|
||||
</component>
|
||||
<component id="e3228" class="javax.swing.JCheckBox" binding="renderExternal">
|
||||
<constraints>
|
||||
<grid row="2" column="0" row-span="1" col-span="2" vsize-policy="0" hsize-policy="3" anchor="8" fill="0" indent="0" use-parent-layout="false"/>
|
||||
</constraints>
|
||||
<properties>
|
||||
<text value="Render external documentation for stdlib"/>
|
||||
</properties>
|
||||
</component>
|
||||
</children>
|
||||
</grid>
|
||||
<grid id="9f040" binding="myRestPanel" layout-manager="GridLayoutManager" row-count="2" column-count="2" same-size-horizontally="false" same-size-vertically="false" hgap="-1" vgap="-1">
|
||||
|
||||
@@ -39,7 +39,6 @@ import com.intellij.ui.ListCellRendererWrapper;
|
||||
import com.intellij.util.FileContentUtil;
|
||||
import com.intellij.util.FileContentUtilCore;
|
||||
import com.jetbrains.python.PyBundle;
|
||||
import com.jetbrains.python.PyNames;
|
||||
import com.jetbrains.python.PythonFileType;
|
||||
import com.jetbrains.python.ReSTService;
|
||||
import com.jetbrains.python.documentation.PyDocumentationSettings;
|
||||
@@ -78,6 +77,7 @@ public class PyIntegratedToolsConfigurable implements SearchableConfigurable {
|
||||
private JCheckBox analyzeDoctest;
|
||||
private JPanel myDocStringsPanel;
|
||||
private JPanel myRestPanel;
|
||||
private JCheckBox renderExternal;
|
||||
|
||||
public PyIntegratedToolsConfigurable(@NotNull Module module) {
|
||||
myModule = module;
|
||||
@@ -99,6 +99,7 @@ public class PyIntegratedToolsConfigurable implements SearchableConfigurable {
|
||||
myWorkDir.setText(service.getWorkdir());
|
||||
txtIsRst.setSelected(service.txtIsRst());
|
||||
analyzeDoctest.setSelected(myDocumentationSettings.isAnalyzeDoctest());
|
||||
renderExternal.setSelected(myDocumentationSettings.isRenderExternalDocumentation());
|
||||
myRequirementsPathField.addBrowseFolderListener("Choose path to the package requirements file:", null, myProject,
|
||||
FileChooserDescriptorFactory.createSingleLocalFileDescriptor());
|
||||
myRequirementsPathField.setText(getRequirementsPath());
|
||||
@@ -207,6 +208,9 @@ public class PyIntegratedToolsConfigurable implements SearchableConfigurable {
|
||||
if (analyzeDoctest.isSelected() != myDocumentationSettings.isAnalyzeDoctest()) {
|
||||
return true;
|
||||
}
|
||||
if (renderExternal.isSelected() != myDocumentationSettings.isRenderExternalDocumentation()) {
|
||||
return true;
|
||||
}
|
||||
if (!ReSTService.getInstance(myModule).getWorkdir().equals(myWorkDir.getText())) {
|
||||
return true;
|
||||
}
|
||||
@@ -235,6 +239,7 @@ public class PyIntegratedToolsConfigurable implements SearchableConfigurable {
|
||||
FileContentUtil.reparseFiles(myProject, Lists.newArrayList(files), false);
|
||||
}
|
||||
myModel.apply();
|
||||
myDocumentationSettings.setRenderExternalDocumentation(renderExternal.isSelected());
|
||||
myDocumentationSettings.setFormat((DocStringFormat)myDocstringFormatComboBox.getSelectedItem());
|
||||
final ReSTService reSTService = ReSTService.getInstance(myModule);
|
||||
reSTService.setWorkdir(myWorkDir.getText());
|
||||
@@ -271,6 +276,7 @@ public class PyIntegratedToolsConfigurable implements SearchableConfigurable {
|
||||
myWorkDir.setText(ReSTService.getInstance(myModule).getWorkdir());
|
||||
txtIsRst.setSelected(ReSTService.getInstance(myModule).txtIsRst());
|
||||
analyzeDoctest.setSelected(myDocumentationSettings.isAnalyzeDoctest());
|
||||
renderExternal.setSelected(myDocumentationSettings.isRenderExternalDocumentation());
|
||||
myRequirementsPathField.setText(getRequirementsPath());
|
||||
}
|
||||
|
||||
|
||||
@@ -47,6 +47,7 @@ public class PyDocumentationSettings implements PersistentStateComponent<PyDocum
|
||||
|
||||
@NotNull private DocStringFormat myDocStringFormat = DEFAULT_DOCSTRING_FORMAT;
|
||||
private boolean myAnalyzeDoctest = true;
|
||||
private boolean myRenderExternalDocumentation;
|
||||
|
||||
public boolean isNumpyFormat(PsiFile file) {
|
||||
return isFormat(file, DocStringFormat.NUMPY);
|
||||
@@ -117,6 +118,14 @@ public class PyDocumentationSettings implements PersistentStateComponent<PyDocum
|
||||
myAnalyzeDoctest = analyze;
|
||||
}
|
||||
|
||||
public boolean isRenderExternalDocumentation() {
|
||||
return myRenderExternalDocumentation;
|
||||
}
|
||||
|
||||
public void setRenderExternalDocumentation(boolean renderExternalDocumentation) {
|
||||
myRenderExternalDocumentation = renderExternalDocumentation;
|
||||
}
|
||||
|
||||
@Override
|
||||
public PyDocumentationSettings getState() {
|
||||
return this;
|
||||
|
||||
@@ -22,16 +22,20 @@ import com.intellij.openapi.application.ApplicationManager;
|
||||
import com.intellij.openapi.application.ModalityState;
|
||||
import com.intellij.openapi.editor.Editor;
|
||||
import com.intellij.openapi.extensions.Extensions;
|
||||
import com.intellij.openapi.module.Module;
|
||||
import com.intellij.openapi.module.ModuleUtilCore;
|
||||
import com.intellij.openapi.project.Project;
|
||||
import com.intellij.openapi.projectRoots.Sdk;
|
||||
import com.intellij.openapi.roots.ProjectRootManager;
|
||||
import com.intellij.openapi.ui.Messages;
|
||||
import com.intellij.openapi.util.Computable;
|
||||
import com.intellij.openapi.vfs.VirtualFile;
|
||||
import com.intellij.psi.*;
|
||||
import com.intellij.psi.util.PsiTreeUtil;
|
||||
import com.intellij.psi.util.QualifiedName;
|
||||
import com.jetbrains.python.PyNames;
|
||||
import com.jetbrains.python.PythonDialectsTokenSetProvider;
|
||||
import com.jetbrains.python.codeInsight.stdlib.PyStdlibDocumentationLinkProvider;
|
||||
import com.jetbrains.python.console.PydevConsoleRunner;
|
||||
import com.jetbrains.python.console.PydevDocumentationProvider;
|
||||
import com.jetbrains.python.documentation.docstrings.DocStringUtil;
|
||||
@@ -50,9 +54,14 @@ import org.apache.commons.httpclient.params.HttpConnectionManagerParams;
|
||||
import org.jetbrains.annotations.NonNls;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
import org.jsoup.Jsoup;
|
||||
import org.jsoup.nodes.Document;
|
||||
import org.jsoup.select.Elements;
|
||||
|
||||
import java.io.File;
|
||||
import java.io.IOException;
|
||||
import java.net.MalformedURLException;
|
||||
import java.net.URL;
|
||||
import java.util.Collections;
|
||||
import java.util.List;
|
||||
|
||||
@@ -96,7 +105,7 @@ public class PythonDocumentationProvider extends AbstractDocumentationProvider i
|
||||
summary = docString.getSummary();
|
||||
}
|
||||
return $(cat.toString()).add(describeDecorators(func, LSame2, ", ", LSame1)).add(describeFunction(func, LSame2, LSame1))
|
||||
.toString() + "\n" + summary;
|
||||
.toString() + "\n" + summary;
|
||||
}
|
||||
else if (element instanceof PyClass) {
|
||||
final PyClass cls = (PyClass)element;
|
||||
@@ -442,7 +451,56 @@ public class PythonDocumentationProvider extends AbstractDocumentationProvider i
|
||||
|
||||
@Override
|
||||
public String fetchExternalDocumentation(Project project, PsiElement element, List<String> docUrls) {
|
||||
return null;
|
||||
final Module module = ModuleUtilCore.findModuleForPsiElement(element);
|
||||
if (module != null && !PyDocumentationSettings.getInstance(module).isRenderExternalDocumentation()) return null;
|
||||
return ApplicationManager.getApplication().runReadAction((Computable<String>)() -> {
|
||||
PsiFileSystemItem file = element instanceof PsiFileSystemItem ? (PsiFileSystemItem)element : element.getContainingFile();
|
||||
if (file == null) return null;
|
||||
if (PyNames.INIT_DOT_PY.equals(file.getName())) {
|
||||
file = file.getParent();
|
||||
assert file != null;
|
||||
}
|
||||
final Sdk sdk = PyBuiltinCache.findSdkForFile(file);
|
||||
if (sdk == null) {
|
||||
return null;
|
||||
}
|
||||
|
||||
final QualifiedName moduleQName = QualifiedNameFinder.findCanonicalImportPath(element, element);
|
||||
if (moduleQName == null) {
|
||||
return null;
|
||||
}
|
||||
PsiNamedElement namedElement = (element instanceof PsiNamedElement && !(element instanceof PsiFileSystemItem))
|
||||
? (PsiNamedElement)element
|
||||
: null;
|
||||
if (namedElement instanceof PyFunction && PyNames.INIT.equals(namedElement.getName())) {
|
||||
final PyClass containingClass = ((PyFunction)namedElement).getContainingClass();
|
||||
if (containingClass != null) {
|
||||
namedElement = containingClass;
|
||||
}
|
||||
}
|
||||
final PyStdlibDocumentationLinkProvider stdlibDocumentationLinkProvider =
|
||||
Extensions.findExtension(PythonDocumentationLinkProvider.EP_NAME, PyStdlibDocumentationLinkProvider.class);
|
||||
final String url = stdlibDocumentationLinkProvider.getExternalDocumentationUrl(element, element);
|
||||
if (url == null) {
|
||||
return null;
|
||||
}
|
||||
|
||||
try {
|
||||
final Document document = Jsoup.parse(new URL(url), 1000);
|
||||
final String elementId = namedElement != null ? moduleQName + "." + namedElement.getName() : "module-" + moduleQName;
|
||||
document.select("a.headerlink").remove();
|
||||
final Elements parents = document.getElementsByAttributeValue("id", elementId).parents();
|
||||
if (parents.isEmpty()) {
|
||||
return document.toString();
|
||||
}
|
||||
return parents.get(0).toString();
|
||||
}
|
||||
catch (MalformedURLException ignored) {
|
||||
}
|
||||
catch (IOException ignored) {
|
||||
}
|
||||
return null;
|
||||
});
|
||||
}
|
||||
|
||||
@Override
|
||||
|
||||
Reference in New Issue
Block a user