package com.werfad.finder; import com.intellij.openapi.editor.Editor; import com.intellij.openapi.util.TextRange; import com.werfad.KeyTagsGenerator; import com.werfad.MarksCanvas; import com.werfad.UserConfig; import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.Nullable; import java.util.ArrayList; import java.util.List; import java.util.regex.Matcher; import java.util.regex.Pattern; public class Word1Finder implements Finder { private static final int STATE_WAIT_SEARCH_CHAR = 0; private static final int STATE_WAIT_KEY = 1; private int state = STATE_WAIT_SEARCH_CHAR; private UserConfig.DataBean config = UserConfig.getDataBean(); private String s; private TextRange visibleRange; @Nullable @Override public List<MarksCanvas.Mark> start(@NotNull Editor e, @NotNull String s, @NotNull TextRange visibleRange) { this.s = s; this.visibleRange = visibleRange; state = STATE_WAIT_SEARCH_CHAR; return null; } @Nullable @Override public List<MarksCanvas.Mark> input(@NotNull Editor e, char c, @NotNull List<MarksCanvas.Mark> lastMarks) { switch (state) { case STATE_WAIT_SEARCH_CHAR: boolean ignoreCase = config.isSmartcase() && Character.isLowerCase(c); Pattern pattern = Pattern.compile((ignoreCase ? "(?i)" : "") + "\\b" + Pattern.quote("" + c)); Matcher m = pattern.matcher(s); List<Integer> offsets = new ArrayList<>(); while (m.find()) { offsets.add(m.start() + visibleRange.getStartOffset()); } offsets.sort((o1, o2) -> { int cOffset = e.getCaretModel().getOffset(); return Math.abs(o1 - cOffset) - Math.abs(o2 - cOffset); }); List<String> tags = KeyTagsGenerator.createTagsTree(offsets.size(), UserConfig.getDataBean().getCharacters()); List<MarksCanvas.Mark> res = new ArrayList<>(); for (int i = 0; i < offsets.size(); i++) { res.add(new MarksCanvas.Mark(tags.get(i), offsets.get(i))); } state = STATE_WAIT_KEY; return res; case STATE_WAIT_KEY: return FinderHelper.matchInputAndCreateMarks(c, lastMarks); default: throw new RuntimeException("Impossible."); } } }