/* * Copyright 2015 Ritesh Kapoor * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package com.ritesh.idea.plugin.ui.controls; import com.intellij.codeInsight.completion.CompletionResultSet; import com.intellij.codeInsight.lookup.LookupElementBuilder; import com.intellij.openapi.application.ApplicationManager; import com.intellij.openapi.components.ServiceManager; import com.intellij.openapi.diagnostic.Logger; import com.intellij.openapi.fileTypes.FileTypes; import com.intellij.openapi.progress.ProgressManager; import com.intellij.openapi.project.Project; import com.intellij.spellchecker.ui.SpellCheckingEditorCustomization; import com.intellij.ui.EditorCustomization; import com.intellij.ui.EditorTextField; import com.intellij.ui.EditorTextFieldProvider; import com.intellij.ui.SoftWrapsEditorCustomization; import com.intellij.util.TextFieldCompletionProvider; import org.apache.commons.lang.mutable.MutableBoolean; import org.jetbrains.annotations.NotNull; import java.util.ArrayList; import java.util.Arrays; import java.util.List; /** * @author ritesh on 24/7/15. */ public class MultiValueAutoComplete { final static Logger LOG = Logger.getInstance(MultiValueAutoComplete.class); private static final char[] SEPARATORS = {','}; public static EditorTextField create(Project project, DataProvider dataProvider) { List<EditorCustomization> customizations = Arrays.<EditorCustomization>asList(SoftWrapsEditorCustomization.ENABLED, SpellCheckingEditorCustomization.DISABLED); EditorTextField editorField = ServiceManager.getService(project, EditorTextFieldProvider.class) .getEditorField(FileTypes.PLAIN_TEXT.getLanguage(), project, customizations); new CommaSeparatedTextFieldCompletion(dataProvider).apply(editorField); return editorField; } public interface DataProvider { List<String> getValues(String prefix); } private static class CommaSeparatedTextFieldCompletion extends TextFieldCompletionProvider { private DataProvider dataProvider; public CommaSeparatedTextFieldCompletion(DataProvider dataProvider) { this.dataProvider = dataProvider; } @NotNull @Override protected String getPrefix(@NotNull String currentTextPrefix) { final int separatorPosition = lastSeparatorPosition(currentTextPrefix); return separatorPosition == -1 ? currentTextPrefix : currentTextPrefix.substring(separatorPosition + 1).trim(); } private static int lastSeparatorPosition(@NotNull String text) { int lastPosition = -1; for (char separator : SEPARATORS) { int lio = text.lastIndexOf(separator); if (lio > lastPosition) { lastPosition = lio; } } return lastPosition; } @Override protected void addCompletionVariants(@NotNull String text, int offset, @NotNull final String prefix, @NotNull CompletionResultSet result) { final List<String> values = new ArrayList<>(); final MutableBoolean completed = new MutableBoolean(false); ApplicationManager.getApplication().executeOnPooledThread(new Runnable() { @Override public void run() { List<String> values = dataProvider.getValues(prefix); if(values!=null) { values.addAll(values); } completed.setValue(true); } }); while (!completed.booleanValue()) { ProgressManager.getInstance().checkCanceled(); try { Thread.sleep(50); } catch (InterruptedException e) { LOG.error(e); } } result.addLookupAdvertisement("Select one or more users separated with comma, | or new lines"); for (String completionVariant : values) { final LookupElementBuilder element = LookupElementBuilder.create(completionVariant); result.addElement(element.withLookupString(completionVariant.toLowerCase())); } } } }