package krasa.grepconsole.filter; import com.google.common.collect.Range; import com.google.common.collect.TreeRangeMap; import com.intellij.execution.filters.InputFilter; import com.intellij.execution.ui.ConsoleViewContentType; import com.intellij.openapi.project.Project; import com.intellij.openapi.util.Pair; import krasa.grepconsole.filter.support.FilterState; import krasa.grepconsole.filter.support.GrepProcessor; import krasa.grepconsole.filter.support.MyResultItem; import krasa.grepconsole.model.GrepExpressionItem; import krasa.grepconsole.model.Profile; import org.jetbrains.annotations.NotNull; import java.util.*; public class GrepHighlightingInputFilter extends GrepHighlightFilter implements InputFilter { public GrepHighlightingInputFilter(Project project) { super(project); } public GrepHighlightingInputFilter(Profile profile, List<GrepProcessor> grepProcessors) { super(profile, grepProcessors); } @Override public List<Pair<String, ConsoleViewContentType>> applyFilter(String s, ConsoleViewContentType consoleViewContentType) { if (s != null) { FilterState state = super.filter(s, 0); if (state != null) { return prepareResult(s, s.length(), state, consoleViewContentType); } } return null; } private List<Pair<String, ConsoleViewContentType>> prepareResult(String s, int entireLength, FilterState state, ConsoleViewContentType originalConsoleViewContentType) { List<MyResultItem> resultItemList = adjustWholeLineMatch(entireLength, state); int lastIndex = 0; List<Pair<String, ConsoleViewContentType>> pairs = null; if (resultItemList != null) { Set<Map.Entry<Range<Integer>, MyResultItem>> entries = toRanges(resultItemList); pairs = new ArrayList<>(entries.size()); for (Map.Entry<Range<Integer>, MyResultItem> entry : entries) { Range<Integer> key = entry.getKey(); MyResultItem value = entry.getValue(); Integer start = key.lowerEndpoint(); Integer end = key.upperEndpoint(); if (lastIndex < start) { pairs.add(Pair.create(s.substring(lastIndex, start), originalConsoleViewContentType)); } pairs.add(Pair.create(s.substring(start, end), value.getConsoleViewContentType())); lastIndex = end; } if (s.length() > lastIndex) { pairs.add(Pair.create(s.substring(lastIndex, s.length()), originalConsoleViewContentType)); } } return pairs; } @NotNull private Set<Map.Entry<Range<Integer>, MyResultItem>> toRanges(List<MyResultItem> resultItemList) { TreeRangeMap<Integer, MyResultItem> treeRangeMap = TreeRangeMap.create(); Collections.reverse(resultItemList); for (MyResultItem resultItem : resultItemList) { int start = resultItem.getHighlightStartOffset(); int end = resultItem.getHighlightEndOffset(); treeRangeMap.put(Range.closed(start, end), resultItem); } return treeRangeMap.asMapOfRanges().entrySet(); } @Override protected GrepProcessor createProcessor(GrepExpressionItem grepExpressionItem) { return grepExpressionItem.createProcessor(); } }