1 package com
.intellij
.ui
;
3 import com
.intellij
.codeInsight
.lookup
.LookupItem
;
4 import com
.intellij
.codeInsight
.lookup
.LookupManager
;
5 import com
.intellij
.codeInsight
.lookup
.PresentableLookupValue
;
6 import com
.intellij
.lang
.Language
;
7 import com
.intellij
.openapi
.actionSystem
.ActionManager
;
8 import com
.intellij
.openapi
.actionSystem
.AnAction
;
9 import com
.intellij
.openapi
.actionSystem
.AnActionEvent
;
10 import com
.intellij
.openapi
.actionSystem
.IdeActions
;
11 import com
.intellij
.openapi
.editor
.Document
;
12 import com
.intellij
.openapi
.editor
.Editor
;
13 import com
.intellij
.openapi
.editor
.EditorFactory
;
14 import com
.intellij
.openapi
.fileTypes
.FileType
;
15 import com
.intellij
.openapi
.fileTypes
.PlainTextLanguage
;
16 import com
.intellij
.openapi
.project
.Project
;
17 import com
.intellij
.psi
.PsiDocumentManager
;
18 import com
.intellij
.psi
.PsiFile
;
19 import com
.intellij
.psi
.PsiFileFactory
;
20 import com
.intellij
.psi
.codeStyle
.NameUtil
;
21 import com
.intellij
.util
.LocalTimeCounter
;
22 import org
.jetbrains
.annotations
.Nullable
;
24 import java
.util
.ArrayList
;
25 import java
.util
.Collections
;
26 import java
.util
.Comparator
;
27 import java
.util
.List
;
28 import java
.util
.regex
.Matcher
;
29 import java
.util
.regex
.Pattern
;
32 * @author Roman Chernyatchik
34 * It is text field with autocompletion from list of values.
36 * Autocompletion is implemented via LookupManager.
37 * Use setVariants(..) set list of values for autocompletion.
38 * For variants you can use not only instances of PresentableLookupValue, but
39 * also instances of LookupValueWithPriority and LookupValueWithUIHint
41 public class TextFieldWithAutoCompletion
extends EditorTextField
{
42 private List
<LookupItem
<PresentableLookupValue
>> myLookupItems
;
44 public TextFieldWithAutoCompletion() {
48 public TextFieldWithAutoCompletion(final Project project
) {
49 super(createDocument(project
), project
, PlainTextLanguage
.INSTANCE
.getAssociatedFileType());
51 new VariantsCompletionAction();
54 private static Document
createDocument(@Nullable final Project project
) {
55 if (project
== null) {
56 return EditorFactory
.getInstance().createDocument("");
59 final Language language
= PlainTextLanguage
.INSTANCE
;
60 final PsiFileFactory factory
= PsiFileFactory
.getInstance(project
);
61 final FileType fileType
= language
.getAssociatedFileType();
62 assert fileType
!= null;
64 final long stamp
= LocalTimeCounter
.currentTime();
65 final PsiFile psiFile
= factory
.createFileFromText("Dummy." + fileType
.getDefaultExtension(), fileType
, "", stamp
, true, false);
66 final Document document
= PsiDocumentManager
.getInstance(project
).getDocument(psiFile
);
67 assert document
!= null;
71 private class VariantsCompletionAction
extends AnAction
{
72 private VariantsCompletionAction() {
73 final AnAction action
= ActionManager
.getInstance().getAction(IdeActions
.ACTION_CODE_COMPLETION
);
75 registerCustomShortcutSet(action
.getShortcutSet(), TextFieldWithAutoCompletion
.this);
79 public void actionPerformed(final AnActionEvent e
) {
80 final LookupItem
<PresentableLookupValue
>[] lookupItems
= calcLookupItems(getPrefix());
82 showCompletionPopup(lookupItems
, null);
86 public void setVariants(@Nullable final List
<PresentableLookupValue
> variants
) {
87 if (variants
== null) {
88 myLookupItems
= Collections
.emptyList();
90 myLookupItems
= new ArrayList
<LookupItem
<PresentableLookupValue
>>(variants
.size());
91 for (PresentableLookupValue variant
: variants
) {
92 myLookupItems
.add(new LookupItem
<PresentableLookupValue
>(variant
, variant
.getPresentation()));
97 private LookupItem
<PresentableLookupValue
>[] calcLookupItems(final String prefix
) {
98 final List
<LookupItem
<PresentableLookupValue
>> items
= new ArrayList
<LookupItem
<PresentableLookupValue
>>();
99 if (prefix
== null || prefix
.length() == 0) {
100 for (LookupItem
<PresentableLookupValue
> lookupItem
: myLookupItems
) {
101 items
.add(lookupItem
);
104 final String regexp
= NameUtil
.buildRegexp(prefix
, 0, true, true);
105 final Pattern pattern
= Pattern
.compile(regexp
);
106 final Matcher matcher
= pattern
.matcher("");
108 for (LookupItem
<PresentableLookupValue
> lookupItem
: myLookupItems
) {
109 matcher
.reset(lookupItem
.getLookupString());
110 if (matcher
.matches()) {
111 items
.add(lookupItem
);
116 Collections
.sort(items
, new Comparator
<LookupItem
<PresentableLookupValue
>>() {
117 public int compare(final LookupItem
<PresentableLookupValue
> item1
,
118 final LookupItem
<PresentableLookupValue
> item2
) {
119 return item1
.getLookupString().compareTo(item2
.getLookupString());
123 return (LookupItem
<PresentableLookupValue
>[])items
.toArray(new LookupItem
[items
.size()]);
126 private String
getPrefix() {
127 return getText().substring(0, getCaretModel().getOffset());
130 private void showCompletionPopup(final LookupItem
[] lookupItems
, final String title
) {
131 final Editor editor
= getEditor();
132 assert editor
!= null;
134 editor
.getSelectionModel().removeSelection();
135 LookupManager
.getInstance(getProject()).showLookup(editor
, lookupItems
, getPrefix(), null, title
);