Merge remote-tracking branch 'origin/master'

This commit is contained in:
Yann Cébron
2016-04-26 16:23:31 +02:00
14 changed files with 141 additions and 17 deletions
@@ -402,7 +402,7 @@ public class CodeStyleSettings extends CommonCodeStyleSettings implements Clonea
@NonNls public String HTML_INLINE_ELEMENTS =
"a,abbr,acronym,b,basefont,bdo,big,br,cite,cite,code,dfn,em,font,i,img,input,kbd,label,q,s,samp,select,span,strike,strong,sub,sup,textarea,tt,u,var";
@NonNls public String HTML_DONT_ADD_BREAKS_IF_INLINE_CONTENT = "title,h1,h2,h3,h4,h5,h6,p";
public QuoteStyle HTML_QUOTE_STYLE = QuoteStyle.Double;
// ---------------------------------------------------------------------------------------
@@ -1019,4 +1019,15 @@ public class CodeStyleSettings extends CommonCodeStyleSettings implements Clonea
return WRAP_WHEN_TYPING_REACHES_RIGHT_MARGIN;
}
public enum QuoteStyle {
Single("'"),
Double("\""),
None("");
public final String quote;
QuoteStyle(String quote) {
this.quote = quote;
}
}
}
@@ -89,6 +89,7 @@ checkbox.wrap.text=Wrap text
checkbox.parentheses.around.method.arguments=Add parentheses around method arguments
checkbox.rename.local.variables.inplace=Enable in-place mode
checkbox.rename.local.variables.preselect=Preselect old name
generated.quote.marks=Generated quote marks:
editbox.keep.blank.lines=Keep blank lines:
checkbox.keep.white.spaces=Keep white spaces
checkbox.align.text=Align text
@@ -576,7 +576,7 @@ public class ReflectionUtil {
public static void copyFieldValue(@NotNull Object from, @NotNull Object to, @NotNull Field field)
throws IllegalAccessException {
Class<?> fieldType = field.getType();
if (fieldType.isPrimitive() || fieldType.equals(String.class)) {
if (fieldType.isPrimitive() || fieldType.equals(String.class) || fieldType.isEnum()) {
field.set(to, field.get(from));
}
else {
@@ -40,7 +40,7 @@
<properties/>
<border type="none"/>
<children>
<grid id="ca5bb" layout-manager="GridLayoutManager" row-count="7" column-count="3" same-size-horizontally="false" same-size-vertically="false" hgap="-1" vgap="-1">
<grid id="ca5bb" layout-manager="GridLayoutManager" row-count="8" column-count="3" same-size-horizontally="false" same-size-vertically="false" hgap="-1" vgap="-1">
<margin top="0" left="0" bottom="0" right="0"/>
<constraints>
<grid row="3" column="0" row-span="1" col-span="1" vsize-policy="3" hsize-policy="3" anchor="0" fill="3" indent="0" use-parent-layout="false"/>
@@ -180,6 +180,20 @@
<text value=""/>
</properties>
</component>
<component id="396b9" class="javax.swing.JLabel">
<constraints>
<grid row="7" column="0" row-span="1" col-span="1" vsize-policy="0" hsize-policy="0" anchor="8" fill="0" indent="0" use-parent-layout="false"/>
</constraints>
<properties>
<text resource-bundle="messages/ApplicationBundle" key="generated.quote.marks"/>
</properties>
</component>
<component id="74327" class="javax.swing.JComboBox" binding="myQuotesCombo">
<constraints>
<grid row="7" column="1" row-span="1" col-span="2" vsize-policy="0" hsize-policy="2" anchor="8" fill="1" indent="0" use-parent-layout="false"/>
</constraints>
<properties/>
</component>
</children>
</grid>
<grid id="b8acc" layout-manager="GridLayoutManager" row-count="1" column-count="2" same-size-horizontally="false" same-size-vertically="false" hgap="-1" vgap="-1">
@@ -28,6 +28,7 @@ import com.intellij.openapi.util.text.StringUtil;
import com.intellij.psi.PsiFile;
import com.intellij.psi.codeStyle.CodeStyleSettings;
import com.intellij.psi.codeStyle.CommonCodeStyleSettings;
import com.intellij.ui.EnumComboBoxModel;
import com.intellij.ui.components.JBScrollPane;
import com.intellij.util.ArrayUtil;
import com.intellij.util.PlatformIcons;
@@ -66,6 +67,7 @@ public class CodeStyleHtmlPanel extends CodeStyleAbstractPanel {
private TextFieldWithBrowseButton myDontBreakIfInlineContent;
private JBScrollPane myJBScrollPane;
private JPanel myRightMarginPanel;
private JComboBox myQuotesCombo;
private RightMarginForm myRightMarginForm;
public CodeStyleHtmlPanel(CodeStyleSettings settings) {
@@ -73,6 +75,7 @@ public class CodeStyleHtmlPanel extends CodeStyleAbstractPanel {
installPreviewPanel(myPreviewPanel);
fillWrappingCombo(myWrapAttributes);
fillQuotesCombo(myQuotesCombo);
customizeField(ApplicationBundle.message("title.insert.new.line.before.tags"), myInsertNewLineTagNames);
customizeField(ApplicationBundle.message("title.remove.line.breaks.before.tags"), myRemoveNewLineTagNames);
@@ -162,9 +165,15 @@ public class CodeStyleHtmlPanel extends CodeStyleAbstractPanel {
settings.HTML_KEEP_WHITESPACES_INSIDE = myKeepWhiteSpacesTagNames.getText();
settings.HTML_KEEP_LINE_BREAKS = myShouldKeepBlankLines.isSelected();
settings.HTML_KEEP_LINE_BREAKS_IN_TEXT = myShouldKeepLineBreaksInText.isSelected();
settings.HTML_QUOTE_STYLE = (CodeStyleSettings.QuoteStyle)myQuotesCombo.getSelectedItem();
myRightMarginForm.apply(settings);
}
@NotNull
protected String getQuotes() {
return ApplicationBundle.message("single.quotes").equals(myQuotesCombo.getSelectedItem()) ? "'" : "\"";
}
private static int getIntValue(JTextField keepBlankLines) {
try {
return Integer.parseInt(keepBlankLines.getText());
@@ -196,6 +205,7 @@ public class CodeStyleHtmlPanel extends CodeStyleAbstractPanel {
myDontBreakIfInlineContent.setText(settings.HTML_DONT_ADD_BREAKS_IF_INLINE_CONTENT);
myKeepWhiteSpacesTagNames.setText(settings.HTML_KEEP_WHITESPACES_INSIDE);
myRightMarginForm.reset(settings);
myQuotesCombo.setSelectedItem(settings.HTML_QUOTE_STYLE);
}
@Override
@@ -266,6 +276,10 @@ public class CodeStyleHtmlPanel extends CodeStyleAbstractPanel {
return true;
}
if (myQuotesCombo.getSelectedItem() != settings.HTML_QUOTE_STYLE) {
return true;
}
return myRightMarginForm.isModified(settings);
}
@@ -290,4 +304,8 @@ public class CodeStyleHtmlPanel extends CodeStyleAbstractPanel {
protected void prepareForReformat(final PsiFile psiFile) {
//psiFile.putUserData(PsiUtil.FILE_LANGUAGE_LEVEL_KEY, LanguageLevel.HIGHEST);
}
private static void fillQuotesCombo(JComboBox combo) {
combo.setModel(new EnumComboBoxModel<>(CodeStyleSettings.QuoteStyle.class));
}
}
@@ -27,6 +27,7 @@ import com.intellij.openapi.util.text.StringUtil;
import com.intellij.psi.PsiDocumentManager;
import com.intellij.psi.PsiElement;
import com.intellij.psi.PsiFile;
import com.intellij.psi.codeStyle.CodeStyleSchemes;
import com.intellij.psi.util.PsiTreeUtil;
import com.intellij.psi.xml.XmlAttribute;
import com.intellij.psi.xml.XmlFile;
@@ -34,6 +35,7 @@ import com.intellij.psi.xml.XmlTag;
import com.intellij.util.IncorrectOperationException;
import com.intellij.util.text.CharArrayUtil;
import com.intellij.xml.XmlNamespaceHelper;
import com.intellij.xml.util.HtmlUtil;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
@@ -66,14 +68,20 @@ public class XmlAttributeInsertHandler implements InsertHandler<LookupElement> {
final PsiFile file = context.getFile();
final CharSequence chars = document.getCharsSequence();
final boolean insertQuotes = WebEditorOptions.getInstance().isInsertQuotesForAttributeValue();
final boolean hasQuotes = CharArrayUtil.regionMatches(chars, caretOffset, "=\"");
if (!hasQuotes && !CharArrayUtil.regionMatches(chars, caretOffset, "='")) {
final String quote = getAttributeQuote(HtmlUtil.hasHtml(file) || HtmlUtil.supportsXmlTypedHandlers(file));
final boolean insertQuotes = WebEditorOptions.getInstance().isInsertQuotesForAttributeValue() && StringUtil.isNotEmpty(quote);
final boolean hasQuotes = CharArrayUtil.regionMatches(chars, caretOffset, "=\"") ||
CharArrayUtil.regionMatches(chars, caretOffset, "='");
if (!hasQuotes) {
PsiElement fileContext = file.getContext();
String toInsert= "=\"\"";
String toInsert = null;
if(fileContext != null) {
if (fileContext.getText().startsWith("\"")) toInsert = "=''";
if (fileContext.getText().startsWith("\'")) toInsert = "=\"\"";
}
if (toInsert == null) {
toInsert = "=" + quote + quote;
}
if (!insertQuotes) toInsert = "=";
@@ -118,6 +126,10 @@ public class XmlAttributeInsertHandler implements InsertHandler<LookupElement> {
}
}
public static String getAttributeQuote(boolean html) {
return html ? CodeStyleSchemes.getInstance().getCurrentScheme().getCodeStyleSettings().HTML_QUOTE_STYLE.quote : "\"";
}
private static void qualifyWithPrefix(@NotNull String namespacePrefix, @NotNull PsiElement context) {
final PsiElement parent = context.getParent();
@@ -230,9 +230,9 @@ public class XmlTagInsertHandler implements InsertHandler<LookupElement> {
if (shouldBeInserted && (tag == null || tag.getAttributeValue(attributeName) == null)) {
if (!notRequiredAttributes.contains(attributeName)) {
if (!extension.isIndirectSyntax(attributeDecl)) {
template.addTextSegment(" " + attributeName + "=\"");
template.addTextSegment(" " + attributeName + "=" + XmlAttributeInsertHandler.getAttributeQuote(htmlCode));
template.addVariable(new MacroCallNode(new CompleteMacro()), true);
template.addTextSegment("\"");
template.addTextSegment(XmlAttributeInsertHandler.getAttributeQuote(htmlCode));
}
else {
if (indirectRequiredAttrs == null) indirectRequiredAttrs = new StringBuilder();
@@ -241,7 +241,8 @@ public class XmlTagInsertHandler implements InsertHandler<LookupElement> {
}
}
else if (shouldBeInserted && attributeDecl.isFixed() && attributeDecl.getDefaultValue() != null && !htmlCode) {
template.addTextSegment(" " + attributeName + "=\"" + attributeDecl.getDefaultValue() + "\"");
template.addTextSegment(" " + attributeName + "=" + XmlAttributeInsertHandler.getAttributeQuote(false) +
attributeDecl.getDefaultValue() + XmlAttributeInsertHandler.getAttributeQuote(false));
}
}
}
@@ -254,6 +255,7 @@ public class XmlTagInsertHandler implements InsertHandler<LookupElement> {
XmlTag tag,
Template template,
StringBuilder indirectRequiredAttrs) {
boolean htmlCode = HtmlUtil.hasHtml(tag.getContainingFile()) || HtmlUtil.supportsXmlTypedHandlers(tag.getContainingFile());
if (completionChar == '>' || (completionChar == '/' && indirectRequiredAttrs != null)) {
template.addTextSegment(">");
@@ -290,7 +292,7 @@ public class XmlTagInsertHandler implements InsertHandler<LookupElement> {
else if (completionChar == ' ' && template.getSegmentsCount() == 0) {
if (WebEditorOptions.getInstance().isAutomaticallyStartAttribute() &&
(descriptor.getAttributesDescriptors(tag).length > 0 || isTagFromHtml(tag) && !HtmlUtil.isTagWithoutAttributes(tag.getName()))) {
completeAttribute(template);
completeAttribute(template, htmlCode);
return true;
}
}
@@ -301,7 +303,7 @@ public class XmlTagInsertHandler implements InsertHandler<LookupElement> {
else {
if (needAlLeastOneAttribute(tag) && WebEditorOptions.getInstance().isAutomaticallyStartAttribute() && tag.getAttributes().length == 0
&& template.getSegmentsCount() == 0) {
completeAttribute(template);
completeAttribute(template, htmlCode);
return true;
}
else {
@@ -313,12 +315,12 @@ public class XmlTagInsertHandler implements InsertHandler<LookupElement> {
return false;
}
private static void completeAttribute(Template template) {
private static void completeAttribute(Template template, boolean htmlCode) {
template.addTextSegment(" ");
template.addVariable(new MacroCallNode(new CompleteMacro()), true);
template.addTextSegment("=\"");
template.addTextSegment("=" + XmlAttributeInsertHandler.getAttributeQuote(htmlCode));
template.addEndVariable();
template.addTextSegment("\"");
template.addTextSegment(XmlAttributeInsertHandler.getAttributeQuote(htmlCode));
}
private static boolean needAlLeastOneAttribute(XmlTag tag) {
@@ -17,12 +17,14 @@ package com.intellij.codeInsight.editorActions;
import com.intellij.application.options.editor.WebEditorOptions;
import com.intellij.codeInsight.AutoPopupController;
import com.intellij.codeInsight.completion.XmlAttributeInsertHandler;
import com.intellij.openapi.editor.Editor;
import com.intellij.openapi.fileTypes.FileType;
import com.intellij.openapi.project.Project;
import com.intellij.psi.PsiElement;
import com.intellij.psi.PsiFile;
import com.intellij.psi.xml.XmlAttribute;
import com.intellij.xml.util.HtmlUtil;
import org.jetbrains.annotations.NotNull;
public class XmlEqTypedHandler extends TypedHandlerDelegate {
@@ -50,13 +52,18 @@ public class XmlEqTypedHandler extends TypedHandlerDelegate {
if (needToInsertQuotes) {
int offset = editor.getCaretModel().getOffset();
PsiElement fileContext = file.getContext();
String toInsert= "\"\"";
String toInsert = null;
if(fileContext != null) {
if (fileContext.getText().startsWith("\"")) toInsert = "''";
if (fileContext.getText().startsWith("\'")) toInsert = "\"\"";
}
if (toInsert == null) {
final String quote = XmlAttributeInsertHandler.getAttributeQuote(HtmlUtil.hasHtml(file) || HtmlUtil.supportsXmlTypedHandlers(file));
toInsert = quote + quote;
}
editor.getDocument().insertString(offset, toInsert);
editor.getCaretModel().moveToOffset(offset + 1);
editor.getCaretModel().moveToOffset(offset + toInsert.length() / 2);
AutoPopupController.getInstance(project).scheduleAutoPopup(editor);
}
needToInsertQuotes = false;
@@ -28,6 +28,8 @@ import com.intellij.javaee.ExternalResourceManagerEx;
import com.intellij.javaee.ExternalResourceManagerExImpl;
import com.intellij.openapi.application.Result;
import com.intellij.openapi.command.WriteCommandAction;
import com.intellij.psi.codeStyle.CodeStyleSchemes;
import com.intellij.psi.codeStyle.CodeStyleSettings;
import com.intellij.psi.statistics.StatisticsManager;
import com.intellij.psi.statistics.impl.StatisticsManagerImpl;
import com.intellij.testFramework.fixtures.LightCodeInsightFixtureTestCase;
@@ -342,6 +344,30 @@ public class XmlCompletionTest extends LightCodeInsightFixtureTestCase {
checkResultByFile("37_after.xml");
}
public void testInsertExtraRequiredAttributeSingleQuote() throws Exception {
final CodeStyleSettings settings = CodeStyleSchemes.getInstance().getCurrentScheme().getCodeStyleSettings();
final CodeStyleSettings.QuoteStyle quote = settings.HTML_QUOTE_STYLE;
try {
settings.HTML_QUOTE_STYLE = CodeStyleSettings.QuoteStyle.Single;
configureByFile(getTestName(true) + ".html");
checkResultByFile(getTestName(true) + "_after.html");
} finally {
CodeStyleSchemes.getInstance().getCurrentScheme().getCodeStyleSettings().HTML_QUOTE_STYLE = quote;
}
}
public void testInsertExtraRequiredAttributeNoneQuote() throws Exception {
final CodeStyleSettings settings = CodeStyleSchemes.getInstance().getCurrentScheme().getCodeStyleSettings();
final CodeStyleSettings.QuoteStyle quote = settings.HTML_QUOTE_STYLE;
try {
settings.HTML_QUOTE_STYLE = CodeStyleSettings.QuoteStyle.None;
configureByFile(getTestName(true) + ".html");
checkResultByFile(getTestName(true) + "_after.html");
} finally {
CodeStyleSchemes.getInstance().getCurrentScheme().getCodeStyleSettings().HTML_QUOTE_STYLE = quote;
}
}
public void testBeforeAttributeValue() throws Throwable {
configureByFile(getTestName(true) + ".xml");
assertEmpty(myFixture.getLookupElements());
@@ -16,7 +16,10 @@
package com.intellij.codeInsight.completion;
import com.intellij.application.options.editor.WebEditorOptions;
import com.intellij.ide.highlighter.HtmlFileType;
import com.intellij.ide.highlighter.XmlFileType;
import com.intellij.psi.codeStyle.CodeStyleSchemes;
import com.intellij.psi.codeStyle.CodeStyleSettings;
import com.intellij.testFramework.fixtures.LightPlatformCodeInsightFixtureTestCase;
/**
@@ -95,6 +98,32 @@ public class XmlTypedHandlersTest extends LightPlatformCodeInsightFixtureTestCas
}
}
public void testSingleQuotes() {
final CodeStyleSettings settings = CodeStyleSchemes.getInstance().getCurrentScheme().getCodeStyleSettings();
final CodeStyleSettings.QuoteStyle quote = settings.HTML_QUOTE_STYLE;
try {
settings.HTML_QUOTE_STYLE = CodeStyleSettings.QuoteStyle.Single;
myFixture.configureByText(HtmlFileType.INSTANCE, "<foo bar<caret>");
myFixture.type('=');
myFixture.checkResult("<foo bar='<caret>'");
} finally {
CodeStyleSchemes.getInstance().getCurrentScheme().getCodeStyleSettings().HTML_QUOTE_STYLE = quote;
}
}
public void testNoneQuotes() {
final CodeStyleSettings settings = CodeStyleSchemes.getInstance().getCurrentScheme().getCodeStyleSettings();
final CodeStyleSettings.QuoteStyle quote = settings.HTML_QUOTE_STYLE;
try {
settings.HTML_QUOTE_STYLE = CodeStyleSettings.QuoteStyle.None;
myFixture.configureByText(HtmlFileType.INSTANCE, "<foo bar<caret>>text");
myFixture.type('=');
myFixture.checkResult("<foo bar=<caret>>text");
} finally {
CodeStyleSchemes.getInstance().getCurrentScheme().getCodeStyleSettings().HTML_QUOTE_STYLE = quote;
}
}
public void testFooBar() throws Exception {
doTest("<foo>\n" +
" <bar<caret></bar>\n" +
@@ -0,0 +1 @@
<im<caret>
@@ -0,0 +1 @@
<img src= alt=>
@@ -0,0 +1 @@
<im<caret>
@@ -0,0 +1 @@
<img src='' alt=''>