goto action: use non-minuscule word-order-independent matcher (IDEA-147849, IDEA-217892)

GitOrigin-RevId: 9f9ad30bcef06dae22e70e0da2a01ab0bc4439fb
This commit is contained in:
peter
2019-07-10 13:03:18 +03:00
committed by intellij-monorepo-bot
parent 09d64a4b1d
commit 349df3fdce
6 changed files with 45 additions and 16 deletions
@@ -76,6 +76,15 @@ class GotoActionTest extends LightJavaCodeInsightFixtureTestCase {
assert actionMatches('refactor variable', extractMethod) == MatchMode.GROUP
}
void "test no lowercase camel-hump action match"() {
def action = ActionManager.instance.getAction("InvalidateCaches")
assert actionMatches('invalid', action) == MatchMode.NAME
assert actionMatches('invalidate caches', action) == MatchMode.NAME
assert actionMatches('cache invalid', action) == MatchMode.NAME
assert actionMatches('rebuild of all caches', action) == MatchMode.DESCRIPTION
assert actionMatches('restart', action) == MatchMode.NONE
}
void "test matched value comparator"() {
def pattern = 'Text'
def names = ['Text', 'Text completion', 'Completion Text', 'Add text', 'Retextovize mapping', 'Value', 'A', 'Z']
@@ -1978,7 +1978,7 @@ public class SearchEverywhereAction extends AnAction implements CustomComponentA
private GotoActionItemProvider createActionProvider() {
GotoActionModel model = new GotoActionModel(project, myFocusComponent, myEditor) {
@Override
protected MatchMode actionMatches(@NotNull String pattern, MinusculeMatcher matcher, @NotNull AnAction anAction) {
protected MatchMode actionMatches(@NotNull String pattern, Matcher matcher, @NotNull AnAction anAction) {
MatchMode mode = super.actionMatches(pattern, matcher, anAction);
return mode == MatchMode.NAME ? mode : MatchMode.NONE;
}
@@ -19,14 +19,13 @@ import com.intellij.openapi.project.Project;
import com.intellij.openapi.util.NotNullLazyValue;
import com.intellij.openapi.util.registry.Registry;
import com.intellij.openapi.util.text.StringUtil;
import com.intellij.psi.codeStyle.MinusculeMatcher;
import com.intellij.psi.codeStyle.NameUtil;
import com.intellij.ui.switcher.QuickActionProvider;
import com.intellij.util.CollectConsumer;
import com.intellij.util.Processor;
import com.intellij.util.containers.ContainerUtil;
import com.intellij.util.containers.JBIterable;
import com.intellij.util.text.Matcher;
import com.intellij.psi.codeStyle.WordPrefixMatcher;
import gnu.trove.THashSet;
import org.jetbrains.annotations.NotNull;
@@ -149,7 +148,7 @@ public class GotoActionItemProvider implements ChooseByNameItemProvider {
}
}
if (!StringUtil.isEmptyOrSpaces(pattern)) {
Matcher matcher = NameUtil.buildMatcher("*" + pattern).build();
Matcher matcher = buildMatcher(pattern);
if (optionDescriptions == null) optionDescriptions = new THashSet<>();
for (Map.Entry<String, String> entry : map.entrySet()) {
if (matcher.matches(entry.getValue())) {
@@ -180,7 +179,7 @@ public class GotoActionItemProvider implements ChooseByNameItemProvider {
private boolean processActions(String pattern, Processor<? super MatchedValue> consumer, DataContext dataContext) {
Set<String> ids = ((ActionManagerImpl)myActionManager).getActionIds();
JBIterable<AnAction> actions = JBIterable.from(ids).filterMap(myActionManager::getAction);
MinusculeMatcher matcher = buildMatcher(pattern);
Matcher matcher = buildMatcher(pattern);
QuickActionProvider provider = dataContext.getData(QuickActionProvider.KEY);
if (provider != null) {
@@ -196,12 +195,12 @@ public class GotoActionItemProvider implements ChooseByNameItemProvider {
}
@NotNull
static MinusculeMatcher buildMatcher(String pattern) {
return NameUtil.buildMatcher("*" + pattern, NameUtil.MatchingCaseSensitivity.NONE);
static Matcher buildMatcher(String pattern) {
return new WordPrefixMatcher(pattern);
}
private boolean processIntentions(String pattern, Processor<? super MatchedValue> consumer, DataContext dataContext) {
MinusculeMatcher matcher = buildMatcher(pattern);
Matcher matcher = buildMatcher(pattern);
Map<String, ApplyIntentionAction> intentionMap = myIntentions.getValue();
JBIterable<ActionWrapper> intentions = JBIterable.from(intentionMap.keySet())
.filterMap(intentionText -> {
@@ -28,7 +28,6 @@ import com.intellij.openapi.util.*;
import com.intellij.openapi.util.text.StringUtil;
import com.intellij.psi.PsiDocumentManager;
import com.intellij.psi.PsiFile;
import com.intellij.psi.codeStyle.MinusculeMatcher;
import com.intellij.ui.*;
import com.intellij.ui.components.JBLabel;
import com.intellij.ui.components.OnOffButton;
@@ -384,7 +383,7 @@ public class GotoActionModel implements ChooseByNameModel, Comparator<Object>, D
return ((MatchedValue) mv).getValueText();
}
protected MatchMode actionMatches(@NotNull String pattern, MinusculeMatcher matcher, @NotNull AnAction anAction) {
protected MatchMode actionMatches(@NotNull String pattern, com.intellij.util.text.Matcher matcher, @NotNull AnAction anAction) {
Presentation presentation = anAction.getTemplatePresentation();
String text = presentation.getText();
String description = presentation.getDescription();
@@ -25,10 +25,10 @@ import com.intellij.openapi.util.Disposer;
import com.intellij.openapi.util.Key;
import com.intellij.openapi.util.Pair;
import com.intellij.openapi.util.text.StringUtil;
import com.intellij.psi.codeStyle.MinusculeMatcher;
import com.intellij.psi.codeStyle.NameUtil;
import com.intellij.psi.codeStyle.WordPrefixMatcher;
import com.intellij.util.ObjectUtils;
import com.intellij.util.containers.ContainerUtil;
import com.intellij.util.text.Matcher;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
@@ -117,13 +117,12 @@ public abstract class OptionsTopHitProvider implements OptionsSearchTopHitProvid
@Nullable Project project) {
if (provider.getId().startsWith(id) || pattern.startsWith(" ")) {
pattern = pattern.startsWith(" ") ? pattern.trim() : StringUtil.toLowerCase(pattern.substring(id.length()).trim());
MinusculeMatcher matcher = NameUtil.buildMatcher("*" + pattern, NameUtil.MatchingCaseSensitivity.NONE);
consumeTopHitsForApplicableProvider(provider, matcher, collector, project);
consumeTopHitsForApplicableProvider(provider, new WordPrefixMatcher(pattern), collector, project);
}
}
private static void consumeTopHitsForApplicableProvider(@NotNull OptionsSearchTopHitProvider provider,
@NotNull MinusculeMatcher matcher,
@NotNull Matcher matcher,
@NotNull Consumer<Object> collector,
@Nullable Project project) {
for (OptionDescription option : getCachedOptions(provider, project, null)) {
@@ -220,7 +219,7 @@ public abstract class OptionsTopHitProvider implements OptionsSearchTopHitProvid
}
public void consumeAllTopHits(@NotNull String pattern, @NotNull Consumer<Object> collector, @Nullable Project project) {
MinusculeMatcher matcher = NameUtil.buildMatcher("*" + pattern, NameUtil.MatchingCaseSensitivity.NONE);
Matcher matcher = new WordPrefixMatcher(pattern);
for (OptionsSearchTopHitProvider.ProjectLevelProvider provider : PROJECT_LEVEL_EP.getExtensionList()) {
consumeTopHitsForApplicableProvider(provider, matcher, collector, project);
}
@@ -0,0 +1,23 @@
// 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.psi.codeStyle;
import com.intellij.openapi.util.text.StringUtil;
import com.intellij.util.containers.ContainerUtil;
import com.intellij.util.text.Matcher;
import org.jetbrains.annotations.NotNull;
import java.util.Arrays;
public class WordPrefixMatcher implements Matcher {
private final String[] myPatternWords;
public WordPrefixMatcher(String pattern) {
myPatternWords = NameUtil.nameToWords(pattern);
}
@Override
public boolean matches(@NotNull String name) {
String[] nameWords = NameUtil.nameToWords(name);
return Arrays.stream(myPatternWords).allMatch(pw -> ContainerUtil.exists(nameWords, nw -> StringUtil.startsWithIgnoreCase(nw, pw)));
}
}