static CharFilter.Result getLookupAction(final char charTyped, final LookupImpl lookup) { final CharFilter.Result filtersDecision = getFiltersDecision(charTyped, lookup); if (!Registry.is("ide.completion.allow.finishing.by.chars") && filtersDecision == CharFilter.Result.SELECT_ITEM_AND_FINISH_LOOKUP) { return CharFilter.Result.HIDE_LOOKUP; } final LookupElement currentItem = lookup.getCurrentItem(); if (currentItem != null && charTyped != ' ') { String postfix = lookup.getAdditionalPrefix() + charTyped; final PrefixMatcher matcher = lookup.itemMatcher(currentItem); for (String lookupString : currentItem.getAllLookupStrings()) { if (lookupString.startsWith(matcher.getPrefix() + postfix)) { return CharFilter.Result.ADD_TO_PREFIX; } } } if (filtersDecision != null) { return filtersDecision; } throw new AssertionError( "Typed char not handler by char filter: c=" + charTyped + "; prefix=" + currentItem + "; filters=" + Arrays.toString(getFilters())); }
@Nullable private static CharFilter.Result getFiltersDecision(char charTyped, LookupImpl lookup) { LookupElement item = lookup.getCurrentItem(); int prefixLength = item == null ? lookup.getAdditionalPrefix().length() : lookup.itemPattern(item).length(); for (final CharFilter extension : getFilters()) { final CharFilter.Result result = extension.acceptChar(charTyped, prefixLength, lookup); if (result != null) { return result; } } return null; }
private static boolean completeTillTypedCharOccurrence( char charTyped, LookupImpl lookup, LookupElement item) { PrefixMatcher matcher = lookup.itemMatcher(item); final String oldPrefix = matcher.getPrefix() + lookup.getAdditionalPrefix(); PrefixMatcher expanded = matcher.cloneWithPrefix(oldPrefix + charTyped); if (expanded.prefixMatches(item)) { for (String s : item.getAllLookupStrings()) { if (matcher.prefixMatches(s)) { int i = -1; while (true) { i = s.indexOf(charTyped, i + 1); if (i < 0) break; final String newPrefix = s.substring(0, i + 1); if (expanded.prefixMatches(newPrefix)) { lookup.replacePrefix(oldPrefix, newPrefix); return true; } } } } } return false; }