IJPL-163538 Convert GroupMapping to Kotlin and add suspended variant of updateBefore method

(cherry picked from commit 5565a07501b2a938cfd4cc4c9ad047aea604b757)

IJ-MR-146410

(cherry picked from commit 3503d25d2342910cfeb55f9e86e80e1fd91b188e)


(cherry picked from commit 808dfd1eaf61aba677e7faa9ba820c8e59d3725e)

IJ-CR-153899

GitOrigin-RevId: 2db57fa549ae38cc6ec7a05c03b74d855468fda0
This commit is contained in:
Mikhail Sokolov
2024-10-09 14:06:47 +02:00
committed by intellij-monorepo-bot
parent a20761acd8
commit 75698d8271
3 changed files with 148 additions and 107 deletions

View File

@@ -360,9 +360,9 @@ internal class ActionAsyncProvider(private val model: GotoActionModel) {
return if (weight == null) MatchedValue(item, pattern, matchType) else MatchedValue(item, pattern, weight, matchType)
}
private fun wrapAnAction(action: AnAction, presentation: Presentation, matchMode: MatchMode = MatchMode.NAME): ActionWrapper {
private suspend fun wrapAnAction(action: AnAction, presentation: Presentation, matchMode: MatchMode = MatchMode.NAME): ActionWrapper {
val groupMapping = model.getGroupMapping(action)
groupMapping?.updateBeforeShow(model.updateSession)
groupMapping?.updateBeforeShowSuspend(model.updateSession)
return ActionWrapper(action, groupMapping, matchMode, presentation)
}

View File

@@ -59,12 +59,10 @@ import java.util.List;
import java.util.*;
import java.util.concurrent.ConcurrentHashMap;
import java.util.function.Supplier;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
public final class GotoActionModel implements ChooseByNameModel, Comparator<Object>, DumbAware {
private static final Logger LOG = Logger.getInstance(GotoActionModel.class);
private static final Pattern INNER_GROUP_WITH_IDS = Pattern.compile("(.*) \\(\\d+\\)");
private static final Icon EMPTY_ICON = EmptyIcon.ICON_16;
private final @Nullable Project myProject;
@@ -519,109 +517,6 @@ public final class GotoActionModel implements ChooseByNameModel, Comparator<Obje
return true;
}
public static final class GroupMapping implements Comparable<GroupMapping> {
private final boolean myShowNonPopupGroups;
private final List<List<ActionGroup>> myPaths = new ArrayList<>();
private @Nullable @ActionText String myBestGroupName;
private boolean myBestNameComputed;
public GroupMapping() {
this(false);
}
public GroupMapping(boolean showNonPopupGroups) {
myShowNonPopupGroups = showNonPopupGroups;
}
public static @NotNull GroupMapping createFromText(@ActionText String text, boolean showGroupText) {
GroupMapping mapping = new GroupMapping(showGroupText);
mapping.addPath(Collections.singletonList(new DefaultActionGroup(text, false)));
return mapping;
}
private void addPath(@NotNull List<ActionGroup> path) {
myPaths.add(path);
}
@Override
public int compareTo(@NotNull GroupMapping o) {
return Comparing.compare(getFirstGroupName(), o.getFirstGroupName());
}
public @ActionText @Nullable String getBestGroupName() {
if (myBestNameComputed) return myBestGroupName;
return getFirstGroupName();
}
public @Nullable List<ActionGroup> getFirstGroup() {
return ContainerUtil.getFirstItem(myPaths);
}
private @Nls @Nullable String getFirstGroupName() {
List<ActionGroup> path = getFirstGroup();
return path != null ? getPathName(path) : null;
}
public void updateBeforeShow(@NotNull UpdateSession session) {
if (myBestNameComputed) return;
myBestNameComputed = true;
for (List<ActionGroup> path : myPaths) {
String name = getActualPathName(path, session);
if (name != null) {
myBestGroupName = name;
return;
}
}
}
public @NotNull List<String> getAllGroupNames() {
return ContainerUtil.map(myPaths, path -> getPathName(path));
}
private @Nls @Nullable String getPathName(@NotNull List<? extends ActionGroup> path) {
String name = "";
for (ActionGroup group : path) {
name = appendGroupName(name, group, group.getTemplatePresentation());
}
return StringUtil.nullize(name);
}
private @Nls @Nullable String getActualPathName(@NotNull List<? extends ActionGroup> path, @NotNull UpdateSession session) {
String name = "";
for (ActionGroup group : path) {
Presentation presentation = session.presentation(group);
if (!presentation.isVisible()) return null;
name = appendGroupName(name, group, presentation);
}
return StringUtil.nullize(name);
}
private @Nls @NotNull String appendGroupName(@NotNull @Nls String prefix, @NotNull ActionGroup group, @NotNull Presentation presentation) {
if (group.isPopup() || myShowNonPopupGroups) {
String groupName = getActionGroupName(presentation);
if (!StringUtil.isEmptyOrSpaces(groupName)) {
return prefix.isEmpty()
? groupName
: prefix + " | " + groupName;
}
}
return prefix;
}
private static @ActionText @Nullable String getActionGroupName(@NotNull Presentation presentation) {
String text = presentation.getText();
if (text == null) return null;
Matcher matcher = INNER_GROUP_WITH_IDS.matcher(text);
if (matcher.matches()) return matcher.group(1);
return text;
}
}
public static class ActionWrapper {
private final @NotNull AnAction myAction;
private final @NotNull MatchMode myMode;

View File

@@ -0,0 +1,146 @@
// Copyright 2000-2024 JetBrains s.r.o. and contributors. Use of this source code is governed by the Apache 2.0 license.
package com.intellij.ide.util.gotoByName
import com.intellij.openapi.actionSystem.ActionGroup
import com.intellij.openapi.actionSystem.DefaultActionGroup
import com.intellij.openapi.actionSystem.Presentation
import com.intellij.openapi.actionSystem.UpdateSession
import com.intellij.openapi.actionSystem.impl.SuspendingUpdateSession
import com.intellij.openapi.util.Comparing
import com.intellij.openapi.util.NlsActions.ActionText
import com.intellij.openapi.util.text.StringUtil
import org.jetbrains.annotations.Nls
import java.util.regex.Matcher
import java.util.regex.Pattern
class GroupMapping @JvmOverloads constructor(private val myShowNonPopupGroups: Boolean = false) : Comparable<GroupMapping?> {
private val myPaths: MutableList<List<ActionGroup>> = ArrayList<List<ActionGroup>>()
private var myBestGroupName: @ActionText String? = null
private var myBestNameComputed = false
fun addPath(path: List<ActionGroup>) {
myPaths.add(path)
}
override fun compareTo(o: GroupMapping?): Int {
return Comparing.compare<String?>(this.firstGroupName, o?.firstGroupName)
}
val bestGroupName: @ActionText String?
get() {
if (myBestNameComputed) return myBestGroupName
return this.firstGroupName
}
val firstGroup: List<ActionGroup>?
get() = myPaths.firstOrNull()
private val firstGroupName: @Nls String?
get() {
val path = this.firstGroup
return path?.let { getPathName(it) }
return if (path != null) getPathName(path) else null
}
suspend fun updateBeforeShowSuspend(session: UpdateSession) {
val suspendingSession = (session as? SuspendingUpdateSession)
if (suspendingSession == null) {
updateBeforeShow(session)
return
}
if (myBestNameComputed) return
myBestNameComputed = true
for (path in myPaths) {
val name = getActualPathNameSuspend(path, suspendingSession)
if (name != null) {
myBestGroupName = name
return
}
}
}
fun updateBeforeShow(session: UpdateSession) {
if (myBestNameComputed) return
myBestNameComputed = true
for (path in myPaths) {
val name = getActualPathName(path, session)
if (name != null) {
myBestGroupName = name
return
}
}
}
val allGroupNames: List<String?>
get() = myPaths.map { path: List<ActionGroup> -> getPathName(path) }
private fun getPathName(path: List<ActionGroup>): @Nls String? {
var name = ""
for (group in path) {
name = appendGroupName(name, group, group.getTemplatePresentation())
}
return StringUtil.nullize(name)
}
private suspend fun getActualPathNameSuspend(path: List<ActionGroup>, session: SuspendingUpdateSession): @Nls String? {
var name = ""
for (group in path) {
val presentation = session.presentationSuspend(group)
if (!presentation.isVisible()) return null
name = appendGroupName(name, group, presentation)
}
return StringUtil.nullize(name)
}
private fun getActualPathName(path: List<ActionGroup>, session: UpdateSession): @Nls String? {
var name = ""
for (group in path) {
val presentation = session.presentation(group)
if (!presentation.isVisible()) return null
name = appendGroupName(name, group, presentation)
}
return StringUtil.nullize(name)
}
private fun appendGroupName(
prefix: @Nls String,
group: ActionGroup,
presentation: Presentation
): @Nls String {
if (group.isPopup() || myShowNonPopupGroups) {
val groupName: String? = getActionGroupName(presentation)
if (!groupName.isNullOrBlank()) {
return (if (prefix.isEmpty())
groupName
else
prefix + " | " + groupName)
}
}
return prefix
}
companion object {
private val INNER_GROUP_WITH_IDS: Pattern = Pattern.compile("(.*) \\(\\d+\\)")
@JvmStatic
fun createFromText(text: @ActionText String?, showGroupText: Boolean): GroupMapping {
val mapping = GroupMapping(showGroupText)
mapping.addPath(listOf<ActionGroup>(DefaultActionGroup(text, false)))
return mapping
}
private fun getActionGroupName(presentation: Presentation): @ActionText String? {
val text = presentation.getText()
if (text == null) return null
val matcher: Matcher = INNER_GROUP_WITH_IDS.matcher(text)
if (matcher.matches()) return matcher.group(1)
return text
}
}
}