1 package com
.intellij
.codeInsight
.lookup
;
3 import com
.intellij
.codeInsight
.TailType
;
4 import com
.intellij
.codeInsight
.completion
.CompletionUtil
;
5 import com
.intellij
.codeInsight
.completion
.InsertHandler
;
6 import com
.intellij
.codeInsight
.completion
.InsertionContext
;
7 import com
.intellij
.codeInsight
.lookup
.impl
.ElementLookupRenderer
;
8 import com
.intellij
.codeInsight
.lookup
.impl
.LookupElementPresentationEx
;
9 import com
.intellij
.openapi
.editor
.Editor
;
10 import com
.intellij
.openapi
.extensions
.Extensions
;
11 import com
.intellij
.openapi
.util
.Comparing
;
12 import com
.intellij
.openapi
.util
.Key
;
13 import com
.intellij
.util
.containers
.HashMap
;
14 import gnu
.trove
.THashSet
;
15 import org
.jetbrains
.annotations
.NonNls
;
16 import org
.jetbrains
.annotations
.NotNull
;
17 import org
.jetbrains
.annotations
.Nullable
;
20 import java
.util
.Arrays
;
25 * This class represents an item of a lookup list.
27 public class LookupItem
<T
> extends MutableLookupElement
<T
> implements Comparable
{
28 public static final Object HIGHLIGHTED_ATTR
= Key
.create("highlighted");
29 public static final Object TYPE_ATTR
= Key
.create("type");
30 public static final Object ICON_ATTR
= Key
.create("icon");
31 public static final Object TYPE_TEXT_ATTR
= Key
.create("typeText");
32 public static final Object TAIL_TEXT_ATTR
= Key
.create("tailText");
33 public static final Object TAIL_TEXT_SMALL_ATTR
= Key
.create("tailTextSmall");
34 public static final Key
<Object
> FORCE_SHOW_SIGNATURE_ATTR
= Key
.create("forceShowSignature");
36 public static final Object DO_AUTOCOMPLETE_ATTR
= Key
.create("DO_AUTOCOMPLETE_ATTR");
38 public static final Object GENERATE_ANONYMOUS_BODY_ATTR
= Key
.create("GENERATE_ANONYMOUS_BODY_ATTR");
39 public static final Key
<Object
> BRACKETS_COUNT_ATTR
= Key
.create("BRACKETS_COUNT_ATTR");
40 public static final Key
<Object
> OVERWRITE_ON_AUTOCOMPLETE_ATTR
= Key
.create("OVERWRITE_ON_AUTOCOMPLETE_ATTR");
41 public static final Object NEW_OBJECT_ATTR
= Key
.create("NEW_OBJECT_ATTR");
42 public static final Object DONT_CHECK_FOR_INNERS
= Key
.create("DONT_CHECK_FOR_INNERS");
43 public static final Object FORCE_QUALIFY
= Key
.create("FORCE_QUALIFY");
44 public static final Object SUBSTITUTOR
= Key
.create("SUBSTITUTOR");
45 public static final Object TYPE
= Key
.create("TYPE");
46 public static final Object INDICATE_ANONYMOUS
= Key
.create("INDICATE ANONYMOUS");
47 public static final Key
<Object
> DEPRECATED_ATTR
= Key
.create("DEPRECATED");
49 public static final Key
<Comparable
[]> WEIGHT
= Key
.create("WEIGHT");
51 public static final Object CASE_INSENSITIVE
= Key
.create("CASE_INSENSITIVE");
53 public static final Key
<TailType
> TAIL_TYPE_ATTR
= Key
.create("myTailType"); // one of constants defined in SimpleTailType interface
55 private Object myObject
;
56 private String myLookupString
;
57 private InsertHandler myInsertHandler
;
58 private double myPriority
;
59 private int myGrouping
;
60 private Map
<Object
,Object
> myAttributes
= null;
61 public static final LookupItem
[] EMPTY_ARRAY
= new LookupItem
[0];
62 private final Set
<String
> myAllLookupStrings
= new THashSet
<String
>();
63 private String myPresentable
;
64 private AutoCompletionPolicy myAutoCompletionPolicy
= AutoCompletionPolicy
.SETTINGS_DEPENDENT
;
66 public LookupItem(T o
, @NotNull @NonNls String lookupString
){
68 setLookupString(lookupString
);
71 public static LookupItem
fromString(String s
) {
72 return new LookupItem
<String
>(s
, s
);
75 public void setObject(@NotNull T o
) {
78 if (o
instanceof LookupValueWithPriority
) {
79 setPriority(((LookupValueWithPriority
)o
).getPriority());
83 public boolean equals(Object o
){
84 if (o
== this) return true;
85 if (o
instanceof LookupItem
){
86 LookupItem item
= (LookupItem
)o
;
87 return Comparing
.equal(myObject
, item
.myObject
)
88 && Comparing
.equal(myLookupString
, item
.myLookupString
)
89 && Comparing
.equal(myAllLookupStrings
, item
.myAllLookupStrings
)
90 && Comparing
.equal(myAttributes
, item
.myAttributes
);
95 public int hashCode() {
96 return myAllLookupStrings
.hashCode() * 239 + getObject().hashCode();
99 public String
toString() {
100 return getLookupString();
104 * Returns a data object. This object is used e.g. for rendering the node.
107 public T
getObject() {
112 * Returns a string which will be inserted to the editor when this item is
116 public String
getLookupString() {
117 return myLookupString
;
120 public void setLookupString(@NotNull String lookupString
) {
121 if (myAllLookupStrings
.contains("")) myAllLookupStrings
.remove("");
122 myLookupString
= lookupString
;
123 myAllLookupStrings
.add(lookupString
);
126 public Object
getAttribute(Object key
){
127 if (myAttributes
!= null){
128 return myAttributes
.get(key
);
135 public <T
> T
getAttribute(Key
<T
> key
) {
136 if (myAttributes
!= null){
137 //noinspection unchecked
138 return (T
)myAttributes
.get(key
);
145 public void setAttribute(Object key
, Object value
){
146 if (myAttributes
== null){
147 myAttributes
= new HashMap
<Object
, Object
>(5);
149 myAttributes
.put(key
, value
);
152 public <T
> void setAttribute(Key
<T
> key
, T value
){
153 if (value
== null && myAttributes
!= null) {
154 myAttributes
.remove(key
);
158 if (myAttributes
== null){
159 myAttributes
= new HashMap
<Object
, Object
>(5);
161 myAttributes
.put(key
, value
);
164 public InsertHandler
<?
extends LookupItem
> getInsertHandler(){
165 return myInsertHandler
;
168 public boolean isBold() {
169 return getAttribute(HIGHLIGHTED_ATTR
) != null;
173 public void handleInsert(final InsertionContext context
) {
174 super.handleInsert(context
);
175 if (getTailType() != TailType
.UNKNOWN
&& myInsertHandler
== null) {
176 context
.setAddCompletionChar(false);
177 final TailType type
= handleCompletionChar(context
.getEditor(), this, context
.getCompletionChar());
178 type
.processTail(context
.getEditor(), context
.getTailOffset());
183 public static TailType
getDefaultTailType(final char completionChar
) {
184 switch(completionChar
){
185 case '.': return TailType
.DOT
;
186 case ',': return TailType
.COMMA
;
187 case ';': return TailType
.SEMICOLON
;
188 case '=': return TailType
.EQ
;
189 case ' ': return TailType
.SPACE
;
190 case ':': return TailType
.CASE_COLON
; //?
191 case Lookup
.COMPLETE_STATEMENT_SELECT_CHAR
: return TailType
.SMART_COMPLETION
;
197 public static TailType
handleCompletionChar(@NotNull final Editor editor
, @NotNull final LookupElement lookupElement
, final char completionChar
) {
198 final TailType type
= getDefaultTailType(completionChar
);
203 final LookupItem
<?
> item
= (LookupItem
)lookupElement
;
204 final TailType attr
= item
.getAttribute(CompletionUtil
.TAIL_TYPE_ATTR
);
205 return attr
!= null ? attr
: TailType
.NONE
;
210 public TailType
getTailType(){
211 final TailType tailType
= getAttribute(TAIL_TYPE_ATTR
);
212 return tailType
!= null ? tailType
: TailType
.UNKNOWN
;
216 public LookupItem
<T
> setTailType(@NotNull TailType type
) {
217 setAttribute(TAIL_TYPE_ATTR
, type
);
221 public int compareTo(Object o
){
222 if(o
instanceof String
){
223 return getLookupString().compareTo((String
)o
);
225 if(!(o
instanceof LookupItem
)){
226 throw new RuntimeException("Trying to compare LookupItem with " + o
.getClass() + "!!!");
228 return getLookupString().compareTo(((LookupItem
)o
).getLookupString());
231 public LookupItem
<T
> setInsertHandler(@NotNull final InsertHandler
<?
extends LookupElement
> handler
) {
232 myInsertHandler
= handler
;
237 protected LookupElementRenderer
<?
extends LookupItem
> getRenderer() {
238 for (final ElementLookupRenderer renderer
: Extensions
.getExtensions(ElementLookupRenderer
.EP_NAME
)) {
239 if (renderer
.handlesItem(getObject())) return new LookupElementRenderer
<LookupItem
>() {
240 public void renderElement(final LookupItem element
, final LookupElementPresentation presentation
) {
241 renderer
.renderElement(element
, element
.getObject(), (LookupElementPresentationEx
)presentation
);
245 return DefaultLookupItemRenderer
.INSTANCE
;
248 public LookupItem
<T
> setBold() {
249 setAttribute(HIGHLIGHTED_ATTR
, "");
253 public LookupItem
<T
> setDeprecated(boolean deprecated
) {
254 setAttribute(DEPRECATED_ATTR
, deprecated ?
"" : null);
258 public LookupItem
<T
> setAutoCompletionPolicy(final AutoCompletionPolicy policy
) {
259 myAutoCompletionPolicy
= policy
;
263 public AutoCompletionPolicy
getAutoCompletionPolicy() {
264 return myAutoCompletionPolicy
;
268 public LookupItem
<T
> setIcon(Icon icon
) {
269 setAttribute(ICON_ATTR
, icon
);
274 public LookupItem
<T
> setPriority(double priority
) {
275 myPriority
= priority
;
280 public LookupItem
<T
> setGrouping(final int grouping
) {
281 myGrouping
= grouping
;
285 public final double getPriority() {
290 public final int getGrouping() {
295 public LookupItem
<T
> setPresentableText(@NotNull final String displayText
) {
296 myPresentable
= displayText
;
301 public String
getPresentableText() {
302 return myPresentable
;
306 public LookupItem
<T
> setTypeText(final String text
) {
307 setAttribute(TYPE_TEXT_ATTR
, text
);
313 public MutableLookupElement
<T
> setTailText(final String text
, final boolean grayed
) {
314 setAttribute(TAIL_TEXT_ATTR
, text
);
315 setAttribute(TAIL_TEXT_SMALL_ATTR
, Boolean
.TRUE
);
320 public LookupItem
<T
> setCaseSensitive(final boolean caseSensitive
) {
321 setAttribute(CASE_INSENSITIVE
, !caseSensitive
);
325 public LookupItem
<T
> addLookupStrings(@NonNls final String
... additionalLookupStrings
) {
326 myAllLookupStrings
.addAll(Arrays
.asList(additionalLookupStrings
));
330 public Set
<String
> getAllLookupStrings() {
331 return myAllLookupStrings
;
334 public void copyAttributes(final LookupItem item
) {
335 if (myAttributes
== null) {
336 if (item
.myAttributes
== null) return;
337 myAttributes
= new HashMap
<Object
, Object
>(5);
339 myAttributes
.putAll(item
.myAttributes
);