Custom LineMarkInfo Repeat

Answered

Why the LineMarkInfo display repeatedly :

 

 

All my code is following:

public class BookmarkLineMarkerProvider implements LineMarkerProvider {

    @Override
    public LineMarkerInfo<?> getLineMarkerInfo(@NotNull PsiElement element) {
        return null;
    }

    @Override
    public void collectSlowLineMarkers(@NotNull List<? extends PsiElement> elements, @NotNull Collection<? super LineMarkerInfo<?>> result) {
        if (elements.isEmpty()) {
            return;
        }

        Project project = elements.get(0).getProject();
        BookmarksManager manager = BookmarksManager.getInstance(project);
        FileMarksCache fileMarksCache = manager.getFileMarksCache();

        Set<Integer> lineNumbers = new HashSet<>();
        for (PsiElement element : elements) {
            PsiFile file = element.getContainingFile();
            String path = file.getVirtualFile().getPath();

            Document document = file.getViewProvider().getDocument();
            int number = document.getLineNumber(element.getTextOffset());
            if (!lineNumbers.add(number)) {
                continue;
            }
            Optional<BookmarkNodeModel> nodeModel = fileMarksCache.findModel(path, number);

            if (nodeModel.isEmpty()) {
                continue;
            }

            LineMarkerInfo<PsiElement> markerInfo = new BkLineMarkerInfo(
                    nodeModel.get(),
                    element,
                    (ev, el) -> {
                    }
            );
            result.add(markerInfo);
        }
    }




    static class BkLineMarkerInfo extends LineMarkerInfo<PsiElement> {

        private final BookmarkNodeModel model;

        public BkLineMarkerInfo(BookmarkNodeModel model,
                                @NotNull PsiElement element,
                                GutterIconNavigationHandler<PsiElement> navHandler) {
            super(element, element.getTextRange(), MyIcons.BOOKMARK, null, navHandler, GutterIconRenderer.Alignment.LEFT, model::getName);
            this.model = model;
        }

        @Override
        public GutterIconRenderer createGutterRenderer() {
            return new LineMarkerGutterIconRenderer<>(this) {

                @Override
                public @NotNull ActionGroup getPopupMenuActions() {
                    DefaultActionGroup actionGroup = new DefaultActionGroup();
                    actionGroup.add(new BookmarkEditAction(model));
                    actionGroup.add(new BookmarkRemoveAction(model));
                    return actionGroup;
                }
            };
        }

        @Override
        public String getLineMarkerTooltip() {
            return model.getDesc();
        }
    }
}
0
5 comments

Hi,

Did you try to debug the code? Isn't result.add(markerInfo); executed multiple times for a single line?

0

I used if (!lineNumbers.add(number)) to ensure that it executed  only one time,and I have tried to save the line number to BkLineMarkerInfo , then I got two same BkLineMarkerInfo 

0

And I don't understand why the icon "I" that represents the interface implementation sometimes turns into two, this is not my custom icon

0

This problem comes with the following warning:

2025-01-03 09:43:01,890 [  57802]   WARN - eInsight.daemon.LineMarkerInfo - Performance warning: LineMarker is supposed to be registered for leaf elements only, but got: PsiCodeBlock (class com.intellij.psi.impl.source.tree.java.PsiCodeBlockImpl) instead. First child: PsiJavaToken:LBRACE (class com.intellij.psi.impl.source.tree.java.PsiJavaTokenImpl)

I want to implement line markup like IDEA's bookmarks and bind the markup to the line instead of the specific element. How do I do this

0

This API is for creating line markers for particular PSI elements.

If you want to create gutter icons for lines, consider using com.intellij.openapi.editor.markup.RangeHighlighter API.

1

Please sign in to leave a comment.