// the current cursor position -- so tokenize ahead.
codeModel.tokenizeUpToRow(row + 100);
// Make a token cursor and place it at the first token previous
// to the cursor.
TokenCursor tokenCursor = codeModel.getTokenCursor();
if (!tokenCursor.moveToPosition(input_.getCursorPosition()))
return context;
TokenCursor startCursor = tokenCursor.cloneCursor();
boolean startedOnEquals = tokenCursor.currentValue() == "=";
if (startCursor.currentType() == "identifier")
if (startCursor.moveToPreviousToken())
if (startCursor.currentValue() == "=")
{
startedOnEquals = true;
startCursor.moveToNextToken();
}
// Find an opening '(' or '[' -- this provides the function or object
// for completion.
int initialNumCommas = 0;
if (tokenCursor.currentValue() != "(" && tokenCursor.currentValue() != "[")
{
int commaCount = tokenCursor.findOpeningBracketCountCommas(new String[]{ "[", "(" }, true);
if (commaCount == -1)
{
commaCount = tokenCursor.findOpeningBracketCountCommas("[", false);
if (commaCount == -1)
return context;
else
initialNumCommas = commaCount;
}
else
{
initialNumCommas = commaCount;
}
}
// Figure out whether we're looking at '(', '[', or '[[',
// and place the token cursor on the first token preceding.
TokenCursor endOfDecl = tokenCursor.cloneCursor();
int initialDataType = AutocompletionContext.TYPE_UNKNOWN;
if (tokenCursor.currentValue() == "(")
{
// Don't produce function argument completions
// if the cursor is on, or after, an '='
if (!startedOnEquals)
initialDataType = AutocompletionContext.TYPE_FUNCTION;
else
initialDataType = AutocompletionContext.TYPE_UNKNOWN;
if (!tokenCursor.moveToPreviousToken())
return context;
}
else if (tokenCursor.currentValue() == "[")
{
if (!tokenCursor.moveToPreviousToken())
return context;
if (tokenCursor.currentValue() == "[")
{
if (!endOfDecl.moveToPreviousToken())
return context;
initialDataType = AutocompletionContext.TYPE_DOUBLE_BRACKET;
if (!tokenCursor.moveToPreviousToken())
return context;
}
else
{
initialDataType = AutocompletionContext.TYPE_SINGLE_BRACKET;
}
}
// Get the string marking the function or data
if (!tokenCursor.findStartOfEvaluationContext())
return context;
// Try to get the function call string -- either there's
// an associated closing paren we can use, or we should just go up
// to the current cursor position
// default case: use start cursor
Position endPos = startCursor.currentPosition();
endPos.setColumn(endPos.getColumn() + startCursor.currentValue().length());
// try to look forward for closing paren
if (endOfDecl.currentValue() == "(")
{
TokenCursor closingParenCursor = endOfDecl.cloneCursor();
if (closingParenCursor.fwdToMatchingToken())
{
endPos = closingParenCursor.currentPosition();
endPos.setColumn(endPos.getColumn() + 1);
}
}
// We can now set the function call string
context.setFunctionCallString(
editor.getTextForRange(Range.fromPoints(
tokenCursor.currentPosition(), endPos)));
String initialData =
docDisplay_.getTextForRange(Range.fromPoints(
tokenCursor.currentPosition(),
endOfDecl.currentPosition()));
// And the first context
context.add(initialData, initialDataType, initialNumCommas);
// Get the rest of the single-bracket contexts for completions as well
String assocData;
int dataType;
int numCommas;
while (true)
{
int commaCount = tokenCursor.findOpeningBracketCountCommas("[", false);
if (commaCount == -1)
break;
numCommas = commaCount;
TokenCursor declEnd = tokenCursor.cloneCursor();
if (!tokenCursor.moveToPreviousToken())
return context;
if (tokenCursor.currentValue() == "[")
{
if (!declEnd.moveToPreviousToken())
return context;
dataType = AutocompletionContext.TYPE_DOUBLE_BRACKET;
if (!tokenCursor.moveToPreviousToken())
return context;
}
else
{
dataType = AutocompletionContext.TYPE_SINGLE_BRACKET;
}
assocData =
docDisplay_.getTextForRange(Range.fromPoints(
tokenCursor.currentPosition(),
declEnd.currentPosition()));
context.add(assocData, dataType, numCommas);
}
return context;