List<TextAttributesKey> (@NotNull Project project, @NotNull Editor editor) { List<TextAttributesKey> keys = new ArrayList<>(); Ref<TextRange> selectionRef = new Ref<>(); Ref<Boolean> hasEraseMarkerRef = new Ref<>(); Processor<RangeHighlighterEx> processor = r -> { HighlightInfo info = HighlightInfo.fromRangeHighlighter(r); boolean relevant = selectionRef.get().getStartOffset() < r.getEndOffset() && (selectionRef.get().getLength() == 0 || r.getStartOffset() < selectionRef.get().getEndOffset()); TextAttributesKey key = info != null && relevant ? ObjectUtils.chooseNotNull(info.forcedTextAttributesKey, info.type.getAttributesKey()) : null; if (r.getForcedTextAttributes() == TextAttributes.ERASE_MARKER) { hasEraseMarkerRef.set(true); } else if (key != null) { keys.add(key); } return true; }; JBIterable<Editor> editors = editor instanceof EditorWindow ? JBIterable.of(editor, ((EditorWindow)editor).getDelegate()) : JBIterable.of( editor); for (Editor ed : editors) { TextRange selection = EditorUtil.getSelectionInAnyMode(ed); selectionRef.set(selection); hasEraseMarkerRef.set(false); MarkupModel forDocument = DocumentMarkupModel.forDocument(ed.getDocument(), project, false); if (forDocument != null) { ((MarkupModelEx)forDocument).processRangeHighlightersOverlappingWith(selection.getStartOffset(), selection.getEndOffset(), processor); } ((MarkupModelEx)ed.getMarkupModel()).processRangeHighlightersOverlappingWith(selection.getStartOffset(), selection.getEndOffset(), processor); EditorHighlighter highlighter = editor.getHighlighter(); SyntaxHighlighter syntaxHighlighter = highlighter instanceof LexerEditorHighlighter ? ((LexerEditorHighlighter)highlighter).getSyntaxHighlighter() : null; if (syntaxHighlighter != null && !hasEraseMarkerRef.get()) { HighlighterIterator iterator = highlighter.createIterator(selection.getStartOffset()); while (!iterator.atEnd()) { for (TextAttributesKey key : syntaxHighlighter.getTokenHighlights(iterator.getTokenType())) { if (key != null) { keys.add(key); } } if (iterator.getEnd() >= selection.getEndOffset()) break; iterator.advance(); } } } return keys; }