WEB-57646 HTML: provide an option to disable completion without typing <

GitOrigin-RevId: 0418212c3ec8e2b080ff4c9d38bdae495b57449e
This commit is contained in:
Piotr Tomiak
2023-02-20 22:15:02 +01:00
committed by intellij-monorepo-bot
parent 9b118175ce
commit ce216843a0
7 changed files with 82 additions and 3 deletions

View File

@@ -35,6 +35,7 @@
key="configurable.XMLCatalogConfigurable.display.name"
id="xml.catalog"/>
</projectConfigurable>
<codeCompletionConfigurable instance="com.intellij.application.options.XmlCodeCompletionConfigurable"/>
<metaLanguage implementation="com.intellij.lang.html.HtmlCompatibleMetaLanguage"/>
<html.compatibleLanguage language="HTML"/>

View File

@@ -0,0 +1,31 @@
// Copyright 2000-2020 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.intellij.application.options;
import com.intellij.openapi.application.ApplicationManager;
import com.intellij.openapi.components.*;
import com.intellij.util.xmlb.XmlSerializerUtil;
import org.jetbrains.annotations.NotNull;
/**
* @author Dmitry Avdeev
*/
@Service(Service.Level.APP)
@State(name = "HtmlSettings", storages = @Storage("editor.xml"), category = SettingsCategory.CODE)
public final class HtmlSettings implements PersistentStateComponent<HtmlSettings> {
public boolean AUTO_POPUP_TAG_CODE_COMPLETION_ON_TYPING_IN_TEXT = true;
public static HtmlSettings getInstance() {
return ApplicationManager.getApplication().getService(HtmlSettings.class);
}
@Override
public HtmlSettings getState() {
return this;
}
@Override
public void loadState(@NotNull final HtmlSettings state) {
XmlSerializerUtil.copyBean(state, this);
}
}

View File

@@ -0,0 +1,25 @@
package com.intellij.application.options
import com.intellij.openapi.options.Configurable
import com.intellij.openapi.options.UiDslUnnamedConfigurable
import com.intellij.ui.dsl.builder.Panel
import com.intellij.ui.dsl.builder.bindSelected
import com.intellij.xml.XmlBundle
class XmlCodeCompletionConfigurable : UiDslUnnamedConfigurable.Simple(), Configurable {
override fun getDisplayName(): String {
return XmlBundle.message("options.html.display.name")
}
override fun Panel.createContent() {
val htmlSettings = HtmlSettings.getInstance()
group(XmlBundle.message("options.html.display.name")) {
row {
checkBox(XmlBundle.message("checkbox.enable.completion.html.auto.popup.code.completion.on.typing.in.text"))
.bindSelected({ htmlSettings.AUTO_POPUP_TAG_CODE_COMPLETION_ON_TYPING_IN_TEXT }, { htmlSettings.AUTO_POPUP_TAG_CODE_COMPLETION_ON_TYPING_IN_TEXT = it })
}
}
}
}

View File

@@ -1,6 +1,7 @@
// Copyright 2000-2019 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.intellij.codeInsight.completion;
import com.intellij.application.options.HtmlSettings;
import com.intellij.codeInsight.completion.impl.CompletionSorterImpl;
import com.intellij.codeInsight.lookup.*;
import com.intellij.codeInsight.lookup.impl.LookupImpl;
@@ -232,11 +233,17 @@ public class HtmlCompletionContributor extends CompletionContributor implements
}
static boolean isHtmlElementInTextCompletionEnabledForFile(@NotNull PsiFile file) {
return HtmlInTextCompletionEnabler.EP_NAME.getExtensionList().stream().anyMatch(enabler -> enabler.isEnabledInFile(file));
return ContainerUtil.exists(HtmlInTextCompletionEnabler.EP_NAME.getExtensionList(), enabler -> enabler.isEnabledInFile(file));
}
static boolean isHtmlElementInTextCompletionAutoPopupEnabledForFile(@NotNull PsiFile file) {
return HtmlSettings.getInstance().AUTO_POPUP_TAG_CODE_COMPLETION_ON_TYPING_IN_TEXT
&& isHtmlElementInTextCompletionEnabledForFile(file);
}
private static boolean isDeselectingFirstPopupItemDisabled(@NotNull PsiElement element) {
return ContainerUtil.exists(HtmlInTextCompletionPopupExtension.EP_NAME.getExtensionList(), ext -> ext.isDeselectingFirstItemDisabled(element));
return ContainerUtil.exists(HtmlInTextCompletionPopupExtension.EP_NAME.getExtensionList(),
ext -> ext.isDeselectingFirstItemDisabled(element));
}
private static CompletionSorter withoutLiveTemplatesWeigher(@Nullable CompletionSorter sorter,

View File

@@ -29,7 +29,7 @@ public class HtmlTextCompletionConfidence extends CompletionConfidence {
@NotNull
@Override
public ThreeState shouldSkipAutopopup(@NotNull PsiElement contextElement, @NotNull PsiFile psiFile, int offset) {
if (HtmlCompletionContributor.isHtmlElementInTextCompletionEnabledForFile(psiFile)) {
if (HtmlCompletionContributor.isHtmlElementInTextCompletionAutoPopupEnabledForFile(psiFile)) {
return notAfterASpace(psiFile, offset);
}
return shouldSkipAutopopupInHtml(contextElement, offset) ? ThreeState.YES : ThreeState.UNSURE;

View File

@@ -303,4 +303,5 @@ border.title.xml=XML
configurable.name.html.css=HTML/CSS
xml.category=XML
ignore.ext.resource.preview=Register {0} as ignored resource in {1}
checkbox.enable.completion.html.auto.popup.code.completion.on.typing.in.text=Enable auto-popup of tag name code completion when typing in HTML text

View File

@@ -15,6 +15,7 @@
*/
package com.intellij.codeInsight.completion;
import com.intellij.application.options.HtmlSettings;
import com.intellij.ide.highlighter.HtmlFileType;
import com.intellij.ide.highlighter.XHtmlFileType;
import com.intellij.openapi.actionSystem.IdeActions;
@@ -169,6 +170,19 @@ public class HtmlAutoPopupTest extends CompletionAutoPopupTestCase {
myFixture.checkResult("p\n");
}
public void testTypingInHtmlDisabledAutopopup() {
myFixture.configureByText(HtmlFileType.INSTANCE, "<caret>");
try {
HtmlSettings.getInstance().AUTO_POPUP_TAG_CODE_COMPLETION_ON_TYPING_IN_TEXT = false;
type("p");
assertNull(getLookup());
myFixture.completeBasic();
assertContainsElements(myFixture.getLookupElementStrings(), "<pre", "<p", "<picture");
} finally {
HtmlSettings.getInstance().AUTO_POPUP_TAG_CODE_COMPLETION_ON_TYPING_IN_TEXT = true;
}
}
public void testStartsWithCharMatchingAutoPopup() {
myFixture.configureByText(HtmlFileType.INSTANCE, "<html lang='en'><caret>");
type("la");