package tern.swing.rsyntaxtextarea.samples;
import java.awt.Point;
import java.util.ArrayList;
import java.util.List;
import javax.swing.JOptionPane;
import javax.swing.text.BadLocationException;
import javax.swing.text.JTextComponent;
import org.fife.ui.autocomplete.AbstractCompletionProvider;
import org.fife.ui.autocomplete.BasicCompletion;
import org.fife.ui.autocomplete.Completion;
import org.fife.ui.autocomplete.CompletionCellRenderer;
import org.fife.ui.autocomplete.CompletionProvider;
import org.fife.ui.autocomplete.FunctionCompletion;
import org.fife.ui.autocomplete.ParameterizedCompletion;
import org.fife.ui.autocomplete.VariableCompletion;
import tern.TernException;
import tern.server.ITernServer;
import tern.server.protocol.IJSONObjectHelper;
import tern.server.protocol.TernDoc;
import tern.server.protocol.completions.ITernCompletionCollector;
import tern.server.protocol.completions.TernCompletionItem;
import tern.server.protocol.completions.TernCompletionProposalRec;
import tern.server.protocol.completions.TernCompletionsQuery;
public class JavaScriptCompletionProvider extends AbstractCompletionProvider {
private String prefix;
private ITernServer server;
private List<Completion> _completions;
public JavaScriptCompletionProvider(ITernServer server) {
this.server = server;
setAutoActivationRules(true, ".");
setParameterizedCompletionParams('(', ",", ')');
setListCellRenderer(new CompletionCellRenderer());
}
@Override
public String getAlreadyEnteredText(JTextComponent comp) {
computeCompletions(comp);
return prefix == null ? "" : prefix;
}
@Override
public List<Completion> getCompletions(JTextComponent comp) {
return getCompletionsAtOffset(comp, comp.getCaretPosition());
}
@Override
public List<Completion> getCompletionsAt(JTextComponent comp, Point p) {
return null;
}
private List<Completion> getCompletionsAtOffset(JTextComponent comp, int offset) {
return _completions;
}
@Override
public List<ParameterizedCompletion> getParameterizedCompletions(JTextComponent tc) {
// TODO: is this better?
return new ArrayList<>();
}
private void computeCompletions(JTextComponent comp) {
_completions = new ArrayList<>();
prefix = null;
int offset = comp.getCaretPosition();
if (offset < 0 || offset > comp.getDocument().getLength()) {
return;
}
queryCompletions(comp, new ITernCompletionCollector() {
@Override
public void addProposal(TernCompletionProposalRec proposal, Object completion,
IJSONObjectHelper jsonManager) {
TernCompletionItem serverCompl = new TernCompletionItem(proposal);
JavaScriptCompletionProvider provider = JavaScriptCompletionProvider.this;
if (prefix == null) {
try {
prefix = comp.getDocument().getText(proposal.start, proposal.end - proposal.start);
} catch (BadLocationException e) {
e.printStackTrace();
JOptionPane.showMessageDialog(null, e.getMessage(), "Error", JOptionPane.ERROR_MESSAGE);
}
}
BasicCompletion compl;
if (serverCompl.isFunction()) {
FunctionCompletion func = new JavaScriptFunctionCompletion(provider, serverCompl);
compl = func;
} else {
String type = serverCompl.getJsType();
for (char c : type.toCharArray()) {
if (!Character.isJavaIdentifierPart(c)) {
type = "Object";
break;
}
}
VariableCompletion var = new VariableCompletion(provider, serverCompl.getName(), type);
compl = var;
}
compl.setRelevance(0);
compl.setShortDescription(serverCompl.getDoc());
compl.setSummary(serverCompl.getDoc());
_completions.add(compl);
}
});
}
private void queryCompletions(JTextComponent comp, ITernCompletionCollector collector) {
int offset = comp.getCaretPosition();
String content = comp.getText();
String filename = "source.js";
TernCompletionsQuery query = new TernCompletionsQuery(filename, Integer.valueOf(offset));
query.setDocs(true);
query.setTypes(true);
query.setGuess(false);
query.setCaseInsensitive(false);
query.setOrigins(false);
query.setUrls(false);
// query.set("sort", false);
// query.set("includeKeywords", true);
TernDoc doc = new TernDoc(query);
doc.addFile(filename, content, null, null);
try {
server.request(doc, collector);
} catch (TernException e) {
e.printStackTrace();
JOptionPane.showMessageDialog(null, e.getMessage(), "Tern", JOptionPane.INFORMATION_MESSAGE);
}
}
static class JavaScriptFunctionCompletion extends FunctionCompletion {
private TernCompletionItem _serverCompl;
public JavaScriptFunctionCompletion(CompletionProvider provider, TernCompletionItem serverCompl) {
super(provider, serverCompl.getName(), serverCompl.getJsType());
_serverCompl = serverCompl;
List<Parameter> list = new ArrayList<>();
List<tern.server.protocol.completions.Parameter> params = serverCompl.getParameters();
if (params != null) {
for (tern.server.protocol.completions.Parameter param : params) {
Parameter complParam = new Parameter(param.getType(), param.getName());
list.add(complParam);
}
}
setParams(list);
}
@Override
public String getShortDescription() {
return _serverCompl.getDoc();
}
@Override
public String getDefinitionString() {
return _serverCompl.getText();
}
@Override
public String getReplacementText() {
return _serverCompl.getName();
}
}
}