mirror of
https://github.com/eclipse-cdt/cdt
synced 2025-04-29 19:45:01 +02:00
Minor improvements for content assist in preprocessor directives
This commit is contained in:
parent
4aa0c4245a
commit
bb5cead81a
4 changed files with 172 additions and 57 deletions
|
@ -695,7 +695,25 @@ public class CompletionTests extends AbstractContentAssistTest {
|
||||||
//#i/*cursor*/
|
//#i/*cursor*/
|
||||||
public void testCompletePreprocessorDirective() throws Exception {
|
public void testCompletePreprocessorDirective() throws Exception {
|
||||||
final String[] expected= {
|
final String[] expected= {
|
||||||
"#if", "#ifdef", "#ifndef", "#include"
|
"#if ", "#ifdef ", "#ifndef ", "#include "
|
||||||
|
};
|
||||||
|
assertCompletionResults(fCursorOffset, expected,
|
||||||
|
AbstractContentAssistTest.COMPARE_ID_STRINGS);
|
||||||
|
}
|
||||||
|
|
||||||
|
//# d/*cursor*/
|
||||||
|
public void testCompletePreprocessorDirective2() throws Exception {
|
||||||
|
final String[] expected= {
|
||||||
|
"define "
|
||||||
|
};
|
||||||
|
assertCompletionResults(fCursorOffset, expected,
|
||||||
|
AbstractContentAssistTest.COMPARE_REP_STRINGS);
|
||||||
|
}
|
||||||
|
|
||||||
|
//# if d/*cursor*/
|
||||||
|
public void testCompletePreprocessorDirective3() throws Exception {
|
||||||
|
final String[] expected= {
|
||||||
|
"defined"
|
||||||
};
|
};
|
||||||
assertCompletionResults(fCursorOffset, expected,
|
assertCompletionResults(fCursorOffset, expected,
|
||||||
AbstractContentAssistTest.COMPARE_ID_STRINGS);
|
AbstractContentAssistTest.COMPARE_ID_STRINGS);
|
||||||
|
|
|
@ -42,7 +42,7 @@ public class FastCPartitioner extends FastPartitioner {
|
||||||
if (!fDocument.get(offset - 2, 2).equals("*/")) { //$NON-NLS-1$
|
if (!fDocument.get(offset - 2, 2).equals("*/")) { //$NON-NLS-1$
|
||||||
return region;
|
return region;
|
||||||
}
|
}
|
||||||
} else if (ICPartitions.C_SINGLE_LINE_COMMENT.equals(region .getType())) {
|
} else if (ICPartitions.C_SINGLE_LINE_COMMENT.equals(region.getType())) {
|
||||||
if (fDocument.getChar(offset - 1) != '\n') {
|
if (fDocument.getChar(offset - 1) != '\n') {
|
||||||
return region;
|
return region;
|
||||||
}
|
}
|
||||||
|
@ -50,7 +50,11 @@ public class FastCPartitioner extends FastPartitioner {
|
||||||
if (!fDocument.get(offset - 2, 2).equals("*/")) { //$NON-NLS-1$
|
if (!fDocument.get(offset - 2, 2).equals("*/")) { //$NON-NLS-1$
|
||||||
return region;
|
return region;
|
||||||
}
|
}
|
||||||
} else if (ICPartitions.C_SINGLE_LINE_DOC_COMMENT.equals(region .getType())) {
|
} else if (ICPartitions.C_SINGLE_LINE_DOC_COMMENT.equals(region.getType())) {
|
||||||
|
if (fDocument.getChar(offset - 1) != '\n') {
|
||||||
|
return region;
|
||||||
|
}
|
||||||
|
} else if (ICPartitions.C_PREPROCESSOR.equals(region.getType())) {
|
||||||
if (fDocument.getChar(offset - 1) != '\n') {
|
if (fDocument.getChar(offset - 1) != '\n') {
|
||||||
return region;
|
return region;
|
||||||
}
|
}
|
||||||
|
|
|
@ -18,6 +18,7 @@ import java.util.List;
|
||||||
import org.eclipse.jface.resource.ImageDescriptor;
|
import org.eclipse.jface.resource.ImageDescriptor;
|
||||||
import org.eclipse.jface.text.BadLocationException;
|
import org.eclipse.jface.text.BadLocationException;
|
||||||
import org.eclipse.jface.text.IDocument;
|
import org.eclipse.jface.text.IDocument;
|
||||||
|
import org.eclipse.jface.text.ITypedRegion;
|
||||||
import org.eclipse.jface.text.TextUtilities;
|
import org.eclipse.jface.text.TextUtilities;
|
||||||
import org.eclipse.swt.graphics.Image;
|
import org.eclipse.swt.graphics.Image;
|
||||||
|
|
||||||
|
@ -88,8 +89,17 @@ public class DOMCompletionProposalComputer extends ParsingBasedProposalComputer
|
||||||
List<CCompletionProposal> proposals = new ArrayList<CCompletionProposal>();
|
List<CCompletionProposal> proposals = new ArrayList<CCompletionProposal>();
|
||||||
|
|
||||||
if(inPreprocessorDirective(context)) {
|
if(inPreprocessorDirective(context)) {
|
||||||
// add only macros
|
if (!inPreprocessorKeyword(context)) {
|
||||||
addMacroProposals(context, prefix, proposals);
|
// add only macros
|
||||||
|
if (prefix.length() == 0) {
|
||||||
|
try {
|
||||||
|
prefix= context.computeIdentifierPrefix().toString();
|
||||||
|
} catch (BadLocationException exc) {
|
||||||
|
CUIPlugin.getDefault().log(exc);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
addMacroProposals(context, prefix, proposals);
|
||||||
|
}
|
||||||
} else {
|
} else {
|
||||||
boolean handleMacros= false;
|
boolean handleMacros= false;
|
||||||
IASTName[] names = completionNode.getNames();
|
IASTName[] names = completionNode.getNames();
|
||||||
|
@ -124,22 +134,46 @@ public class DOMCompletionProposalComputer extends ParsingBasedProposalComputer
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Check if given offset is inside a preprocessor directive.
|
* Test whether the invocation offset is inside or before the preprocessor directive keyword.
|
||||||
*
|
*
|
||||||
* @param doc the document
|
* @param context the invocation context
|
||||||
* @param offset the offset to check
|
* @return <code>true</code> if the invocation offset is inside or before the directive keyword
|
||||||
* @return <code>true</code> if offset is inside a preprocessor directive
|
*/
|
||||||
|
private boolean inPreprocessorKeyword(CContentAssistInvocationContext context) {
|
||||||
|
IDocument doc = context.getDocument();
|
||||||
|
int offset = context.getInvocationOffset();
|
||||||
|
|
||||||
|
try {
|
||||||
|
final ITypedRegion partition= TextUtilities.getPartition(doc, ICPartitions.C_PARTITIONING, offset, true);
|
||||||
|
if (ICPartitions.C_PREPROCESSOR.equals(partition.getType())) {
|
||||||
|
String ppPrefix= doc.get(partition.getOffset(), offset - partition.getOffset());
|
||||||
|
if (ppPrefix.matches("\\s*#\\s*\\w*")) { //$NON-NLS-1$
|
||||||
|
// we are inside the directive keyword
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
} catch (BadLocationException exc) {
|
||||||
|
}
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Check if the invocation offset is inside a preprocessor directive.
|
||||||
|
*
|
||||||
|
* @param context the content asist invocation context
|
||||||
|
* @return <code>true</code> if invocation offset is inside a preprocessor directive
|
||||||
*/
|
*/
|
||||||
private boolean inPreprocessorDirective(CContentAssistInvocationContext context) {
|
private boolean inPreprocessorDirective(CContentAssistInvocationContext context) {
|
||||||
IDocument doc = context.getViewer().getDocument();
|
IDocument doc = context.getDocument();
|
||||||
int offset = context.getParseOffset();
|
int offset = context.getInvocationOffset();
|
||||||
|
|
||||||
if (offset > 0 && offset == doc.getLength()) {
|
|
||||||
--offset;
|
|
||||||
}
|
|
||||||
try {
|
try {
|
||||||
return ICPartitions.C_PREPROCESSOR
|
final ITypedRegion partition= TextUtilities.getPartition(doc, ICPartitions.C_PARTITIONING, offset, true);
|
||||||
.equals(TextUtilities.getContentType(doc, ICPartitions.C_PARTITIONING, offset, false));
|
if (ICPartitions.C_PREPROCESSOR.equals(partition.getType())) {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
} catch (BadLocationException exc) {
|
} catch (BadLocationException exc) {
|
||||||
}
|
}
|
||||||
return false;
|
return false;
|
||||||
|
|
|
@ -1,12 +1,13 @@
|
||||||
/*******************************************************************************
|
/*******************************************************************************
|
||||||
* Copyright (c) 2007 QNX Software Systems and others.
|
* Copyright (c) 2007, 2008 QNX Software Systems and others.
|
||||||
* All rights reserved. This program and the accompanying materials
|
* All rights reserved. This program and the accompanying materials
|
||||||
* are made available under the terms of the Eclipse Public License v1.0
|
* are made available under the terms of the Eclipse Public License v1.0
|
||||||
* which accompanies this distribution, and is available at
|
* which accompanies this distribution, and is available at
|
||||||
* http://www.eclipse.org/legal/epl-v10.html
|
* http://www.eclipse.org/legal/epl-v10.html
|
||||||
*
|
*
|
||||||
* Contributors:
|
* Contributors:
|
||||||
* Bryan Wilkinson (QNX) - Initial API and implementation
|
* Bryan Wilkinson (QNX) - Initial API and implementation
|
||||||
|
* Anton Leherbauer (Wind River Systems)
|
||||||
*******************************************************************************/
|
*******************************************************************************/
|
||||||
package org.eclipse.cdt.internal.ui.text.contentassist;
|
package org.eclipse.cdt.internal.ui.text.contentassist;
|
||||||
|
|
||||||
|
@ -18,6 +19,7 @@ import org.eclipse.core.runtime.CoreException;
|
||||||
import org.eclipse.jface.resource.ImageDescriptor;
|
import org.eclipse.jface.resource.ImageDescriptor;
|
||||||
import org.eclipse.jface.text.BadLocationException;
|
import org.eclipse.jface.text.BadLocationException;
|
||||||
import org.eclipse.jface.text.IDocument;
|
import org.eclipse.jface.text.IDocument;
|
||||||
|
import org.eclipse.jface.text.ITypedRegion;
|
||||||
import org.eclipse.jface.text.TextUtilities;
|
import org.eclipse.jface.text.TextUtilities;
|
||||||
import org.eclipse.swt.graphics.Image;
|
import org.eclipse.swt.graphics.Image;
|
||||||
|
|
||||||
|
@ -35,21 +37,53 @@ import org.eclipse.cdt.internal.ui.viewsupport.CElementImageProvider;
|
||||||
|
|
||||||
public class KeywordCompletionProposalComputer extends ParsingBasedProposalComputer implements ICompletionProposalComputer {
|
public class KeywordCompletionProposalComputer extends ParsingBasedProposalComputer implements ICompletionProposalComputer {
|
||||||
|
|
||||||
protected List computeCompletionProposals(
|
protected List<CCompletionProposal> computeCompletionProposals(
|
||||||
CContentAssistInvocationContext context,
|
CContentAssistInvocationContext context,
|
||||||
IASTCompletionNode completionNode, String prefix)
|
IASTCompletionNode completionNode, String prefix)
|
||||||
throws CoreException {
|
throws CoreException {
|
||||||
|
|
||||||
|
if (prefix.length() == 0) {
|
||||||
|
try {
|
||||||
|
prefix= context.computeIdentifierPrefix().toString();
|
||||||
|
} catch (BadLocationException exc) {
|
||||||
|
CUIPlugin.getDefault().log(exc);
|
||||||
|
}
|
||||||
|
}
|
||||||
// No prefix, no completions
|
// No prefix, no completions
|
||||||
if (prefix.length() == 0 || context.isContextInformationStyle())
|
if (prefix.length() == 0 || context.isContextInformationStyle())
|
||||||
return Collections.EMPTY_LIST;
|
return Collections.emptyList();
|
||||||
|
|
||||||
String[] keywords;
|
String[] keywords;
|
||||||
if(inPreprocessorDirective(context.getDocument(), context.getInvocationOffset())) {
|
List<CCompletionProposal> proposals = new ArrayList<CCompletionProposal>();
|
||||||
|
|
||||||
|
if (inPreprocessorDirective(context)) {
|
||||||
|
// TODO split this into a separate proposal computer?
|
||||||
|
boolean needDirectiveKeyword= inPreprocessorKeyword(context);
|
||||||
keywords= preprocessorKeywords;
|
keywords= preprocessorKeywords;
|
||||||
|
|
||||||
|
// add matching preprocessor keyword proposals
|
||||||
|
ImageDescriptor imagedesc = CElementImageProvider.getKeywordImageDescriptor();
|
||||||
|
Image image = imagedesc != null ? CUIPlugin.getImageDescriptorRegistry().get(imagedesc) : null;
|
||||||
|
for (int i = 0; i < keywords.length; ++i) {
|
||||||
|
String repString= keywords[i];
|
||||||
|
if (repString.startsWith(prefix)) {
|
||||||
|
int repLength = prefix.length();
|
||||||
|
int repOffset = context.getInvocationOffset() - repLength;
|
||||||
|
if (prefix.charAt(0) == '#') {
|
||||||
|
// strip leading '#' from replacement
|
||||||
|
repLength--;
|
||||||
|
repOffset++;
|
||||||
|
repString= repString.substring(1);
|
||||||
|
} else if (needDirectiveKeyword) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
proposals.add(new CCompletionProposal(repString, repOffset,
|
||||||
|
repLength, image, keywords[i], 1, context.getViewer()));
|
||||||
|
}
|
||||||
|
}
|
||||||
} else {
|
} else {
|
||||||
if (!isValidContext(completionNode))
|
if (!isValidContext(completionNode))
|
||||||
return Collections.EMPTY_LIST;
|
return Collections.emptyList();
|
||||||
|
|
||||||
ITranslationUnit tu = context.getTranslationUnit();
|
ITranslationUnit tu = context.getTranslationUnit();
|
||||||
|
|
||||||
|
@ -57,21 +91,18 @@ public class KeywordCompletionProposalComputer extends ParsingBasedProposalCompu
|
||||||
if (tu != null && tu.isCLanguage())
|
if (tu != null && tu.isCLanguage())
|
||||||
keywords = ckeywords;
|
keywords = ckeywords;
|
||||||
|
|
||||||
|
// add matching keyword proposals
|
||||||
|
ImageDescriptor imagedesc = CElementImageProvider.getKeywordImageDescriptor();
|
||||||
|
Image image = imagedesc != null ? CUIPlugin.getImageDescriptorRegistry().get(imagedesc) : null;
|
||||||
|
for (int i = 0; i < keywords.length; ++i) {
|
||||||
|
if (keywords[i].startsWith(prefix)) {
|
||||||
|
int repLength = prefix.length();
|
||||||
|
int repOffset = context.getInvocationOffset() - repLength;
|
||||||
|
proposals.add(new CCompletionProposal(keywords[i], repOffset,
|
||||||
|
repLength, image, keywords[i], 1, context.getViewer()));
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
List proposals = new ArrayList();
|
|
||||||
|
|
||||||
// add matching keyword proposals
|
|
||||||
ImageDescriptor imagedesc = CElementImageProvider.getKeywordImageDescriptor();
|
|
||||||
Image image = imagedesc != null ? CUIPlugin.getImageDescriptorRegistry().get(imagedesc) : null;
|
|
||||||
for (int i = 0; i < keywords.length; ++i) {
|
|
||||||
if (keywords[i].startsWith(prefix)) {
|
|
||||||
int repLength = prefix.length();
|
|
||||||
int repOffset = context.getInvocationOffset() - repLength;
|
|
||||||
proposals.add(new CCompletionProposal(keywords[i], repOffset,
|
|
||||||
repLength, image, keywords[i], 1, context.getViewer()));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return proposals;
|
return proposals;
|
||||||
}
|
}
|
||||||
|
@ -100,26 +131,53 @@ public class KeywordCompletionProposalComputer extends ParsingBasedProposalCompu
|
||||||
|
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Check if given offset is inside a preprocessor directive.
|
* Test whether the invocation offset is inside or before the preprocessor directive keyword.
|
||||||
*
|
*
|
||||||
* @param doc the document
|
* @param context the invocation context
|
||||||
* @param offset the offset to check
|
* @return <code>true</code> if the invocation offset is inside or before the directive keyword
|
||||||
* @return <code>true</code> if offset is inside a preprocessor directive
|
|
||||||
*/
|
*/
|
||||||
private boolean inPreprocessorDirective(IDocument doc, int offset) {
|
private boolean inPreprocessorKeyword(CContentAssistInvocationContext context) {
|
||||||
if (offset > 0 && offset == doc.getLength()) {
|
IDocument doc = context.getDocument();
|
||||||
--offset;
|
int offset = context.getInvocationOffset();
|
||||||
}
|
|
||||||
try {
|
try {
|
||||||
return ICPartitions.C_PREPROCESSOR
|
final ITypedRegion partition= TextUtilities.getPartition(doc, ICPartitions.C_PARTITIONING, offset, true);
|
||||||
.equals(TextUtilities.getContentType(doc, ICPartitions.C_PARTITIONING, offset, false));
|
if (ICPartitions.C_PREPROCESSOR.equals(partition.getType())) {
|
||||||
|
String ppPrefix= doc.get(partition.getOffset(), offset - partition.getOffset());
|
||||||
|
if (ppPrefix.matches("\\s*#\\s*\\w*")) { //$NON-NLS-1$
|
||||||
|
// we are inside the directive keyword
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
} catch (BadLocationException exc) {
|
} catch (BadLocationException exc) {
|
||||||
}
|
}
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Check if the invocation offset is inside a preprocessor directive.
|
||||||
|
*
|
||||||
|
* @param context the content asist invocation context
|
||||||
|
* @return <code>true</code> if invocation offset is inside a preprocessor directive
|
||||||
|
*/
|
||||||
|
private boolean inPreprocessorDirective(CContentAssistInvocationContext context) {
|
||||||
|
IDocument doc = context.getDocument();
|
||||||
|
int offset = context.getInvocationOffset();
|
||||||
|
|
||||||
|
try {
|
||||||
|
final ITypedRegion partition= TextUtilities.getPartition(doc, ICPartitions.C_PARTITIONING, offset, true);
|
||||||
|
if (ICPartitions.C_PREPROCESSOR.equals(partition.getType())) {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
} catch (BadLocationException exc) {
|
||||||
|
}
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
// These are the keywords we complete
|
// These are the keywords we complete
|
||||||
// We only do the ones that are >= 5 characters long
|
// We only do the ones that are >= 5 characters long
|
||||||
private static String [] ckeywords = {
|
private static String [] ckeywords = {
|
||||||
|
@ -199,16 +257,17 @@ public class KeywordCompletionProposalComputer extends ParsingBasedProposalCompu
|
||||||
};
|
};
|
||||||
|
|
||||||
private static String [] preprocessorKeywords = {
|
private static String [] preprocessorKeywords = {
|
||||||
Directives.POUND_DEFINE,
|
Directives.POUND_DEFINE + ' ',
|
||||||
Directives.POUND_ELIF,
|
Directives.POUND_ELIF + ' ',
|
||||||
Directives.POUND_ELSE,
|
Directives.POUND_ELSE,
|
||||||
Directives.POUND_ENDIF,
|
Directives.POUND_ENDIF,
|
||||||
Directives.POUND_ERROR,
|
Directives.POUND_ERROR + ' ',
|
||||||
Directives.POUND_IF,
|
Directives.POUND_IF + ' ',
|
||||||
Directives.POUND_IFDEF,
|
Directives.POUND_IFDEF + ' ',
|
||||||
Directives.POUND_IFNDEF,
|
Directives.POUND_IFNDEF + ' ',
|
||||||
Directives.POUND_INCLUDE,
|
Directives.POUND_INCLUDE + ' ',
|
||||||
Directives.POUND_PRAGMA,
|
Directives.POUND_PRAGMA + ' ',
|
||||||
Directives.POUND_UNDEF,
|
Directives.POUND_UNDEF + ' ',
|
||||||
|
"defined" //$NON-NLS-1$
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
Loading…
Add table
Reference in a new issue