mirror of
https://gitflic.ru/project/openide/openide.git
synced 2026-09-13 21:55:01 +07:00
PY-45729 Intention to convert between single-line comma-separated things and multi-line representation
Merge-request: IJ-MR-155221 Merged-by: Aleksandr Govenko <aleksandr.govenko@jetbrains.com> GitOrigin-RevId: 1da524fe3f995e28bf23843f02761065ae45f965
This commit is contained in:
committed by
intellij-monorepo-bot
parent
a04f2e9512
commit
ab13d9dfd2
@@ -269,6 +269,8 @@ The Python plug-in provides smart editing for Python scripts. The feature set of
|
||||
key="INSP.pandas.series.values.replace.with.tolist" enabledByDefault="true" level="WARNING"
|
||||
implementationClass="com.jetbrains.python.inspections.PyPandasSeriesToListInspection"/>
|
||||
|
||||
<listSplitJoinContext language="Python" implementationClass="com.jetbrains.python.codeInsight.editorActions.PyListSplitJoinContext"/>
|
||||
|
||||
<defaultLiveTemplates file="liveTemplates/Python.xml"/>
|
||||
<liveTemplateContext contextId="Python"
|
||||
implementation="com.jetbrains.python.codeInsight.liveTemplates.PythonTemplateContextType$General"/>
|
||||
|
||||
@@ -0,0 +1,67 @@
|
||||
// Copyright 2000-2025 JetBrains s.r.o. and contributors. Use of this source code is governed by the Apache 2.0 license.
|
||||
package com.jetbrains.python.codeInsight.editorActions
|
||||
|
||||
import com.intellij.openapi.editor.actions.lists.CommaListSplitJoinContext
|
||||
import com.intellij.openapi.editor.actions.lists.JoinOrSplit
|
||||
import com.intellij.openapi.editor.actions.lists.ListWithElements
|
||||
import com.intellij.openapi.util.TextRange
|
||||
import com.intellij.psi.PsiElement
|
||||
import com.intellij.psi.PsiFile
|
||||
import com.intellij.psi.codeStyle.CodeStyleManager
|
||||
import com.intellij.psi.util.PsiTreeUtil
|
||||
import com.jetbrains.python.psi.*
|
||||
|
||||
class PyListSplitJoinContext : CommaListSplitJoinContext() {
|
||||
override fun extractData(context: PsiElement): ListWithElements? {
|
||||
val parent = PsiTreeUtil.findFirstParent(context) {
|
||||
// This is needed only for intention to work before the first and after the last element of a tuple
|
||||
(it is PyParenthesizedExpression && it.containedExpression is PyTupleExpression)
|
||||
|| it is PySequenceExpression || it is PyParameterList || it is PyArgumentList
|
||||
}.let { if (it is PyParenthesizedExpression) it.containedExpression else it }
|
||||
|
||||
return when (parent) {
|
||||
is PySequenceExpression -> ListWithElements(parent, parent.elements.toList())
|
||||
is PyParameterList -> ListWithElements(parent, parent.parameters.toList())
|
||||
is PyArgumentList -> ListWithElements(parent, parent.arguments.toList())
|
||||
else -> null
|
||||
}
|
||||
}
|
||||
|
||||
override fun needTailBreak(data: ListWithElements, lastElement: PsiElement, mode: JoinOrSplit): Boolean {
|
||||
// if there is a trailing comma, add tail break
|
||||
return if (mode == JoinOrSplit.SPLIT) hasSeparatorAfter(data, lastElement) else super.needTailBreak(data, lastElement, mode)
|
||||
}
|
||||
|
||||
override fun needHeadBreak(data: ListWithElements, firstElement: PsiElement, mode: JoinOrSplit): Boolean {
|
||||
// if there is a trailing comma, also add head break
|
||||
return needTailBreak(data, data.elements.last(), mode)
|
||||
}
|
||||
|
||||
override fun nextBreak(data: ListWithElements, element: PsiElement): PsiElement? {
|
||||
// in PyTupleExpression spaces for first/last elements are stored in parent psi
|
||||
val nextBreak = super.nextBreak(data, element)
|
||||
if (nextBreak != null || data.list !is PyTupleExpression || data.elements.last() != element) {
|
||||
return nextBreak
|
||||
}
|
||||
return super.nextBreak(data, data.list)
|
||||
}
|
||||
|
||||
override fun prevBreak(data: ListWithElements, element: PsiElement): PsiElement? {
|
||||
// in PyTupleExpression spaces for first/last elements are stored in parent psi
|
||||
val prevBreak = super.prevBreak(data, element)
|
||||
if (prevBreak != null || data.list !is PyTupleExpression || data.elements.first() != element) {
|
||||
return prevBreak
|
||||
}
|
||||
return super.prevBreak(data, data.list)
|
||||
}
|
||||
|
||||
override fun reformatRange(file: PsiFile, rangeToAdjust: TextRange, split: JoinOrSplit) {
|
||||
val tupleExpression = PsiTreeUtil.findElementOfClassAtRange(file, rangeToAdjust.startOffset, rangeToAdjust.endOffset, PyTupleExpression::class.java)
|
||||
if (tupleExpression != null && tupleExpression.parent is PyParenthesizedExpression) {
|
||||
CodeStyleManager.getInstance(file.project).reformat(tupleExpression.parent)
|
||||
return
|
||||
}
|
||||
|
||||
CodeStyleManager.getInstance(file.project).reformatText(file, rangeToAdjust.startOffset, rangeToAdjust.endOffset)
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,5 @@
|
||||
a = (
|
||||
1,
|
||||
2,
|
||||
3,<caret>
|
||||
)
|
||||
@@ -0,0 +1 @@
|
||||
a = (1, 2, 3,)
|
||||
@@ -0,0 +1 @@
|
||||
a = (1, 2, 3, <caret>)
|
||||
@@ -0,0 +1,5 @@
|
||||
a = (
|
||||
1,
|
||||
2,
|
||||
3,
|
||||
)
|
||||
@@ -1,6 +1,7 @@
|
||||
// Copyright 2000-2024 JetBrains s.r.o. and contributors. Use of this source code is governed by the Apache 2.0 license.
|
||||
package com.jetbrains.python.intentions;
|
||||
|
||||
import com.intellij.codeInsight.CodeInsightBundle;
|
||||
import com.intellij.codeInsight.CodeInsightSettings;
|
||||
import com.intellij.codeInsight.intention.IntentionAction;
|
||||
import com.intellij.openapi.application.impl.NonBlockingReadActionImpl;
|
||||
@@ -94,6 +95,15 @@ public class PyIntentionTest extends PyTestCase {
|
||||
runWithLanguageLevel(LanguageLevel.PYTHON35, () -> doTest(PyPsiBundle.message("QFIX.remove.string.prefix", "F")));
|
||||
}
|
||||
|
||||
// PY-45729
|
||||
public void testJoinTupleToSingleLine() {
|
||||
doTest(CodeInsightBundle.message("intention.name.join.comma.values"));
|
||||
}
|
||||
|
||||
public void testSplitTupleToMultiLine() {
|
||||
doTest(CodeInsightBundle.message("intention.name.split.comma.values"));
|
||||
}
|
||||
|
||||
// PY-18972
|
||||
public void testRemoveTrailingL() {
|
||||
doTest(PyPsiBundle.message("QFIX.remove.trailing.suffix"));
|
||||
|
||||
Reference in New Issue
Block a user