/*
 * Copyright (c) 2000-2005 by JetBrains s.r.o. All Rights Reserved.
 * Use is subject to license terms.
 */
package com.intellij.codeInsight.completion;

import com.intellij.codeInsight.TailType;
import com.intellij.codeInsight.lookup.LookupItem;
import com.intellij.lang.ASTNode;
import com.intellij.lang.LanguageWordCompletion;
import com.intellij.psi.PlainTextTokenTypes;
import com.intellij.psi.PsiElement;
import com.intellij.psi.PsiFile;
import com.intellij.psi.PsiReference;
import com.intellij.psi.filters.getters.AllWordsGetter;
import com.intellij.psi.tree.IElementType;
import com.intellij.openapi.application.ApplicationManager;
import com.intellij.openapi.util.Computable;

import java.util.Set;
import java.util.HashSet;

/**
 * @author peter
 */
public class WordCompletionContributor extends CompletionContributor{

  @Override
  public boolean fillCompletionVariants(final CompletionParameters parameters, final CompletionResultSet result) {
    if (parameters.getCompletionType() != CompletionType.BASIC) return true;

    final PsiFile file = parameters.getOriginalFile();
    final int startOffset = parameters.getOffset();
    final PsiElement element = ApplicationManager.getApplication().runReadAction(new Computable<PsiElement>() {
      public PsiElement compute() {
        return file.findElementAt(startOffset - 1);
      }
    });
    final PsiElement insertedElement = parameters.getPosition();

    Set<CompletionVariant> toAdd = new HashSet<CompletionVariant>();
    final CompletionData data = CompletionUtil.getCompletionDataByElement(file);
    data.addKeywordVariants(toAdd, insertedElement, file);
    for (CompletionVariant completionVariant : toAdd) {
      if (completionVariant.hasKeywordCompletions()) {
        return true;
      }
    }

    final PsiReference reference = ApplicationManager.getApplication().runReadAction(new Computable<PsiReference>() {
      public PsiReference compute() {
        return file.findReferenceAt(startOffset);
      }
    });
    if (reference == null) {
      ASTNode textContainer = element != null ? element.getNode() : null;
      while (textContainer != null) {
        final IElementType elementType = textContainer.getElementType();
        if (LanguageWordCompletion.INSTANCE.isEnabledIn(elementType) || elementType == PlainTextTokenTypes.PLAIN_TEXT) {
          final String prefix = CompletionUtil.findJavaIdentifierPrefix(insertedElement, startOffset);
          final CompletionResultSet resultSet = result.withPrefixMatcher(prefix);
          for (final String word : AllWordsGetter.getAllWords(insertedElement, startOffset)) {
            resultSet.addElement(new LookupItem<String>(word, word).setTailType(TailType.SPACE));
          }
        }
        textContainer = textContainer.getTreeParent();
      }
    }

    return true;
  }
}

@@ -1426,20 +1426,22 @@
 );%0A%0A    
-Set%3C
+final 
 Completi
@@ -1446,37 +1446,38 @@
 tion
-Variant%3E toAdd = new HashS
+Data data = CompletionUtil.g
 et
-%3C
 Comp
@@ -1486,70 +1486,134 @@
 tion
-Variant%3E();%0A    final CompletionData data = CompletionUtil.g
+DataByElement(file);%0A    if (!(data instanceof SyntaxTableCompletionData)) %7B%0A      Set%3CCompletionVariant%3E toAdd = new HashS
 et
+%3C
 Comp
@@ -1618,37 +1618,30 @@
 mpletion
-DataByElement(file
+Variant%3E(
 );%0A
+  
     data
@@ -1691,24 +1691,26 @@
  file);%0A    
+  
 for (Complet
@@ -1751,24 +1751,26 @@
 dd) %7B%0A      
+  
 if (completi
@@ -1810,24 +1810,26 @@
 ) %7B%0A        
+ 
+ 
 return true;
@@ -1829,16 +1829,26 @@
 n true;%0A
+        %7D%0A
       %7D%0A

make word completion work in custom file type files