IDEA-225120 Search bar in Plugins Marketplace does not react to some search query changes

GitOrigin-RevId: a863121c90e30528fc7101429bbf4c6973daa7fa
This commit is contained in:
Alexander Lobas
2019-11-25 12:09:00 +00:00
committed by intellij-monorepo-bot
parent f2fbea9ac8
commit b8c624cdf2
5 changed files with 113 additions and 284 deletions
@@ -487,19 +487,8 @@ public class PluginManagerConfigurable
return null;
}
@Override
protected void handleAppendToQuery() {
showPopupForQuery();
}
@Override
protected void handleAppendAttributeValue() {
showPopupForQuery();
}
@Override
protected void showPopupForQuery() {
hidePopup();
showSearchPanel(mySearchTextField.getText());
}
@@ -600,14 +589,12 @@ public class PluginManagerConfigurable
new SearchQueryParser.Marketplace(mySearchTextField.getText()) {
@Override
protected void addToSearchQuery(@NotNull String query) {
super.addToSearchQuery(query);
queries.add(query);
}
@Override
protected void handleAttribute(@NotNull String name, @NotNull String value, boolean invert) {
super.handleAttribute(name, value, invert);
queries.add(name + ":" + SearchQueryParser.wrapAttribute(value));
protected void handleAttribute(@NotNull String name, @NotNull String value) {
queries.add(name + SearchQueryParser.wrapAttribute(value));
}
};
if (removeAction != null) {
@@ -926,16 +913,6 @@ public class PluginManagerConfigurable
return null;
}
@Override
protected void handleAppendToQuery() {
showPopupForQuery();
}
@Override
protected void handleAppendAttributeValue() {
showPopupForQuery();
}
@Override
protected void showPopupForQuery() {
showSearchPanel(mySearchTextField.getText());
@@ -955,18 +932,16 @@ public class PluginManagerConfigurable
myInstalledSearchCallback = updateAction -> {
List<String> queries = new ArrayList<>();
new SearchQueryParser.InstalledWithVendorAndTag(mySearchTextField.getText()) {
new SearchQueryParser.Installed(mySearchTextField.getText()) {
@Override
protected void addToSearchQuery(@NotNull String query) {
super.addToSearchQuery(query);
queries.add(query);
}
@Override
protected void handleAttribute(@NotNull String name, @NotNull String value, boolean invert) {
super.handleAttribute(name, value, invert);
protected void handleAttribute(@NotNull String name, @NotNull String value) {
if (!updateAction.myState) {
queries.add("/" + name + (value.isEmpty() ? "" : ":" + SearchQueryParser.wrapAttribute(value)));
queries.add(name + (value.isEmpty() ? "" : SearchQueryParser.wrapAttribute(value)));
}
}
};
@@ -1013,7 +988,7 @@ public class PluginManagerConfigurable
protected void handleQuery(@NotNull String query, @NotNull PluginsGroup result) {
myPluginModel.setInvalidFixCallback(null);
SearchQueryParser.InstalledWithVendorAndTag parser = new SearchQueryParser.InstalledWithVendorAndTag(query);
SearchQueryParser.Installed parser = new SearchQueryParser.Installed(query);
if (myInstalledSearchSetState) {
for (AnAction action : myInstalledSearchGroup.getChildren(null)) {
@@ -1413,7 +1388,7 @@ public class PluginManagerConfigurable
myInstalledSearchCallback.accept(this);
}
public void setState(@Nullable SearchQueryParser.InstalledWithVendorAndTag parser) {
public void setState(@Nullable SearchQueryParser.Installed parser) {
if (parser == null) {
myState = false;
return;
@@ -49,7 +49,7 @@ public abstract class PluginsTab {
query = (String)data;
}
else if (data instanceof TagComponent) {
query = "/" + SearchQueryParser.getTagQuery(((TagComponent)data).getText());
query = SearchQueryParser.getTagQuery(((TagComponent)data).getText());
}
else {
return;
@@ -22,7 +22,6 @@ import java.util.List;
*/
public abstract class SearchPopupController {
protected final PluginSearchTextField myTextField;
private final boolean myHandleSpace;
protected SearchPopup myPopup;
private final JBPopupListener mySearchPopupListener = new JBPopupAdapter() {
@Override
@@ -32,12 +31,7 @@ public abstract class SearchPopupController {
};
public SearchPopupController(@NotNull PluginSearchTextField searchTextField) {
this(searchTextField, true);
}
public SearchPopupController(@NotNull PluginSearchTextField searchTextField, boolean handleSpace) {
myTextField = searchTextField;
myHandleSpace = handleSpace;
}
public void handleShowPopup() {
@@ -46,24 +40,13 @@ public abstract class SearchPopupController {
int position = getCaretPosition();
if (position < length) {
if (query.charAt(position) == ' ') {
if (position == 0 || query.charAt(position - 1) == ' ') {
if (myHandleSpace) {
showAttributesPopup(null, position);
}
return;
}
}
else {
hidePopup();
handleAppendToQuery();
if (query.charAt(position) != ' ') {
handleShowPopupForQuery();
return;
}
}
else if (query.charAt(position - 1) == ' ') {
if (myHandleSpace) {
showAttributesPopup(null, position);
}
handleShowPopupForQuery();
return;
}
@@ -107,13 +90,11 @@ public abstract class SearchPopupController {
index--;
}
String name = StringUtil.trimStart(query.substring(index + 1, end), "-");
if (startPosition.isNull()) {
startPosition.set(index + (query.charAt(index + 1) == '-' ? 2 : 1));
startPosition.set(index + 1);
}
return Pair.create(name, value);
return Pair.create(query.substring(index + 1, end), value);
}
public void showAttributesPopup(@Nullable String namePrefix, int caretPosition) {
@@ -141,7 +122,7 @@ public abstract class SearchPopupController {
private void handleShowAttributeValuesPopup(@NotNull String name, @Nullable String valuePrefix, int caretPosition) {
List<String> values = getValues(name);
if (ContainerUtil.isEmpty(values)) {
showPopupForQuery();
handleShowPopupForQuery();
return;
}
@@ -159,7 +140,7 @@ public abstract class SearchPopupController {
@Override
public void consume(String value) {
appendSearchText(SearchQueryParser.wrapAttribute(value), prefix);
handleAppendAttributeValue();
handleShowPopupForQuery();
}
});
}
@@ -218,7 +199,7 @@ public abstract class SearchPopupController {
}
if (model.isEmpty()) {
showPopupForQuery();
handleShowPopupForQuery();
return true;
}
@@ -231,14 +212,13 @@ public abstract class SearchPopupController {
@Nullable
protected abstract List<String> getValues(@NotNull String attribute);
private void handleShowPopupForQuery() {
hidePopup();
showPopupForQuery();
}
protected abstract void showPopupForQuery();
protected void handleAppendToQuery() {
}
protected void handleAppendAttributeValue() {
}
public boolean isPopupShow() {
return myPopup != null && myPopup.isValid();
}
@@ -4,7 +4,6 @@ package com.intellij.ide.plugins.newui;
import com.intellij.openapi.util.text.StringUtil;
import com.intellij.util.io.URLUtil;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
import java.util.ArrayList;
import java.util.HashSet;
@@ -17,34 +16,13 @@ import java.util.Set;
public abstract class SearchQueryParser {
public String searchQuery;
@NotNull
public static List<String> split(@NotNull String name, @Nullable String query) {
List<String> result = new ArrayList<>();
if (query == null) {
result.add(name);
return result;
protected void addToSearchQuery(@NotNull String query) {
if (searchQuery == null) {
searchQuery = query;
}
int length = name.length();
int queryLength = query.length();
int index = 0;
while (true) {
int end = StringUtil.indexOfIgnoreCase(name, query, index);
if (end == -1) {
break;
}
result.add(name.substring(index, end));
index = end + queryLength;
result.add(name.substring(end, index));
else {
searchQuery += " " + query;
}
if (index < length) {
result.add(name.substring(index));
}
return result;
}
@NotNull
@@ -70,7 +48,11 @@ public abstract class SearchQueryParser {
}
int start = index - 1;
while (index < length) {
while (index <= length) {
if (index == length) {
words.add(query.substring(start));
break;
}
char nextCh = query.charAt(index++);
if (nextCh == ':' || nextCh == ' ' || index == length) {
words.add(query.substring(start, nextCh == ' ' ? index - 1 : index));
@@ -79,71 +61,72 @@ public abstract class SearchQueryParser {
}
}
if (words.isEmpty() && length > 0) {
words.add(query);
}
return words;
}
protected final void parse(@NotNull String query) {
List<String> words = splitQuery(query);
int size = words.size();
if (size == 0) {
return;
}
if (size == 1) {
addToSearchQuery(words.get(0));
return;
}
int index = 0;
while (index < size) {
String name = words.get(index++);
if (name.endsWith(":")) {
if (index < size) {
boolean invert = name.startsWith("-");
name = name.substring(invert ? 1 : 0, name.length() - 1);
handleAttribute(name, words.get(index++), invert);
}
else {
addToSearchQuery(query);
return;
}
}
else {
addToSearchQuery(name);
}
}
}
protected void addToSearchQuery(@NotNull String query) {
if (searchQuery == null) {
searchQuery = query;
}
else {
searchQuery += " " + query;
}
}
protected abstract void handleAttribute(@NotNull String name, @NotNull String value, boolean invert);
@NotNull
public static String getTagQuery(@NotNull String tag) {
return "tag:" + (tag.indexOf(' ') == -1 ? tag : StringUtil.wrapWithDoubleQuote(tag));
return "/tag:" + (tag.indexOf(' ') == -1 ? tag : StringUtil.wrapWithDoubleQuote(tag));
}
public static class Trending extends SearchQueryParser {
@NotNull
public static String wrapAttribute(@NotNull String value) {
return StringUtil.containsAnyChar(value, " ,:") ? StringUtil.wrapWithDoubleQuote(value) : value;
}
public static class Marketplace extends SearchQueryParser {
public final Set<String> vendors = new HashSet<>();
public final Set<String> tags = new HashSet<>();
public final Set<String> repositories = new HashSet<>();
public String sortBy;
public Trending(@NotNull String query) {
public Marketplace(@NotNull String query) {
parse(query);
}
protected Trending() {
private void parse(@NotNull String query) {
List<String> words = splitQuery(query);
int size = words.size();
if (size == 0) {
return;
}
if (size == 1) {
addToSearchQuery(words.get(0));
return;
}
int index = 0;
while (index < size) {
String name = words.get(index++);
if (name.endsWith(":")) {
if (index < size) {
handleAttribute(name, words.get(index++));
}
else {
addToSearchQuery(query);
return;
}
}
else {
addToSearchQuery(name);
}
}
}
protected void handleAttribute(@NotNull String name, @NotNull String value) {
if (name.equals("/tag:")) {
tags.add(value);
}
else if (name.equals("/sortBy:")) {
sortBy = value;
}
else if (name.equals("/repository:")) {
repositories.add(value);
}
else if (name.equals("/vendor:")) {
vendors.add(value);
}
}
@NotNull
@@ -182,105 +165,9 @@ public abstract class SearchQueryParser {
return url.toString();
}
@Override
protected void handleAttribute(@NotNull String name, @NotNull String value, boolean invert) {
if (name.equals("tag")) {
tags.add(value);
}
else if (name.equals("sortBy")) {
sortBy = value;
}
else if (name.equals("repository")) {
repositories.add(value);
}
}
}
public static class Marketplace extends Trending {
public final Set<String> vendors = new HashSet<>();
public Marketplace(@NotNull String query) {
parse(query);
}
@Override
protected void handleAttribute(@NotNull String name, @NotNull String value, boolean invert) {
if (name.equals("/vendor")) {
vendors.add(value);
}
else if (name.startsWith("/")) {
super.handleAttribute(name.substring(1), value, invert);
}
}
}
public static class Installed extends SearchQueryParser {
public Boolean enabled; // False == disabled
public Boolean bundled; // False == custom
public Boolean invalid;
public Boolean needUpdate;
public Boolean deleted;
public Boolean needRestart; // inactive & after update
public boolean attributes;
public Installed(@NotNull String query) {
localParse(query);
}
private void localParse(@NotNull String query) {
for (String word : splitQuery(query)) {
if (word.startsWith("#")) {
handleAttribute(word.substring(1), "", false);
}
else if (word.startsWith("-#")) {
handleAttribute(word.substring(2), "", true);
}
else {
addToSearchQuery(word);
}
}
attributes = enabled != null || bundled != null || invalid != null || needUpdate != null || deleted != null || needRestart != null;
}
@Override
protected void handleAttribute(@NotNull String name, @NotNull String value, boolean invert) {
switch (name) {
case "enabled":
enabled = !invert;
break;
case "disabled":
enabled = invert;
break;
case "bundled":
bundled = !invert;
break;
case "custom":
bundled = invert;
break;
case "invalid":
invalid = !invert;
break;
case "outdated":
needUpdate = !invert;
break;
case "uninstalled":
deleted = !invert;
break;
case "inactive":
needRestart = !invert;
break;
}
}
}
public static class InstalledWithVendorAndTag extends SearchQueryParser {
public final Set<String> vendors = new HashSet<>();
public final Set<String> tags = new HashSet<>();
public boolean enabled;
@@ -291,11 +178,11 @@ public abstract class SearchQueryParser {
public boolean needUpdate;
public boolean attributes;
public InstalledWithVendorAndTag(@NotNull String query) {
localParse(query);
public Installed(@NotNull String query) {
parse(query);
}
private void localParse(@NotNull String query) {
private void parse(@NotNull String query) {
List<String> words = splitQuery(query);
int size = words.size();
@@ -309,7 +196,7 @@ public abstract class SearchQueryParser {
if (name.startsWith("/")) {
if (name.equals("/vendor:") || name.equals("/tag:")) {
if (index < size) {
handleAttribute(name.substring(1, name.length() - 1), words.get(index++), false);
handleAttribute(name, words.get(index++));
}
else {
addToSearchQuery(query);
@@ -317,7 +204,7 @@ public abstract class SearchQueryParser {
}
}
else {
handleAttribute(name.substring(1), "", false);
handleAttribute(name, "");
}
}
else {
@@ -328,44 +215,31 @@ public abstract class SearchQueryParser {
attributes = enabled || disabled || bundled || downloaded || invalid || needUpdate;
}
@Override
protected void handleAttribute(@NotNull String name, @NotNull String value, boolean invert) {
switch (name) {
case "enabled":
enabled = true;
break;
case "disabled":
disabled = true;
break;
case "bundled":
bundled = true;
break;
case "downloaded":
downloaded = true;
break;
case "invalid":
invalid = true;
break;
case "outdated":
needUpdate = true;
break;
case "vendor":
vendors.add(value);
break;
case "tag":
tags.add(value);
break;
protected void handleAttribute(@NotNull String name, @NotNull String value) {
if ("/enabled".equals(name)) {
enabled = true;
}
else if ("/disabled".equals(name)) {
disabled = true;
}
else if ("/bundled".equals(name)) {
bundled = true;
}
else if ("/downloaded".equals(name)) {
downloaded = true;
}
else if ("/invalid".equals(name)) {
invalid = true;
}
else if ("/outdated".equals(name)) {
needUpdate = true;
}
else if ("/vendor:".equals(name)) {
vendors.add(value);
}
else if ("/tag:".equals(name)) {
tags.add(value);
}
}
}
@NotNull
public static String wrapAttribute(@NotNull String value) {
return StringUtil.containsAnyChar(value, " ,:") ? StringUtil.wrapWithDoubleQuote(value) : value;
}
}
@@ -13,7 +13,7 @@ public abstract class SearchUpDownPopupController extends SearchPopupController
private EventHandler mySearchResultEventHandler;
public SearchUpDownPopupController(@NotNull PluginSearchTextField searchTextField) {
super(searchTextField, false);
super(searchTextField);
}
public void setEventHandler(@NotNull EventHandler eventHandler) {