goto action: do not show duplicated actions in "Go To Action" completion

ActionWrappers with same AnAction and different MatchMode should not be shown together.
This commit is contained in:
Aleksey Pivovarov
2019-03-03 19:36:13 +03:00
parent 2c7348e1d2
commit 2d52e24a33
3 changed files with 21 additions and 22 deletions
@@ -14,6 +14,7 @@ import com.intellij.openapi.project.Project
import com.intellij.openapi.util.Computable
import com.intellij.testFramework.PlatformTestUtil
import com.intellij.testFramework.fixtures.LightCodeInsightFixtureTestCase
import gnu.trove.Equality
import groovy.transform.CompileStatic
import org.jetbrains.annotations.NonNls
import org.jetbrains.annotations.NotNull
@@ -26,13 +27,17 @@ import java.util.concurrent.TimeUnit
@CompileStatic
class GotoActionTest extends LightCodeInsightFixtureTestCase {
private static final DataKey<Boolean> SHOW_HIDDEN_KEY = DataKey.create("GotoActionTest.DataKey")
private static final Comparator<MatchedValue> MATCH_COMPARATOR =
{ MatchedValue item1, MatchedValue item2 -> return item1.compareWeights(item2) } as Comparator<MatchedValue>
private static final Equality<MatchedValue> MATCH_EQUALITY =
{ MatchedValue item1, MatchedValue item2 -> item1 == item2 } as Equality<MatchedValue>
void "test shorter actions first despite ellipsis"() {
def pattern = 'Rebas'
def fork = 'Rebase my GitHub fork'
def rebase = 'Rebase...'
def items = [matchedAction(fork, pattern),
matchedAction(rebase, pattern)].sort()
matchedAction(rebase, pattern)].toSorted(MATCH_COMPARATOR)
assert [rebase, fork] == items.collect { it.valueText }
}
@@ -41,7 +46,7 @@ class GotoActionTest extends LightCodeInsightFixtureTestCase {
def byName = 'By Name'
def byDesc = 'By Desc'
def items = [matchedAction(byName, pattern),
matchedAction(byDesc, pattern, MatchMode.DESCRIPTION)].sort()
matchedAction(byDesc, pattern, MatchMode.DESCRIPTION)].toSorted(MATCH_COMPARATOR)
assert [byName, byDesc] == items.collect { it.valueText }
}
@@ -60,7 +65,7 @@ class GotoActionTest extends LightCodeInsightFixtureTestCase {
matchedAction(eclaire, pattern),
matchedAction(deaf, pattern),
matchedAction(cut, pattern),
matchedAction(c, pattern)].sort()
matchedAction(c, pattern)].toSorted(MATCH_COMPARATOR)
assert [c, copy, cut, aardvark, eclaire, boom, deaf] == items.collect { it.valueText }
}
@@ -86,20 +91,16 @@ class GotoActionTest extends LightCodeInsightFixtureTestCase {
items += matchedBooleanOption(name, pattern)
}
PlatformTestUtil.assertComparisonContractNotViolated(items,
{ def item1, def item2 -> (item1 <=> item2) },
{ def item1, def item2 -> item1 == item2 })
PlatformTestUtil.assertComparisonContractNotViolated(items, MATCH_COMPARATOR, MATCH_EQUALITY)
// order can be different on EDT and pooled threads
ApplicationManager.getApplication().executeOnPooledThread {
PlatformTestUtil.assertComparisonContractNotViolated(items,
{ def item1, def item2 -> (item1 <=> item2) },
{ def item1, def item2 -> item1 == item2 })
PlatformTestUtil.assertComparisonContractNotViolated(items, MATCH_COMPARATOR, MATCH_EQUALITY)
}.get(20000, TimeUnit.MILLISECONDS)
}
void "test same action is not reported twice"() {
def patterns = ["Patch", "Add", "Delete", "Show", "Toggle"]
def patterns = ["Patch", "Add", "Delete", "Show", "Toggle", "New", "New Class"]
def model = new GotoActionModel(project, null, null)
def provider = new GotoActionItemProvider(model)
@@ -126,7 +126,7 @@ public class GotoActionItemProvider implements ChooseByNameItemProvider {
Map<String, String> map = myModel.getConfigurablesNames();
SearchableOptionsRegistrarImpl registrar = (SearchableOptionsRegistrarImpl)SearchableOptionsRegistrar.getInstance();
List<Comparable> options = ContainerUtil.newArrayList();
List<Object> options = ContainerUtil.newArrayList();
final Set<String> words = registrar.getProcessedWords(pattern);
Set<OptionDescription> optionDescriptions = null;
final String actionManagerName = myActionManager.getComponentName();
@@ -224,10 +224,10 @@ public class GotoActionItemProvider implements ChooseByNameItemProvider {
private final static Logger LOG = Logger.getInstance(GotoActionItemProvider.class);
private static boolean processItems(String pattern, JBIterable<? extends Comparable> items, Processor<? super MatchedValue> consumer) {
private static boolean processItems(String pattern, JBIterable<?> items, Processor<? super MatchedValue> consumer) {
List<MatchedValue> matched = ContainerUtil.newArrayList(items.map(o -> o instanceof MatchedValue ? (MatchedValue)o : new MatchedValue(o, pattern)));
try {
Collections.sort(matched);
Collections.sort(matched, (o1, o2) -> o1.compareWeights(o2));
}
catch (IllegalArgumentException e) {
LOG.error("Comparison method violates its general contract with pattern '" + pattern + "'", e);
@@ -167,7 +167,7 @@ public class GotoActionModel implements ChooseByNameModel, Comparator<Object>, D
public void saveInitialCheckBoxState(boolean state) {
}
public static class MatchedValue implements Comparable<MatchedValue> {
public static class MatchedValue {
@NotNull public final Object value;
@NotNull final String pattern;
@@ -207,8 +207,7 @@ public class GotoActionModel implements ChooseByNameModel, Comparator<Object>, D
return 0;
}
@Override
public int compareTo(@NotNull MatchedValue o) {
public int compareWeights(@NotNull MatchedValue o) {
if (o == this) return 0;
int diff = o.getMatchingDegree() - getMatchingDegree();
if (diff != 0) return diff;
@@ -219,7 +218,7 @@ public class GotoActionModel implements ChooseByNameModel, Comparator<Object>, D
if (value instanceof ActionWrapper && o.value instanceof ActionWrapper) {
ActionWrapper value1 = (ActionWrapper)value;
ActionWrapper value2 = (ActionWrapper)o.value;
int compared = value1.compareTo(value2);
int compared = value1.compareWeights(value2);
if (compared != 0) return compared;
}
@@ -299,7 +298,7 @@ public class GotoActionModel implements ChooseByNameModel, Comparator<Object>, D
public int compare(@NotNull Object o1, @NotNull Object o2) {
if (ChooseByNameBase.EXTRA_ELEM.equals(o1)) return 1;
if (ChooseByNameBase.EXTRA_ELEM.equals(o2)) return -1;
return ((MatchedValue)o1).compareTo((MatchedValue)o2);
return ((MatchedValue)o1).compareWeights((MatchedValue)o2);
}
@NotNull
@@ -587,7 +586,7 @@ public class GotoActionModel implements ChooseByNameModel, Comparator<Object>, D
}
}
public static class ActionWrapper implements Comparable<ActionWrapper> {
public static class ActionWrapper {
@NotNull private final AnAction myAction;
@NotNull private final MatchMode myMode;
@Nullable private final GroupMapping myGroupMapping;
@@ -617,8 +616,7 @@ public class GotoActionModel implements ChooseByNameModel, Comparator<Object>, D
return myMode;
}
@Override
public int compareTo(@NotNull ActionWrapper o) {
public int compareWeights(@NotNull ActionWrapper o) {
int compared = myMode.compareTo(o.getMode());
if (compared != 0) return compared;
Presentation myPresentation = myAction.getTemplatePresentation();
@@ -679,7 +677,7 @@ public class GotoActionModel implements ChooseByNameModel, Comparator<Object>, D
@Override
public boolean equals(Object obj) {
return obj instanceof ActionWrapper && compareTo((ActionWrapper)obj) == 0;
return obj instanceof ActionWrapper && myAction.equals(((ActionWrapper)obj).myAction);
}
@Override