From 6a79ca62eca26dbfacbfa04e516a52ece4120cd7 Mon Sep 17 00:00:00 2001 From: Ekaterina Tuzova Date: Tue, 19 Feb 2013 18:19:13 +0400 Subject: [PATCH 1/2] reparse python files if analyze docstring settings changed rerun code analyze on apply fix a PY-8925 "Analyze Python code in docstrings" check box always returns to selected state --- .../PyIntegratedToolsConfigurable.java | 24 +++++++++++++++++-- 1 file changed, 22 insertions(+), 2 deletions(-) diff --git a/python/src/com/jetbrains/python/configuration/PyIntegratedToolsConfigurable.java b/python/src/com/jetbrains/python/configuration/PyIntegratedToolsConfigurable.java index 3bf58506046b..f463a490983e 100644 --- a/python/src/com/jetbrains/python/configuration/PyIntegratedToolsConfigurable.java +++ b/python/src/com/jetbrains/python/configuration/PyIntegratedToolsConfigurable.java @@ -1,5 +1,6 @@ package com.jetbrains.python.configuration; +import com.google.common.collect.Lists; import com.intellij.codeInsight.daemon.DaemonCodeAnalyzer; import com.intellij.facet.impl.ui.FacetErrorPanel; import com.intellij.facet.ui.FacetConfigurationQuickFix; @@ -14,12 +15,17 @@ import com.intellij.openapi.options.NonDefaultProjectConfigurable; import com.intellij.openapi.options.SearchableConfigurable; import com.intellij.openapi.project.Project; import com.intellij.openapi.projectRoots.Sdk; +import com.intellij.openapi.roots.ContentIterator; +import com.intellij.openapi.roots.ProjectRootManager; import com.intellij.openapi.ui.TextFieldWithBrowseButton; import com.intellij.openapi.util.Comparing; +import com.intellij.openapi.vfs.VirtualFile; import com.intellij.ui.CollectionComboBoxModel; import com.intellij.ui.IdeBorderFactory; +import com.intellij.util.FileContentUtil; 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.DocStringFormat; import com.jetbrains.python.documentation.PyDocumentationSettings; @@ -179,11 +185,9 @@ public class PyIntegratedToolsConfigurable implements SearchableConfigurable, No return true; } if (!Comparing.equal(myDocstringFormatComboBox.getSelectedItem(), myDocumentationSettings.myDocStringFormat)) { - DaemonCodeAnalyzer.getInstance(myProject).restart(); return true; } if (analyzeDoctest.isSelected() != myDocumentationSettings.analyzeDoctest) { - DaemonCodeAnalyzer.getInstance(myProject).restart(); return true; } if (!ReSTService.getInstance(myProject).getWorkdir().equals(myWorkDir.getText())) { @@ -200,6 +204,22 @@ public class PyIntegratedToolsConfigurable implements SearchableConfigurable, No @Override public void apply() throws ConfigurationException { + if (!Comparing.equal(myDocstringFormatComboBox.getSelectedItem(), myDocumentationSettings.myDocStringFormat)) { + DaemonCodeAnalyzer.getInstance(myProject).restart(); + } + if (analyzeDoctest.isSelected() != myDocumentationSettings.analyzeDoctest) { + final List files = Lists.newArrayList(); + ProjectRootManager.getInstance(myProject).getFileIndex().iterateContent(new ContentIterator() { + @Override + public boolean processFile(VirtualFile fileOrDir) { + if (!fileOrDir.isDirectory() && PythonFileType.INSTANCE.getDefaultExtension().equals(fileOrDir.getExtension())) { + files.add(fileOrDir); + } + return true; + } + }); + FileContentUtil.reparseFiles(myProject, Lists.newArrayList(files), false); + } myModel.apply(); myDocumentationSettings.myDocStringFormat = (String) myDocstringFormatComboBox.getSelectedItem(); ReSTService.getInstance(myProject).setWorkdir(myWorkDir.getText()); From 2815efb76e818b0ac2cf34c148178b4e81dd472a Mon Sep 17 00:00:00 2001 From: Ekaterina Tuzova Date: Tue, 19 Feb 2013 20:29:20 +0400 Subject: [PATCH 2/2] fixed PY-8581 Fill Paragraph should not corrupt indentation PY-8937 fill paragraph works wrong on simple strings --- .../actions/PyFillParagraphHandler.java | 31 +++++++++++++++- python/testData/fillParagraph/docstring.py | 6 +++ .../testData/fillParagraph/docstring_after.py | 7 ++++ python/testData/fillParagraph/string.py | 1 + python/testData/fillParagraph/string_after.py | 2 + .../jetbrains/python/PyFillParagraphTest.java | 37 +++++++++++++++++++ 6 files changed, 82 insertions(+), 2 deletions(-) create mode 100644 python/testData/fillParagraph/docstring.py create mode 100644 python/testData/fillParagraph/docstring_after.py create mode 100644 python/testData/fillParagraph/string.py create mode 100644 python/testData/fillParagraph/string_after.py create mode 100644 python/testSrc/com/jetbrains/python/PyFillParagraphTest.java diff --git a/python/src/com/jetbrains/python/actions/PyFillParagraphHandler.java b/python/src/com/jetbrains/python/actions/PyFillParagraphHandler.java index 13e1a4d39259..fb182b160bc5 100644 --- a/python/src/com/jetbrains/python/actions/PyFillParagraphHandler.java +++ b/python/src/com/jetbrains/python/actions/PyFillParagraphHandler.java @@ -5,9 +5,12 @@ import com.intellij.openapi.util.Pair; import com.intellij.psi.PsiComment; import com.intellij.psi.PsiElement; import com.intellij.psi.PsiFile; +import com.intellij.psi.PsiWhiteSpace; import com.intellij.psi.util.PsiTreeUtil; import com.jetbrains.python.PythonStringUtil; +import com.jetbrains.python.psi.PyDocStringOwner; import com.jetbrains.python.psi.PyFile; +import com.jetbrains.python.psi.PyStatementList; import com.jetbrains.python.psi.PyStringLiteralExpression; import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.Nullable; @@ -24,7 +27,19 @@ public class PyFillParagraphHandler extends ParagraphFillHandler { if (stringLiteralExpression != null) { final Pair quotes = PythonStringUtil.getQuotes(stringLiteralExpression.getText()); - return quotes != null? quotes.getFirst()+"\n" : "\"\n"; + final PyDocStringOwner docStringOwner = PsiTreeUtil.getParentOfType(stringLiteralExpression, PyDocStringOwner.class); + if (docStringOwner != null && stringLiteralExpression.equals(docStringOwner.getDocStringExpression())) { + final PyStatementList statementList = PsiTreeUtil.getParentOfType(stringLiteralExpression, PyStatementList.class); + final PsiElement whiteSpace = statementList.getPrevSibling(); + String indent; + if (whiteSpace instanceof PsiWhiteSpace) + indent = whiteSpace.getText(); + else + indent = "\n"; + return quotes != null? quotes.getFirst()+ indent : "\"" + indent; + } + else + return quotes != null? quotes.getFirst() : "\""; } return element instanceof PsiComment? "# " : ""; } @@ -37,7 +52,19 @@ public class PyFillParagraphHandler extends ParagraphFillHandler { if (stringLiteralExpression != null) { final Pair quotes = PythonStringUtil.getQuotes(stringLiteralExpression.getText()); - return quotes != null? "\n" + quotes.getSecond() : "\n\""; + final PyDocStringOwner docStringOwner = PsiTreeUtil.getParentOfType(stringLiteralExpression, PyDocStringOwner.class); + if (docStringOwner != null && stringLiteralExpression.equals(docStringOwner.getDocStringExpression())) { + final PyStatementList statementList = PsiTreeUtil.getParentOfType(stringLiteralExpression, PyStatementList.class); + final PsiElement whiteSpace = statementList.getPrevSibling(); + String indent; + if (whiteSpace instanceof PsiWhiteSpace) + indent = whiteSpace.getText(); + else + indent = "\n"; + return quotes != null? indent + quotes.getSecond() : indent + "\""; + } + else + return quotes != null? quotes.getSecond() : "\""; } return ""; } diff --git a/python/testData/fillParagraph/docstring.py b/python/testData/fillParagraph/docstring.py new file mode 100644 index 000000000000..92f249fe5b19 --- /dev/null +++ b/python/testData/fillParagraph/docstring.py @@ -0,0 +1,6 @@ +__author__ = 'ktisha' + +def foo(): + """ + This is my docstring. There are many like it, but this one mine. My docstring is my best friend. it is my life. I must master it as I must master my life. + """ \ No newline at end of file diff --git a/python/testData/fillParagraph/docstring_after.py b/python/testData/fillParagraph/docstring_after.py new file mode 100644 index 000000000000..38be37ba1f25 --- /dev/null +++ b/python/testData/fillParagraph/docstring_after.py @@ -0,0 +1,7 @@ +__author__ = 'ktisha' + +def foo(): + """ + This is my docstring. There are many like it, but this one mine. My docstring is my best friend. it is my life. I + must master it as I must master my life. + """ \ No newline at end of file diff --git a/python/testData/fillParagraph/string.py b/python/testData/fillParagraph/string.py new file mode 100644 index 000000000000..7d0263eb24ff --- /dev/null +++ b/python/testData/fillParagraph/string.py @@ -0,0 +1 @@ +p = "my new string blah blah blah ;j;dsjv sd;fj;dsjf;ds js;djgf ;jsg s;dgj; sjd;gj sd;gj ;sjg;j asdl j;sjdg; jasdgl j;sldjg ;jsd;gj " \ No newline at end of file diff --git a/python/testData/fillParagraph/string_after.py b/python/testData/fillParagraph/string_after.py new file mode 100644 index 000000000000..5ae082b534ff --- /dev/null +++ b/python/testData/fillParagraph/string_after.py @@ -0,0 +1,2 @@ +p = "my new string blah blah blah ;j;dsjv sd;fj;dsjf;ds js;djgf ;jsg s;dgj; sjd;gj sd;gj ;sjg;j asdl j;sjdg; jasdgl " \ + "j;sldjg ;jsd;gj " \ No newline at end of file diff --git a/python/testSrc/com/jetbrains/python/PyFillParagraphTest.java b/python/testSrc/com/jetbrains/python/PyFillParagraphTest.java new file mode 100644 index 000000000000..4f33c590f64e --- /dev/null +++ b/python/testSrc/com/jetbrains/python/PyFillParagraphTest.java @@ -0,0 +1,37 @@ +package com.jetbrains.python; + +import com.intellij.codeInsight.editorActions.fillParagraph.FillParagraphAction; +import com.intellij.ide.DataManager; +import com.intellij.openapi.actionSystem.ActionManager; +import com.intellij.openapi.actionSystem.AnActionEvent; +import com.intellij.openapi.command.CommandProcessor; +import com.jetbrains.python.fixtures.PyTestCase; + +/** + * User : ktisha + */ +public class PyFillParagraphTest extends PyTestCase { + + public void testDocstring() { + doTest(); + } + + public void testString() { + doTest(); + } + + private void doTest() { + String baseName = "/fillParagraph/" + getTestName(true); + myFixture.configureByFile(baseName + ".py"); + CommandProcessor.getInstance().executeCommand(myFixture.getProject(), new Runnable() { + @Override + public void run() { + FillParagraphAction action = new FillParagraphAction(); + action.actionPerformed(new AnActionEvent(null, DataManager.getInstance().getDataContext(), "", + action.getTemplatePresentation(), + ActionManager.getInstance(), 0)); + } + }, "", null); + myFixture.checkResultByFile(baseName + "_after.py", true); + } +}