mirror of
https://gitflic.ru/project/openide/openide.git
synced 2026-09-27 10:03:11 +07:00
PY-40996 Add ability to collapse and expand python type annotations
"Collapse/Expand Python Type Annotations" actions, an intention and a setting GitOrigin-RevId: e055538b29b07c1836399f52754b786a15351050
This commit is contained in:
committed by
intellij-monorepo-bot
parent
531290213f
commit
e768aa3785
@@ -574,6 +574,10 @@ action.PyDebugger.ViewArray.text=View as Array
|
||||
action.PyDebugger.CustomizeDataView.text=Customize Data View
|
||||
action.PythonGenerateDictionaries.text=Generate Python Spellchecker Dictionaries
|
||||
group.PyPackagingMenu.text=Packaging
|
||||
action.CollapsePythonTypeAnnotations.text=Collapse Python Type Annotations
|
||||
action.CollapsePythonTypeAnnotations.description=Collapse python type annotations
|
||||
action.ExpandPythonTypeAnnotations.text=Expand Python Type Annotations
|
||||
action.ExpandPythonTypeAnnotations.description=Expand python type annotations
|
||||
action.CleanPyc.text=Clean Python Compiled Files
|
||||
action.CleanPyc.description=Delete compiled bytecode files in selected directory and its subdirectories
|
||||
action.CleanPyc.status.bar.text.deleted.bytecode.files=Deleted {0} bytecode {0,choice,0#files|1#file|2#files}
|
||||
@@ -1138,6 +1142,7 @@ python.folding.options.title=Python
|
||||
python.long.string.literals=Long string literals
|
||||
python.long.collection.literals=Long collection literals
|
||||
python.sequential.comments=Sequential comments
|
||||
python.type.annotations=Type annotations
|
||||
python.provide.a.qualified.name.of.a.module=Provide a qualified name of a module
|
||||
python.input.file.doesn.t.exist=Input file doesn't exist
|
||||
python.call.graph=Call Graph
|
||||
|
||||
@@ -249,6 +249,12 @@
|
||||
<categoryKey>INTN.category.python</categoryKey>
|
||||
</intentionAction>
|
||||
|
||||
<intentionAction>
|
||||
<className>com.jetbrains.python.codeInsight.intentions.PyHideTypeAnnotationsIntention</className>
|
||||
<bundleName>messages.PyPsiBundle</bundleName>
|
||||
<categoryKey>INTN.category.python</categoryKey>
|
||||
</intentionAction>
|
||||
|
||||
<intentionAction>
|
||||
<className>com.jetbrains.python.codeInsight.intentions.SpecifyTypeInPy3AnnotationsIntention</className>
|
||||
<bundleName>messages.PyPsiBundle</bundleName>
|
||||
@@ -434,7 +440,7 @@
|
||||
<bundleName>messages.PyPsiBundle</bundleName>
|
||||
<categoryKey>INTN.category.python</categoryKey>
|
||||
</intentionAction>
|
||||
|
||||
|
||||
<registryKey defaultValue="false"
|
||||
description="Enable pyi stubs distributed with numpy (see https://github.com/numpy/numpy/issues/18565)"
|
||||
key="enable.numpy.pyi.stubs"/>
|
||||
|
||||
+2
@@ -0,0 +1,2 @@
|
||||
def foo(var: ...) -> ...:
|
||||
x: ...
|
||||
+2
@@ -0,0 +1,2 @@
|
||||
def foo(var: str) -> str:
|
||||
x: str
|
||||
+7
@@ -0,0 +1,7 @@
|
||||
<html>
|
||||
<body>
|
||||
<span>
|
||||
Collapses type annotations in .py files
|
||||
</span>
|
||||
</body>
|
||||
</html>
|
||||
@@ -371,6 +371,10 @@ INTN.NAME.specify.type.in.docstring=Specify type for reference in docstring
|
||||
INTN.specify.type.in.docstring=Specify type for the reference in docstring
|
||||
INTN.specify.return.type.in.docstring=Specify return type in docstring
|
||||
|
||||
#HideTypeAnnotationsIntention
|
||||
INTN.NAME.hide.type.annotations=Hide type annotations
|
||||
INTN.hide.type.annotations=Hide type annotations
|
||||
|
||||
#SpecifyTypeInPy3AnnotationsIntention
|
||||
INTN.NAME.specify.type.in.annotation=Specify type for reference using annotation
|
||||
INTN.specify.type.in.annotation=Specify type for the reference using annotation
|
||||
|
||||
+43
@@ -0,0 +1,43 @@
|
||||
// Copyright 2000-2023 JetBrains s.r.o. Use of this source code is governed by the Apache 2.0 license that can be found in the LICENSE file.
|
||||
package com.jetbrains.python.codeInsight.intentions
|
||||
|
||||
import com.intellij.codeInsight.TargetElementUtilBase
|
||||
import com.intellij.openapi.editor.Editor
|
||||
import com.intellij.openapi.project.Project
|
||||
import com.intellij.psi.PsiFile
|
||||
import com.intellij.psi.util.PsiTreeUtil
|
||||
import com.jetbrains.python.PyPsiBundle
|
||||
import com.jetbrains.python.psi.PyAnnotation
|
||||
import com.jetbrains.python.psi.PyUtil
|
||||
|
||||
/**
|
||||
* Folds type annotations in Python code
|
||||
*/
|
||||
class PyHideTypeAnnotationsIntention : PyBaseIntentionAction() {
|
||||
override fun getFamilyName(): String {
|
||||
return PyPsiBundle.message("INTN.NAME.hide.type.annotations")
|
||||
}
|
||||
|
||||
override fun isAvailable(project: Project, editor: Editor?, file: PsiFile?): Boolean {
|
||||
val offset = TargetElementUtilBase.adjustOffset(file, editor?.document ?: return false, editor.caretModel.offset)
|
||||
val element = PyUtil.findNonWhitespaceAtOffset(file, offset)
|
||||
val annotation = PsiTreeUtil.getParentOfType(element, PyAnnotation::class.java)
|
||||
text = PyPsiBundle.message("INTN.hide.type.annotations")
|
||||
return annotation != null
|
||||
}
|
||||
|
||||
override fun doInvoke(project: Project, editor: Editor, file: PsiFile) {
|
||||
val allRegions = editor.foldingModel.allFoldRegions
|
||||
val result = allRegions.filter { it.group != null && it.group.toString() == "Python type annotation" }
|
||||
|
||||
editor.foldingModel.runBatchFoldingOperation {
|
||||
for (region in result) {
|
||||
region.isExpanded = false
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
override fun startInWriteAction(): Boolean {
|
||||
return false
|
||||
}
|
||||
}
|
||||
@@ -766,6 +766,9 @@
|
||||
<add-to-group group-id="ProjectViewPopupMenu" anchor="after" relative-to-action="ProjectViewPopupMenuRefactoringGroup"/>
|
||||
</action>
|
||||
|
||||
<action id="CollapsePythonTypeAnnotations" class="com.jetbrains.python.actions.PyCollapseTypeAnnotationsAction"/>
|
||||
<action id="ExpandPythonTypeAnnotations" class="com.jetbrains.python.actions.PyExpandTypeAnnotationsAction"/>
|
||||
|
||||
<group id="PyPackagingMenu">
|
||||
<action id="PySyncPythonRequirements" class="com.jetbrains.python.packaging.PySyncPythonRequirementsAction"/>
|
||||
<action id="CreateSetupPy" class="com.jetbrains.python.packaging.setupPy.CreateSetupPyAction"/>
|
||||
|
||||
@@ -6,6 +6,7 @@ import com.intellij.lang.ASTNode;
|
||||
import com.intellij.lang.folding.CustomFoldingBuilder;
|
||||
import com.intellij.lang.folding.FoldingDescriptor;
|
||||
import com.intellij.openapi.editor.Document;
|
||||
import com.intellij.openapi.editor.FoldingGroup;
|
||||
import com.intellij.openapi.project.DumbAware;
|
||||
import com.intellij.openapi.util.Pair;
|
||||
import com.intellij.openapi.util.TextRange;
|
||||
@@ -34,6 +35,8 @@ public class PythonFoldingBuilder extends CustomFoldingBuilder implements DumbAw
|
||||
PyElementTypes.LIST_COMP_EXPRESSION,
|
||||
PyElementTypes.TUPLE_EXPRESSION);
|
||||
|
||||
public static final String PYTHON_TYPE_ANNOTATION_GROUP_NAME = "Python type annotation";
|
||||
|
||||
@Override
|
||||
protected void buildLanguageFoldRegions(@NotNull List<FoldingDescriptor> descriptors,
|
||||
@NotNull PsiElement root,
|
||||
@@ -65,6 +68,13 @@ public class PythonFoldingBuilder extends CustomFoldingBuilder implements DumbAw
|
||||
else if (elementType == PyTokenTypes.END_OF_LINE_COMMENT) {
|
||||
foldSequentialComments(node, descriptors);
|
||||
}
|
||||
else if (elementType == PyElementTypes.ANNOTATION) {
|
||||
var annotation = node.getPsi();
|
||||
if (annotation instanceof PyAnnotation pyAnnotation && pyAnnotation.getValue() != null) {
|
||||
descriptors.add(new FoldingDescriptor(node, pyAnnotation.getValue().getTextRange(),
|
||||
FoldingGroup.newGroup(PYTHON_TYPE_ANNOTATION_GROUP_NAME)));
|
||||
}
|
||||
}
|
||||
ASTNode child = node.getFirstChildNode();
|
||||
while (child != null) {
|
||||
appendDescriptors(child, descriptors);
|
||||
@@ -220,7 +230,8 @@ public class PythonFoldingBuilder extends CustomFoldingBuilder implements DumbAw
|
||||
if (isImport(node)) {
|
||||
return CodeFoldingSettings.getInstance().COLLAPSE_IMPORTS;
|
||||
}
|
||||
if (node.getElementType() == PyElementTypes.STRING_LITERAL_EXPRESSION) {
|
||||
var elementType = node.getElementType();
|
||||
if (elementType == PyElementTypes.STRING_LITERAL_EXPRESSION) {
|
||||
if (getDocStringOwnerType(node) == PyElementTypes.FUNCTION_DECLARATION && CodeFoldingSettings.getInstance().COLLAPSE_METHODS) {
|
||||
// method will be collapsed, no need to also collapse docstring
|
||||
return false;
|
||||
@@ -230,13 +241,16 @@ public class PythonFoldingBuilder extends CustomFoldingBuilder implements DumbAw
|
||||
}
|
||||
return PythonFoldingSettings.getInstance().isCollapseLongStrings();
|
||||
}
|
||||
if (node.getElementType() == PyTokenTypes.END_OF_LINE_COMMENT) {
|
||||
if (elementType == PyTokenTypes.END_OF_LINE_COMMENT) {
|
||||
return PythonFoldingSettings.getInstance().isCollapseSequentialComments();
|
||||
}
|
||||
if (node.getElementType() == PyElementTypes.STATEMENT_LIST && node.getTreeParent().getElementType() == PyElementTypes.FUNCTION_DECLARATION) {
|
||||
if (elementType == PyElementTypes.ANNOTATION) {
|
||||
return PythonFoldingSettings.getInstance().isCollapseTypeAnnotations();
|
||||
}
|
||||
if (elementType == PyElementTypes.STATEMENT_LIST && node.getTreeParent().getElementType() == PyElementTypes.FUNCTION_DECLARATION) {
|
||||
return CodeFoldingSettings.getInstance().COLLAPSE_METHODS;
|
||||
}
|
||||
if (FOLDABLE_COLLECTIONS_LITERALS.contains(node.getElementType())) {
|
||||
if (FOLDABLE_COLLECTIONS_LITERALS.contains(elementType)) {
|
||||
return PythonFoldingSettings.getInstance().isCollapseLongCollections();
|
||||
}
|
||||
return false;
|
||||
|
||||
@@ -14,5 +14,6 @@ final class PythonFoldingOptionsProvider extends BeanConfigurable<PythonFoldingS
|
||||
checkBox(PyBundle.message("python.long.string.literals"), settings::isCollapseLongStrings, v -> settings.COLLAPSE_LONG_STRINGS = v);
|
||||
checkBox(PyBundle.message("python.long.collection.literals"), settings::isCollapseLongCollections, v -> settings.COLLAPSE_LONG_COLLECTIONS = v);
|
||||
checkBox(PyBundle.message("python.sequential.comments"), settings::isCollapseSequentialComments, v -> settings.COLLAPSE_SEQUENTIAL_COMMENTS = v);
|
||||
checkBox(PyBundle.message("python.type.annotations"), settings::isCollapseTypeAnnotations, v -> settings.COLLAPSE_TYPE_ANNOTATIONS = v);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -15,6 +15,7 @@ public class PythonFoldingSettings implements PersistentStateComponent<PythonFol
|
||||
public boolean COLLAPSE_LONG_STRINGS;
|
||||
public boolean COLLAPSE_LONG_COLLECTIONS;
|
||||
public boolean COLLAPSE_SEQUENTIAL_COMMENTS;
|
||||
public boolean COLLAPSE_TYPE_ANNOTATIONS;
|
||||
|
||||
@Nullable
|
||||
@Override
|
||||
@@ -44,4 +45,7 @@ public class PythonFoldingSettings implements PersistentStateComponent<PythonFol
|
||||
return COLLAPSE_SEQUENTIAL_COMMENTS;
|
||||
}
|
||||
|
||||
public boolean isCollapseTypeAnnotations() {
|
||||
return COLLAPSE_TYPE_ANNOTATIONS;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -0,0 +1,25 @@
|
||||
// Copyright 2000-2023 JetBrains s.r.o. and contributors. Use of this source code is governed by the Apache 2.0 license.
|
||||
package com.jetbrains.python.actions
|
||||
|
||||
import com.intellij.codeInsight.folding.impl.actions.BaseFoldingHandler
|
||||
import com.intellij.openapi.actionSystem.DataContext
|
||||
import com.intellij.openapi.editor.Caret
|
||||
import com.intellij.openapi.editor.Editor
|
||||
import com.intellij.openapi.editor.actionSystem.EditorAction
|
||||
import com.jetbrains.python.PythonFoldingBuilder
|
||||
|
||||
class PyCollapseTypeAnnotationsAction : EditorAction(PyTypeAnnotationsFoldingHandler(false))
|
||||
|
||||
class PyExpandTypeAnnotationsAction : EditorAction(PyTypeAnnotationsFoldingHandler(true))
|
||||
|
||||
class PyTypeAnnotationsFoldingHandler(val expand: Boolean) : BaseFoldingHandler() {
|
||||
override fun doExecute(editor: Editor, caret: Caret?, dataContext: DataContext) {
|
||||
val pythonTypeRegions = getFoldRegionsForSelection(editor, caret)
|
||||
.filter { it.group != null && it.group.toString() == PythonFoldingBuilder.PYTHON_TYPE_ANNOTATION_GROUP_NAME }
|
||||
editor.foldingModel.runBatchFoldingOperation {
|
||||
for (region in pythonTypeRegions) {
|
||||
region.isExpanded = expand
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user