IDEA-212693 vcs: show navigatable links in annotations popup

GitOrigin-RevId: 37b2b1c079bc75b0ba908034e0311cb702496472
This commit is contained in:
Aleksey Pivovarov
2019-07-29 18:49:22 +03:00
committed by intellij-monorepo-bot
parent 3dabdc6845
commit 87eb311629
5 changed files with 144 additions and 44 deletions
@@ -0,0 +1,90 @@
// 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 git4idea.annotate;
import com.intellij.openapi.project.Project;
import com.intellij.openapi.vcs.changes.issueLinks.IssueLinkHtmlRenderer;
import com.intellij.openapi.vcs.history.VcsRevisionNumber;
import com.intellij.util.containers.Convertor;
import com.intellij.vcsUtil.VcsUtil;
import com.intellij.xml.util.XmlStringUtil;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
public class AnnotationTooltipBuilder {
@NotNull private final Project myProject;
private final boolean myAsHtml;
private final StringBuilder sb = new StringBuilder();
public AnnotationTooltipBuilder(@NotNull Project project, boolean asHtml) {
myProject = project;
myAsHtml = asHtml;
}
private void append(@NotNull String text) {
sb.append(myAsHtml ? XmlStringUtil.escapeString(text) : text);
}
private void appendRaw(@NotNull String text) {
sb.append(text);
}
public void appendRevisionLine(@NotNull VcsRevisionNumber revisionNumber,
@Nullable Convertor<? super VcsRevisionNumber, String> linkBuilder) {
appendNewline();
append("commit ");
String link = myAsHtml && linkBuilder != null ? linkBuilder.convert(revisionNumber) : null;
if (link != null) {
appendRaw(link);
}
else {
append(revisionNumber.asString());
}
}
public void appendLine(@NotNull String content) {
appendNewline();
append(content);
}
public void appendCommitMessageBlock(@NotNull String message) {
append("\n\n");
appendTextWithLinks(message);
}
public void appendTextWithLinks(@NotNull String message) {
if (myAsHtml) {
appendRaw(IssueLinkHtmlRenderer.formatTextWithLinks(myProject, message));
}
else {
append(VcsUtil.trimCommitMessageToSaneSize(message));
}
}
private void appendNewline() {
if (sb.length() != 0) append("\n");
}
@Override
public String toString() {
return sb.toString();
}
@NotNull
public static String buildSimpleTooltip(@NotNull Project project,
boolean asHtml,
@NotNull String prefix,
@NotNull String revision,
@Nullable String commitMessage) {
AnnotationTooltipBuilder builder = new AnnotationTooltipBuilder(project, asHtml);
builder.append(prefix);
builder.append(" ");
builder.append(revision);
if (commitMessage != null) {
builder.append(": ");
builder.appendTextWithLinks(commitMessage);
}
return builder.toString();
}
}
@@ -26,7 +26,6 @@ import com.intellij.openapi.vcs.annotate.FileAnnotation;
import com.intellij.openapi.vcs.annotate.LineAnnotationAspect;
import com.intellij.openapi.vcs.annotate.LineAnnotationAspectAdapter;
import com.intellij.openapi.vcs.changes.ContentRevision;
import com.intellij.openapi.vcs.changes.issueLinks.IssueLinkHtmlRenderer;
import com.intellij.openapi.vcs.history.VcsFileRevision;
import com.intellij.openapi.vcs.history.VcsRevisionNumber;
import com.intellij.openapi.vcs.impl.AbstractVcsHelperImpl;
@@ -35,7 +34,6 @@ import com.intellij.util.containers.ContainerUtil;
import com.intellij.util.text.DateFormatUtil;
import com.intellij.vcs.log.VcsUser;
import com.intellij.vcsUtil.VcsUtil;
import com.intellij.xml.util.XmlStringUtil;
import git4idea.GitContentRevision;
import git4idea.GitFileRevision;
import git4idea.GitRevisionNumber;
@@ -168,40 +166,23 @@ public class GitFileAnnotation extends FileAnnotation {
LineInfo lineInfo = getLineInfo(lineNumber);
if (lineInfo == null) return null;
StringBuilder sb = new StringBuilder();
AnnotationTooltipBuilder atb = new AnnotationTooltipBuilder(myProject, asHtml);
GitRevisionNumber revisionNumber = lineInfo.getRevisionNumber();
String revisionLink = asHtml ? GitCommitTooltipLinkHandler.createLink(revisionNumber.asString(), revisionNumber) : null;
if (revisionLink != null) {
sb.append("commit ").append(revisionLink);
}
else {
appendLine(sb, asHtml, "commit " + revisionNumber.asString());
}
appendLine(sb, asHtml, "Author: " + lineInfo.getAuthor());
appendLine(sb, asHtml, "Date: " + DateFormatUtil.formatDateTime(lineInfo.getAuthorDate()));
atb.appendRevisionLine(revisionNumber, it -> GitCommitTooltipLinkHandler.createLink(it.asString(), it));
atb.appendLine("Author: " + lineInfo.getAuthor());
atb.appendLine("Date: " + DateFormatUtil.formatDateTime(lineInfo.getAuthorDate()));
if (!myFilePath.equals(lineInfo.myFilePath)) {
String path = FileUtil.getLocationRelativeToUserHome(lineInfo.myFilePath.getPresentableUrl());
appendLine(sb, asHtml, "Path: " + path);
atb.appendLine("Path: " + path);
}
String commitMessage = getCommitMessage(revisionNumber);
if (commitMessage == null) commitMessage = lineInfo.getSubject() + "\n...";
if (asHtml) {
sb.append("\n\n").append(IssueLinkHtmlRenderer.formatTextWithLinks(myProject, commitMessage));
}
else {
sb.append("\n\n").append(VcsUtil.trimCommitMessageToSaneSize(commitMessage));
}
atb.appendCommitMessageBlock(commitMessage);
return sb.toString();
}
private static void appendLine(@NotNull StringBuilder sb, boolean asHtml, @NotNull String content) {
if (sb.length() != 0) sb.append('\n');
sb.append(asHtml ? XmlStringUtil.escapeString(content) : content);
return atb.toString();
}
@Nullable
@@ -136,7 +136,6 @@ hg4idea.exception.file.not.under.hg=The file {0} is not under Mercurial.
hg4idea.changelist.column.branch=Branch
hg4idea.annotation.tool.tip=commit {0}\nAuthor: {1}\nDate: {2}\n\n{3}
hg4idea.push.asNewBranch=push as &new remote branch
hg4idea.push.bookmark=Book&mark
@@ -18,17 +18,21 @@ package org.zmlx.hg4idea.provider.annotate;
import com.intellij.openapi.project.Project;
import com.intellij.openapi.vcs.VcsKey;
import com.intellij.openapi.vcs.annotate.*;
import com.intellij.openapi.vcs.annotate.FileAnnotation;
import com.intellij.openapi.vcs.annotate.LineAnnotationAspect;
import com.intellij.openapi.vcs.annotate.LineAnnotationAspectAdapter;
import com.intellij.openapi.vcs.annotate.ShowAllAffectedGenericAction;
import com.intellij.openapi.vcs.history.VcsFileRevision;
import com.intellij.openapi.vcs.history.VcsRevisionNumber;
import com.intellij.openapi.vfs.LocalFileSystem;
import com.intellij.openapi.vfs.VirtualFile;
import com.intellij.util.containers.ContainerUtil;
import git4idea.annotate.AnnotationTooltipBuilder;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
import org.zmlx.hg4idea.HgFile;
import org.zmlx.hg4idea.HgFileRevision;
import org.zmlx.hg4idea.HgVcs;
import org.zmlx.hg4idea.HgVcsMessages;
import java.util.Date;
import java.util.LinkedList;
@@ -80,9 +84,20 @@ public class HgAnnotation extends FileAnnotation {
};
}
@Override
@Nullable
@Override
public String getToolTip(int lineNumber) {
return getToolTip(lineNumber, false);
}
@Nullable
@Override
public String getHtmlToolTip(int lineNumber) {
return getToolTip(lineNumber, true);
}
@Nullable
private String getToolTip(int lineNumber, boolean asHtml) {
if ( myLines.size() <= lineNumber || lineNumber < 0 ) {
return null;
}
@@ -91,14 +106,16 @@ public class HgAnnotation extends FileAnnotation {
return null;
}
for (HgFileRevision revision : myFileRevisions) {
if (revision.getRevisionNumber().equals(info.getVcsRevisionNumber())) {
return HgVcsMessages.message("hg4idea.annotation.tool.tip", revision.getRevisionNumber().asString(),
revision.getAuthor(), revision.getRevisionDate(), revision.getCommitMessage());
}
}
HgFileRevision revision = ContainerUtil.find(myFileRevisions, it -> it.getRevisionNumber().equals(info.getVcsRevisionNumber()));
if (revision == null) return null;
return null;
AnnotationTooltipBuilder atb = new AnnotationTooltipBuilder(myProject, asHtml);
atb.appendRevisionLine(revision.getRevisionNumber(), null);
atb.appendLine("Author: " + revision.getAuthor());
atb.appendLine("Date: " + revision.getRevisionDate());
String message = revision.getCommitMessage();
if (message != null) atb.appendCommitMessageBlock(message);
return atb.toString();
}
@Override
@@ -7,6 +7,7 @@ import com.intellij.openapi.vcs.history.VcsFileRevision;
import com.intellij.openapi.vcs.history.VcsRevisionNumber;
import com.intellij.util.text.DateFormatUtil;
import com.intellij.xml.util.XmlStringUtil;
import git4idea.annotate.AnnotationTooltipBuilder;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
import org.jetbrains.idea.svn.SvnBundle;
@@ -113,18 +114,30 @@ public abstract class BaseSvnFileAnnotation extends FileAnnotation {
return new LineAnnotationAspect[]{REVISION_ASPECT, DATE_ASPECT, AUTHOR_ASPECT};
}
@Nullable
@Override
public String getToolTip(final int lineNumber) {
public String getToolTip(int lineNumber) {
return getToolTip(lineNumber, false);
}
@Nullable
@Override
public String getHtmlToolTip(int lineNumber) {
return getToolTip(lineNumber, true);
}
@Nullable
private String getToolTip(int lineNumber, boolean asHtml) {
final CommitInfo info = myInfos.getOrNull(lineNumber);
if (info == null) return "";
if (info == null) return null;
SvnFileRevision revision = myRevisionMap.get(info.getRevisionNumber());
if (revision != null) {
String prefix = myInfos.getAnnotationSource(lineNumber).showMerged() ? "Merge source revision" : "Revision";
if (revision == null) return null;
return prefix + " " + info.getRevisionNumber() + ": " + revision.getCommitMessage();
}
return "";
String prefix = myInfos.getAnnotationSource(lineNumber).showMerged() ? "Merge source revision" : "Revision";
return AnnotationTooltipBuilder.buildSimpleTooltip(getProject(), asHtml, prefix,
String.valueOf(info.getRevisionNumber()),
revision.getCommitMessage());
}
@Override