mirror of
https://github.com/SuspiciousActivity/ByteEdit.git
synced 2026-08-13 17:56:17 +00:00
383 lines
11 KiB
Java
383 lines
11 KiB
Java
/*
|
|
* 01/03/2009
|
|
* LanguageAwareCompletionProvider.java - A completion provider that is aware
|
|
* of the language it is working with.
|
|
* This library is distributed under a modified BSD license. See the included
|
|
* AutoComplete.License.txt file for details.
|
|
*/
|
|
package org.fife.ui.autocomplete;
|
|
|
|
import java.awt.Point;
|
|
import java.awt.event.MouseEvent;
|
|
import java.util.Collections;
|
|
import java.util.List;
|
|
|
|
import javax.swing.text.JTextComponent;
|
|
|
|
import org.fife.ui.rsyntaxtextarea.RSyntaxDocument;
|
|
import org.fife.ui.rsyntaxtextarea.RSyntaxTextArea;
|
|
import org.fife.ui.rsyntaxtextarea.RSyntaxUtilities;
|
|
import org.fife.ui.rsyntaxtextarea.Token;
|
|
import org.fife.ui.rtextarea.RTextArea;
|
|
import org.fife.ui.rtextarea.ToolTipSupplier;
|
|
|
|
/**
|
|
* A completion provider for the C programming language (and other languages
|
|
* with similar syntax). This provider simply delegates to another provider,
|
|
* depending on whether the caret is in:
|
|
*
|
|
* <ul>
|
|
* <li>Code (plain text)</li>
|
|
* <li>A string</li>
|
|
* <li>A comment</li>
|
|
* <li>A documentation comment</li>
|
|
* </ul>
|
|
*
|
|
* This allows for different completion choices in comments than in code, for
|
|
* example.
|
|
* <p>
|
|
*
|
|
* This provider also implements the
|
|
* <tt>org.fife.ui.rtextarea.ToolTipSupplier</tt> interface, which allows it to
|
|
* display tooltips for completion choices. Thus the standard
|
|
* {@link VariableCompletion} and {@link FunctionCompletion} completions should
|
|
* be able to display tooltips with the variable declaration or function
|
|
* definition (provided the <tt>RSyntaxTextArea</tt> was registered with the
|
|
* <tt>javax.swing.ToolTipManager</tt>).
|
|
*
|
|
* @author Robert Futrell
|
|
* @version 1.0
|
|
*/
|
|
public class LanguageAwareCompletionProvider extends CompletionProviderBase implements ToolTipSupplier {
|
|
|
|
/**
|
|
* The provider to use when no provider is assigned to a particular token type.
|
|
*/
|
|
private CompletionProvider defaultProvider;
|
|
/**
|
|
* The provider to use when completing in a string.
|
|
*/
|
|
private CompletionProvider stringCompletionProvider;
|
|
/**
|
|
* The provider to use when completing in a comment.
|
|
*/
|
|
private CompletionProvider commentCompletionProvider;
|
|
/**
|
|
* The provider to use while in documentation comments.
|
|
*/
|
|
private CompletionProvider docCommentCompletionProvider;
|
|
|
|
/**
|
|
* Constructor subclasses can use when they don't have their default provider
|
|
* created at construction time. They should call
|
|
* {@link #setDefaultCompletionProvider(CompletionProvider)} in this
|
|
* constructor.
|
|
*/
|
|
protected LanguageAwareCompletionProvider() {
|
|
}
|
|
|
|
/**
|
|
* Constructor.
|
|
*
|
|
* @param defaultProvider The provider to use when no provider is assigned to a
|
|
* particular token type. This cannot be
|
|
* <code>null</code>.
|
|
*/
|
|
public LanguageAwareCompletionProvider(CompletionProvider defaultProvider) {
|
|
setDefaultCompletionProvider(defaultProvider);
|
|
}
|
|
|
|
/**
|
|
* Calling this method will result in an {@link UnsupportedOperationException}
|
|
* being thrown. To set the parameter completion parameters, do so on the
|
|
* provider returned by {@link #getDefaultCompletionProvider()}.
|
|
*
|
|
* @throws UnsupportedOperationException Always.
|
|
* @see #setParameterizedCompletionParams(char, String, char)
|
|
*/
|
|
@Override
|
|
public void clearParameterizedCompletionParams() {
|
|
throw new UnsupportedOperationException();
|
|
}
|
|
|
|
/**
|
|
* {@inheritDoc}
|
|
*/
|
|
@Override
|
|
public String getAlreadyEnteredText(JTextComponent comp) {
|
|
if (!(comp instanceof RSyntaxTextArea)) {
|
|
return EMPTY_STRING;
|
|
}
|
|
CompletionProvider provider = getProviderFor(comp);
|
|
return provider != null ? provider.getAlreadyEnteredText(comp) : null;
|
|
}
|
|
|
|
/**
|
|
* Returns the completion provider to use for comments.
|
|
*
|
|
* @return The completion provider to use.
|
|
* @see #setCommentCompletionProvider(CompletionProvider)
|
|
*/
|
|
public CompletionProvider getCommentCompletionProvider() {
|
|
return commentCompletionProvider;
|
|
}
|
|
|
|
/**
|
|
* {@inheritDoc}
|
|
*/
|
|
@Override
|
|
public List<Completion> getCompletionsAt(JTextComponent tc, Point p) {
|
|
return defaultProvider == null ? null : defaultProvider.getCompletionsAt(tc, p);
|
|
}
|
|
|
|
/**
|
|
* Does the dirty work of creating a list of completions.
|
|
*
|
|
* @param comp The text component to look in.
|
|
* @return The list of possible completions, or an empty list if there are none.
|
|
*/
|
|
@Override
|
|
protected List<Completion> getCompletionsImpl(JTextComponent comp) {
|
|
if (comp instanceof RSyntaxTextArea) {
|
|
CompletionProvider provider = getProviderFor(comp);
|
|
if (provider != null) {
|
|
return provider.getCompletions(comp);
|
|
}
|
|
}
|
|
return Collections.emptyList();
|
|
}
|
|
|
|
/**
|
|
* Returns the completion provider used when one isn't defined for a particular
|
|
* token type.
|
|
*
|
|
* @return The completion provider to use.
|
|
* @see #setDefaultCompletionProvider(CompletionProvider)
|
|
*/
|
|
public CompletionProvider getDefaultCompletionProvider() {
|
|
return defaultProvider;
|
|
}
|
|
|
|
/**
|
|
* Returns the completion provider to use for documentation comments.
|
|
*
|
|
* @return The completion provider to use.
|
|
* @see #setDocCommentCompletionProvider(CompletionProvider)
|
|
*/
|
|
public CompletionProvider getDocCommentCompletionProvider() {
|
|
return docCommentCompletionProvider;
|
|
}
|
|
|
|
/**
|
|
* {@inheritDoc}
|
|
*/
|
|
@Override
|
|
public List<ParameterizedCompletion> getParameterizedCompletions(JTextComponent tc) {
|
|
// Parameterized completions can only come from the "code" completion
|
|
// provider. We do not do function/method completions while editing
|
|
// strings or comments.
|
|
CompletionProvider provider = getProviderFor(tc);
|
|
return provider == defaultProvider ? provider.getParameterizedCompletions(tc) : null;
|
|
}
|
|
|
|
/**
|
|
* {@inheritDoc}
|
|
*/
|
|
@Override
|
|
public char getParameterListEnd() {
|
|
return defaultProvider.getParameterListEnd();
|
|
}
|
|
|
|
/**
|
|
* {@inheritDoc}
|
|
*/
|
|
@Override
|
|
public String getParameterListSeparator() {
|
|
return defaultProvider.getParameterListSeparator();
|
|
}
|
|
|
|
/**
|
|
* {@inheritDoc}
|
|
*/
|
|
@Override
|
|
public char getParameterListStart() {
|
|
return defaultProvider.getParameterListStart();
|
|
}
|
|
|
|
/**
|
|
* Returns the completion provider to use at the current caret position in a
|
|
* text component.
|
|
*
|
|
* @param comp The text component to check.
|
|
* @return The completion provider to use.
|
|
*/
|
|
private CompletionProvider getProviderFor(JTextComponent comp) {
|
|
RSyntaxTextArea rsta = (RSyntaxTextArea) comp;
|
|
RSyntaxDocument doc = (RSyntaxDocument) rsta.getDocument();
|
|
int line = rsta.getCaretLineNumber();
|
|
Token t = doc.getTokenListForLine(line);
|
|
if (t == null) {
|
|
return getDefaultCompletionProvider();
|
|
}
|
|
int dot = rsta.getCaretPosition();
|
|
Token curToken = RSyntaxUtilities.getTokenAtOffset(t, dot);
|
|
if (curToken == null) { // At end of the line
|
|
int type = doc.getLastTokenTypeOnLine(line);
|
|
if (type == Token.NULL) {
|
|
Token temp = t.getLastPaintableToken();
|
|
if (temp == null) {
|
|
return getDefaultCompletionProvider();
|
|
}
|
|
type = temp.getType();
|
|
}
|
|
// TokenMakers can use types < 0 for "internal types." This
|
|
// gives them a chance to map their internal types back to "real"
|
|
// types to get completion providers.
|
|
else if (type < 0) {
|
|
type = doc.getClosestStandardTokenTypeForInternalType(type);
|
|
}
|
|
switch (type) {
|
|
case Token.ERROR_STRING_DOUBLE:
|
|
return getStringCompletionProvider();
|
|
case Token.COMMENT_EOL:
|
|
case Token.COMMENT_MULTILINE:
|
|
return getCommentCompletionProvider();
|
|
case Token.COMMENT_DOCUMENTATION:
|
|
return getDocCommentCompletionProvider();
|
|
default:
|
|
return getDefaultCompletionProvider();
|
|
}
|
|
}
|
|
// FIXME: This isn't always a safe assumption.
|
|
if (dot == curToken.getOffset()) { // At the very beginning of a new
|
|
// token
|
|
// Need to check previous token for its type before deciding.
|
|
// Previous token may also be on previous line!
|
|
return getDefaultCompletionProvider();
|
|
}
|
|
switch (curToken.getType()) {
|
|
case Token.LITERAL_STRING_DOUBLE_QUOTE:
|
|
case Token.ERROR_STRING_DOUBLE:
|
|
return getStringCompletionProvider();
|
|
case Token.COMMENT_EOL:
|
|
case Token.COMMENT_MULTILINE:
|
|
return getCommentCompletionProvider();
|
|
case Token.COMMENT_DOCUMENTATION:
|
|
return getDocCommentCompletionProvider();
|
|
case Token.NULL:
|
|
case Token.WHITESPACE:
|
|
case Token.IDENTIFIER:
|
|
case Token.VARIABLE:
|
|
case Token.PREPROCESSOR:
|
|
case Token.DATA_TYPE:
|
|
case Token.FUNCTION:
|
|
case Token.OPERATOR:
|
|
return getDefaultCompletionProvider();
|
|
}
|
|
return null; // In a token type we can't auto-complete from.
|
|
}
|
|
|
|
/**
|
|
* Returns the completion provider to use for strings.
|
|
*
|
|
* @return The completion provider to use.
|
|
* @see #setStringCompletionProvider(CompletionProvider)
|
|
*/
|
|
public CompletionProvider getStringCompletionProvider() {
|
|
return stringCompletionProvider;
|
|
}
|
|
|
|
/**
|
|
* {@inheritDoc}
|
|
*/
|
|
@Override
|
|
public boolean isAutoActivateOkay(JTextComponent tc) {
|
|
CompletionProvider provider = getProviderFor(tc);
|
|
return provider != null ? provider.isAutoActivateOkay(tc) : false;
|
|
}
|
|
|
|
/**
|
|
* Sets the comment completion provider.
|
|
*
|
|
* @param provider The provider to use in comments.
|
|
* @see #getCommentCompletionProvider()
|
|
*/
|
|
public void setCommentCompletionProvider(CompletionProvider provider) {
|
|
this.commentCompletionProvider = provider;
|
|
}
|
|
|
|
/**
|
|
* Sets the default completion provider.
|
|
*
|
|
* @param provider The provider to use when no provider is assigned to a
|
|
* particular token type. This cannot be <code>null</code>.
|
|
* @see #getDefaultCompletionProvider()
|
|
*/
|
|
public void setDefaultCompletionProvider(CompletionProvider provider) {
|
|
if (provider == null) {
|
|
throw new IllegalArgumentException("provider cannot be null");
|
|
}
|
|
this.defaultProvider = provider;
|
|
}
|
|
|
|
/**
|
|
* Sets the documentation comment completion provider.
|
|
*
|
|
* @param provider The provider to use in comments.
|
|
* @see #getDocCommentCompletionProvider()
|
|
*/
|
|
public void setDocCommentCompletionProvider(CompletionProvider provider) {
|
|
this.docCommentCompletionProvider = provider;
|
|
}
|
|
|
|
/**
|
|
* Calling this method will result in an {@link UnsupportedOperationException}
|
|
* being thrown. To set the parameter completion parameters, do so on the
|
|
* provider returned by {@link #getDefaultCompletionProvider()}.
|
|
*
|
|
* @throws UnsupportedOperationException Always.
|
|
* @see #clearParameterizedCompletionParams()
|
|
*/
|
|
@Override
|
|
public void setParameterizedCompletionParams(char listStart, String separator, char listEnd) {
|
|
throw new UnsupportedOperationException();
|
|
}
|
|
|
|
/**
|
|
* Sets the completion provider to use while in a string.
|
|
*
|
|
* @param provider The provider to use.
|
|
* @see #getStringCompletionProvider()
|
|
*/
|
|
public void setStringCompletionProvider(CompletionProvider provider) {
|
|
stringCompletionProvider = provider;
|
|
}
|
|
|
|
/**
|
|
* Returns the tool tip to display for a mouse event.
|
|
* <p>
|
|
*
|
|
* For this method to be called, the <tt>RSyntaxTextArea</tt> must be registered
|
|
* with the <tt>javax.swing.ToolTipManager</tt> like so:
|
|
*
|
|
* <pre>
|
|
* ToolTipManager.sharedInstance().registerComponent(textArea);
|
|
* </pre>
|
|
*
|
|
* @param textArea The text area.
|
|
* @param e The mouse event.
|
|
* @return The tool tip text, or <code>null</code> if none.
|
|
*/
|
|
@Override
|
|
public String getToolTipText(RTextArea textArea, MouseEvent e) {
|
|
String tip = null;
|
|
List<Completion> completions = getCompletionsAt(textArea, e.getPoint());
|
|
if (completions != null && completions.size() > 0) {
|
|
// Only ever 1 match for us in C...
|
|
Completion c = completions.get(0);
|
|
tip = c.getToolTipText();
|
|
}
|
|
return tip;
|
|
}
|
|
}
|