mirror of
https://github.com/eclipse-cdt/cdt
synced 2025-04-29 19:45:01 +02:00
Improve content assist auto-activation check, related to bugs 126871 and 193728
This commit is contained in:
parent
39053ae062
commit
d12b37a95c
6 changed files with 83 additions and 81 deletions
|
@ -175,7 +175,7 @@ public class ContentAssistTests extends BaseUITestCase {
|
|||
|
||||
String contentType = editor.getViewer().getDocument().getContentType(offset);
|
||||
ContentAssistant assistant = new ContentAssistant();
|
||||
CContentAssistProcessor processor = new CContentAssistProcessor(editor, editor.getViewer(), assistant, contentType);
|
||||
CContentAssistProcessor processor = new CContentAssistProcessor(editor, assistant, contentType);
|
||||
return processor.computeCompletionProposals(editor.getViewer(), offset);
|
||||
}
|
||||
|
||||
|
|
|
@ -113,7 +113,7 @@ public abstract class AbstractContentAssistTest extends BaseUITestCase {
|
|||
ISourceViewer sourceViewer= EditorTestHelper.getSourceViewer((AbstractTextEditor)fEditor);
|
||||
String contentType = sourceViewer.getDocument().getContentType(offset);
|
||||
ContentAssistant assistant = new ContentAssistant();
|
||||
CContentAssistProcessor processor = new CContentAssistProcessor(fEditor, sourceViewer, assistant, contentType);
|
||||
CContentAssistProcessor processor = new CContentAssistProcessor(fEditor, assistant, contentType);
|
||||
long startTime= System.currentTimeMillis();
|
||||
Object[] results = isCompletion
|
||||
? (Object[]) processor.computeCompletionProposals(sourceViewer, offset)
|
||||
|
|
|
@ -365,25 +365,25 @@ public class CSourceViewerConfiguration extends TextSourceViewerConfiguration {
|
|||
|
||||
assistant.setRestoreCompletionProposalSize(getSettings("completion_proposal_size")); //$NON-NLS-1$
|
||||
|
||||
IContentAssistProcessor processor = new CContentAssistProcessor(getEditor(), sourceViewer, assistant, IDocument.DEFAULT_CONTENT_TYPE);
|
||||
IContentAssistProcessor processor = new CContentAssistProcessor(getEditor(), assistant, IDocument.DEFAULT_CONTENT_TYPE);
|
||||
assistant.setContentAssistProcessor(processor, IDocument.DEFAULT_CONTENT_TYPE);
|
||||
|
||||
processor = new CContentAssistProcessor(getEditor(), sourceViewer, assistant, ICPartitions.C_MULTI_LINE_COMMENT);
|
||||
processor = new CContentAssistProcessor(getEditor(), assistant, ICPartitions.C_MULTI_LINE_COMMENT);
|
||||
assistant.setContentAssistProcessor(processor, ICPartitions.C_MULTI_LINE_COMMENT);
|
||||
|
||||
processor = new CContentAssistProcessor(getEditor(), sourceViewer, assistant, ICPartitions.C_SINGLE_LINE_COMMENT);
|
||||
processor = new CContentAssistProcessor(getEditor(), assistant, ICPartitions.C_SINGLE_LINE_COMMENT);
|
||||
assistant.setContentAssistProcessor(processor, ICPartitions.C_SINGLE_LINE_COMMENT);
|
||||
|
||||
processor = new CContentAssistProcessor(getEditor(), sourceViewer, assistant, ICPartitions.C_MULTI_LINE_DOC_COMMENT);
|
||||
processor = new CContentAssistProcessor(getEditor(), assistant, ICPartitions.C_MULTI_LINE_DOC_COMMENT);
|
||||
assistant.setContentAssistProcessor(processor, ICPartitions.C_MULTI_LINE_DOC_COMMENT);
|
||||
|
||||
processor = new CContentAssistProcessor(getEditor(), sourceViewer, assistant, ICPartitions.C_SINGLE_LINE_DOC_COMMENT);
|
||||
processor = new CContentAssistProcessor(getEditor(), assistant, ICPartitions.C_SINGLE_LINE_DOC_COMMENT);
|
||||
assistant.setContentAssistProcessor(processor, ICPartitions.C_SINGLE_LINE_DOC_COMMENT);
|
||||
|
||||
processor = new CContentAssistProcessor(getEditor(), sourceViewer, assistant, ICPartitions.C_STRING);
|
||||
processor = new CContentAssistProcessor(getEditor(), assistant, ICPartitions.C_STRING);
|
||||
assistant.setContentAssistProcessor(processor, ICPartitions.C_STRING);
|
||||
|
||||
processor = new CContentAssistProcessor(getEditor(), sourceViewer, assistant, ICPartitions.C_PREPROCESSOR);
|
||||
processor = new CContentAssistProcessor(getEditor(), assistant, ICPartitions.C_PREPROCESSOR);
|
||||
assistant.setContentAssistProcessor(processor, ICPartitions.C_PREPROCESSOR);
|
||||
|
||||
ContentAssistPreference.configure(assistant, fPreferenceStore);
|
||||
|
|
|
@ -43,6 +43,7 @@ public class CContentAssistInvocationContext extends ContentAssistInvocationCont
|
|||
|
||||
private final IEditorPart fEditor;
|
||||
private final boolean fIsCompletion;
|
||||
private final boolean fIsAutoActivated;
|
||||
|
||||
private ITranslationUnit fTU= null;
|
||||
private boolean fTUComputed= false;
|
||||
|
@ -59,12 +60,14 @@ public class CContentAssistInvocationContext extends ContentAssistInvocationCont
|
|||
* @param viewer the viewer used by the editor
|
||||
* @param offset the invocation offset
|
||||
* @param editor the editor that content assist is invoked in
|
||||
* @param isAutoActivated inidicates whether content assist was auto-activated
|
||||
*/
|
||||
public CContentAssistInvocationContext(ITextViewer viewer, int offset, IEditorPart editor, boolean isCompletion) {
|
||||
public CContentAssistInvocationContext(ITextViewer viewer, int offset, IEditorPart editor, boolean isCompletion, boolean isAutoActivated) {
|
||||
super(viewer, offset);
|
||||
Assert.isNotNull(editor);
|
||||
fEditor= editor;
|
||||
fIsCompletion= isCompletion;
|
||||
fIsAutoActivated= isAutoActivated;
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -78,6 +81,7 @@ public class CContentAssistInvocationContext extends ContentAssistInvocationCont
|
|||
fTUComputed= true;
|
||||
fEditor= null;
|
||||
fIsCompletion= isCompletion;
|
||||
fIsAutoActivated= false;
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -109,7 +113,7 @@ public class CContentAssistInvocationContext extends ContentAssistInvocationCont
|
|||
if (fCNComputed) return fCN;
|
||||
|
||||
fCNComputed = true;
|
||||
|
||||
|
||||
int offset = getParseOffset();
|
||||
if (offset < 0) return null;
|
||||
|
||||
|
@ -255,6 +259,10 @@ public class CContentAssistInvocationContext extends ContentAssistInvocationCont
|
|||
return !fIsCompletion || (getParseOffset() != getInvocationOffset());
|
||||
}
|
||||
|
||||
public boolean isAutoActivated() {
|
||||
return fIsAutoActivated;
|
||||
}
|
||||
|
||||
public void dispose() {
|
||||
if (fIndex != null) {
|
||||
fIndex.releaseReadLock();
|
||||
|
|
|
@ -28,7 +28,6 @@ import org.eclipse.jface.text.contentassist.ContentAssistant;
|
|||
import org.eclipse.jface.text.contentassist.ICompletionProposal;
|
||||
import org.eclipse.jface.text.contentassist.IContextInformation;
|
||||
import org.eclipse.jface.text.contentassist.IContextInformationValidator;
|
||||
import org.eclipse.jface.text.source.ISourceViewer;
|
||||
import org.eclipse.swt.graphics.Image;
|
||||
import org.eclipse.swt.graphics.Point;
|
||||
import org.eclipse.ui.IEditorPart;
|
||||
|
@ -39,7 +38,9 @@ import org.eclipse.cdt.ui.text.contentassist.ContentAssistInvocationContext;
|
|||
import org.eclipse.cdt.ui.text.contentassist.IProposalFilter;
|
||||
|
||||
import org.eclipse.cdt.internal.ui.preferences.ProposalFilterPreferencesUtil;
|
||||
import org.eclipse.cdt.internal.ui.text.CHeuristicScanner;
|
||||
import org.eclipse.cdt.internal.ui.text.CParameterListValidator;
|
||||
import org.eclipse.cdt.internal.ui.text.Symbols;
|
||||
|
||||
/**
|
||||
* C/C++ content assist processor.
|
||||
|
@ -123,22 +124,12 @@ public class CContentAssistProcessor extends ContentAssistProcessor {
|
|||
}
|
||||
|
||||
|
||||
private static final int IDX_AFTERDASH = 0;
|
||||
private static final int IDX_AFTERCOLON = 1;
|
||||
private static final int IDX_AFTEROTHER = 2;
|
||||
private static final int IDX_ALL = 3;
|
||||
|
||||
|
||||
|
||||
private IContextInformationValidator fValidator;
|
||||
private final IEditorPart fEditor;
|
||||
private char[][] fCompletionAutoActivationCharacters;
|
||||
private ISourceViewer fViewer;
|
||||
|
||||
public CContentAssistProcessor(IEditorPart editor, ISourceViewer viewer, ContentAssistant assistant, String partition) {
|
||||
public CContentAssistProcessor(IEditorPart editor, ContentAssistant assistant, String partition) {
|
||||
super(assistant, partition);
|
||||
fEditor= editor;
|
||||
fViewer= viewer;
|
||||
}
|
||||
|
||||
/*
|
||||
|
@ -216,69 +207,41 @@ public class CContentAssistProcessor extends ContentAssistProcessor {
|
|||
* @see org.eclipse.cdt.internal.ui.text.contentassist.ContentAssistProcessor#createContext(org.eclipse.jface.text.ITextViewer, int)
|
||||
*/
|
||||
protected ContentAssistInvocationContext createContext(ITextViewer viewer, int offset, boolean isCompletion) {
|
||||
return new CContentAssistInvocationContext(viewer, offset, fEditor, isCompletion);
|
||||
}
|
||||
|
||||
public void setCompletionProposalAutoActivationCharacters(char[] activationSet) {
|
||||
if (activationSet == null) {
|
||||
fCompletionAutoActivationCharacters= null;
|
||||
}
|
||||
else {
|
||||
final int len= activationSet.length;
|
||||
StringBuffer afterDash= new StringBuffer(len);
|
||||
StringBuffer afterColon= new StringBuffer(len);
|
||||
StringBuffer afterOther= new StringBuffer(len);
|
||||
for (int i = 0; i < activationSet.length; i++) {
|
||||
final char c = activationSet[i];
|
||||
switch(c) {
|
||||
case ':':
|
||||
afterColon.append(c);
|
||||
break;
|
||||
case '>':
|
||||
afterDash.append(c);
|
||||
break;
|
||||
default:
|
||||
afterDash.append(c);
|
||||
afterColon.append(c);
|
||||
afterOther.append(c);
|
||||
break;
|
||||
}
|
||||
}
|
||||
fCompletionAutoActivationCharacters= new char[4][];
|
||||
fCompletionAutoActivationCharacters[IDX_AFTERDASH]= afterDash.toString().toCharArray();
|
||||
fCompletionAutoActivationCharacters[IDX_AFTERCOLON]= afterColon.toString().toCharArray();
|
||||
fCompletionAutoActivationCharacters[IDX_AFTEROTHER]= afterOther.toString().toCharArray();
|
||||
fCompletionAutoActivationCharacters[IDX_ALL]= activationSet;
|
||||
}
|
||||
return new CContentAssistInvocationContext(viewer, offset, fEditor, isCompletion, isAutoActivated());
|
||||
}
|
||||
|
||||
|
||||
public char[] getCompletionProposalAutoActivationCharacters() {
|
||||
if (fCompletionAutoActivationCharacters == null) {
|
||||
return null;
|
||||
/*
|
||||
* @see org.eclipse.cdt.internal.ui.text.contentassist.ContentAssistProcessor#verifyAutoActivation(org.eclipse.jface.text.ITextViewer, int)
|
||||
*/
|
||||
protected boolean verifyAutoActivation(ITextViewer viewer, int offset) {
|
||||
IDocument doc= viewer.getDocument();
|
||||
if (doc == null) {
|
||||
return false;
|
||||
}
|
||||
|
||||
if (fViewer != null) {
|
||||
char prevChar= 0;
|
||||
try {
|
||||
final IDocument doc= fViewer.getDocument();
|
||||
if (doc != null) {
|
||||
prevChar= doc.getChar(fViewer.getSelectedRange().x-1);
|
||||
if (offset <= 0) {
|
||||
return false;
|
||||
}
|
||||
try {
|
||||
char activationChar= doc.getChar(--offset);
|
||||
switch (activationChar) {
|
||||
case ':':
|
||||
return offset > 0 && doc.getChar(--offset) == ':';
|
||||
case '>':
|
||||
return offset > 0 && doc.getChar(--offset) == '-';
|
||||
case '.':
|
||||
// avoid completion of float literals
|
||||
CHeuristicScanner scanner= new CHeuristicScanner(doc);
|
||||
int token= scanner.previousToken(--offset, Math.max(0, offset - 200));
|
||||
// the scanner reports numbers as identifiers
|
||||
if (token == Symbols.TokenIDENT && !Character.isJavaIdentifierStart(doc.getChar(scanner.getPosition() + 1))) {
|
||||
// not a valid identifier
|
||||
return false;
|
||||
}
|
||||
}
|
||||
catch (BadLocationException e) {
|
||||
// beginning of document.
|
||||
}
|
||||
switch (prevChar) {
|
||||
case ':':
|
||||
return fCompletionAutoActivationCharacters[IDX_AFTERCOLON];
|
||||
case '-':
|
||||
return fCompletionAutoActivationCharacters[IDX_AFTERDASH];
|
||||
default:
|
||||
return fCompletionAutoActivationCharacters[IDX_AFTEROTHER];
|
||||
return true;
|
||||
}
|
||||
} catch (BadLocationException exc) {
|
||||
}
|
||||
return fCompletionAutoActivationCharacters[IDX_ALL];
|
||||
return false;
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -102,6 +102,8 @@ public class ContentAssistProcessor implements IContentAssistProcessor {
|
|||
}
|
||||
|
||||
};
|
||||
|
||||
private static final ICompletionProposal[] NO_PROPOSALS= {};
|
||||
|
||||
private final List fCategories;
|
||||
private final String fPartition;
|
||||
|
@ -115,7 +117,8 @@ public class ContentAssistProcessor implements IContentAssistProcessor {
|
|||
private String fIterationGesture= null;
|
||||
private int fNumberOfComputedResults= 0;
|
||||
private String fErrorMessage;
|
||||
|
||||
private boolean fIsAutoActivated;
|
||||
|
||||
public ContentAssistProcessor(ContentAssistant assistant, String partition) {
|
||||
Assert.isNotNull(partition);
|
||||
Assert.isNotNull(assistant);
|
||||
|
@ -131,6 +134,7 @@ public class ContentAssistProcessor implements IContentAssistProcessor {
|
|||
if (event.processor != ContentAssistProcessor.this)
|
||||
return;
|
||||
|
||||
fIsAutoActivated= event.isAutoActivated;
|
||||
fIterationGesture= getIterationGesture();
|
||||
KeySequence binding= getIterationBinding();
|
||||
|
||||
|
@ -203,6 +207,10 @@ public class ContentAssistProcessor implements IContentAssistProcessor {
|
|||
public final ICompletionProposal[] computeCompletionProposals(ITextViewer viewer, int offset) {
|
||||
long start= DEBUG ? System.currentTimeMillis() : 0;
|
||||
|
||||
if (isAutoActivated() && !verifyAutoActivation(viewer, offset)) {
|
||||
return NO_PROPOSALS;
|
||||
}
|
||||
|
||||
clearState();
|
||||
|
||||
IProgressMonitor monitor= createProgressMonitor();
|
||||
|
@ -238,6 +246,20 @@ public class ContentAssistProcessor implements IContentAssistProcessor {
|
|||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Verify that auto activation is allowed.
|
||||
* <p>
|
||||
* The default implementation always returns <code>true</code>.
|
||||
* </p>
|
||||
*
|
||||
* @param viewer the text viewer
|
||||
* @param offset the offset where content assist was invoked on
|
||||
* @return <code>true</code> if auto activation is allowed
|
||||
*/
|
||||
protected boolean verifyAutoActivation(ITextViewer viewer, int offset) {
|
||||
return true;
|
||||
}
|
||||
|
||||
private void clearState() {
|
||||
fErrorMessage=null;
|
||||
fNumberOfComputedResults= 0;
|
||||
|
@ -396,6 +418,15 @@ public class ContentAssistProcessor implements IContentAssistProcessor {
|
|||
return new ContentAssistInvocationContext(viewer, offset);
|
||||
}
|
||||
|
||||
/**
|
||||
* Test whether the current session was auto-activated.
|
||||
*
|
||||
* @return <code>true</code> if the current session was auto-activated.
|
||||
*/
|
||||
protected boolean isAutoActivated() {
|
||||
return fIsAutoActivated;
|
||||
}
|
||||
|
||||
private List getCategories() {
|
||||
if (fCategoryIteration == null)
|
||||
return fCategories;
|
||||
|
|
Loading…
Add table
Reference in a new issue