[vcs] IJPL-173922 Move GitBranchesClippedNamesCache to shared module

Also, move used APIs from GitBranchPopupActions.java

GitOrigin-RevId: 31cd5e7e4d6f72cb330006f1547971168aaf01ca
This commit is contained in:
Ilia.Shulgin
2025-05-25 16:32:18 +00:00
committed by intellij-monorepo-bot
parent c191be6a78
commit c4dd7b9e83
7 changed files with 103 additions and 83 deletions
+1
View File
@@ -25,6 +25,7 @@ jvm_library(
"//platform/dvcs-impl/shared",
"//platform/core-ui",
"//platform/util/coroutines",
"@lib//:caffeine",
],
runtime_deps = [":shared_resources"]
)
@@ -46,5 +46,6 @@
<orderEntry type="module" module-name="intellij.platform.vcs.dvcs.impl.shared" />
<orderEntry type="module" module-name="intellij.platform.core.ui" />
<orderEntry type="module" module-name="intellij.platform.util.coroutines" />
<orderEntry type="library" name="caffeine" level="project" />
</component>
</module>
@@ -1,5 +1,5 @@
// Copyright 2000-2023 JetBrains s.r.o. and contributors. Use of this source code is governed by the Apache 2.0 license.
package git4idea.ui.branch
// Copyright 2000-2025 JetBrains s.r.o. and contributors. Use of this source code is governed by the Apache 2.0 license.
package com.intellij.vcs.git.shared.branch
import com.github.benmanes.caffeine.cache.Cache
import com.github.benmanes.caffeine.cache.Caffeine
@@ -7,7 +7,7 @@ import com.intellij.openapi.Disposable
import com.intellij.openapi.components.Service
import com.intellij.openapi.project.Project
import com.intellij.openapi.util.Disposer
import git4idea.ui.branch.GitBranchPopupActions.truncateBranchName
import com.intellij.vcs.git.shared.ui.GitBranchPresentation
import java.util.concurrent.TimeUnit
@Service(Service.Level.PROJECT)
@@ -42,7 +42,7 @@ class GitBranchesClippedNamesCache(private val project: Project) : Disposable {
}
private fun truncateBranchName(branchName: String, maxBranchNameLength: Int): ClippedBranch {
return ClippedBranch(truncateBranchName(project, branchName, maxBranchNameLength, 0, 0), maxBranchNameLength)
return ClippedBranch(GitBranchPresentation.truncateBranchName(project, branchName, maxBranchNameLength, 0, 0), maxBranchNameLength)
}
fun clear() = cache.invalidateAll()
@@ -55,4 +55,4 @@ class GitBranchesClippedNamesCache(private val project: Project) : Disposable {
private const val CACHE_MAX_SIZE = 1_000L
private const val CACHE_ACCESS_EXPIRATION_MIN = 5L
}
}
}
@@ -0,0 +1,91 @@
// Copyright 2000-2025 JetBrains s.r.o. and contributors. Use of this source code is governed by the Apache 2.0 license.
package com.intellij.vcs.git.shared.ui;
import com.intellij.openapi.project.Project;
import com.intellij.openapi.util.NlsSafe;
import com.intellij.openapi.util.TextRange;
import com.intellij.openapi.util.text.StringUtil;
import com.intellij.openapi.vcs.IssueNavigationConfiguration;
import org.jetbrains.annotations.ApiStatus;
import org.jetbrains.annotations.NotNull;
import java.util.List;
@ApiStatus.Internal
public final class GitBranchPresentation {
public static final int BRANCH_NAME_LENGTH_DELTA = 4;
public static final int BRANCH_NAME_SUFFIX_LENGTH = 5;
public static @NlsSafe @NotNull String truncateBranchName(@NotNull Project project,
@NotNull @NlsSafe String branchName,
int maxBranchNameLength) {
return truncateBranchName(project, branchName, maxBranchNameLength, BRANCH_NAME_SUFFIX_LENGTH, BRANCH_NAME_LENGTH_DELTA);
}
public static @NlsSafe @NotNull String truncateBranchName(@NotNull Project project, @NotNull @NlsSafe String branchName,
int maxBranchNameLength, int suffixLength, int delta) {
int branchNameLength = branchName.length();
if (branchNameLength <= maxBranchNameLength + delta) {
return branchName;
}
IssueNavigationConfiguration issueNavigationConfiguration = IssueNavigationConfiguration.getInstance(project);
List<IssueNavigationConfiguration.LinkMatch> issueMatches = issueNavigationConfiguration.findIssueLinks(branchName);
int affectedMaxBranchNameLength = maxBranchNameLength - StringUtil.ELLIPSIS.length();
if (!issueMatches.isEmpty()) {
// never truncate the first occurrence of the issue id
IssueNavigationConfiguration.LinkMatch firstMatch = issueMatches.get(0);
TextRange firstMatchRange = firstMatch.getRange();
return truncateAndSaveIssueId(firstMatchRange, branchName, affectedMaxBranchNameLength, suffixLength, delta);
}
if (affectedMaxBranchNameLength - suffixLength - StringUtil.ELLIPSIS.length() < 0) {
return branchName;
}
return StringUtil.shortenTextWithEllipsis(branchName, affectedMaxBranchNameLength, suffixLength, true);
}
private static @NlsSafe @NotNull String truncateAndSaveIssueId(@NotNull TextRange issueIdRange,
@NotNull String branchName,
int maxBranchNameLength,
int suffixLength, int delta) {
String truncatedByDefault = StringUtil.shortenTextWithEllipsis(branchName,
maxBranchNameLength,
suffixLength, true);
String issueId = issueIdRange.substring(branchName);
if (truncatedByDefault.contains(issueId)) return truncatedByDefault;
try {
int branchNameLength = branchName.length();
int endOffset = issueIdRange.getEndOffset();
int startOffset = issueIdRange.getStartOffset();
// suffix intersects with the issue id
if (endOffset >= branchNameLength - suffixLength - delta) {
return StringUtil.shortenTextWithEllipsis(branchName,
maxBranchNameLength,
branchNameLength - startOffset, true);
}
String suffix = branchName.substring(branchNameLength - suffixLength);
int prefixLength = maxBranchNameLength - suffixLength - issueId.length();
String prefixAndIssue;
if (Math.abs(startOffset - prefixLength) <= delta) {
prefixAndIssue = branchName.substring(0, endOffset);
}
else {
String prefix = branchName.substring(0, prefixLength);
prefixAndIssue = prefix + StringUtil.ELLIPSIS + issueId;
}
return prefixAndIssue + StringUtil.ELLIPSIS + suffix;
}
catch (Throwable e) {
return truncatedByDefault;
}
}
}
@@ -12,11 +12,10 @@ import com.intellij.openapi.project.DumbAwareAction;
import com.intellij.openapi.project.Project;
import com.intellij.openapi.util.NlsContexts;
import com.intellij.openapi.util.NlsSafe;
import com.intellij.openapi.util.TextRange;
import com.intellij.openapi.util.text.StringUtil;
import com.intellij.openapi.vcs.IssueNavigationConfiguration;
import com.intellij.util.concurrency.annotations.RequiresEdt;
import com.intellij.util.ui.EmptyIcon;
import com.intellij.vcs.git.shared.ui.GitBranchPresentation;
import git4idea.*;
import git4idea.branch.GitBranchIncomingOutgoingManager;
import git4idea.branch.GitBrancher;
@@ -48,8 +47,6 @@ public final class GitBranchPopupActions {
public static final @NonNls String EXPERIMENTAL_BRANCH_POPUP_ACTION_GROUP = "Git.Experimental.Branch.Popup.Actions";
private static final int MAX_BRANCH_NAME_LENGTH = 40;
public static final int BRANCH_NAME_LENGTH_DELTA = 4;
public static final int BRANCH_NAME_SUFFIX_LENGTH = 5;
private GitBranchPopupActions() { }
@@ -95,75 +92,7 @@ public final class GitBranchPopupActions {
}
public static @NlsSafe @NotNull String truncateBranchName(@NotNull @NlsSafe String branchName, @NotNull Project project) {
return truncateBranchName(project, branchName,
MAX_BRANCH_NAME_LENGTH, BRANCH_NAME_SUFFIX_LENGTH, BRANCH_NAME_LENGTH_DELTA);
}
public static @NlsSafe @NotNull String truncateBranchName(@NotNull Project project, @NotNull @NlsSafe String branchName,
int maxBranchNameLength, int suffixLength, int delta) {
int branchNameLength = branchName.length();
if (branchNameLength <= maxBranchNameLength + delta) {
return branchName;
}
IssueNavigationConfiguration issueNavigationConfiguration = IssueNavigationConfiguration.getInstance(project);
List<IssueNavigationConfiguration.LinkMatch> issueMatches = issueNavigationConfiguration.findIssueLinks(branchName);
int affectedMaxBranchNameLength = maxBranchNameLength - StringUtil.ELLIPSIS.length();
if (!issueMatches.isEmpty()) {
// never truncate the first occurrence of the issue id
IssueNavigationConfiguration.LinkMatch firstMatch = issueMatches.get(0);
TextRange firstMatchRange = firstMatch.getRange();
return truncateAndSaveIssueId(firstMatchRange, branchName, affectedMaxBranchNameLength, suffixLength, delta);
}
if (affectedMaxBranchNameLength - suffixLength - StringUtil.ELLIPSIS.length() < 0) {
return branchName;
}
return StringUtil.shortenTextWithEllipsis(branchName, affectedMaxBranchNameLength, suffixLength, true);
}
private static @NlsSafe @NotNull String truncateAndSaveIssueId(@NotNull TextRange issueIdRange,
@NotNull String branchName,
int maxBranchNameLength,
int suffixLength, int delta) {
String truncatedByDefault = StringUtil.shortenTextWithEllipsis(branchName,
maxBranchNameLength,
suffixLength, true);
String issueId = issueIdRange.substring(branchName);
if (truncatedByDefault.contains(issueId)) return truncatedByDefault;
try {
int branchNameLength = branchName.length();
int endOffset = issueIdRange.getEndOffset();
int startOffset = issueIdRange.getStartOffset();
// suffix intersects with the issue id
if (endOffset >= branchNameLength - suffixLength - delta) {
return StringUtil.shortenTextWithEllipsis(branchName,
maxBranchNameLength,
branchNameLength - startOffset, true);
}
String suffix = branchName.substring(branchNameLength - suffixLength);
int prefixLength = maxBranchNameLength - suffixLength - issueId.length();
String prefixAndIssue;
if (Math.abs(startOffset - prefixLength) <= delta) {
prefixAndIssue = branchName.substring(0, endOffset);
}
else {
String prefix = branchName.substring(0, prefixLength);
prefixAndIssue = prefix + StringUtil.ELLIPSIS + issueId;
}
return prefixAndIssue + StringUtil.ELLIPSIS + suffix;
}
catch (Throwable e) {
return truncatedByDefault;
}
return GitBranchPresentation.truncateBranchName(project, branchName, MAX_BRANCH_NAME_LENGTH);
}
private static @NlsSafe @NotNull String wrapWithQuotes(@NlsSafe @NotNull String branchName) {
@@ -11,6 +11,7 @@ import com.intellij.openapi.util.text.HtmlBuilder
import com.intellij.openapi.util.text.StringUtil
import com.intellij.util.messages.Topic
import com.intellij.vcs.git.shared.branch.calcTooltip
import com.intellij.vcs.git.shared.ui.GitBranchPresentation
import git4idea.GitTag
import git4idea.GitUtil
import git4idea.GitVcs
@@ -84,10 +85,7 @@ private fun getDefaultPresentation(repository: GitRepository): GitCurrentBranchP
private fun calcText(repository: GitRepository): @NlsSafe String =
StringUtil.escapeMnemonics(GitBranchUtil.getDisplayableBranchText(repository) { branchName ->
GitBranchPopupActions.truncateBranchName(repository.project, branchName,
GitToolbarWidgetAction.BRANCH_NAME_MAX_LENGTH,
GitBranchPopupActions.BRANCH_NAME_SUFFIX_LENGTH,
GitBranchPopupActions.BRANCH_NAME_LENGTH_DELTA)
GitBranchPresentation.truncateBranchName(repository.project, branchName, GitToolbarWidgetAction.BRANCH_NAME_MAX_LENGTH)
})
private fun GitRepository.calcIcon(): Icon? {
@@ -17,11 +17,11 @@ import com.intellij.util.ui.JBUI
import com.intellij.util.ui.UpdateScaleHelper
import com.intellij.util.ui.components.BorderLayoutPanel
import com.intellij.util.ui.tree.TreeUtil
import com.intellij.vcs.git.shared.branch.GitBranchesClippedNamesCache
import com.intellij.vcs.git.shared.repo.GitRepositoryFrontendModel
import com.intellij.vcs.git.shared.ui.GitBranchesTreeIconProvider
import git4idea.GitBranch
import git4idea.GitReference
import git4idea.ui.branch.GitBranchesClippedNamesCache
import git4idea.ui.branch.popup.GitBranchesTreePopupBase
import git4idea.ui.branch.popup.GitBranchesTreePopupStepBase
import git4idea.ui.branch.tree.GitBranchesTreeModel.RefUnderRepository