mirror of
https://github.com/eclipse-cdt/cdt
synced 2025-04-23 06:32:10 +02:00
Patch from Sergey Prigogin for bug 148582 - Support smart indenting in C editor
This commit is contained in:
parent
3b95e39b47
commit
7a61449698
22 changed files with 9180 additions and 185 deletions
|
@ -141,6 +141,26 @@ public class CCorePlugin extends Plugin {
|
||||||
*/
|
*/
|
||||||
public final static String CONTENT_TYPE_ASMSOURCE = "org.eclipse.cdt.core.asmSource"; //$NON-NLS-1$
|
public final static String CONTENT_TYPE_ASMSOURCE = "org.eclipse.cdt.core.asmSource"; //$NON-NLS-1$
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Possible configurable option value.
|
||||||
|
* @see #getDefaultOptions()
|
||||||
|
*/
|
||||||
|
public static final String INSERT = "insert"; //$NON-NLS-1$
|
||||||
|
/**
|
||||||
|
* Possible configurable option value.
|
||||||
|
* @see #getDefaultOptions()
|
||||||
|
*/
|
||||||
|
public static final String DO_NOT_INSERT = "do not insert"; //$NON-NLS-1$
|
||||||
|
/**
|
||||||
|
* Possible configurable option value.
|
||||||
|
* @see #getDefaultOptions()
|
||||||
|
*/
|
||||||
|
public static final String TAB = "tab"; //$NON-NLS-1$
|
||||||
|
/**
|
||||||
|
* Possible configurable option value.
|
||||||
|
* @see #getDefaultOptions()
|
||||||
|
*/
|
||||||
|
public static final String SPACE = "space"; //$NON-NLS-1$
|
||||||
|
|
||||||
public CDTLogWriter cdtLog = null;
|
public CDTLogWriter cdtLog = null;
|
||||||
|
|
||||||
|
|
File diff suppressed because it is too large
Load diff
|
@ -7,16 +7,23 @@
|
||||||
*
|
*
|
||||||
* Contributors:
|
* Contributors:
|
||||||
* QNX Software Systems - Initial API and implementation
|
* QNX Software Systems - Initial API and implementation
|
||||||
|
* Sergey Prigogin, Google
|
||||||
*******************************************************************************/
|
*******************************************************************************/
|
||||||
package org.eclipse.cdt.internal.core;
|
package org.eclipse.cdt.internal.core;
|
||||||
|
|
||||||
import java.util.HashSet;
|
import java.util.HashSet;
|
||||||
|
import java.util.Iterator;
|
||||||
|
import java.util.Map;
|
||||||
|
|
||||||
import org.eclipse.cdt.core.CCorePlugin;
|
import org.eclipse.cdt.core.CCorePlugin;
|
||||||
import org.eclipse.cdt.core.CCorePreferenceConstants;
|
import org.eclipse.cdt.core.CCorePreferenceConstants;
|
||||||
|
import org.eclipse.cdt.core.formatter.CodeFormatterConstants;
|
||||||
import org.eclipse.cdt.internal.core.model.CModelManager;
|
import org.eclipse.cdt.internal.core.model.CModelManager;
|
||||||
import org.eclipse.core.runtime.Preferences;
|
//import org.eclipse.core.runtime.Preferences;
|
||||||
import org.eclipse.core.runtime.preferences.AbstractPreferenceInitializer;
|
import org.eclipse.core.runtime.preferences.AbstractPreferenceInitializer;
|
||||||
|
import org.eclipse.core.runtime.preferences.DefaultScope;
|
||||||
|
import org.eclipse.core.runtime.preferences.IEclipsePreferences;
|
||||||
|
import org.eclipse.core.runtime.preferences.IScopeContext;
|
||||||
|
|
||||||
|
|
||||||
public class CCorePreferenceInitializer extends AbstractPreferenceInitializer {
|
public class CCorePreferenceInitializer extends AbstractPreferenceInitializer {
|
||||||
|
@ -25,19 +32,24 @@ public class CCorePreferenceInitializer extends AbstractPreferenceInitializer {
|
||||||
* @see org.eclipse.core.runtime.preferences.AbstractPreferenceInitializer#initializeDefaultPreferences()
|
* @see org.eclipse.core.runtime.preferences.AbstractPreferenceInitializer#initializeDefaultPreferences()
|
||||||
*/
|
*/
|
||||||
public void initializeDefaultPreferences() {
|
public void initializeDefaultPreferences() {
|
||||||
Preferences preferences = CCorePlugin.getDefault().getPluginPreferences();
|
|
||||||
HashSet optionNames = CModelManager.OptionNames;
|
HashSet optionNames = CModelManager.OptionNames;
|
||||||
|
|
||||||
// Compiler settings
|
// Formatter settings
|
||||||
preferences.setDefault(CCorePreferenceConstants.TRANSLATION_TASK_TAGS, CCorePreferenceConstants.DEFAULT_TASK_TAG);
|
Map defaultOptionsMap = CodeFormatterConstants.getEclipseDefaultSettings(); // code formatter defaults
|
||||||
optionNames.add(CCorePreferenceConstants.TRANSLATION_TASK_TAGS);
|
|
||||||
|
|
||||||
preferences.setDefault(CCorePreferenceConstants.TRANSLATION_TASK_PRIORITIES, CCorePreferenceConstants.DEFAULT_TASK_PRIORITY);
|
// Compiler settings
|
||||||
optionNames.add(CCorePreferenceConstants.TRANSLATION_TASK_PRIORITIES);
|
defaultOptionsMap.put(CCorePreferenceConstants.TRANSLATION_TASK_TAGS, CCorePreferenceConstants.DEFAULT_TASK_TAG);
|
||||||
|
defaultOptionsMap.put(CCorePreferenceConstants.TRANSLATION_TASK_PRIORITIES, CCorePreferenceConstants.DEFAULT_TASK_PRIORITY);
|
||||||
preferences.setDefault(CCorePreferenceConstants.CODE_FORMATTER, CCorePreferenceConstants.DEFAULT_CODE_FORMATTER);
|
defaultOptionsMap.put(CCorePreferenceConstants.CODE_FORMATTER, CCorePreferenceConstants.DEFAULT_CODE_FORMATTER);
|
||||||
optionNames.add(CCorePreferenceConstants.CODE_FORMATTER);
|
|
||||||
|
|
||||||
|
// Store default values to default preferences
|
||||||
|
IEclipsePreferences defaultPreferences = ((IScopeContext) new DefaultScope()).getNode(CCorePlugin.PLUGIN_ID);
|
||||||
|
for (Iterator iter = defaultOptionsMap.entrySet().iterator(); iter.hasNext();) {
|
||||||
|
Map.Entry entry = (Map.Entry) iter.next();
|
||||||
|
String optionName = (String) entry.getKey();
|
||||||
|
defaultPreferences.put(optionName, (String)entry.getValue());
|
||||||
|
optionNames.add(optionName);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
File diff suppressed because it is too large
Load diff
|
@ -0,0 +1,124 @@
|
||||||
|
/*******************************************************************************
|
||||||
|
* Copyright (c) 2000, 2005 IBM Corporation and others.
|
||||||
|
* All rights reserved. This program and the accompanying materials
|
||||||
|
* are made available under the terms of the Eclipse Public License v1.0
|
||||||
|
* which accompanies this distribution, and is available at
|
||||||
|
* http://www.eclipse.org/legal/epl-v10.html
|
||||||
|
*
|
||||||
|
* Contributors:
|
||||||
|
* IBM Corporation - initial API and implementation
|
||||||
|
*******************************************************************************/
|
||||||
|
package org.eclipse.cdt.internal.formatter.align;
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Alignment management
|
||||||
|
*/
|
||||||
|
public class Alignment {
|
||||||
|
|
||||||
|
// name of alignment
|
||||||
|
public String name;
|
||||||
|
|
||||||
|
// link to enclosing alignment
|
||||||
|
public Alignment enclosing;
|
||||||
|
|
||||||
|
// indentation management
|
||||||
|
public int fragmentIndex;
|
||||||
|
public int fragmentCount;
|
||||||
|
public int[] fragmentIndentations;
|
||||||
|
public boolean needRedoColumnAlignment;
|
||||||
|
|
||||||
|
// chunk management
|
||||||
|
public int chunkStartIndex;
|
||||||
|
public int chunkKind;
|
||||||
|
|
||||||
|
// break management
|
||||||
|
public int originalIndentationLevel;
|
||||||
|
public int breakIndentationLevel;
|
||||||
|
public int shiftBreakIndentationLevel;
|
||||||
|
public int[] fragmentBreaks;
|
||||||
|
public boolean wasSplit;
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Alignment modes
|
||||||
|
*/
|
||||||
|
public static final int M_FORCE = 1; // if bit set, then alignment will be non-optional (default is optional)
|
||||||
|
public static final int M_INDENT_ON_COLUMN = 2; // if bit set, broken fragments will be aligned on current location column (default is to break at current indentation level)
|
||||||
|
public static final int M_INDENT_BY_ONE = 4; // if bit set, broken fragments will be indented one level below current (not using continuation indentation)
|
||||||
|
|
||||||
|
// split modes can be combined either with M_FORCE or M_INDENT_ON_COLUMN
|
||||||
|
|
||||||
|
/** foobar(#fragment1, #fragment2, <ul>
|
||||||
|
* <li> #fragment3, #fragment4 </li>
|
||||||
|
* </ul>
|
||||||
|
*/
|
||||||
|
public static final int M_COMPACT_SPLIT = 16; // fill each line with all possible fragments
|
||||||
|
|
||||||
|
/** foobar(<ul>
|
||||||
|
* <li> #fragment1, #fragment2, </li>
|
||||||
|
* <li> #fragment5, #fragment4, </li>
|
||||||
|
* </ul>
|
||||||
|
*/
|
||||||
|
public static final int M_COMPACT_FIRST_BREAK_SPLIT = 32; // compact mode, but will first try to break before first fragment
|
||||||
|
|
||||||
|
/** foobar(<ul>
|
||||||
|
* <li> #fragment1, </li>
|
||||||
|
* <li> #fragment2, </li>
|
||||||
|
* <li> #fragment3 </li>
|
||||||
|
* <li> #fragment4, </li>
|
||||||
|
* </ul>
|
||||||
|
*/
|
||||||
|
public static final int M_ONE_PER_LINE_SPLIT = 32+16; // one fragment per line
|
||||||
|
|
||||||
|
/**
|
||||||
|
* foobar(<ul>
|
||||||
|
* <li> #fragment1, </li>
|
||||||
|
* <li> #fragment2, </li>
|
||||||
|
* <li> #fragment3 </li>
|
||||||
|
* <li> #fragment4, </li>
|
||||||
|
* </ul>
|
||||||
|
*/
|
||||||
|
public static final int M_NEXT_SHIFTED_SPLIT = 64; // one fragment per line, subsequent are indented further
|
||||||
|
|
||||||
|
/** foobar(#fragment1, <ul>
|
||||||
|
* <li> #fragment2, </li>
|
||||||
|
* <li> #fragment3 </li>
|
||||||
|
* <li> #fragment4, </li>
|
||||||
|
* </ul>
|
||||||
|
*/
|
||||||
|
public static final int M_NEXT_PER_LINE_SPLIT = 64+16; // one per line, except first fragment (if possible)
|
||||||
|
|
||||||
|
//64+32
|
||||||
|
//64+32+16
|
||||||
|
|
||||||
|
// mode controlling column alignments
|
||||||
|
/**
|
||||||
|
* <table BORDER COLS=4 WIDTH="100%" >
|
||||||
|
* <tr><td>#fragment1A</td> <td>#fragment2A</td> <td>#fragment3A</td> <td>#very-long-fragment4A</td></tr>
|
||||||
|
* <tr><td>#fragment1B</td> <td>#long-fragment2B</td> <td>#fragment3B</td> <td>#fragment4B</td></tr>
|
||||||
|
* <tr><td>#very-long-fragment1C</td> <td>#fragment2C</td> <td>#fragment3C</td> <td>#fragment4C</td></tr>
|
||||||
|
* </table>
|
||||||
|
*/
|
||||||
|
public static final int M_MULTICOLUMN = 256; // fragments are on same line, but multiple line of fragments will be aligned vertically
|
||||||
|
|
||||||
|
public static final int M_NO_ALIGNMENT = 0;
|
||||||
|
|
||||||
|
public int mode;
|
||||||
|
|
||||||
|
public static final int SPLIT_MASK = M_ONE_PER_LINE_SPLIT | M_NEXT_SHIFTED_SPLIT | M_COMPACT_SPLIT | M_COMPACT_FIRST_BREAK_SPLIT | M_NEXT_PER_LINE_SPLIT;
|
||||||
|
|
||||||
|
// alignment tie-break rules - when split is needed, will decide whether innermost/outermost alignment is to be chosen
|
||||||
|
public static final int R_OUTERMOST = 1;
|
||||||
|
public static final int R_INNERMOST = 2;
|
||||||
|
public int tieBreakRule;
|
||||||
|
|
||||||
|
// alignment effects on a per fragment basis
|
||||||
|
public static int NONE = 0;
|
||||||
|
public static int BREAK = 1;
|
||||||
|
|
||||||
|
// chunk kind
|
||||||
|
public static final int CHUNK_FIELD = 1;
|
||||||
|
public static final int CHUNK_METHOD = 2;
|
||||||
|
public static final int CHUNK_TYPE = 3;
|
||||||
|
public static final int CHUNK_ENUM = 4;
|
||||||
|
}
|
|
@ -19,11 +19,6 @@ import junit.framework.Test;
|
||||||
import junit.framework.TestCase;
|
import junit.framework.TestCase;
|
||||||
import junit.framework.TestSuite;
|
import junit.framework.TestSuite;
|
||||||
|
|
||||||
import org.eclipse.cdt.internal.ui.text.CAutoIndentStrategy;
|
|
||||||
import org.eclipse.cdt.internal.ui.text.CCommentAutoIndentStrategy;
|
|
||||||
import org.eclipse.cdt.internal.ui.text.CTextTools;
|
|
||||||
import org.eclipse.cdt.internal.ui.text.ICPartitions;
|
|
||||||
import org.eclipse.cdt.ui.CUIPlugin;
|
|
||||||
import org.eclipse.core.runtime.CoreException;
|
import org.eclipse.core.runtime.CoreException;
|
||||||
import org.eclipse.jface.text.BadLocationException;
|
import org.eclipse.jface.text.BadLocationException;
|
||||||
import org.eclipse.jface.text.Document;
|
import org.eclipse.jface.text.Document;
|
||||||
|
@ -32,6 +27,15 @@ import org.eclipse.jface.text.IAutoEditStrategy;
|
||||||
import org.eclipse.jface.text.IDocument;
|
import org.eclipse.jface.text.IDocument;
|
||||||
import org.eclipse.jface.text.IRegion;
|
import org.eclipse.jface.text.IRegion;
|
||||||
import org.eclipse.jface.text.TextUtilities;
|
import org.eclipse.jface.text.TextUtilities;
|
||||||
|
import org.eclipse.swt.widgets.Shell;
|
||||||
|
import org.eclipse.ui.PlatformUI;
|
||||||
|
|
||||||
|
import org.eclipse.cdt.ui.CUIPlugin;
|
||||||
|
import org.eclipse.cdt.ui.text.ICPartitions;
|
||||||
|
|
||||||
|
import org.eclipse.cdt.internal.ui.text.CAutoIndentStrategy;
|
||||||
|
import org.eclipse.cdt.internal.ui.text.CCommentAutoIndentStrategy;
|
||||||
|
import org.eclipse.cdt.internal.ui.text.CTextTools;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Testing the auto indent strategies.
|
* Testing the auto indent strategies.
|
||||||
|
@ -71,7 +75,7 @@ public class CAutoIndentTest extends TestCase {
|
||||||
public void type(char c) throws BadLocationException {
|
public void type(char c) throws BadLocationException {
|
||||||
TestDocumentCommand command = new TestDocumentCommand(fCaretOffset, 0, new String(new char[] { c }));
|
TestDocumentCommand command = new TestDocumentCommand(fCaretOffset, 0, new String(new char[] { c }));
|
||||||
customizeDocumentCommand(command);
|
customizeDocumentCommand(command);
|
||||||
fCaretOffset += command.exec(fDoc);
|
fCaretOffset = command.exec(fDoc);
|
||||||
}
|
}
|
||||||
|
|
||||||
private void customizeDocumentCommand(TestDocumentCommand command) throws BadLocationException {
|
private void customizeDocumentCommand(TestDocumentCommand command) throws BadLocationException {
|
||||||
|
@ -94,7 +98,7 @@ public class CAutoIndentTest extends TestCase {
|
||||||
public void paste(String text) throws BadLocationException {
|
public void paste(String text) throws BadLocationException {
|
||||||
TestDocumentCommand command = new TestDocumentCommand(fCaretOffset, 0, text);
|
TestDocumentCommand command = new TestDocumentCommand(fCaretOffset, 0, text);
|
||||||
customizeDocumentCommand(command);
|
customizeDocumentCommand(command);
|
||||||
fCaretOffset += command.exec(fDoc);
|
fCaretOffset = command.exec(fDoc);
|
||||||
}
|
}
|
||||||
|
|
||||||
public void paste(int offset, String text) throws BadLocationException {
|
public void paste(int offset, String text) throws BadLocationException {
|
||||||
|
@ -110,13 +114,32 @@ public class CAutoIndentTest extends TestCase {
|
||||||
public void backspace() throws BadLocationException {
|
public void backspace() throws BadLocationException {
|
||||||
TestDocumentCommand command = new TestDocumentCommand(fCaretOffset-1, 1, ""); //$NON-NLS-1$
|
TestDocumentCommand command = new TestDocumentCommand(fCaretOffset-1, 1, ""); //$NON-NLS-1$
|
||||||
customizeDocumentCommand(command);
|
customizeDocumentCommand(command);
|
||||||
fCaretOffset += command.exec(fDoc);
|
fCaretOffset = command.exec(fDoc);
|
||||||
}
|
}
|
||||||
|
|
||||||
public int getCaretOffset() {
|
public int getCaretOffset() {
|
||||||
return fCaretOffset;
|
return fCaretOffset;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public int setCaretOffset(int offset) {
|
||||||
|
fCaretOffset = offset;
|
||||||
|
if (fCaretOffset < 0)
|
||||||
|
fCaretOffset = 0;
|
||||||
|
else if (fCaretOffset > fDoc.getLength())
|
||||||
|
fCaretOffset = fDoc.getLength();
|
||||||
|
return fCaretOffset;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Moves caret right or left by the given number of characters.
|
||||||
|
*
|
||||||
|
* @param shift Move distance.
|
||||||
|
* @return New caret offset.
|
||||||
|
*/
|
||||||
|
public int moveCaret(int shift) {
|
||||||
|
return setCaretOffset(fCaretOffset + shift);
|
||||||
|
}
|
||||||
|
|
||||||
public int getCaretLine() throws BadLocationException {
|
public int getCaretLine() throws BadLocationException {
|
||||||
return fDoc.getLineOfOffset(fCaretOffset);
|
return fDoc.getLineOfOffset(fCaretOffset);
|
||||||
}
|
}
|
||||||
|
@ -167,12 +190,16 @@ public class CAutoIndentTest extends TestCase {
|
||||||
|
|
||||||
owner = null;
|
owner = null;
|
||||||
caretOffset = -1;
|
caretOffset = -1;
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Returns new caret position.
|
||||||
|
*/
|
||||||
public int exec(IDocument doc) throws BadLocationException {
|
public int exec(IDocument doc) throws BadLocationException {
|
||||||
doc.replace(offset, length, text);
|
doc.replace(offset, length, text);
|
||||||
return text.length() - length;
|
return caretOffset != -1 ?
|
||||||
|
caretOffset :
|
||||||
|
offset + (text == null ? 0 : text.length());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -188,13 +215,21 @@ public class CAutoIndentTest extends TestCase {
|
||||||
return new TestSuite(CAutoIndentTest.class);
|
return new TestSuite(CAutoIndentTest.class);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
protected void setUp() throws Exception {
|
||||||
|
super.setUp();
|
||||||
|
Shell shell = PlatformUI.getWorkbench().getActiveWorkbenchWindow().getShell();
|
||||||
|
shell.forceActive();
|
||||||
|
shell.forceFocus();
|
||||||
|
}
|
||||||
|
|
||||||
private AutoEditTester createAutoEditTester() {
|
private AutoEditTester createAutoEditTester() {
|
||||||
CTextTools textTools = CUIPlugin.getDefault().getTextTools();
|
CTextTools textTools = CUIPlugin.getDefault().getTextTools();
|
||||||
IDocument doc = new Document();
|
IDocument doc = new Document();
|
||||||
textTools.setupCDocument(doc);
|
textTools.setupCDocument(doc);
|
||||||
AutoEditTester tester = new AutoEditTester(doc, textTools.getDocumentPartitioning());
|
AutoEditTester tester = new AutoEditTester(doc, textTools.getDocumentPartitioning());
|
||||||
tester.setAutoEditStrategy(IDocument.DEFAULT_CONTENT_TYPE, new CAutoIndentStrategy());
|
tester.setAutoEditStrategy(IDocument.DEFAULT_CONTENT_TYPE,
|
||||||
tester.setAutoEditStrategy(ICPartitions.C_MULTILINE_COMMENT, new CCommentAutoIndentStrategy());
|
new CAutoIndentStrategy(textTools.getDocumentPartitioning(), null));
|
||||||
|
tester.setAutoEditStrategy(ICPartitions.C_MULTI_LINE_COMMENT, new CCommentAutoIndentStrategy());
|
||||||
return tester;
|
return tester;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -202,10 +237,38 @@ public class CAutoIndentTest extends TestCase {
|
||||||
AutoEditTester tester = createAutoEditTester(); //$NON-NLS-1$
|
AutoEditTester tester = createAutoEditTester(); //$NON-NLS-1$
|
||||||
tester.type("void main() {\n"); //$NON-NLS-1$
|
tester.type("void main() {\n"); //$NON-NLS-1$
|
||||||
assertEquals(1, tester.getCaretLine());
|
assertEquals(1, tester.getCaretLine());
|
||||||
|
// Nested statement is indented by one.
|
||||||
assertEquals(1, tester.getCaretColumn());
|
assertEquals(1, tester.getCaretColumn());
|
||||||
tester.type("}\n"); //$NON-NLS-1$
|
// The brace was closed automatically.
|
||||||
|
assertEquals("}", tester.getLine(1)); //$NON-NLS-1$
|
||||||
|
tester.type("if (expression1 &&\n"); //$NON-NLS-1$
|
||||||
assertEquals(2, tester.getCaretLine());
|
assertEquals(2, tester.getCaretLine());
|
||||||
assertEquals(0, tester.getCaretColumn());
|
// Continuation line is indented by two relative to the statement.
|
||||||
|
assertEquals(3, tester.getCaretColumn());
|
||||||
|
tester.type("expression2 &&\n"); //$NON-NLS-1$
|
||||||
|
assertEquals(3, tester.getCaretLine());
|
||||||
|
// Second continuation line is also indented by two relative to the statement.
|
||||||
|
assertEquals(3, tester.getCaretColumn());
|
||||||
|
tester.type("expression3) {"); //$NON-NLS-1$
|
||||||
|
// Remember caret position.
|
||||||
|
int offset = tester.getCaretOffset();
|
||||||
|
// Press Enter
|
||||||
|
tester.type("\n"); //$NON-NLS-1$
|
||||||
|
assertEquals(4, tester.getCaretLine());
|
||||||
|
// Nested statement is indented by one relative to the containing statement.
|
||||||
|
assertEquals(2, tester.getCaretColumn());
|
||||||
|
// The brace was closed automatically.
|
||||||
|
assertEquals("\t}", tester.getLine(1)); //$NON-NLS-1$
|
||||||
|
tester.type("int x = 5;"); //$NON-NLS-1$
|
||||||
|
// Move caret back after the opening brace.
|
||||||
|
tester.setCaretOffset(offset);
|
||||||
|
// Press Enter
|
||||||
|
tester.type("\n"); //$NON-NLS-1$
|
||||||
|
assertEquals(4, tester.getCaretLine());
|
||||||
|
// Nested statement is indented by one relative to the containing statement.
|
||||||
|
assertEquals(2, tester.getCaretColumn());
|
||||||
|
// No auto closing brace since the braces are already balanced.
|
||||||
|
assertEquals("\t\tint x = 5;", tester.getLine(1)); //$NON-NLS-1$
|
||||||
}
|
}
|
||||||
|
|
||||||
public void testDefaultAutoIndent() throws IOException, CoreException, BadLocationException {
|
public void testDefaultAutoIndent() throws IOException, CoreException, BadLocationException {
|
||||||
|
@ -233,7 +296,7 @@ public class CAutoIndentTest extends TestCase {
|
||||||
public void testCCommentAutoIndent() throws IOException, CoreException, BadLocationException {
|
public void testCCommentAutoIndent() throws IOException, CoreException, BadLocationException {
|
||||||
AutoEditTester tester = createAutoEditTester(); //$NON-NLS-1$
|
AutoEditTester tester = createAutoEditTester(); //$NON-NLS-1$
|
||||||
tester.type("/*\n"); //$NON-NLS-1$
|
tester.type("/*\n"); //$NON-NLS-1$
|
||||||
assertEquals(ICPartitions.C_MULTILINE_COMMENT, tester.getContentType(-1));
|
assertEquals(ICPartitions.C_MULTI_LINE_COMMENT, tester.getContentType(-1));
|
||||||
assertEquals(1, tester.getCaretLine());
|
assertEquals(1, tester.getCaretLine());
|
||||||
assertEquals(3, tester.getCaretColumn());
|
assertEquals(3, tester.getCaretColumn());
|
||||||
assertEquals(" * ", tester.getLine()); //$NON-NLS-1$
|
assertEquals(" * ", tester.getLine()); //$NON-NLS-1$
|
||||||
|
|
|
@ -12,9 +12,13 @@ package org.eclipse.cdt.internal.corext.util;
|
||||||
|
|
||||||
import java.util.Map;
|
import java.util.Map;
|
||||||
|
|
||||||
|
import org.eclipse.cdt.core.CCorePlugin;
|
||||||
import org.eclipse.cdt.core.ToolFactory;
|
import org.eclipse.cdt.core.ToolFactory;
|
||||||
import org.eclipse.cdt.core.formatter.CodeFormatter;
|
import org.eclipse.cdt.core.formatter.CodeFormatter;
|
||||||
|
import org.eclipse.cdt.core.formatter.CodeFormatterConstants;
|
||||||
|
import org.eclipse.cdt.core.model.ICProject;
|
||||||
import org.eclipse.cdt.ui.CUIPlugin;
|
import org.eclipse.cdt.ui.CUIPlugin;
|
||||||
|
|
||||||
import org.eclipse.core.runtime.Assert;
|
import org.eclipse.core.runtime.Assert;
|
||||||
import org.eclipse.jface.preference.IPreferenceStore;
|
import org.eclipse.jface.preference.IPreferenceStore;
|
||||||
import org.eclipse.jface.text.BadLocationException;
|
import org.eclipse.jface.text.BadLocationException;
|
||||||
|
@ -34,7 +38,82 @@ public class CodeFormatterUtil {
|
||||||
// String str= format(CodeFormatter.K_EXPRESSION, "x", indent, null, "", (Map) null); //$NON-NLS-1$ //$NON-NLS-2$
|
// String str= format(CodeFormatter.K_EXPRESSION, "x", indent, null, "", (Map) null); //$NON-NLS-1$ //$NON-NLS-2$
|
||||||
// return str.substring(0, str.indexOf('x'));
|
// return str.substring(0, str.indexOf('x'));
|
||||||
// }
|
// }
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Gets the current tab width.
|
||||||
|
*
|
||||||
|
* @param project The project where the source is used, used for project
|
||||||
|
* specific options or <code>null</code> if the project is unknown
|
||||||
|
* and the workspace default should be used
|
||||||
|
* @return The tab width
|
||||||
|
*/
|
||||||
|
public static int getTabWidth(ICProject project) {
|
||||||
|
/*
|
||||||
|
* If the tab-char is SPACE, FORMATTER_INDENTATION_SIZE is not used
|
||||||
|
* by the core formatter.
|
||||||
|
* We piggy back the visual tab length setting in that preference in
|
||||||
|
* that case.
|
||||||
|
*/
|
||||||
|
String key;
|
||||||
|
if (CCorePlugin.SPACE.equals(getCoreOption(project, CodeFormatterConstants.FORMATTER_TAB_CHAR)))
|
||||||
|
key= CodeFormatterConstants.FORMATTER_INDENTATION_SIZE;
|
||||||
|
else
|
||||||
|
key= CodeFormatterConstants.FORMATTER_TAB_SIZE;
|
||||||
|
|
||||||
|
return getCoreOption(project, key, 4);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Returns the current indent width.
|
||||||
|
*
|
||||||
|
* @param project the project where the source is used or <code>null</code>
|
||||||
|
* if the project is unknown and the workspace default should be used
|
||||||
|
* @return the indent width
|
||||||
|
*/
|
||||||
|
public static int getIndentWidth(ICProject project) {
|
||||||
|
String key;
|
||||||
|
if (CodeFormatterConstants.MIXED.equals(getCoreOption(project, CodeFormatterConstants.FORMATTER_TAB_CHAR)))
|
||||||
|
key= CodeFormatterConstants.FORMATTER_INDENTATION_SIZE;
|
||||||
|
else
|
||||||
|
key= CodeFormatterConstants.FORMATTER_TAB_SIZE;
|
||||||
|
|
||||||
|
return getCoreOption(project, key, 4);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Returns the possibly <code>project</code>-specific core preference
|
||||||
|
* defined under <code>key</code>.
|
||||||
|
*
|
||||||
|
* @param project the project to get the preference from, or
|
||||||
|
* <code>null</code> to get the global preference
|
||||||
|
* @param key the key of the preference
|
||||||
|
* @return the value of the preference
|
||||||
|
*/
|
||||||
|
private static String getCoreOption(ICProject project, String key) {
|
||||||
|
if (project == null)
|
||||||
|
return CCorePlugin.getOption(key);
|
||||||
|
return project.getOption(key, true);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Returns the possibly <code>project</code>-specific core preference
|
||||||
|
* defined under <code>key</code>, or <code>def</code> if the value is
|
||||||
|
* not a integer.
|
||||||
|
*
|
||||||
|
* @param project the project to get the preference from, or
|
||||||
|
* <code>null</code> to get the global preference
|
||||||
|
* @param key the key of the preference
|
||||||
|
* @param def the default value
|
||||||
|
* @return the value of the preference
|
||||||
|
*/
|
||||||
|
private static int getCoreOption(ICProject project, String key, int def) {
|
||||||
|
try {
|
||||||
|
return Integer.parseInt(getCoreOption(project, key));
|
||||||
|
} catch (NumberFormatException e) {
|
||||||
|
return def;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Evaluates the edit on the given string.
|
* Evaluates the edit on the given string.
|
||||||
* @throws IllegalArgumentException If the positions are not inside the string, a
|
* @throws IllegalArgumentException If the positions are not inside the string, a
|
||||||
|
|
|
@ -15,7 +15,6 @@ import java.util.LinkedList;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
import java.util.ResourceBundle;
|
import java.util.ResourceBundle;
|
||||||
|
|
||||||
import org.eclipse.cdt.internal.ui.text.ICPartitions;
|
|
||||||
import org.eclipse.jface.text.Assert;
|
import org.eclipse.jface.text.Assert;
|
||||||
import org.eclipse.jface.text.BadLocationException;
|
import org.eclipse.jface.text.BadLocationException;
|
||||||
import org.eclipse.jface.text.BadPartitioningException;
|
import org.eclipse.jface.text.BadPartitioningException;
|
||||||
|
@ -25,6 +24,8 @@ import org.eclipse.jface.text.ITextSelection;
|
||||||
import org.eclipse.jface.text.ITypedRegion;
|
import org.eclipse.jface.text.ITypedRegion;
|
||||||
import org.eclipse.ui.texteditor.ITextEditor;
|
import org.eclipse.ui.texteditor.ITextEditor;
|
||||||
|
|
||||||
|
import org.eclipse.cdt.ui.text.ICPartitions;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Action that encloses the editor's current selection with Java block comment terminators
|
* Action that encloses the editor's current selection with Java block comment terminators
|
||||||
* (<code>/*</code> and <code>*/</code>).
|
* (<code>/*</code> and <code>*/</code>).
|
||||||
|
@ -109,7 +110,7 @@ public class AddBlockCommentAction extends BlockCommentAction {
|
||||||
int partEndOffset= partition.getOffset() + partition.getLength();
|
int partEndOffset= partition.getOffset() + partition.getLength();
|
||||||
int tokenLength= getCommentStart().length();
|
int tokenLength= getCommentStart().length();
|
||||||
|
|
||||||
if (partType == ICPartitions.C_MULTILINE_COMMENT) {
|
if (partType == ICPartitions.C_MULTI_LINE_COMMENT) {
|
||||||
// already in a comment - remove ending mark
|
// already in a comment - remove ending mark
|
||||||
edits.add(factory.createEdit(partEndOffset - tokenLength, tokenLength, "")); //$NON-NLS-1$
|
edits.add(factory.createEdit(partEndOffset - tokenLength, tokenLength, "")); //$NON-NLS-1$
|
||||||
}
|
}
|
||||||
|
@ -119,7 +120,7 @@ public class AddBlockCommentAction extends BlockCommentAction {
|
||||||
partType= partition.getType();
|
partType= partition.getType();
|
||||||
|
|
||||||
// start of next partition
|
// start of next partition
|
||||||
if (partType == ICPartitions.C_MULTILINE_COMMENT) {
|
if (partType == ICPartitions.C_MULTI_LINE_COMMENT) {
|
||||||
// already in a comment - remove startToken
|
// already in a comment - remove startToken
|
||||||
edits.add(factory.createEdit(partition.getOffset(), getCommentStart().length(), "")); //$NON-NLS-1$
|
edits.add(factory.createEdit(partition.getOffset(), getCommentStart().length(), "")); //$NON-NLS-1$
|
||||||
}
|
}
|
||||||
|
|
|
@ -15,7 +15,6 @@ import java.util.LinkedList;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
import java.util.ResourceBundle;
|
import java.util.ResourceBundle;
|
||||||
|
|
||||||
import org.eclipse.cdt.internal.ui.text.ICPartitions;
|
|
||||||
import org.eclipse.jface.text.BadLocationException;
|
import org.eclipse.jface.text.BadLocationException;
|
||||||
import org.eclipse.jface.text.BadPartitioningException;
|
import org.eclipse.jface.text.BadPartitioningException;
|
||||||
import org.eclipse.jface.text.IDocumentExtension3;
|
import org.eclipse.jface.text.IDocumentExtension3;
|
||||||
|
@ -23,6 +22,8 @@ import org.eclipse.jface.text.ITextSelection;
|
||||||
import org.eclipse.jface.text.ITypedRegion;
|
import org.eclipse.jface.text.ITypedRegion;
|
||||||
import org.eclipse.ui.texteditor.ITextEditor;
|
import org.eclipse.ui.texteditor.ITextEditor;
|
||||||
|
|
||||||
|
import org.eclipse.cdt.ui.text.ICPartitions;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Action that removes the enclosing comment marks from a Java block comment.
|
* Action that removes the enclosing comment marks from a Java block comment.
|
||||||
*
|
*
|
||||||
|
@ -59,7 +60,7 @@ public class RemoveBlockCommentAction extends BlockCommentAction {
|
||||||
|
|
||||||
while (partEndOffset < endOffset) {
|
while (partEndOffset < endOffset) {
|
||||||
|
|
||||||
if (partition.getType() == ICPartitions.C_MULTILINE_COMMENT) {
|
if (partition.getType() == ICPartitions.C_MULTI_LINE_COMMENT) {
|
||||||
edits.add(factory.createEdit(partOffset, tokenLength, "")); //$NON-NLS-1$
|
edits.add(factory.createEdit(partOffset, tokenLength, "")); //$NON-NLS-1$
|
||||||
edits.add(factory.createEdit(partEndOffset - tokenLength, tokenLength, "")); //$NON-NLS-1$
|
edits.add(factory.createEdit(partEndOffset - tokenLength, tokenLength, "")); //$NON-NLS-1$
|
||||||
}
|
}
|
||||||
|
@ -69,7 +70,7 @@ public class RemoveBlockCommentAction extends BlockCommentAction {
|
||||||
partEndOffset= partOffset + partition.getLength();
|
partEndOffset= partOffset + partition.getLength();
|
||||||
}
|
}
|
||||||
|
|
||||||
if (partition.getType() == ICPartitions.C_MULTILINE_COMMENT) {
|
if (partition.getType() == ICPartitions.C_MULTI_LINE_COMMENT) {
|
||||||
edits.add(factory.createEdit(partOffset, tokenLength, "")); //$NON-NLS-1$
|
edits.add(factory.createEdit(partOffset, tokenLength, "")); //$NON-NLS-1$
|
||||||
edits.add(factory.createEdit(partEndOffset - tokenLength, tokenLength, "")); //$NON-NLS-1$
|
edits.add(factory.createEdit(partEndOffset - tokenLength, tokenLength, "")); //$NON-NLS-1$
|
||||||
}
|
}
|
||||||
|
|
|
@ -129,6 +129,7 @@ import org.eclipse.cdt.ui.CUIPlugin;
|
||||||
import org.eclipse.cdt.ui.IWorkingCopyManager;
|
import org.eclipse.cdt.ui.IWorkingCopyManager;
|
||||||
import org.eclipse.cdt.ui.PreferenceConstants;
|
import org.eclipse.cdt.ui.PreferenceConstants;
|
||||||
import org.eclipse.cdt.ui.actions.ShowInCViewAction;
|
import org.eclipse.cdt.ui.actions.ShowInCViewAction;
|
||||||
|
import org.eclipse.cdt.ui.text.ICPartitions;
|
||||||
import org.eclipse.cdt.ui.text.folding.ICFoldingStructureProvider;
|
import org.eclipse.cdt.ui.text.folding.ICFoldingStructureProvider;
|
||||||
|
|
||||||
import org.eclipse.cdt.internal.ui.ICHelpContextIds;
|
import org.eclipse.cdt.internal.ui.ICHelpContextIds;
|
||||||
|
@ -149,7 +150,6 @@ import org.eclipse.cdt.internal.ui.text.CTextTools;
|
||||||
import org.eclipse.cdt.internal.ui.text.CWordIterator;
|
import org.eclipse.cdt.internal.ui.text.CWordIterator;
|
||||||
import org.eclipse.cdt.internal.ui.text.DocumentCharacterIterator;
|
import org.eclipse.cdt.internal.ui.text.DocumentCharacterIterator;
|
||||||
import org.eclipse.cdt.internal.ui.text.HTMLTextPresenter;
|
import org.eclipse.cdt.internal.ui.text.HTMLTextPresenter;
|
||||||
import org.eclipse.cdt.internal.ui.text.ICPartitions;
|
|
||||||
import org.eclipse.cdt.internal.ui.text.c.hover.SourceViewerInformationControl;
|
import org.eclipse.cdt.internal.ui.text.c.hover.SourceViewerInformationControl;
|
||||||
import org.eclipse.cdt.internal.ui.text.contentassist.ContentAssistPreference;
|
import org.eclipse.cdt.internal.ui.text.contentassist.ContentAssistPreference;
|
||||||
import org.eclipse.cdt.internal.ui.util.CUIHelp;
|
import org.eclipse.cdt.internal.ui.util.CUIHelp;
|
||||||
|
@ -1481,52 +1481,50 @@ public class CEditor extends TextEditor implements ISelectionChangedListener, IS
|
||||||
}
|
}
|
||||||
|
|
||||||
public void customizeDocumentCommand(IDocument document, DocumentCommand command) {
|
public void customizeDocumentCommand(IDocument document, DocumentCommand command) {
|
||||||
String text= command.text;
|
String text = command.text;
|
||||||
if (text == null)
|
if (text == null)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
int index= text.indexOf('\t');
|
int index = text.indexOf('\t');
|
||||||
if (index > -1) {
|
if (index > -1) {
|
||||||
|
StringBuffer buffer = new StringBuffer();
|
||||||
StringBuffer buffer= new StringBuffer();
|
|
||||||
|
|
||||||
fLineTracker.set(command.text);
|
fLineTracker.set(command.text);
|
||||||
int lines= fLineTracker.getNumberOfLines();
|
int lines = fLineTracker.getNumberOfLines();
|
||||||
|
|
||||||
try {
|
try {
|
||||||
|
for (int i = 0; i < lines; i++) {
|
||||||
|
int offset = fLineTracker.getLineOffset(i);
|
||||||
|
int endOffset = offset + fLineTracker.getLineLength(i);
|
||||||
|
String line = text.substring(offset, endOffset);
|
||||||
|
|
||||||
for (int i= 0; i < lines; i++) {
|
int position= 0;
|
||||||
|
if (i == 0) {
|
||||||
int offset= fLineTracker.getLineOffset(i);
|
IRegion firstLine = document.getLineInformationOfOffset(command.offset);
|
||||||
int endOffset= offset + fLineTracker.getLineLength(i);
|
position = command.offset - firstLine.getOffset();
|
||||||
String line= text.substring(offset, endOffset);
|
|
||||||
|
|
||||||
int position= 0;
|
|
||||||
if (i == 0) {
|
|
||||||
IRegion firstLine= document.getLineInformationOfOffset(command.offset);
|
|
||||||
position= command.offset - firstLine.getOffset();
|
|
||||||
}
|
|
||||||
|
|
||||||
int length= line.length();
|
|
||||||
for (int j= 0; j < length; j++) {
|
|
||||||
char c= line.charAt(j);
|
|
||||||
if (c == '\t') {
|
|
||||||
position += insertTabString(buffer, position);
|
|
||||||
} else {
|
|
||||||
buffer.append(c);
|
|
||||||
++ position;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
command.text= buffer.toString();
|
int length = line.length();
|
||||||
|
for (int j = 0; j < length; j++) {
|
||||||
|
char c = line.charAt(j);
|
||||||
|
if (c == '\t') {
|
||||||
|
int oldPosition = position;
|
||||||
|
position += insertTabString(buffer, position);
|
||||||
|
if (command.caretOffset > command.offset + oldPosition) {
|
||||||
|
command.caretOffset += position - oldPosition - 1;
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
buffer.append(c);
|
||||||
|
++position;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
command.text = buffer.toString();
|
||||||
} catch (BadLocationException x) {
|
} catch (BadLocationException x) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
|
|
|
@ -20,7 +20,7 @@ import org.eclipse.jface.text.rules.RuleBasedScanner;
|
||||||
import org.eclipse.jface.text.source.ISourceViewer;
|
import org.eclipse.jface.text.source.ISourceViewer;
|
||||||
import org.eclipse.ui.editors.text.TextSourceViewerConfiguration;
|
import org.eclipse.ui.editors.text.TextSourceViewerConfiguration;
|
||||||
|
|
||||||
import org.eclipse.cdt.internal.ui.text.ICPartitions;
|
import org.eclipse.cdt.ui.text.ICPartitions;
|
||||||
|
|
||||||
|
|
||||||
public class AsmSourceViewerConfiguration extends TextSourceViewerConfiguration {
|
public class AsmSourceViewerConfiguration extends TextSourceViewerConfiguration {
|
||||||
|
@ -83,8 +83,8 @@ public class AsmSourceViewerConfiguration extends TextSourceViewerConfiguration
|
||||||
reconciler.setRepairer(dr, IDocument.DEFAULT_CONTENT_TYPE);
|
reconciler.setRepairer(dr, IDocument.DEFAULT_CONTENT_TYPE);
|
||||||
|
|
||||||
dr= new DefaultDamagerRepairer(getMultilineCommentScanner());
|
dr= new DefaultDamagerRepairer(getMultilineCommentScanner());
|
||||||
reconciler.setDamager(dr, ICPartitions.C_MULTILINE_COMMENT);
|
reconciler.setDamager(dr, ICPartitions.C_MULTI_LINE_COMMENT);
|
||||||
reconciler.setRepairer(dr, ICPartitions.C_MULTILINE_COMMENT);
|
reconciler.setRepairer(dr, ICPartitions.C_MULTI_LINE_COMMENT);
|
||||||
|
|
||||||
dr= new DefaultDamagerRepairer(getSinglelineCommentScanner());
|
dr= new DefaultDamagerRepairer(getSinglelineCommentScanner());
|
||||||
reconciler.setDamager(dr, ICPartitions.C_SINGLE_LINE_COMMENT);
|
reconciler.setDamager(dr, ICPartitions.C_SINGLE_LINE_COMMENT);
|
||||||
|
@ -108,7 +108,7 @@ public class AsmSourceViewerConfiguration extends TextSourceViewerConfiguration
|
||||||
public String[] getConfiguredContentTypes(ISourceViewer sourceViewer) {
|
public String[] getConfiguredContentTypes(ISourceViewer sourceViewer) {
|
||||||
return new String[] {
|
return new String[] {
|
||||||
IDocument.DEFAULT_CONTENT_TYPE,
|
IDocument.DEFAULT_CONTENT_TYPE,
|
||||||
ICPartitions.C_MULTILINE_COMMENT,
|
ICPartitions.C_MULTI_LINE_COMMENT,
|
||||||
ICPartitions.C_SINGLE_LINE_COMMENT,
|
ICPartitions.C_SINGLE_LINE_COMMENT,
|
||||||
ICPartitions.C_STRING,
|
ICPartitions.C_STRING,
|
||||||
ICPartitions.C_CHARACTER };
|
ICPartitions.C_CHARACTER };
|
||||||
|
|
|
@ -9,33 +9,66 @@
|
||||||
* IBM Corporation - initial API and implementation
|
* IBM Corporation - initial API and implementation
|
||||||
* QNX Software System
|
* QNX Software System
|
||||||
* Anton Leherbauer (Wind River Systems) - Fixed bug 48339
|
* Anton Leherbauer (Wind River Systems) - Fixed bug 48339
|
||||||
|
* Sergey Prigogin, Google
|
||||||
*******************************************************************************/
|
*******************************************************************************/
|
||||||
package org.eclipse.cdt.internal.ui.text;
|
package org.eclipse.cdt.internal.ui.text;
|
||||||
|
|
||||||
|
import org.eclipse.jface.preference.IPreferenceStore;
|
||||||
import org.eclipse.jface.text.BadLocationException;
|
import org.eclipse.jface.text.BadLocationException;
|
||||||
import org.eclipse.jface.text.DefaultIndentLineAutoEditStrategy;
|
import org.eclipse.jface.text.DefaultIndentLineAutoEditStrategy;
|
||||||
import org.eclipse.jface.text.DocumentCommand;
|
import org.eclipse.jface.text.DocumentCommand;
|
||||||
import org.eclipse.jface.text.IDocument;
|
import org.eclipse.jface.text.IDocument;
|
||||||
|
import org.eclipse.jface.text.IRegion;
|
||||||
|
import org.eclipse.jface.text.TextUtilities;
|
||||||
|
import org.eclipse.ui.IEditorPart;
|
||||||
|
import org.eclipse.ui.IWorkbenchPage;
|
||||||
|
import org.eclipse.ui.texteditor.ITextEditorExtension3;
|
||||||
|
|
||||||
|
import org.eclipse.cdt.core.model.ICProject;
|
||||||
import org.eclipse.cdt.ui.CUIPlugin;
|
import org.eclipse.cdt.ui.CUIPlugin;
|
||||||
|
import org.eclipse.cdt.ui.PreferenceConstants;
|
||||||
|
import org.eclipse.cdt.ui.text.ICPartitions;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Auto indent strategy sensitive to brackets.
|
* Auto indent strategy sensitive to brackets.
|
||||||
*/
|
*/
|
||||||
public class CAutoIndentStrategy extends DefaultIndentLineAutoEditStrategy {
|
public class CAutoIndentStrategy extends DefaultIndentLineAutoEditStrategy {
|
||||||
|
private static final String MULTILINE_COMMENT_CLOSE = "*/"; //$NON-NLS-1$
|
||||||
|
// private static final GCCScannerExtensionConfiguration C_GNU_SCANNER_EXTENSION = new GCCScannerExtensionConfiguration();
|
||||||
|
|
||||||
private final static String MULTILINE_COMMENT_CLOSE = "*/"; //$NON-NLS-1$
|
private static class CompilationUnitInfo {
|
||||||
|
char[] buffer;
|
||||||
|
int delta;
|
||||||
|
|
||||||
public CAutoIndentStrategy() {
|
CompilationUnitInfo(char[] buffer, int delta) {
|
||||||
|
this.buffer = buffer;
|
||||||
|
this.delta = delta;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private boolean fCloseBrace;
|
||||||
|
private boolean fIsSmartMode;
|
||||||
|
|
||||||
|
private String fPartitioning;
|
||||||
|
private final ICProject fProject;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Creates a new C auto indent strategy for the given document partitioning.
|
||||||
|
*
|
||||||
|
* @param partitioning the document partitioning
|
||||||
|
* @param project the project to get formatting preferences from, or null to use default preferences
|
||||||
|
*/
|
||||||
|
public CAutoIndentStrategy(String partitioning, ICProject project) {
|
||||||
|
fPartitioning = partitioning;
|
||||||
|
fProject = project;
|
||||||
|
}
|
||||||
|
|
||||||
// evaluate the line with the opening bracket that matches the closing bracket on the given line
|
// evaluate the line with the opening bracket that matches the closing bracket on the given line
|
||||||
protected int findMatchingOpenBracket(IDocument d, int line, int end, int closingBracketIncrease) throws BadLocationException {
|
protected int findMatchingOpenBracket(IDocument d, int line, int end, int closingBracketIncrease) throws BadLocationException {
|
||||||
|
|
||||||
|
|
||||||
int start= d.getLineOffset(line);
|
int start = d.getLineOffset(line);
|
||||||
int brackcount= getBracketCount(d, start, end, false) - closingBracketIncrease;
|
int brackcount = getBracketCount(d, start, end, false) - closingBracketIncrease;
|
||||||
|
|
||||||
|
|
||||||
// sum up the brackets counts of each line (closing brackets count negative,
|
// sum up the brackets counts of each line (closing brackets count negative,
|
||||||
|
@ -45,8 +78,8 @@ public class CAutoIndentStrategy extends DefaultIndentLineAutoEditStrategy {
|
||||||
if (line < 0) {
|
if (line < 0) {
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
start= d.getLineOffset(line);
|
start = d.getLineOffset(line);
|
||||||
end= start + d.getLineLength(line) - 1;
|
end = start + d.getLineLength(line) - 1;
|
||||||
brackcount += getBracketCount(d, start, end, false);
|
brackcount += getBracketCount(d, start, end, false);
|
||||||
}
|
}
|
||||||
return line;
|
return line;
|
||||||
|
@ -54,36 +87,36 @@ public class CAutoIndentStrategy extends DefaultIndentLineAutoEditStrategy {
|
||||||
|
|
||||||
|
|
||||||
private int getBracketCount(IDocument d, int start, int end, boolean ignoreCloseBrackets) throws BadLocationException {
|
private int getBracketCount(IDocument d, int start, int end, boolean ignoreCloseBrackets) throws BadLocationException {
|
||||||
int bracketcount= 0;
|
int bracketcount = 0;
|
||||||
while (start < end) {
|
while (start < end) {
|
||||||
char curr= d.getChar(start);
|
char curr = d.getChar(start);
|
||||||
start++;
|
start++;
|
||||||
switch (curr) {
|
switch (curr) {
|
||||||
case '/' :
|
case '/' :
|
||||||
if (start < end) {
|
if (start < end) {
|
||||||
char next= d.getChar(start);
|
char next = d.getChar(start);
|
||||||
if (next == '*') {
|
if (next == '*') {
|
||||||
// a comment starts, advance to the comment end
|
// a comment starts, advance to the comment end
|
||||||
start= getCommentEnd(d, start + 1, end);
|
start = getCommentEnd(d, start + 1, end);
|
||||||
} else if (next == '/') {
|
} else if (next == '/') {
|
||||||
// '//'-comment: nothing to do anymore on this line
|
// '//'-comment: nothing to do anymore on this line
|
||||||
start= end;
|
start = end;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
case '*' :
|
case '*' :
|
||||||
if (start < end) {
|
if (start < end) {
|
||||||
char next= d.getChar(start);
|
char next = d.getChar(start);
|
||||||
if (next == '/') {
|
if (next == '/') {
|
||||||
// we have been in a comment: forget what we read before
|
// we have been in a comment: forget what we read before
|
||||||
bracketcount= 0;
|
bracketcount = 0;
|
||||||
start++;
|
start++;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
case '{' :
|
case '{' :
|
||||||
bracketcount++;
|
bracketcount++;
|
||||||
ignoreCloseBrackets= false;
|
ignoreCloseBrackets = false;
|
||||||
break;
|
break;
|
||||||
case '}' :
|
case '}' :
|
||||||
if (!ignoreCloseBrackets) {
|
if (!ignoreCloseBrackets) {
|
||||||
|
@ -92,7 +125,7 @@ public class CAutoIndentStrategy extends DefaultIndentLineAutoEditStrategy {
|
||||||
break;
|
break;
|
||||||
case '"' :
|
case '"' :
|
||||||
case '\'' :
|
case '\'' :
|
||||||
start= getStringEnd(d, start, end, curr);
|
start = getStringEnd(d, start, end, curr);
|
||||||
break;
|
break;
|
||||||
default :
|
default :
|
||||||
}
|
}
|
||||||
|
@ -105,7 +138,7 @@ public class CAutoIndentStrategy extends DefaultIndentLineAutoEditStrategy {
|
||||||
|
|
||||||
private int getCommentEnd(IDocument d, int pos, int end) throws BadLocationException {
|
private int getCommentEnd(IDocument d, int pos, int end) throws BadLocationException {
|
||||||
while (pos < end) {
|
while (pos < end) {
|
||||||
char curr= d.getChar(pos);
|
char curr = d.getChar(pos);
|
||||||
pos++;
|
pos++;
|
||||||
if (curr == '*') {
|
if (curr == '*') {
|
||||||
if (pos < end && d.getChar(pos) == '/') {
|
if (pos < end && d.getChar(pos) == '/') {
|
||||||
|
@ -118,9 +151,9 @@ public class CAutoIndentStrategy extends DefaultIndentLineAutoEditStrategy {
|
||||||
|
|
||||||
protected String getIndentOfLine(IDocument d, int line) throws BadLocationException {
|
protected String getIndentOfLine(IDocument d, int line) throws BadLocationException {
|
||||||
if (line > -1) {
|
if (line > -1) {
|
||||||
int start= d.getLineOffset(line);
|
int start = d.getLineOffset(line);
|
||||||
int end= start + d.getLineLength(line) - 1;
|
int end = start + d.getLineLength(line) - 1;
|
||||||
int whiteend= findEndOfWhiteSpace(d, start, end);
|
int whiteend = findEndOfWhiteSpace(d, start, end);
|
||||||
return d.get(start, whiteend - start);
|
return d.get(start, whiteend - start);
|
||||||
}
|
}
|
||||||
return ""; //$NON-NLS-1$
|
return ""; //$NON-NLS-1$
|
||||||
|
@ -128,7 +161,7 @@ public class CAutoIndentStrategy extends DefaultIndentLineAutoEditStrategy {
|
||||||
|
|
||||||
private int getStringEnd(IDocument d, int pos, int end, char ch) throws BadLocationException {
|
private int getStringEnd(IDocument d, int pos, int end, char ch) throws BadLocationException {
|
||||||
while (pos < end) {
|
while (pos < end) {
|
||||||
char curr= d.getChar(pos);
|
char curr = d.getChar(pos);
|
||||||
pos++;
|
pos++;
|
||||||
if (curr == '\\') {
|
if (curr == '\\') {
|
||||||
// ignore escaped characters
|
// ignore escaped characters
|
||||||
|
@ -145,26 +178,26 @@ public class CAutoIndentStrategy extends DefaultIndentLineAutoEditStrategy {
|
||||||
return;
|
return;
|
||||||
|
|
||||||
try {
|
try {
|
||||||
int p= (c.offset == d.getLength() ? c.offset - 1 : c.offset);
|
int p = (c.offset == d.getLength() ? c.offset - 1 : c.offset);
|
||||||
int line= d.getLineOfOffset(p);
|
int line = d.getLineOfOffset(p);
|
||||||
int start= d.getLineOffset(line);
|
int start = d.getLineOffset(line);
|
||||||
int whiteend= findEndOfWhiteSpace(d, start, c.offset);
|
int whiteend = findEndOfWhiteSpace(d, start, c.offset);
|
||||||
|
|
||||||
|
|
||||||
// shift only when line does not contain any text up to the closing bracket
|
// shift only when line does not contain any text up to the closing bracket
|
||||||
if (whiteend == c.offset) {
|
if (whiteend == c.offset) {
|
||||||
// evaluate the line with the opening bracket that matches out closing bracket
|
// evaluate the line with the opening bracket that matches out closing bracket
|
||||||
int indLine= findMatchingOpenBracket(d, line, c.offset, 1);
|
int indLine = findMatchingOpenBracket(d, line, c.offset, 1);
|
||||||
if (indLine != -1 && indLine != line) {
|
if (indLine != -1 && indLine != line) {
|
||||||
// take the indent of the found line
|
// take the indent of the found line
|
||||||
StringBuffer replaceText= new StringBuffer(getIndentOfLine(d, indLine));
|
StringBuffer replaceText = new StringBuffer(getIndentOfLine(d, indLine));
|
||||||
// add the rest of the current line including the just added close bracket
|
// add the rest of the current line including the just added close bracket
|
||||||
replaceText.append(d.get(whiteend, c.offset - whiteend));
|
replaceText.append(d.get(whiteend, c.offset - whiteend));
|
||||||
replaceText.append(c.text);
|
replaceText.append(c.text);
|
||||||
// modify document command
|
// modify document command
|
||||||
c.length= c.offset - start;
|
c.length = c.offset - start;
|
||||||
c.offset= start;
|
c.offset = start;
|
||||||
c.text= replaceText.toString();
|
c.text = replaceText.toString();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
} catch (BadLocationException excp) {
|
} catch (BadLocationException excp) {
|
||||||
|
@ -172,69 +205,453 @@ public class CAutoIndentStrategy extends DefaultIndentLineAutoEditStrategy {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
protected void smartIndentAfterNewLine(IDocument d, DocumentCommand c) {
|
private void smartIndentAfterClosingBracket(IDocument d, DocumentCommand c) {
|
||||||
int docLength= d.getLength();
|
if (c.offset == -1 || d.getLength() == 0)
|
||||||
|
return;
|
||||||
|
|
||||||
|
try {
|
||||||
|
int p = (c.offset == d.getLength() ? c.offset - 1 : c.offset);
|
||||||
|
int line = d.getLineOfOffset(p);
|
||||||
|
int start = d.getLineOffset(line);
|
||||||
|
int whiteend = findEndOfWhiteSpace(d, start, c.offset);
|
||||||
|
|
||||||
|
CHeuristicScanner scanner = new CHeuristicScanner(d);
|
||||||
|
CIndenter indenter = new CIndenter(d, scanner, fProject);
|
||||||
|
|
||||||
|
// shift only when line does not contain any text up to the closing bracket
|
||||||
|
if (whiteend == c.offset) {
|
||||||
|
// evaluate the line with the opening bracket that matches out closing bracket
|
||||||
|
int reference = indenter.findReferencePosition(c.offset, false, true, false, false);
|
||||||
|
int indLine = d.getLineOfOffset(reference);
|
||||||
|
if (indLine != -1 && indLine != line) {
|
||||||
|
// take the indent of the found line
|
||||||
|
StringBuffer replaceText = new StringBuffer(getIndentOfLine(d, indLine));
|
||||||
|
// add the rest of the current line including the just added close bracket
|
||||||
|
replaceText.append(d.get(whiteend, c.offset - whiteend));
|
||||||
|
replaceText.append(c.text);
|
||||||
|
// modify document command
|
||||||
|
c.length += c.offset - start;
|
||||||
|
c.offset = start;
|
||||||
|
c.text = replaceText.toString();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} catch (BadLocationException e) {
|
||||||
|
CUIPlugin.getDefault().log(e);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private void smartIndentAfterOpeningBracket(IDocument d, DocumentCommand c) {
|
||||||
|
if (c.offset < 1 || d.getLength() == 0)
|
||||||
|
return;
|
||||||
|
|
||||||
|
CHeuristicScanner scanner = new CHeuristicScanner(d);
|
||||||
|
|
||||||
|
int p = (c.offset == d.getLength() ? c.offset - 1 : c.offset);
|
||||||
|
|
||||||
|
try {
|
||||||
|
// current line
|
||||||
|
int line = d.getLineOfOffset(p);
|
||||||
|
int lineOffset = d.getLineOffset(line);
|
||||||
|
|
||||||
|
// make sure we don't have any leading comments etc.
|
||||||
|
if (d.get(lineOffset, p - lineOffset).trim().length() != 0)
|
||||||
|
return;
|
||||||
|
|
||||||
|
// line of last javacode
|
||||||
|
int pos = scanner.findNonWhitespaceBackward(p, CHeuristicScanner.UNBOUND);
|
||||||
|
if (pos == -1)
|
||||||
|
return;
|
||||||
|
int lastLine = d.getLineOfOffset(pos);
|
||||||
|
|
||||||
|
// only shift if the last java line is further up and is a braceless block candidate
|
||||||
|
if (lastLine < line) {
|
||||||
|
CIndenter indenter = new CIndenter(d, scanner, fProject);
|
||||||
|
StringBuffer indent = indenter.computeIndentation(p, true);
|
||||||
|
String toDelete = d.get(lineOffset, c.offset - lineOffset);
|
||||||
|
if (indent != null && !indent.toString().equals(toDelete)) {
|
||||||
|
c.text = indent.append(c.text).toString();
|
||||||
|
c.length += c.offset - lineOffset;
|
||||||
|
c.offset = lineOffset;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
} catch (BadLocationException e) {
|
||||||
|
CUIPlugin.getDefault().log(e);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private void smartIndentAfterNewLine(IDocument d, DocumentCommand c) {
|
||||||
|
CHeuristicScanner scanner = new CHeuristicScanner(d);
|
||||||
|
CIndenter indenter = new CIndenter(d, scanner, fProject);
|
||||||
|
StringBuffer indent = indenter.computeIndentation(c.offset);
|
||||||
|
if (indent == null)
|
||||||
|
indent = new StringBuffer();
|
||||||
|
|
||||||
|
int docLength = d.getLength();
|
||||||
if (c.offset == -1 || docLength == 0)
|
if (c.offset == -1 || docLength == 0)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
try {
|
try {
|
||||||
int p= (c.offset == docLength ? c.offset - 1 : c.offset);
|
int p = (c.offset == docLength ? c.offset - 1 : c.offset);
|
||||||
int line= d.getLineOfOffset(p);
|
int line = d.getLineOfOffset(p);
|
||||||
|
|
||||||
|
StringBuffer buf = new StringBuffer(c.text + indent);
|
||||||
|
|
||||||
StringBuffer buf= new StringBuffer(c.text);
|
IRegion reg = d.getLineInformation(line);
|
||||||
if (c.offset < docLength && d.getChar(c.offset) == '}') {
|
int lineEnd = reg.getOffset() + reg.getLength();
|
||||||
int indLine= findMatchingOpenBracket(d, line, c.offset, 0);
|
|
||||||
if (indLine == -1) {
|
int contentStart = findEndOfWhiteSpace(d, c.offset, lineEnd);
|
||||||
indLine= line;
|
c.length = Math.max(contentStart - c.offset, 0);
|
||||||
|
|
||||||
|
int start = reg.getOffset();
|
||||||
|
|
||||||
|
// insert closing brace on new line after an unclosed opening brace
|
||||||
|
if (getBracketCount(d, start, c.offset, true) > 0 && fCloseBrace && !isClosedBrace(d, c.offset, c.length)) {
|
||||||
|
c.caretOffset = c.offset + buf.length();
|
||||||
|
c.shiftsCaret = false;
|
||||||
|
|
||||||
|
// copy old content of line behind insertion point to new line
|
||||||
|
// unless we think we are inserting an anonymous type definition
|
||||||
|
if (c.offset == 0 || !(computeAnonymousPosition(d, c.offset - 1, fPartitioning, lineEnd) != -1)) {
|
||||||
|
if (lineEnd - contentStart > 0) {
|
||||||
|
c.length = lineEnd - c.offset;
|
||||||
|
buf.append(d.get(contentStart, lineEnd - contentStart).toCharArray());
|
||||||
|
}
|
||||||
}
|
}
|
||||||
buf.append(getIndentOfLine(d, indLine));
|
|
||||||
} else {
|
buf.append(TextUtilities.getDefaultLineDelimiter(d));
|
||||||
int start= d.getLineOffset(line);
|
StringBuffer reference = null;
|
||||||
int whiteend= findEndOfWhiteSpace(d, start, c.offset);
|
int nonWS = findEndOfWhiteSpace(d, start, lineEnd);
|
||||||
buf.append(d.get(start, whiteend - start));
|
if (nonWS < c.offset && d.getChar(nonWS) == '{')
|
||||||
if (getBracketCount(d, start, c.offset, true) > 0) {
|
reference = new StringBuffer(d.get(start, nonWS - start));
|
||||||
buf.append('\t');
|
else
|
||||||
|
reference = indenter.getReferenceIndentation(c.offset);
|
||||||
|
if (reference != null)
|
||||||
|
buf.append(reference);
|
||||||
|
buf.append('}');
|
||||||
|
}
|
||||||
|
// insert extra line upon new line between two braces
|
||||||
|
else if (c.offset > start && contentStart < lineEnd && d.getChar(contentStart) == '}') {
|
||||||
|
int firstCharPos = scanner.findNonWhitespaceBackward(c.offset - 1, start);
|
||||||
|
if (firstCharPos != CHeuristicScanner.NOT_FOUND && d.getChar(firstCharPos) == '{') {
|
||||||
|
c.caretOffset = c.offset + buf.length();
|
||||||
|
c.shiftsCaret = false;
|
||||||
|
|
||||||
|
StringBuffer reference = null;
|
||||||
|
int nonWS = findEndOfWhiteSpace(d, start, lineEnd);
|
||||||
|
if (nonWS < c.offset && d.getChar(nonWS) == '{')
|
||||||
|
reference = new StringBuffer(d.get(start, nonWS - start));
|
||||||
|
else
|
||||||
|
reference = indenter.getReferenceIndentation(c.offset);
|
||||||
|
|
||||||
|
buf.append(TextUtilities.getDefaultLineDelimiter(d));
|
||||||
|
|
||||||
|
if (reference != null)
|
||||||
|
buf.append(reference);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
c.text= buf.toString();
|
c.text = buf.toString();
|
||||||
|
|
||||||
|
} catch (BadLocationException e) {
|
||||||
} catch (BadLocationException excp) {
|
CUIPlugin.getDefault().log(e);
|
||||||
CUIPlugin.getDefault().log(excp);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Returns whether the text ends with one of the given search strings.
|
* Computes an insert position for an opening brace if <code>offset</code> maps to a position in
|
||||||
|
* <code>document</code> with a expression in parenthesis that will take a block after the closing parenthesis.
|
||||||
|
*
|
||||||
|
* @param document the document being modified
|
||||||
|
* @param offset the offset of the caret position, relative to the line start.
|
||||||
|
* @param partitioning the document partitioning
|
||||||
|
* @param max the max position
|
||||||
|
* @return an insert position relative to the line start if <code>line</code> contains a parenthesized expression that can be followed by a block, -1 otherwise
|
||||||
*/
|
*/
|
||||||
private boolean endsWithDelimiter(IDocument d, String txt) {
|
private static int computeAnonymousPosition(IDocument document, int offset, String partitioning, int max) {
|
||||||
String[] delimiters= d.getLegalLineDelimiters();
|
// find the opening parenthesis for every closing parenthesis on the current line after offset
|
||||||
|
// return the position behind the closing parenthesis if it looks like a method declaration
|
||||||
for (int i= 0; i < delimiters.length; i++) {
|
// or an expression for an if, while, for, catch statement
|
||||||
if (txt.endsWith(delimiters[i]))
|
|
||||||
return true;
|
CHeuristicScanner scanner = new CHeuristicScanner(document);
|
||||||
|
int pos = offset;
|
||||||
|
int length = max;
|
||||||
|
int scanTo = scanner.scanForward(pos, length, '}');
|
||||||
|
if (scanTo == -1)
|
||||||
|
scanTo = length;
|
||||||
|
|
||||||
|
int closingParen = findClosingParenToLeft(scanner, pos) - 1;
|
||||||
|
|
||||||
|
while (true) {
|
||||||
|
int startScan = closingParen + 1;
|
||||||
|
closingParen = scanner.scanForward(startScan, scanTo, ')');
|
||||||
|
if (closingParen == -1)
|
||||||
|
break;
|
||||||
|
|
||||||
|
int openingParen = scanner.findOpeningPeer(closingParen - 1, '(', ')');
|
||||||
|
|
||||||
|
// no way an expression at the beginning of the document can mean anything
|
||||||
|
if (openingParen < 1)
|
||||||
|
break;
|
||||||
|
|
||||||
|
// only select insert positions for parenthesis currently embracing the caret
|
||||||
|
if (openingParen > pos)
|
||||||
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Finds a closing parenthesis to the left of <code>position</code> in document, where that parenthesis is only
|
||||||
|
* separated by whitespace from <code>position</code>. If no such parenthesis can be found, <code>position</code> is returned.
|
||||||
|
*
|
||||||
|
* @param scanner the java heuristic scanner set up on the document
|
||||||
|
* @param position the first character position in <code>document</code> to be considered
|
||||||
|
* @return the position of a closing parenthesis left to <code>position</code> separated only by whitespace, or <code>position</code> if no parenthesis can be found
|
||||||
|
*/
|
||||||
|
private static int findClosingParenToLeft(CHeuristicScanner scanner, int position) {
|
||||||
|
if (position < 1)
|
||||||
|
return position;
|
||||||
|
|
||||||
|
if (scanner.previousToken(position - 1, CHeuristicScanner.UNBOUND) == Symbols.TokenRPAREN)
|
||||||
|
return scanner.getPosition() + 1;
|
||||||
|
return position;
|
||||||
|
}
|
||||||
|
|
||||||
|
private boolean isClosedBrace(IDocument document, int offset, int length) {
|
||||||
|
CompilationUnitInfo info = getCompilationUnitForMethod(document, offset, fPartitioning);
|
||||||
|
if (info == null)
|
||||||
|
return false;
|
||||||
|
|
||||||
|
return getBlockBalance(document, offset, fPartitioning) <= 0;
|
||||||
|
//TODO: Use smarter algorithm based on
|
||||||
|
// CodeReader reader = new CodeReader(info.buffer);
|
||||||
|
// ICodeReaderFactory fileCreator = CDOM.getInstance().getCodeReaderFactory(CDOM.PARSE_WORKING_COPY_WHENEVER_POSSIBLE);
|
||||||
|
//
|
||||||
|
// IScanner domScanner = new DOMScanner(reader, new ScannerInfo(), ParserMode.COMPLETE_PARSE,
|
||||||
|
// ParserLanguage.C, ParserFactory.createDefaultLogService(),
|
||||||
|
// C_GNU_SCANNER_EXTENSION, fileCreator);
|
||||||
|
//
|
||||||
|
// ISourceCodeParser parser = new GNUCPPSourceParser(
|
||||||
|
// domScanner,
|
||||||
|
// ParserMode.COMPLETE_PARSE,
|
||||||
|
// ParserUtil.getParserLogService(),
|
||||||
|
// new GPPParserExtensionConfiguration());
|
||||||
|
//
|
||||||
|
// IASTTranslationUnit translationUnit = parser.parse();
|
||||||
|
// final int relativeOffset = offset - info.delta;
|
||||||
|
// IASTNode node = translationUnit.selectNodeForLocation(reader.getPath(), relativeOffset, length);
|
||||||
|
//
|
||||||
|
// if (node == null)
|
||||||
|
// return false;
|
||||||
|
//
|
||||||
|
// if (node instanceof IASTCompoundStatement) {
|
||||||
|
// return getBlockBalance(document, offset, fPartitioning) <= 0;
|
||||||
|
// } else if (node instanceof IASTIfStatement) {
|
||||||
|
// IASTIfStatement ifStatement = (IASTIfStatement) node;
|
||||||
|
// IASTExpression expression = ifStatement.getConditionExpression();
|
||||||
|
// IRegion expressionRegion = createRegion(expression, info.delta);
|
||||||
|
// IASTStatement thenStatement = ifStatement.getThenClause();
|
||||||
|
// IRegion thenRegion = createRegion(thenStatement, info.delta);
|
||||||
|
//
|
||||||
|
// // Between expression and then statement
|
||||||
|
// if (expressionRegion.getOffset() + expressionRegion.getLength() <= offset && offset + length <= thenRegion.getOffset())
|
||||||
|
// return thenStatement != null;
|
||||||
|
//
|
||||||
|
// IASTStatement elseStatement = ifStatement.getElseClause();
|
||||||
|
// IRegion elseRegion = createRegion(elseStatement, info.delta);
|
||||||
|
//
|
||||||
|
// if (elseStatement != null) {
|
||||||
|
// int sourceOffset = thenRegion.getOffset() + thenRegion.getLength();
|
||||||
|
// int sourceLength = elseRegion.getOffset() - sourceOffset;
|
||||||
|
// CHeuristicScanner scanner = new CHeuristicScanner(new SimpleDocument(info.buffer));
|
||||||
|
// int pos = sourceOffset;
|
||||||
|
// int id;
|
||||||
|
// while ((id = scanner.nextToken(pos, sourceOffset + sourceLength - pos)) != CHeuristicScanner.TokenEOF) {
|
||||||
|
// if (id == CHeuristicScanner.TokenELSE) {
|
||||||
|
// pos = scanner.getPosition();
|
||||||
|
// // Between 'else' token and else statement.
|
||||||
|
// return pos <= offset && offset + length < elseRegion.getOffset();
|
||||||
|
// }
|
||||||
|
// }
|
||||||
|
//
|
||||||
|
// return true;
|
||||||
|
// }
|
||||||
|
// } else if (node instanceof IASTForStatement) {
|
||||||
|
// IASTExpression expression = ((IASTForStatement) node).getConditionExpression();
|
||||||
|
// IRegion expressionRegion = createRegion(expression, info.delta);
|
||||||
|
// IASTStatement body = ((IASTForStatement) node).getBody();
|
||||||
|
// IRegion bodyRegion = createRegion(body, info.delta);
|
||||||
|
//
|
||||||
|
// // Between expression and body statement
|
||||||
|
// if (expressionRegion.getOffset() + expressionRegion.getLength() <= offset && offset + length <= bodyRegion.getOffset()) {
|
||||||
|
// return body != null;
|
||||||
|
// }
|
||||||
|
// } else if (node instanceof IASTWhileStatement) {
|
||||||
|
// IASTExpression expression = ((IASTWhileStatement) node).getCondition();
|
||||||
|
// IRegion expressionRegion = createRegion(expression, info.delta);
|
||||||
|
// IASTStatement body = ((IASTWhileStatement) node).getBody();
|
||||||
|
// IRegion bodyRegion = createRegion(body, info.delta);
|
||||||
|
//
|
||||||
|
// // Between expression and body statement
|
||||||
|
// if (expressionRegion.getOffset() + expressionRegion.getLength() <= offset && offset + length <= bodyRegion.getOffset()) {
|
||||||
|
// return body != null;
|
||||||
|
// }
|
||||||
|
// } else if (node instanceof IASTDoStatement) {
|
||||||
|
// IASTDoStatement doStatement = (IASTDoStatement) node;
|
||||||
|
// IRegion doRegion = createRegion(doStatement, info.delta);
|
||||||
|
// IASTStatement body = doStatement.getBody();
|
||||||
|
// IRegion bodyRegion = createRegion(body, info.delta);
|
||||||
|
//
|
||||||
|
// // Between 'do' and body statement.
|
||||||
|
// if (doRegion.getOffset() + doRegion.getLength() <= offset && offset + length <= bodyRegion.getOffset()) {
|
||||||
|
// return body != null;
|
||||||
|
// }
|
||||||
|
// }
|
||||||
|
//
|
||||||
|
// return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
private boolean isLineDelimiter(IDocument document, String text) {
|
||||||
|
String[] delimiters = document.getLegalLineDelimiters();
|
||||||
|
if (delimiters != null)
|
||||||
|
return TextUtilities.equals(delimiters, text) > -1;
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private void smartIndentOnKeypress(IDocument document, DocumentCommand command) {
|
||||||
|
switch (command.text.charAt(0)) {
|
||||||
|
case '}':
|
||||||
|
smartIndentAfterClosingBracket(document, command);
|
||||||
|
break;
|
||||||
|
case '{':
|
||||||
|
smartIndentAfterOpeningBracket(document, command);
|
||||||
|
break;
|
||||||
|
case 'e':
|
||||||
|
smartIndentUponE(document, command);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private void smartIndentUponE(IDocument d, DocumentCommand c) {
|
||||||
|
if (c.offset < 4 || d.getLength() == 0)
|
||||||
|
return;
|
||||||
|
|
||||||
|
try {
|
||||||
|
String content = d.get(c.offset - 3, 3);
|
||||||
|
if (content.equals("els")) { //$NON-NLS-1$
|
||||||
|
CHeuristicScanner scanner = new CHeuristicScanner(d);
|
||||||
|
int p = c.offset - 3;
|
||||||
|
|
||||||
|
// current line
|
||||||
|
int line = d.getLineOfOffset(p);
|
||||||
|
int lineOffset = d.getLineOffset(line);
|
||||||
|
|
||||||
|
// make sure we don't have any leading comments etc.
|
||||||
|
if (d.get(lineOffset, p - lineOffset).trim().length() != 0)
|
||||||
|
return;
|
||||||
|
|
||||||
|
// line of last javacode
|
||||||
|
int pos = scanner.findNonWhitespaceBackward(p - 1, CHeuristicScanner.UNBOUND);
|
||||||
|
if (pos == -1)
|
||||||
|
return;
|
||||||
|
int lastLine = d.getLineOfOffset(pos);
|
||||||
|
|
||||||
|
// only shift if the last java line is further up and is a braceless block candidate
|
||||||
|
if (lastLine < line) {
|
||||||
|
|
||||||
|
CIndenter indenter = new CIndenter(d, scanner, fProject);
|
||||||
|
int ref = indenter.findReferencePosition(p, true, false, false, false);
|
||||||
|
if (ref == CHeuristicScanner.NOT_FOUND)
|
||||||
|
return;
|
||||||
|
int refLine = d.getLineOfOffset(ref);
|
||||||
|
String indent = getIndentOfLine(d, refLine);
|
||||||
|
|
||||||
|
if (indent != null) {
|
||||||
|
c.text = indent.toString() + "else"; //$NON-NLS-1$
|
||||||
|
c.length += c.offset - lineOffset;
|
||||||
|
c.offset = lineOffset;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (content.equals("cas")) { //$NON-NLS-1$
|
||||||
|
CHeuristicScanner scanner = new CHeuristicScanner(d);
|
||||||
|
int p = c.offset - 3;
|
||||||
|
|
||||||
|
// current line
|
||||||
|
int line = d.getLineOfOffset(p);
|
||||||
|
int lineOffset = d.getLineOffset(line);
|
||||||
|
|
||||||
|
// make sure we don't have any leading comments etc.
|
||||||
|
if (d.get(lineOffset, p - lineOffset).trim().length() != 0)
|
||||||
|
return;
|
||||||
|
|
||||||
|
// line of last javacode
|
||||||
|
int pos = scanner.findNonWhitespaceBackward(p - 1, CHeuristicScanner.UNBOUND);
|
||||||
|
if (pos == -1)
|
||||||
|
return;
|
||||||
|
int lastLine = d.getLineOfOffset(pos);
|
||||||
|
|
||||||
|
// only shift if the last java line is further up and is a braceless block candidate
|
||||||
|
if (lastLine < line) {
|
||||||
|
|
||||||
|
CIndenter indenter = new CIndenter(d, scanner, fProject);
|
||||||
|
int ref = indenter.findReferencePosition(p, false, false, false, true);
|
||||||
|
if (ref == CHeuristicScanner.NOT_FOUND)
|
||||||
|
return;
|
||||||
|
int refLine = d.getLineOfOffset(ref);
|
||||||
|
int nextToken = scanner.nextToken(ref, CHeuristicScanner.UNBOUND);
|
||||||
|
String indent;
|
||||||
|
if (nextToken == Symbols.TokenCASE || nextToken == Symbols.TokenDEFAULT)
|
||||||
|
indent = getIndentOfLine(d, refLine);
|
||||||
|
else // at the brace of the switch
|
||||||
|
indent = indenter.computeIndentation(p).toString();
|
||||||
|
|
||||||
|
if (indent != null) {
|
||||||
|
c.text = indent.toString() + "case"; //$NON-NLS-1$
|
||||||
|
c.length += c.offset - lineOffset;
|
||||||
|
c.offset = lineOffset;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
} catch (BadLocationException e) {
|
||||||
|
CUIPlugin.getDefault().log(e);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* @see org.eclipse.jface.text.DefaultIndentLineAutoEditStrategy#customizeDocumentCommand(org.eclipse.jface.text.IDocument, org.eclipse.jface.text.DocumentCommand)
|
* @see org.eclipse.jface.text.IAutoEditStrategy#customizeDocumentCommand(IDocument, DocumentCommand)
|
||||||
*/
|
*/
|
||||||
public void customizeDocumentCommand(IDocument d, DocumentCommand c) {
|
public void customizeDocumentCommand(IDocument d, DocumentCommand c) {
|
||||||
if (c.length == 0 && c.text != null && endsWithDelimiter(d, c.text)) {
|
if (!c.doit)
|
||||||
|
return;
|
||||||
|
|
||||||
|
clearCachedValues();
|
||||||
|
if (!fIsSmartMode) {
|
||||||
|
super.customizeDocumentCommand(d, c);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (c.length == 0 && c.text != null && isLineDelimiter(d, c.text)) {
|
||||||
if (isAppendToOpenMultilineComment(d, c)) {
|
if (isAppendToOpenMultilineComment(d, c)) {
|
||||||
// special case: multi-line comment at end of document (bug 48339)
|
// special case: multi-line comment at end of document (bug 48339)
|
||||||
CCommentAutoIndentStrategy.commentIndentAfterNewLine(d, c);
|
CCommentAutoIndentStrategy.commentIndentAfterNewLine(d, c);
|
||||||
} else {
|
} else {
|
||||||
smartIndentAfterNewLine(d, c);
|
smartIndentAfterNewLine(d, c);
|
||||||
}
|
}
|
||||||
} else if ("}".equals(c.text)) { //$NON-NLS-1$
|
} else if ("/".equals(c.text) && isAppendToOpenMultilineComment(d, c)) { //$NON-NLS-1$
|
||||||
smartInsertAfterBracket(d, c);
|
|
||||||
}
|
|
||||||
else if ("/".equals(c.text) && isAppendToOpenMultilineComment(d, c)) { //$NON-NLS-1$
|
|
||||||
// special case: multi-line comment at end of document (bug 48339)
|
// special case: multi-line comment at end of document (bug 48339)
|
||||||
CCommentAutoIndentStrategy.commentIndentForCommentEnd(d, c);
|
CCommentAutoIndentStrategy.commentIndentForCommentEnd(d, c);
|
||||||
|
} else if (c.text.length() == 1) {
|
||||||
|
smartIndentOnKeypress(d, c);
|
||||||
|
// TODO Support smart paste.
|
||||||
|
// } else if (c.text.length() > 1 && getPreferenceStore().getBoolean(PreferenceConstants.EDITOR_SMART_PASTE)) {
|
||||||
|
// smartPaste(d, c); // no smart backspace for paste
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -244,12 +661,11 @@ public class CAutoIndentStrategy extends DefaultIndentLineAutoEditStrategy {
|
||||||
* @param c the document command
|
* @param c the document command
|
||||||
* @return true, if the command appends to an open multi-line comment.
|
* @return true, if the command appends to an open multi-line comment.
|
||||||
*/
|
*/
|
||||||
static boolean isAppendToOpenMultilineComment(IDocument d, DocumentCommand c) {
|
private boolean isAppendToOpenMultilineComment(IDocument d, DocumentCommand c) {
|
||||||
if (d.getLength() >= 2 && c.offset == d.getLength()) {
|
if (d.getLength() >= 2 && c.offset == d.getLength()) {
|
||||||
try {
|
try {
|
||||||
String partitioning = CUIPlugin.getDefault().getTextTools().getDocumentPartitioning();
|
String contentType = org.eclipse.jface.text.TextUtilities.getContentType(d, fPartitioning, c.offset - 1, false);
|
||||||
String contentType = org.eclipse.jface.text.TextUtilities.getContentType(d, partitioning, c.offset - 1, false);
|
if (ICPartitions.C_MULTI_LINE_COMMENT.equals(contentType)) {
|
||||||
if (ICPartitions.C_MULTILINE_COMMENT.equals(contentType)) {
|
|
||||||
return !d.get(c.offset - 2, 2).equals(MULTILINE_COMMENT_CLOSE);
|
return !d.get(c.offset - 2, 2).equals(MULTILINE_COMMENT_CLOSE);
|
||||||
}
|
}
|
||||||
} catch (BadLocationException exc) {
|
} catch (BadLocationException exc) {
|
||||||
|
@ -259,4 +675,91 @@ public class CAutoIndentStrategy extends DefaultIndentLineAutoEditStrategy {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private static IPreferenceStore getPreferenceStore() {
|
||||||
|
return CUIPlugin.getDefault().getCombinedPreferenceStore();
|
||||||
|
}
|
||||||
|
|
||||||
|
private void clearCachedValues() {
|
||||||
|
IPreferenceStore preferenceStore = getPreferenceStore();
|
||||||
|
fCloseBrace = preferenceStore.getBoolean(PreferenceConstants.EDITOR_CLOSE_BRACES);
|
||||||
|
fIsSmartMode = computeSmartMode();
|
||||||
|
}
|
||||||
|
|
||||||
|
private boolean computeSmartMode() {
|
||||||
|
IWorkbenchPage page = CUIPlugin.getActivePage();
|
||||||
|
if (page != null) {
|
||||||
|
IEditorPart part = page.getActiveEditor();
|
||||||
|
if (part instanceof ITextEditorExtension3) {
|
||||||
|
ITextEditorExtension3 extension = (ITextEditorExtension3) part;
|
||||||
|
return extension.getInsertMode() == ITextEditorExtension3.SMART_INSERT;
|
||||||
|
}
|
||||||
|
if (part == null) {
|
||||||
|
// TODO: Remove this if statement once CAutoIndentTest is fixed so that getActiveEditor does not return null.
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
private static CompilationUnitInfo getCompilationUnitForMethod(IDocument document, int offset, String partitioning) {
|
||||||
|
try {
|
||||||
|
CHeuristicScanner scanner = new CHeuristicScanner(document);
|
||||||
|
|
||||||
|
IRegion sourceRange = scanner.findSurroundingBlock(offset);
|
||||||
|
if (sourceRange == null)
|
||||||
|
return null;
|
||||||
|
String source = document.get(sourceRange.getOffset(), sourceRange.getLength());
|
||||||
|
|
||||||
|
StringBuffer contents = new StringBuffer();
|
||||||
|
contents.append("class ____C{void ____m()"); //$NON-NLS-1$
|
||||||
|
final int methodOffset = contents.length();
|
||||||
|
contents.append(source);
|
||||||
|
contents.append("};"); //$NON-NLS-1$
|
||||||
|
|
||||||
|
char[] buffer = contents.toString().toCharArray();
|
||||||
|
return new CompilationUnitInfo(buffer, sourceRange.getOffset() - methodOffset);
|
||||||
|
} catch (BadLocationException e) {
|
||||||
|
CUIPlugin.getDefault().log(e);
|
||||||
|
}
|
||||||
|
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Returns the block balance, i.e. zero if the blocks are balanced at
|
||||||
|
* <code>offset</code>, a negative number if there are more closing than opening
|
||||||
|
* braces, and a positive number if there are more opening than closing braces.
|
||||||
|
*
|
||||||
|
* @param document
|
||||||
|
* @param offset
|
||||||
|
* @param partitioning
|
||||||
|
* @return the block balance
|
||||||
|
*/
|
||||||
|
private static int getBlockBalance(IDocument document, int offset, String partitioning) {
|
||||||
|
if (offset < 1)
|
||||||
|
return -1;
|
||||||
|
if (offset >= document.getLength())
|
||||||
|
return 1;
|
||||||
|
|
||||||
|
int begin = offset;
|
||||||
|
int end = offset - 1;
|
||||||
|
|
||||||
|
CHeuristicScanner scanner = new CHeuristicScanner(document);
|
||||||
|
|
||||||
|
while (true) {
|
||||||
|
begin = scanner.findOpeningPeer(begin - 1, '{', '}');
|
||||||
|
end = scanner.findClosingPeer(end + 1, '{', '}');
|
||||||
|
if (begin == -1 && end == -1)
|
||||||
|
return 0;
|
||||||
|
if (begin == -1)
|
||||||
|
return -1;
|
||||||
|
if (end == -1)
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// private static IRegion createRegion(IASTNode node, int delta) {
|
||||||
|
// IASTNodeLocation nodeLocation = node.getNodeLocations()[0];
|
||||||
|
// return node == null ? null : new Region(nodeLocation.getNodeOffset() + delta, nodeLocation.getNodeLength());
|
||||||
|
// }
|
||||||
}
|
}
|
||||||
|
|
|
@ -0,0 +1,867 @@
|
||||||
|
/*******************************************************************************
|
||||||
|
* Copyright (c) 2000, 2006 IBM Corporation and others.
|
||||||
|
* All rights reserved. This program and the accompanying materials
|
||||||
|
* are made available under the terms of the Eclipse Public License v1.0
|
||||||
|
* which accompanies this distribution, and is available at
|
||||||
|
* http://www.eclipse.org/legal/epl-v10.html
|
||||||
|
*
|
||||||
|
* Contributors:
|
||||||
|
* IBM Corporation - initial API and implementation
|
||||||
|
*******************************************************************************/
|
||||||
|
package org.eclipse.cdt.internal.ui.text;
|
||||||
|
|
||||||
|
import java.util.Arrays;
|
||||||
|
|
||||||
|
import org.eclipse.cdt.ui.text.ICPartitions;
|
||||||
|
|
||||||
|
import org.eclipse.jface.text.Assert;
|
||||||
|
import org.eclipse.jface.text.BadLocationException;
|
||||||
|
import org.eclipse.jface.text.IDocument;
|
||||||
|
import org.eclipse.jface.text.IRegion;
|
||||||
|
import org.eclipse.jface.text.ITypedRegion;
|
||||||
|
import org.eclipse.jface.text.Region;
|
||||||
|
import org.eclipse.jface.text.TextUtilities;
|
||||||
|
import org.eclipse.jface.text.TypedRegion;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Utility methods for heuristic based C manipulations in an incomplete C source file.
|
||||||
|
*
|
||||||
|
* <p>An instance holds some internal position in the document and is therefore not threadsafe.</p>
|
||||||
|
*/
|
||||||
|
public final class CHeuristicScanner implements Symbols {
|
||||||
|
/**
|
||||||
|
* Returned by all methods when the requested position could not be found, or if a
|
||||||
|
* {@link BadLocationException} was thrown while scanning.
|
||||||
|
*/
|
||||||
|
public static final int NOT_FOUND= -1;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Special bound parameter that means either -1 (backward scanning) or
|
||||||
|
* <code>fDocument.getLength()</code> (forward scanning).
|
||||||
|
*/
|
||||||
|
public static final int UNBOUND= -2;
|
||||||
|
|
||||||
|
|
||||||
|
/* character constants */
|
||||||
|
private static final char LBRACE= '{';
|
||||||
|
private static final char RBRACE= '}';
|
||||||
|
private static final char LPAREN= '(';
|
||||||
|
private static final char RPAREN= ')';
|
||||||
|
private static final char SEMICOLON= ';';
|
||||||
|
private static final char COLON= ':';
|
||||||
|
private static final char COMMA= ',';
|
||||||
|
private static final char LBRACKET= '[';
|
||||||
|
private static final char RBRACKET= ']';
|
||||||
|
private static final char QUESTIONMARK= '?';
|
||||||
|
private static final char EQUAL= '=';
|
||||||
|
private static final char LANGLE= '<';
|
||||||
|
private static final char RANGLE= '>';
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Specifies the stop condition, upon which the <code>scanXXX</code> methods will decide whether
|
||||||
|
* to keep scanning or not. This interface may implemented by clients.
|
||||||
|
*/
|
||||||
|
private static abstract class StopCondition {
|
||||||
|
/**
|
||||||
|
* Instructs the scanner to return the current position.
|
||||||
|
*
|
||||||
|
* @param ch the char at the current position
|
||||||
|
* @param position the current position
|
||||||
|
* @param forward the iteration direction
|
||||||
|
* @return <code>true</code> if the stop condition is met.
|
||||||
|
*/
|
||||||
|
public abstract boolean stop(char ch, int position, boolean forward);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Asks the condition to return the next position to query. The default
|
||||||
|
* is to return the next/previous position.
|
||||||
|
*
|
||||||
|
* @return the next position to scan
|
||||||
|
*/
|
||||||
|
public int nextPosition(int position, boolean forward) {
|
||||||
|
return forward ? position + 1 : position - 1;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Stops upon a non-whitespace (as defined by {@link Character#isWhitespace(char)}) character.
|
||||||
|
*/
|
||||||
|
private static class NonWhitespace extends StopCondition {
|
||||||
|
/*
|
||||||
|
* @see org.eclipse.jdt.internal.ui.text.JavaHeuristicScanner.StopCondition#stop(char)
|
||||||
|
*/
|
||||||
|
public boolean stop(char ch, int position, boolean forward) {
|
||||||
|
return !Character.isWhitespace(ch);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Stops upon a non-whitespace character in the default partition.
|
||||||
|
*
|
||||||
|
* @see NonWhitespace
|
||||||
|
*/
|
||||||
|
private final class NonWhitespaceDefaultPartition extends NonWhitespace {
|
||||||
|
/*
|
||||||
|
* @see org.eclipse.jdt.internal.ui.text.JavaHeuristicScanner.StopCondition#stop(char)
|
||||||
|
*/
|
||||||
|
public boolean stop(char ch, int position, boolean forward) {
|
||||||
|
return super.stop(ch, position, true) && isDefaultPartition(position);
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* @see org.eclipse.jdt.internal.ui.text.JavaHeuristicScanner.StopCondition#nextPosition(int, boolean)
|
||||||
|
*/
|
||||||
|
public int nextPosition(int position, boolean forward) {
|
||||||
|
ITypedRegion partition= getPartition(position);
|
||||||
|
if (fPartition.equals(partition.getType()))
|
||||||
|
return super.nextPosition(position, forward);
|
||||||
|
|
||||||
|
if (forward) {
|
||||||
|
int end= partition.getOffset() + partition.getLength();
|
||||||
|
if (position < end)
|
||||||
|
return end;
|
||||||
|
} else {
|
||||||
|
int offset= partition.getOffset();
|
||||||
|
if (position > offset)
|
||||||
|
return offset - 1;
|
||||||
|
}
|
||||||
|
return super.nextPosition(position, forward);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Stops upon a non-java identifier (as defined by {@link Character#isJavaIdentifierPart(char)}) character.
|
||||||
|
*/
|
||||||
|
private static class NonJavaIdentifierPart extends StopCondition {
|
||||||
|
/*
|
||||||
|
* @see org.eclipse.jdt.internal.ui.text.JavaHeuristicScanner.StopCondition#stop(char)
|
||||||
|
*/
|
||||||
|
public boolean stop(char ch, int position, boolean forward) {
|
||||||
|
return !Character.isJavaIdentifierPart(ch);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Stops upon a non-java identifier character in the default partition.
|
||||||
|
*
|
||||||
|
* @see NonJavaIdentifierPart
|
||||||
|
*/
|
||||||
|
private final class NonJavaIdentifierPartDefaultPartition extends NonJavaIdentifierPart {
|
||||||
|
/*
|
||||||
|
* @see org.eclipse.jdt.internal.ui.text.JavaHeuristicScanner.StopCondition#stop(char)
|
||||||
|
*/
|
||||||
|
public boolean stop(char ch, int position, boolean forward) {
|
||||||
|
return super.stop(ch, position, true) || !isDefaultPartition(position);
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* @see org.eclipse.jdt.internal.ui.text.JavaHeuristicScanner.StopCondition#nextPosition(int, boolean)
|
||||||
|
*/
|
||||||
|
public int nextPosition(int position, boolean forward) {
|
||||||
|
ITypedRegion partition= getPartition(position);
|
||||||
|
if (fPartition.equals(partition.getType()))
|
||||||
|
return super.nextPosition(position, forward);
|
||||||
|
|
||||||
|
if (forward) {
|
||||||
|
int end= partition.getOffset() + partition.getLength();
|
||||||
|
if (position < end)
|
||||||
|
return end;
|
||||||
|
} else {
|
||||||
|
int offset= partition.getOffset();
|
||||||
|
if (position > offset)
|
||||||
|
return offset - 1;
|
||||||
|
}
|
||||||
|
return super.nextPosition(position, forward);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Stops upon a character in the default partition that matches the given character list.
|
||||||
|
*/
|
||||||
|
private final class CharacterMatch extends StopCondition {
|
||||||
|
private final char[] fChars;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Creates a new instance.
|
||||||
|
* @param ch the single character to match
|
||||||
|
*/
|
||||||
|
public CharacterMatch(char ch) {
|
||||||
|
this(new char[] {ch});
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Creates a new instance.
|
||||||
|
* @param chars the chars to match.
|
||||||
|
*/
|
||||||
|
public CharacterMatch(char[] chars) {
|
||||||
|
Assert.isNotNull(chars);
|
||||||
|
Assert.isTrue(chars.length > 0);
|
||||||
|
fChars= chars;
|
||||||
|
Arrays.sort(chars);
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* @see org.eclipse.jdt.internal.ui.text.JavaHeuristicScanner.StopCondition#stop(char, int)
|
||||||
|
*/
|
||||||
|
public boolean stop(char ch, int position, boolean forward) {
|
||||||
|
return Arrays.binarySearch(fChars, ch) >= 0 && isDefaultPartition(position);
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* @see org.eclipse.jdt.internal.ui.text.JavaHeuristicScanner.StopCondition#nextPosition(int, boolean)
|
||||||
|
*/
|
||||||
|
public int nextPosition(int position, boolean forward) {
|
||||||
|
ITypedRegion partition= getPartition(position);
|
||||||
|
if (fPartition.equals(partition.getType()))
|
||||||
|
return super.nextPosition(position, forward);
|
||||||
|
|
||||||
|
if (forward) {
|
||||||
|
int end= partition.getOffset() + partition.getLength();
|
||||||
|
if (position < end)
|
||||||
|
return end;
|
||||||
|
} else {
|
||||||
|
int offset= partition.getOffset();
|
||||||
|
if (position > offset)
|
||||||
|
return offset - 1;
|
||||||
|
}
|
||||||
|
return super.nextPosition(position, forward);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/** The document being scanned. */
|
||||||
|
private final IDocument fDocument;
|
||||||
|
/** The partitioning being used for scanning. */
|
||||||
|
private final String fPartitioning;
|
||||||
|
/** The partition to scan in. */
|
||||||
|
private final String fPartition;
|
||||||
|
|
||||||
|
/* internal scan state */
|
||||||
|
|
||||||
|
/** the most recently read character. */
|
||||||
|
private char fChar;
|
||||||
|
/** the most recently read position. */
|
||||||
|
private int fPos;
|
||||||
|
/**
|
||||||
|
* The most recently used partition.
|
||||||
|
*/
|
||||||
|
private ITypedRegion fCachedPartition= new TypedRegion(-1, 0, "__no_partition_at_all"); //$NON-NLS-1$
|
||||||
|
|
||||||
|
/* preset stop conditions */
|
||||||
|
private final StopCondition fNonWSDefaultPart= new NonWhitespaceDefaultPartition();
|
||||||
|
private final static StopCondition fNonWS= new NonWhitespace();
|
||||||
|
private final StopCondition fNonIdent= new NonJavaIdentifierPartDefaultPartition();
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Creates a new instance.
|
||||||
|
*
|
||||||
|
* @param document the document to scan
|
||||||
|
* @param partitioning the partitioning to use for scanning
|
||||||
|
* @param partition the partition to scan in
|
||||||
|
*/
|
||||||
|
public CHeuristicScanner(IDocument document, String partitioning, String partition) {
|
||||||
|
Assert.isLegal(document != null);
|
||||||
|
Assert.isLegal(partitioning != null);
|
||||||
|
Assert.isLegal(partition != null);
|
||||||
|
fDocument= document;
|
||||||
|
fPartitioning= partitioning;
|
||||||
|
fPartition= partition;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Calls <code>this(document, IJavaPartitions.JAVA_PARTITIONING, IDocument.DEFAULT_CONTENT_TYPE)</code>.
|
||||||
|
*
|
||||||
|
* @param document the document to scan.
|
||||||
|
*/
|
||||||
|
public CHeuristicScanner(IDocument document) {
|
||||||
|
this(document, ICPartitions.C_PARTITIONING, IDocument.DEFAULT_CONTENT_TYPE);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Returns the most recent internal scan position.
|
||||||
|
*
|
||||||
|
* @return the most recent internal scan position.
|
||||||
|
*/
|
||||||
|
public int getPosition() {
|
||||||
|
return fPos;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Returns the next token in forward direction, starting at <code>start</code>, and not extending
|
||||||
|
* further than <code>bound</code>. The return value is one of the constants defined in {@link Symbols}.
|
||||||
|
* After a call, {@link #getPosition()} will return the position just after the scanned token
|
||||||
|
* (i.e. the next position that will be scanned).
|
||||||
|
*
|
||||||
|
* @param start the first character position in the document to consider
|
||||||
|
* @param bound the first position not to consider any more
|
||||||
|
* @return a constant from {@link Symbols} describing the next token
|
||||||
|
*/
|
||||||
|
public int nextToken(int start, int bound) {
|
||||||
|
int pos= scanForward(start, bound, fNonWSDefaultPart);
|
||||||
|
if (pos == NOT_FOUND)
|
||||||
|
return TokenEOF;
|
||||||
|
|
||||||
|
fPos++;
|
||||||
|
|
||||||
|
switch (fChar) {
|
||||||
|
case LBRACE:
|
||||||
|
return TokenLBRACE;
|
||||||
|
case RBRACE:
|
||||||
|
return TokenRBRACE;
|
||||||
|
case LBRACKET:
|
||||||
|
return TokenLBRACKET;
|
||||||
|
case RBRACKET:
|
||||||
|
return TokenRBRACKET;
|
||||||
|
case LPAREN:
|
||||||
|
return TokenLPAREN;
|
||||||
|
case RPAREN:
|
||||||
|
return TokenRPAREN;
|
||||||
|
case SEMICOLON:
|
||||||
|
return TokenSEMICOLON;
|
||||||
|
case COMMA:
|
||||||
|
return TokenCOMMA;
|
||||||
|
case QUESTIONMARK:
|
||||||
|
return TokenQUESTIONMARK;
|
||||||
|
case EQUAL:
|
||||||
|
return TokenEQUAL;
|
||||||
|
case LANGLE:
|
||||||
|
return TokenLESSTHAN;
|
||||||
|
case RANGLE:
|
||||||
|
return TokenGREATERTHAN;
|
||||||
|
}
|
||||||
|
|
||||||
|
// else
|
||||||
|
if (Character.isJavaIdentifierPart(fChar)) {
|
||||||
|
// assume an identifier or keyword
|
||||||
|
int from= pos, to;
|
||||||
|
pos= scanForward(pos + 1, bound, fNonIdent);
|
||||||
|
if (pos == NOT_FOUND)
|
||||||
|
to= bound == UNBOUND ? fDocument.getLength() : bound;
|
||||||
|
else
|
||||||
|
to= pos;
|
||||||
|
|
||||||
|
String identOrKeyword;
|
||||||
|
try {
|
||||||
|
identOrKeyword= fDocument.get(from, to - from);
|
||||||
|
} catch (BadLocationException e) {
|
||||||
|
return TokenEOF;
|
||||||
|
}
|
||||||
|
|
||||||
|
return getToken(identOrKeyword);
|
||||||
|
|
||||||
|
|
||||||
|
} else {
|
||||||
|
// operators, number literals etc
|
||||||
|
return TokenOTHER;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Returns the next token in backward direction, starting at <code>start</code>, and not extending
|
||||||
|
* further than <code>bound</code>. The return value is one of the constants defined in {@link Symbols}.
|
||||||
|
* After a call, {@link #getPosition()} will return the position just before the scanned token
|
||||||
|
* starts (i.e. the next position that will be scanned).
|
||||||
|
*
|
||||||
|
* @param start the first character position in the document to consider
|
||||||
|
* @param bound the first position not to consider any more
|
||||||
|
* @return a constant from {@link Symbols} describing the previous token
|
||||||
|
*/
|
||||||
|
public int previousToken(int start, int bound) {
|
||||||
|
int pos= scanBackward(start, bound, fNonWSDefaultPart);
|
||||||
|
if (pos == NOT_FOUND)
|
||||||
|
return TokenEOF;
|
||||||
|
|
||||||
|
fPos--;
|
||||||
|
|
||||||
|
switch (fChar) {
|
||||||
|
case LBRACE:
|
||||||
|
return TokenLBRACE;
|
||||||
|
case RBRACE:
|
||||||
|
return TokenRBRACE;
|
||||||
|
case LBRACKET:
|
||||||
|
return TokenLBRACKET;
|
||||||
|
case RBRACKET:
|
||||||
|
return TokenRBRACKET;
|
||||||
|
case LPAREN:
|
||||||
|
return TokenLPAREN;
|
||||||
|
case RPAREN:
|
||||||
|
return TokenRPAREN;
|
||||||
|
case SEMICOLON:
|
||||||
|
return TokenSEMICOLON;
|
||||||
|
case COLON:
|
||||||
|
return TokenCOLON;
|
||||||
|
case COMMA:
|
||||||
|
return TokenCOMMA;
|
||||||
|
case QUESTIONMARK:
|
||||||
|
return TokenQUESTIONMARK;
|
||||||
|
case EQUAL:
|
||||||
|
return TokenEQUAL;
|
||||||
|
case LANGLE:
|
||||||
|
return TokenLESSTHAN;
|
||||||
|
case RANGLE:
|
||||||
|
return TokenGREATERTHAN;
|
||||||
|
}
|
||||||
|
|
||||||
|
// else
|
||||||
|
if (Character.isJavaIdentifierPart(fChar)) {
|
||||||
|
// assume an ident or keyword
|
||||||
|
int from, to= pos + 1;
|
||||||
|
pos= scanBackward(pos - 1, bound, fNonIdent);
|
||||||
|
if (pos == NOT_FOUND)
|
||||||
|
from= bound == UNBOUND ? 0 : bound + 1;
|
||||||
|
else
|
||||||
|
from= pos + 1;
|
||||||
|
|
||||||
|
String identOrKeyword;
|
||||||
|
try {
|
||||||
|
identOrKeyword= fDocument.get(from, to - from);
|
||||||
|
} catch (BadLocationException e) {
|
||||||
|
return TokenEOF;
|
||||||
|
}
|
||||||
|
|
||||||
|
return getToken(identOrKeyword);
|
||||||
|
|
||||||
|
|
||||||
|
} else {
|
||||||
|
// operators, number literals etc
|
||||||
|
return TokenOTHER;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Returns one of the keyword constants or <code>TokenIDENT</code> for a scanned identifier.
|
||||||
|
*
|
||||||
|
* @param s a scanned identifier
|
||||||
|
* @return one of the constants defined in {@link Symbols}
|
||||||
|
*/
|
||||||
|
private int getToken(String s) {
|
||||||
|
Assert.isNotNull(s);
|
||||||
|
|
||||||
|
switch (s.length()) {
|
||||||
|
case 2:
|
||||||
|
if ("if".equals(s)) //$NON-NLS-1$
|
||||||
|
return TokenIF;
|
||||||
|
if ("do".equals(s)) //$NON-NLS-1$
|
||||||
|
return TokenDO;
|
||||||
|
break;
|
||||||
|
case 3:
|
||||||
|
if ("for".equals(s)) //$NON-NLS-1$
|
||||||
|
return TokenFOR;
|
||||||
|
if ("try".equals(s)) //$NON-NLS-1$
|
||||||
|
return TokenTRY;
|
||||||
|
if ("new".equals(s)) //$NON-NLS-1$
|
||||||
|
return TokenNEW;
|
||||||
|
break;
|
||||||
|
case 4:
|
||||||
|
if ("case".equals(s)) //$NON-NLS-1$
|
||||||
|
return TokenCASE;
|
||||||
|
if ("else".equals(s)) //$NON-NLS-1$
|
||||||
|
return TokenELSE;
|
||||||
|
if ("enum".equals(s)) //$NON-NLS-1$
|
||||||
|
return TokenENUM;
|
||||||
|
if ("goto".equals(s)) //$NON-NLS-1$
|
||||||
|
return TokenGOTO;
|
||||||
|
break;
|
||||||
|
case 5:
|
||||||
|
if ("break".equals(s)) //$NON-NLS-1$
|
||||||
|
return TokenBREAK;
|
||||||
|
if ("catch".equals(s)) //$NON-NLS-1$
|
||||||
|
return TokenCATCH;
|
||||||
|
if ("class".equals(s)) //$NON-NLS-1$
|
||||||
|
return TokenCLASS;
|
||||||
|
if ("while".equals(s)) //$NON-NLS-1$
|
||||||
|
return TokenWHILE;
|
||||||
|
break;
|
||||||
|
case 6:
|
||||||
|
if ("return".equals(s)) //$NON-NLS-1$
|
||||||
|
return TokenRETURN;
|
||||||
|
if ("static".equals(s)) //$NON-NLS-1$
|
||||||
|
return TokenSTATIC;
|
||||||
|
if ("switch".equals(s)) //$NON-NLS-1$
|
||||||
|
return TokenSWITCH;
|
||||||
|
break;
|
||||||
|
case 7:
|
||||||
|
if ("default".equals(s)) //$NON-NLS-1$
|
||||||
|
return TokenDEFAULT;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
return TokenIDENT;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Returns the position of the closing peer character (forward search). Any scopes introduced by opening peers
|
||||||
|
* are skipped. All peers accounted for must reside in the default partition.
|
||||||
|
*
|
||||||
|
* <p>Note that <code>start</code> must not point to the opening peer, but to the first
|
||||||
|
* character being searched.</p>
|
||||||
|
*
|
||||||
|
* @param start the start position
|
||||||
|
* @param openingPeer the opening peer character (e.g. '{')
|
||||||
|
* @param closingPeer the closing peer character (e.g. '}')
|
||||||
|
* @return the matching peer character position, or <code>NOT_FOUND</code>
|
||||||
|
*/
|
||||||
|
public int findClosingPeer(int start, final char openingPeer, final char closingPeer) {
|
||||||
|
Assert.isLegal(start >= 0);
|
||||||
|
|
||||||
|
try {
|
||||||
|
int depth= 1;
|
||||||
|
start -= 1;
|
||||||
|
while (true) {
|
||||||
|
start= scanForward(start + 1, UNBOUND, new CharacterMatch(new char[] {openingPeer, closingPeer}));
|
||||||
|
if (start == NOT_FOUND)
|
||||||
|
return NOT_FOUND;
|
||||||
|
|
||||||
|
if (fDocument.getChar(start) == openingPeer)
|
||||||
|
depth++;
|
||||||
|
else
|
||||||
|
depth--;
|
||||||
|
|
||||||
|
if (depth == 0)
|
||||||
|
return start;
|
||||||
|
}
|
||||||
|
|
||||||
|
} catch (BadLocationException e) {
|
||||||
|
return NOT_FOUND;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Returns the position of the opening peer character (backward search). Any scopes introduced by closing peers
|
||||||
|
* are skipped. All peers accounted for must reside in the default partition.
|
||||||
|
*
|
||||||
|
* <p>Note that <code>start</code> must not point to the closing peer, but to the first
|
||||||
|
* character being searched.</p>
|
||||||
|
*
|
||||||
|
* @param start the start position
|
||||||
|
* @param openingPeer the opening peer character (e.g. '{')
|
||||||
|
* @param closingPeer the closing peer character (e.g. '}')
|
||||||
|
* @return the matching peer character position, or <code>NOT_FOUND</code>
|
||||||
|
*/
|
||||||
|
public int findOpeningPeer(int start, char openingPeer, char closingPeer) {
|
||||||
|
Assert.isLegal(start < fDocument.getLength());
|
||||||
|
|
||||||
|
try {
|
||||||
|
int depth= 1;
|
||||||
|
start += 1;
|
||||||
|
while (true) {
|
||||||
|
start= scanBackward(start - 1, UNBOUND, new CharacterMatch(new char[] {openingPeer, closingPeer}));
|
||||||
|
if (start == NOT_FOUND)
|
||||||
|
return NOT_FOUND;
|
||||||
|
|
||||||
|
if (fDocument.getChar(start) == closingPeer)
|
||||||
|
depth++;
|
||||||
|
else
|
||||||
|
depth--;
|
||||||
|
|
||||||
|
if (depth == 0)
|
||||||
|
return start;
|
||||||
|
}
|
||||||
|
|
||||||
|
} catch (BadLocationException e) {
|
||||||
|
return NOT_FOUND;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Computes the surrounding block around <code>offset</code>. The search is started at the
|
||||||
|
* beginning of <code>offset</code>, i.e. an opening brace at <code>offset</code> will not be
|
||||||
|
* part of the surrounding block, but a closing brace will.
|
||||||
|
*
|
||||||
|
* @param offset the offset for which the surrounding block is computed
|
||||||
|
* @return a region describing the surrounding block, or <code>null</code> if none can be found
|
||||||
|
*/
|
||||||
|
public IRegion findSurroundingBlock(int offset) {
|
||||||
|
if (offset < 1 || offset >= fDocument.getLength())
|
||||||
|
return null;
|
||||||
|
|
||||||
|
int begin= findOpeningPeer(offset - 1, LBRACE, RBRACE);
|
||||||
|
int end= findClosingPeer(offset, LBRACE, RBRACE);
|
||||||
|
if (begin == NOT_FOUND || end == NOT_FOUND)
|
||||||
|
return null;
|
||||||
|
return new Region(begin, end + 1 - begin);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Finds the smallest position in <code>fDocument</code> such that the position is >= <code>position</code>
|
||||||
|
* and < <code>bound</code> and <code>Character.isWhitespace(fDocument.getChar(pos))</code> evaluates to <code>false</code>
|
||||||
|
* and the position is in the default partition.
|
||||||
|
*
|
||||||
|
* @param position the first character position in <code>fDocument</code> to be considered
|
||||||
|
* @param bound the first position in <code>fDocument</code> to not consider any more, with <code>bound</code> > <code>position</code>, or <code>UNBOUND</code>
|
||||||
|
* @return the smallest position of a non-whitespace character in [<code>position</code>, <code>bound</code>) that resides in a C partition, or <code>NOT_FOUND</code> if none can be found
|
||||||
|
*/
|
||||||
|
public int findNonWhitespaceForward(int position, int bound) {
|
||||||
|
return scanForward(position, bound, fNonWSDefaultPart);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Finds the smallest position in <code>fDocument</code> such that the position is >= <code>position</code>
|
||||||
|
* and < <code>bound</code> and <code>Character.isWhitespace(fDocument.getChar(pos))</code> evaluates to <code>false</code>.
|
||||||
|
*
|
||||||
|
* @param position the first character position in <code>fDocument</code> to be considered
|
||||||
|
* @param bound the first position in <code>fDocument</code> to not consider any more, with <code>bound</code> > <code>position</code>, or <code>UNBOUND</code>
|
||||||
|
* @return the smallest position of a non-whitespace character in [<code>position</code>, <code>bound</code>), or <code>NOT_FOUND</code> if none can be found
|
||||||
|
*/
|
||||||
|
public int findNonWhitespaceForwardInAnyPartition(int position, int bound) {
|
||||||
|
return scanForward(position, bound, fNonWS);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Finds the highest position in <code>fDocument</code> such that the position is <= <code>position</code>
|
||||||
|
* and > <code>bound</code> and <code>Character.isWhitespace(fDocument.getChar(pos))</code> evaluates to <code>false</code>
|
||||||
|
* and the position is in the default partition.
|
||||||
|
*
|
||||||
|
* @param position the first character position in <code>fDocument</code> to be considered
|
||||||
|
* @param bound the first position in <code>fDocument</code> to not consider any more, with <code>bound</code> < <code>position</code>, or <code>UNBOUND</code>
|
||||||
|
* @return the highest position of a non-whitespace character in (<code>bound</code>, <code>position</code>] that resides in a C partition, or <code>NOT_FOUND</code> if none can be found
|
||||||
|
*/
|
||||||
|
public int findNonWhitespaceBackward(int position, int bound) {
|
||||||
|
return scanBackward(position, bound, fNonWSDefaultPart);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Finds the lowest position <code>p</code> in <code>fDocument</code> such that <code>start</code> <= p <
|
||||||
|
* <code>bound</code> and <code>condition.stop(fDocument.getChar(p), p)</code> evaluates to <code>true</code>.
|
||||||
|
*
|
||||||
|
* @param start the first character position in <code>fDocument</code> to be considered
|
||||||
|
* @param bound the first position in <code>fDocument</code> to not consider any more, with <code>bound</code> > <code>start</code>, or <code>UNBOUND</code>
|
||||||
|
* @param condition the <code>StopCondition</code> to check
|
||||||
|
* @return the lowest position in [<code>start</code>, <code>bound</code>) for which <code>condition</code> holds, or <code>NOT_FOUND</code> if none can be found
|
||||||
|
*/
|
||||||
|
public int scanForward(int start, int bound, StopCondition condition) {
|
||||||
|
Assert.isLegal(start >= 0);
|
||||||
|
|
||||||
|
if (bound == UNBOUND)
|
||||||
|
bound= fDocument.getLength();
|
||||||
|
|
||||||
|
Assert.isLegal(bound <= fDocument.getLength());
|
||||||
|
|
||||||
|
try {
|
||||||
|
fPos= start;
|
||||||
|
while (fPos < bound) {
|
||||||
|
|
||||||
|
fChar= fDocument.getChar(fPos);
|
||||||
|
if (condition.stop(fChar, fPos, true))
|
||||||
|
return fPos;
|
||||||
|
|
||||||
|
fPos= condition.nextPosition(fPos, true);
|
||||||
|
}
|
||||||
|
} catch (BadLocationException e) {
|
||||||
|
}
|
||||||
|
return NOT_FOUND;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Finds the lowest position in <code>fDocument</code> such that the position is >= <code>position</code>
|
||||||
|
* and < <code>bound</code> and <code>fDocument.getChar(position) == ch</code> evaluates to <code>true</code>
|
||||||
|
* and the position is in the default partition.
|
||||||
|
*
|
||||||
|
* @param position the first character position in <code>fDocument</code> to be considered
|
||||||
|
* @param bound the first position in <code>fDocument</code> to not consider any more, with <code>bound</code> > <code>position</code>, or <code>UNBOUND</code>
|
||||||
|
* @param ch the <code>char</code> to search for
|
||||||
|
* @return the lowest position of <code>ch</code> in (<code>bound</code>, <code>position</code>] that resides in a C partition, or <code>NOT_FOUND</code> if none can be found
|
||||||
|
*/
|
||||||
|
public int scanForward(int position, int bound, char ch) {
|
||||||
|
return scanForward(position, bound, new CharacterMatch(ch));
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Finds the lowest position in <code>fDocument</code> such that the position is >= <code>position</code>
|
||||||
|
* and < <code>bound</code> and <code>fDocument.getChar(position) == ch</code> evaluates to <code>true</code> for at least one
|
||||||
|
* ch in <code>chars</code> and the position is in the default partition.
|
||||||
|
*
|
||||||
|
* @param position the first character position in <code>fDocument</code> to be considered
|
||||||
|
* @param bound the first position in <code>fDocument</code> to not consider any more, with <code>bound</code> > <code>position</code>, or <code>UNBOUND</code>
|
||||||
|
* @param chars an array of <code>char</code> to search for
|
||||||
|
* @return the lowest position of a non-whitespace character in [<code>position</code>, <code>bound</code>) that resides in a C partition, or <code>NOT_FOUND</code> if none can be found
|
||||||
|
*/
|
||||||
|
public int scanForward(int position, int bound, char[] chars) {
|
||||||
|
return scanForward(position, bound, new CharacterMatch(chars));
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Finds the highest position <code>p</code> in <code>fDocument</code> such that <code>bound</code> < <code>p</code> <= <code>start</code>
|
||||||
|
* and <code>condition.stop(fDocument.getChar(p), p)</code> evaluates to <code>true</code>.
|
||||||
|
*
|
||||||
|
* @param start the first character position in <code>fDocument</code> to be considered
|
||||||
|
* @param bound the first position in <code>fDocument</code> to not consider any more, with <code>bound</code> < <code>start</code>, or <code>UNBOUND</code>
|
||||||
|
* @param condition the <code>StopCondition</code> to check
|
||||||
|
* @return the highest position in (<code>bound</code>, <code>start</code> for which <code>condition</code> holds, or <code>NOT_FOUND</code> if none can be found
|
||||||
|
*/
|
||||||
|
public int scanBackward(int start, int bound, StopCondition condition) {
|
||||||
|
if (bound == UNBOUND)
|
||||||
|
bound= -1;
|
||||||
|
|
||||||
|
Assert.isLegal(bound >= -1);
|
||||||
|
Assert.isLegal(start < fDocument.getLength() );
|
||||||
|
|
||||||
|
try {
|
||||||
|
fPos= start;
|
||||||
|
while (fPos > bound) {
|
||||||
|
|
||||||
|
fChar= fDocument.getChar(fPos);
|
||||||
|
if (condition.stop(fChar, fPos, false))
|
||||||
|
return fPos;
|
||||||
|
|
||||||
|
fPos= condition.nextPosition(fPos, false);
|
||||||
|
}
|
||||||
|
} catch (BadLocationException e) {
|
||||||
|
}
|
||||||
|
return NOT_FOUND;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Finds the highest position in <code>fDocument</code> such that the position is <= <code>position</code>
|
||||||
|
* and > <code>bound</code> and <code>fDocument.getChar(position) == ch</code> evaluates to <code>true</code> for at least one
|
||||||
|
* ch in <code>chars</code> and the position is in the default partition.
|
||||||
|
*
|
||||||
|
* @param position the first character position in <code>fDocument</code> to be considered
|
||||||
|
* @param bound the first position in <code>fDocument</code> to not consider any more, with <code>bound</code> < <code>position</code>, or <code>UNBOUND</code>
|
||||||
|
* @param ch the <code>char</code> to search for
|
||||||
|
* @return the highest position of one element in <code>chars</code> in (<code>bound</code>, <code>position</code>] that resides in a C partition, or <code>NOT_FOUND</code> if none can be found
|
||||||
|
*/
|
||||||
|
public int scanBackward(int position, int bound, char ch) {
|
||||||
|
return scanBackward(position, bound, new CharacterMatch(ch));
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Finds the highest position in <code>fDocument</code> such that the position is <= <code>position</code>
|
||||||
|
* and > <code>bound</code> and <code>fDocument.getChar(position) == ch</code> evaluates to <code>true</code> for at least one
|
||||||
|
* ch in <code>chars</code> and the position is in the default partition.
|
||||||
|
*
|
||||||
|
* @param position the first character position in <code>fDocument</code> to be considered
|
||||||
|
* @param bound the first position in <code>fDocument</code> to not consider any more, with <code>bound</code> < <code>position</code>, or <code>UNBOUND</code>
|
||||||
|
* @param chars an array of <code>char</code> to search for
|
||||||
|
* @return the highest position of one element in <code>chars</code> in (<code>bound</code>, <code>position</code>] that resides in a C partition, or <code>NOT_FOUND</code> if none can be found
|
||||||
|
*/
|
||||||
|
public int scanBackward(int position, int bound, char[] chars) {
|
||||||
|
return scanBackward(position, bound, new CharacterMatch(chars));
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Checks whether <code>position</code> resides in a default (C) partition of <code>fDocument</code>.
|
||||||
|
*
|
||||||
|
* @param position the position to be checked
|
||||||
|
* @return <code>true</code> if <code>position</code> is in the default partition of <code>fDocument</code>, <code>false</code> otherwise
|
||||||
|
*/
|
||||||
|
public boolean isDefaultPartition(int position) {
|
||||||
|
return fPartition.equals(getPartition(position).getType());
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Returns the partition at <code>position</code>.
|
||||||
|
*
|
||||||
|
* @param position the position to get the partition for
|
||||||
|
* @return the partition at <code>position</code> or a dummy zero-length
|
||||||
|
* partition if accessing the document fails
|
||||||
|
*/
|
||||||
|
private ITypedRegion getPartition(int position) {
|
||||||
|
if (!contains(fCachedPartition, position)) {
|
||||||
|
Assert.isTrue(position >= 0);
|
||||||
|
Assert.isTrue(position <= fDocument.getLength());
|
||||||
|
|
||||||
|
try {
|
||||||
|
fCachedPartition= TextUtilities.getPartition(fDocument, fPartitioning, position, false);
|
||||||
|
} catch (BadLocationException e) {
|
||||||
|
fCachedPartition= new TypedRegion(position, 0, "__no_partition_at_all"); //$NON-NLS-1$
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return fCachedPartition;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Returns <code>true</code> if <code>region</code> contains <code>position</code>.
|
||||||
|
*
|
||||||
|
* @param region a region
|
||||||
|
* @param position an offset
|
||||||
|
* @return <code>true</code> if <code>region</code> contains <code>position</code>
|
||||||
|
*/
|
||||||
|
private boolean contains(IRegion region, int position) {
|
||||||
|
int offset= region.getOffset();
|
||||||
|
return offset <= position && position < offset + region.getLength();
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Checks if the line seems to be an open condition not followed by a block (i.e. an if, while,
|
||||||
|
* or for statement with just one following statement, see example below).
|
||||||
|
*
|
||||||
|
* <pre>
|
||||||
|
* if (condition)
|
||||||
|
* doStuff();
|
||||||
|
* </pre>
|
||||||
|
*
|
||||||
|
* <p>Algorithm: if the last non-WS, non-Comment code on the line is an if (condition), while (condition),
|
||||||
|
* for( expression), do, else, and there is no statement after that </p>
|
||||||
|
*
|
||||||
|
* @param position the insert position of the new character
|
||||||
|
* @param bound the lowest position to consider
|
||||||
|
* @return <code>true</code> if the code is a conditional statement or loop without a block, <code>false</code> otherwise
|
||||||
|
*/
|
||||||
|
public boolean isBracelessBlockStart(int position, int bound) {
|
||||||
|
if (position < 1)
|
||||||
|
return false;
|
||||||
|
|
||||||
|
switch (previousToken(position, bound)) {
|
||||||
|
case TokenDO:
|
||||||
|
case TokenELSE:
|
||||||
|
return true;
|
||||||
|
case TokenRPAREN:
|
||||||
|
position= findOpeningPeer(fPos, LPAREN, RPAREN);
|
||||||
|
if (position > 0) {
|
||||||
|
switch (previousToken(position - 1, bound)) {
|
||||||
|
case TokenIF:
|
||||||
|
case TokenFOR:
|
||||||
|
case TokenWHILE:
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Returns <code>true</code> if the document, when scanned backwards from <code>start</code>
|
||||||
|
* appears to contain a class instance creation, i.e. a possibly qualified name preceded by a
|
||||||
|
* <code>new</code> keyword. The <code>start</code> must be at the end of the type name, and
|
||||||
|
* before any generic signature or constructor parameter list. The heuristic will return
|
||||||
|
* <code>true</code> if <code>start</code> is at the following positions (|):
|
||||||
|
*
|
||||||
|
* <pre>
|
||||||
|
* new java.util. ArrayList|<String>(10)
|
||||||
|
* new ArrayList |(10)
|
||||||
|
* new / * comment * / ArrayList |(10)
|
||||||
|
* </pre>
|
||||||
|
*
|
||||||
|
* but not the following:
|
||||||
|
*
|
||||||
|
* <pre>
|
||||||
|
* new java.util. ArrayList<String>(10)|
|
||||||
|
* new java.util. ArrayList<String>|(10)
|
||||||
|
* new ArrayList (10)|
|
||||||
|
* ArrayList |(10)
|
||||||
|
* </pre>
|
||||||
|
*
|
||||||
|
* @param start the position where the type name of the class instance creation supposedly ends
|
||||||
|
* @param bound the first position in <code>fDocument</code> to not consider any more, with
|
||||||
|
* <code>bound</code> < <code>start</code>, or <code>UNBOUND</code>
|
||||||
|
* @return <code>true</code> if the current position looks like after the type name of a class
|
||||||
|
* instance creation
|
||||||
|
*/
|
||||||
|
public boolean looksLikeClassInstanceCreationBackward(int start, int bound) {
|
||||||
|
int token= previousToken(start - 1, bound);
|
||||||
|
if (token == Symbols.TokenIDENT) { // type name
|
||||||
|
token= previousToken(getPosition(), bound);
|
||||||
|
while (token == Symbols.TokenOTHER) { // dot of qualification
|
||||||
|
token= previousToken(getPosition(), bound);
|
||||||
|
if (token != Symbols.TokenIDENT) // qualification name
|
||||||
|
return false;
|
||||||
|
token= previousToken(getPosition(), bound);
|
||||||
|
}
|
||||||
|
return token == Symbols.TokenNEW;
|
||||||
|
}
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
File diff suppressed because it is too large
Load diff
|
@ -25,6 +25,8 @@ import org.eclipse.jface.text.rules.SingleLineRule;
|
||||||
import org.eclipse.jface.text.rules.Token;
|
import org.eclipse.jface.text.rules.Token;
|
||||||
import org.eclipse.jface.text.rules.WordRule;
|
import org.eclipse.jface.text.rules.WordRule;
|
||||||
|
|
||||||
|
import org.eclipse.cdt.ui.text.ICPartitions;
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* This scanner is not actually use in the code it was relace by
|
* This scanner is not actually use in the code it was relace by
|
||||||
|
@ -90,7 +92,7 @@ public class CPartitionScanner extends RuleBasedPartitionScanner implements ICPa
|
||||||
public CPartitionScanner() {
|
public CPartitionScanner() {
|
||||||
super();
|
super();
|
||||||
|
|
||||||
IToken comment= new Token(C_MULTILINE_COMMENT);
|
IToken comment= new Token(C_MULTI_LINE_COMMENT);
|
||||||
IToken single_comment= new Token(C_SINGLE_LINE_COMMENT);
|
IToken single_comment= new Token(C_SINGLE_LINE_COMMENT);
|
||||||
IToken string= new Token(C_STRING);
|
IToken string= new Token(C_STRING);
|
||||||
IToken character = new Token(C_CHARACTER);
|
IToken character = new Token(C_CHARACTER);
|
||||||
|
|
|
@ -44,17 +44,23 @@ import org.eclipse.jface.text.source.SourceViewerConfiguration;
|
||||||
import org.eclipse.jface.util.PropertyChangeEvent;
|
import org.eclipse.jface.util.PropertyChangeEvent;
|
||||||
import org.eclipse.swt.SWT;
|
import org.eclipse.swt.SWT;
|
||||||
import org.eclipse.swt.widgets.Shell;
|
import org.eclipse.swt.widgets.Shell;
|
||||||
|
import org.eclipse.ui.IEditorInput;
|
||||||
import org.eclipse.ui.editors.text.TextSourceViewerConfiguration;
|
import org.eclipse.ui.editors.text.TextSourceViewerConfiguration;
|
||||||
import org.eclipse.ui.texteditor.AbstractDecoratedTextEditorPreferenceConstants;
|
import org.eclipse.ui.texteditor.AbstractDecoratedTextEditorPreferenceConstants;
|
||||||
|
import org.eclipse.ui.texteditor.IDocumentProvider;
|
||||||
import org.eclipse.ui.texteditor.ITextEditor;
|
import org.eclipse.ui.texteditor.ITextEditor;
|
||||||
|
|
||||||
import org.eclipse.cdt.core.dom.ast.gnu.c.GCCLanguage;
|
import org.eclipse.cdt.core.dom.ast.gnu.c.GCCLanguage;
|
||||||
import org.eclipse.cdt.core.dom.ast.gnu.cpp.GPPLanguage;
|
import org.eclipse.cdt.core.dom.ast.gnu.cpp.GPPLanguage;
|
||||||
|
import org.eclipse.cdt.core.model.ICElement;
|
||||||
|
import org.eclipse.cdt.core.model.ICProject;
|
||||||
import org.eclipse.cdt.core.model.ILanguage;
|
import org.eclipse.cdt.core.model.ILanguage;
|
||||||
import org.eclipse.cdt.ui.CElementContentProvider;
|
import org.eclipse.cdt.ui.CElementContentProvider;
|
||||||
import org.eclipse.cdt.ui.CUIPlugin;
|
import org.eclipse.cdt.ui.CUIPlugin;
|
||||||
import org.eclipse.cdt.ui.ILanguageUI;
|
import org.eclipse.cdt.ui.ILanguageUI;
|
||||||
|
import org.eclipse.cdt.ui.text.ICPartitions;
|
||||||
|
|
||||||
|
import org.eclipse.cdt.internal.ui.editor.CDocumentProvider;
|
||||||
import org.eclipse.cdt.internal.ui.editor.CEditor;
|
import org.eclipse.cdt.internal.ui.editor.CEditor;
|
||||||
import org.eclipse.cdt.internal.ui.editor.CElementHyperlinkDetector;
|
import org.eclipse.cdt.internal.ui.editor.CElementHyperlinkDetector;
|
||||||
import org.eclipse.cdt.internal.ui.editor.CSourceViewer;
|
import org.eclipse.cdt.internal.ui.editor.CSourceViewer;
|
||||||
|
@ -64,7 +70,6 @@ import org.eclipse.cdt.internal.ui.text.contentassist.CCompletionProcessor2;
|
||||||
import org.eclipse.cdt.internal.ui.text.contentassist.ContentAssistPreference;
|
import org.eclipse.cdt.internal.ui.text.contentassist.ContentAssistPreference;
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Configuration for an <code>SourceViewer</code> which shows C code.
|
* Configuration for an <code>SourceViewer</code> which shows C code.
|
||||||
*/
|
*/
|
||||||
|
@ -144,7 +149,7 @@ public class CSourceViewerConfiguration extends TextSourceViewerConfiguration {
|
||||||
presenter.setDocumentPartitioning(getConfiguredDocumentPartitioning(null));
|
presenter.setDocumentPartitioning(getConfiguredDocumentPartitioning(null));
|
||||||
final IInformationProvider provider = new CElementContentProvider(getEditor());
|
final IInformationProvider provider = new CElementContentProvider(getEditor());
|
||||||
presenter.setInformationProvider(provider, IDocument.DEFAULT_CONTENT_TYPE);
|
presenter.setInformationProvider(provider, IDocument.DEFAULT_CONTENT_TYPE);
|
||||||
presenter.setInformationProvider(provider, ICPartitions.C_MULTILINE_COMMENT);
|
presenter.setInformationProvider(provider, ICPartitions.C_MULTI_LINE_COMMENT);
|
||||||
presenter.setInformationProvider(provider, ICPartitions.C_SINGLE_LINE_COMMENT);
|
presenter.setInformationProvider(provider, ICPartitions.C_SINGLE_LINE_COMMENT);
|
||||||
presenter.setInformationProvider(provider, ICPartitions.C_STRING);
|
presenter.setInformationProvider(provider, ICPartitions.C_STRING);
|
||||||
presenter.setInformationProvider(provider, ICPartitions.C_CHARACTER);
|
presenter.setInformationProvider(provider, ICPartitions.C_CHARACTER);
|
||||||
|
@ -190,8 +195,8 @@ public class CSourceViewerConfiguration extends TextSourceViewerConfiguration {
|
||||||
reconciler.setRepairer(dr, ICPartitions.C_SINGLE_LINE_COMMENT);
|
reconciler.setRepairer(dr, ICPartitions.C_SINGLE_LINE_COMMENT);
|
||||||
|
|
||||||
dr= new DefaultDamagerRepairer(getMultilineCommentScanner());
|
dr= new DefaultDamagerRepairer(getMultilineCommentScanner());
|
||||||
reconciler.setDamager(dr, ICPartitions.C_MULTILINE_COMMENT);
|
reconciler.setDamager(dr, ICPartitions.C_MULTI_LINE_COMMENT);
|
||||||
reconciler.setRepairer(dr, ICPartitions.C_MULTILINE_COMMENT);
|
reconciler.setRepairer(dr, ICPartitions.C_MULTI_LINE_COMMENT);
|
||||||
|
|
||||||
dr= new DefaultDamagerRepairer(getStringScanner());
|
dr= new DefaultDamagerRepairer(getStringScanner());
|
||||||
reconciler.setDamager(dr, ICPartitions.C_STRING);
|
reconciler.setDamager(dr, ICPartitions.C_STRING);
|
||||||
|
@ -247,10 +252,13 @@ public class CSourceViewerConfiguration extends TextSourceViewerConfiguration {
|
||||||
* @see org.eclipse.jface.text.source.SourceViewerConfiguration#getAutoEditStrategies(org.eclipse.jface.text.source.ISourceViewer, java.lang.String)
|
* @see org.eclipse.jface.text.source.SourceViewerConfiguration#getAutoEditStrategies(org.eclipse.jface.text.source.ISourceViewer, java.lang.String)
|
||||||
*/
|
*/
|
||||||
public IAutoEditStrategy[] getAutoEditStrategies(ISourceViewer sourceViewer, String contentType) {
|
public IAutoEditStrategy[] getAutoEditStrategies(ISourceViewer sourceViewer, String contentType) {
|
||||||
if(ICPartitions.C_MULTILINE_COMMENT.equals(contentType)) {
|
String partitioning= getConfiguredDocumentPartitioning(sourceViewer);
|
||||||
return new IAutoEditStrategy[] {new CCommentAutoIndentStrategy()};
|
if (ICPartitions.C_MULTI_LINE_COMMENT.equals(contentType))
|
||||||
}
|
return new IAutoEditStrategy[] { new CCommentAutoIndentStrategy() };
|
||||||
return new IAutoEditStrategy[] {new CAutoIndentStrategy()};
|
// else if (ICPartitions.C_STRING.equals(contentType))
|
||||||
|
// return new IAutoEditStrategy[] { new SmartSemicolonAutoEditStrategy(partitioning), new JavaStringAutoIndentStrategy(partitioning) };
|
||||||
|
else
|
||||||
|
return new IAutoEditStrategy[] { new CAutoIndentStrategy(partitioning, getProject()) };
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -303,6 +311,25 @@ public class CSourceViewerConfiguration extends TextSourceViewerConfiguration {
|
||||||
return (String[]) vector.toArray(new String[vector.size()]);
|
return (String[]) vector.toArray(new String[vector.size()]);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private ICProject getProject() {
|
||||||
|
ITextEditor editor= getEditor();
|
||||||
|
if (editor == null)
|
||||||
|
return null;
|
||||||
|
|
||||||
|
ICElement element= null;
|
||||||
|
IEditorInput input= editor.getEditorInput();
|
||||||
|
IDocumentProvider provider= editor.getDocumentProvider();
|
||||||
|
if (provider instanceof CDocumentProvider) {
|
||||||
|
CDocumentProvider cudp= (CDocumentProvider) provider;
|
||||||
|
element= cudp.getWorkingCopy(input);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (element == null)
|
||||||
|
return null;
|
||||||
|
|
||||||
|
return element.getCProject();
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @see SourceViewerConfiguration#getAnnotationHover(ISourceViewer)
|
* @see SourceViewerConfiguration#getAnnotationHover(ISourceViewer)
|
||||||
*/
|
*/
|
||||||
|
@ -370,7 +397,7 @@ public class CSourceViewerConfiguration extends TextSourceViewerConfiguration {
|
||||||
public String[] getConfiguredContentTypes(ISourceViewer sourceViewer) {
|
public String[] getConfiguredContentTypes(ISourceViewer sourceViewer) {
|
||||||
return new String[] {
|
return new String[] {
|
||||||
IDocument.DEFAULT_CONTENT_TYPE,
|
IDocument.DEFAULT_CONTENT_TYPE,
|
||||||
ICPartitions.C_MULTILINE_COMMENT,
|
ICPartitions.C_MULTI_LINE_COMMENT,
|
||||||
ICPartitions.C_SINGLE_LINE_COMMENT,
|
ICPartitions.C_SINGLE_LINE_COMMENT,
|
||||||
ICPartitions.C_STRING,
|
ICPartitions.C_STRING,
|
||||||
ICPartitions.C_CHARACTER};
|
ICPartitions.C_CHARACTER};
|
||||||
|
|
|
@ -11,11 +11,7 @@
|
||||||
*******************************************************************************/
|
*******************************************************************************/
|
||||||
package org.eclipse.cdt.internal.ui.text;
|
package org.eclipse.cdt.internal.ui.text;
|
||||||
|
|
||||||
import org.eclipse.cdt.internal.ui.text.util.CColorManager;
|
|
||||||
import org.eclipse.cdt.ui.CUIPlugin;
|
|
||||||
|
|
||||||
import org.eclipse.core.runtime.Preferences;
|
import org.eclipse.core.runtime.Preferences;
|
||||||
|
|
||||||
import org.eclipse.jface.preference.IPreferenceStore;
|
import org.eclipse.jface.preference.IPreferenceStore;
|
||||||
import org.eclipse.jface.text.IDocument;
|
import org.eclipse.jface.text.IDocument;
|
||||||
import org.eclipse.jface.text.IDocumentExtension3;
|
import org.eclipse.jface.text.IDocumentExtension3;
|
||||||
|
@ -26,6 +22,11 @@ import org.eclipse.jface.text.rules.RuleBasedScanner;
|
||||||
import org.eclipse.jface.util.IPropertyChangeListener;
|
import org.eclipse.jface.util.IPropertyChangeListener;
|
||||||
import org.eclipse.jface.util.PropertyChangeEvent;
|
import org.eclipse.jface.util.PropertyChangeEvent;
|
||||||
|
|
||||||
|
import org.eclipse.cdt.ui.CUIPlugin;
|
||||||
|
import org.eclipse.cdt.ui.text.ICPartitions;
|
||||||
|
|
||||||
|
import org.eclipse.cdt.internal.ui.text.util.CColorManager;
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* This type shares all scanners and the color manager between
|
* This type shares all scanners and the color manager between
|
||||||
|
@ -178,7 +179,7 @@ public class CTextTools {
|
||||||
public IDocumentPartitioner createDocumentPartitioner() {
|
public IDocumentPartitioner createDocumentPartitioner() {
|
||||||
|
|
||||||
String[] types= new String[] {
|
String[] types= new String[] {
|
||||||
ICPartitions.C_MULTILINE_COMMENT,
|
ICPartitions.C_MULTI_LINE_COMMENT,
|
||||||
ICPartitions.C_SINGLE_LINE_COMMENT,
|
ICPartitions.C_SINGLE_LINE_COMMENT,
|
||||||
ICPartitions.C_STRING,
|
ICPartitions.C_STRING,
|
||||||
ICPartitions.C_CHARACTER
|
ICPartitions.C_CHARACTER
|
||||||
|
|
|
@ -18,6 +18,8 @@ import org.eclipse.jface.text.rules.IPartitionTokenScanner;
|
||||||
import org.eclipse.jface.text.rules.IToken;
|
import org.eclipse.jface.text.rules.IToken;
|
||||||
import org.eclipse.jface.text.rules.Token;
|
import org.eclipse.jface.text.rules.Token;
|
||||||
|
|
||||||
|
import org.eclipse.cdt.ui.text.ICPartitions;
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* This scanner recognizes the C multi line comments, C single line comments,
|
* This scanner recognizes the C multi line comments, C single line comments,
|
||||||
|
@ -59,7 +61,7 @@ public class FastCPartitionScanner implements IPartitionTokenScanner, ICPartitio
|
||||||
private final IToken[] fTokens= new IToken[] {
|
private final IToken[] fTokens= new IToken[] {
|
||||||
new Token(null),
|
new Token(null),
|
||||||
new Token(C_SINGLE_LINE_COMMENT),
|
new Token(C_SINGLE_LINE_COMMENT),
|
||||||
new Token(C_MULTILINE_COMMENT),
|
new Token(C_MULTI_LINE_COMMENT),
|
||||||
new Token(C_CHARACTER),
|
new Token(C_CHARACTER),
|
||||||
new Token(C_STRING)
|
new Token(C_STRING)
|
||||||
};
|
};
|
||||||
|
@ -340,7 +342,7 @@ public class FastCPartitionScanner implements IPartitionTokenScanner, ICPartitio
|
||||||
else if (contentType.equals(C_SINGLE_LINE_COMMENT))
|
else if (contentType.equals(C_SINGLE_LINE_COMMENT))
|
||||||
return SINGLE_LINE_COMMENT;
|
return SINGLE_LINE_COMMENT;
|
||||||
|
|
||||||
else if (contentType.equals(C_MULTILINE_COMMENT))
|
else if (contentType.equals(C_MULTI_LINE_COMMENT))
|
||||||
return MULTI_LINE_COMMENT;
|
return MULTI_LINE_COMMENT;
|
||||||
|
|
||||||
else if (contentType.equals(C_STRING))
|
else if (contentType.equals(C_STRING))
|
||||||
|
|
|
@ -0,0 +1,374 @@
|
||||||
|
/*******************************************************************************
|
||||||
|
* Copyright (c) 2000, 2006 IBM Corporation and others.
|
||||||
|
* All rights reserved. This program and the accompanying materials
|
||||||
|
* are made available under the terms of the Eclipse Public License v1.0
|
||||||
|
* which accompanies this distribution, and is available at
|
||||||
|
* http://www.eclipse.org/legal/epl-v10.html
|
||||||
|
*
|
||||||
|
* Contributors:
|
||||||
|
* IBM Corporation - initial API and implementation
|
||||||
|
*******************************************************************************/
|
||||||
|
package org.eclipse.cdt.internal.ui.text;
|
||||||
|
|
||||||
|
import org.eclipse.jface.text.IDocument;
|
||||||
|
import org.eclipse.jface.text.IDocumentListener;
|
||||||
|
import org.eclipse.jface.text.IDocumentPartitioner;
|
||||||
|
import org.eclipse.jface.text.IDocumentPartitioningListener;
|
||||||
|
import org.eclipse.jface.text.IPositionUpdater;
|
||||||
|
import org.eclipse.jface.text.IRegion;
|
||||||
|
import org.eclipse.jface.text.ITypedRegion;
|
||||||
|
import org.eclipse.jface.text.Position;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Minimal implementation of IDocument to apply text edit onto a string.
|
||||||
|
*/
|
||||||
|
public class SimpleDocument implements IDocument {
|
||||||
|
|
||||||
|
private StringBuffer buffer;
|
||||||
|
|
||||||
|
public SimpleDocument(String source) {
|
||||||
|
buffer = new StringBuffer(source);
|
||||||
|
}
|
||||||
|
|
||||||
|
public SimpleDocument(char[] source) {
|
||||||
|
buffer = new StringBuffer(source.length);
|
||||||
|
buffer.append(source);
|
||||||
|
}
|
||||||
|
|
||||||
|
/* (non-Javadoc)
|
||||||
|
* @see org.eclipse.jface.text.IDocument#getChar(int)
|
||||||
|
*/
|
||||||
|
public char getChar(int offset) {
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* (non-Javadoc)
|
||||||
|
* @see org.eclipse.jface.text.IDocument#getLength()
|
||||||
|
*/
|
||||||
|
public int getLength() {
|
||||||
|
return this.buffer.length();
|
||||||
|
}
|
||||||
|
|
||||||
|
/* (non-Javadoc)
|
||||||
|
* @see org.eclipse.jface.text.IDocument#get()
|
||||||
|
*/
|
||||||
|
public String get() {
|
||||||
|
return this.buffer.toString();
|
||||||
|
}
|
||||||
|
|
||||||
|
/* (non-Javadoc)
|
||||||
|
* @see org.eclipse.jface.text.IDocument#get(int, int)
|
||||||
|
*/
|
||||||
|
public String get(int offset, int length) {
|
||||||
|
return this.buffer.substring(offset, offset + length);
|
||||||
|
}
|
||||||
|
|
||||||
|
/* (non-Javadoc)
|
||||||
|
* @see org.eclipse.jface.text.IDocument#set(java.lang.String)
|
||||||
|
*/
|
||||||
|
public void set(String text) {
|
||||||
|
// defining interface method
|
||||||
|
}
|
||||||
|
|
||||||
|
/* (non-Javadoc)
|
||||||
|
* @see org.eclipse.jface.text.IDocument#replace(int, int, java.lang.String)
|
||||||
|
*/
|
||||||
|
public void replace(int offset, int length, String text) {
|
||||||
|
|
||||||
|
this.buffer.replace(offset, offset + length, text);
|
||||||
|
}
|
||||||
|
|
||||||
|
/* (non-Javadoc)
|
||||||
|
* @see org.eclipse.jface.text.IDocument#addDocumentListener(org.eclipse.jface.text.IDocumentListener)
|
||||||
|
*/
|
||||||
|
public void addDocumentListener(IDocumentListener listener) {
|
||||||
|
// defining interface method
|
||||||
|
}
|
||||||
|
|
||||||
|
/* (non-Javadoc)
|
||||||
|
* @see org.eclipse.jface.text.IDocument#removeDocumentListener(org.eclipse.jface.text.IDocumentListener)
|
||||||
|
*/
|
||||||
|
public void removeDocumentListener(IDocumentListener listener) {
|
||||||
|
// defining interface method
|
||||||
|
}
|
||||||
|
|
||||||
|
/* (non-Javadoc)
|
||||||
|
* @see org.eclipse.jface.text.IDocument#addPrenotifiedDocumentListener(org.eclipse.jface.text.IDocumentListener)
|
||||||
|
*/
|
||||||
|
public void addPrenotifiedDocumentListener(IDocumentListener documentAdapter) {
|
||||||
|
// defining interface method
|
||||||
|
}
|
||||||
|
|
||||||
|
/* (non-Javadoc)
|
||||||
|
* @see org.eclipse.jface.text.IDocument#removePrenotifiedDocumentListener(org.eclipse.jface.text.IDocumentListener)
|
||||||
|
*/
|
||||||
|
public void removePrenotifiedDocumentListener(IDocumentListener documentAdapter) {
|
||||||
|
// defining interface method
|
||||||
|
}
|
||||||
|
|
||||||
|
/* (non-Javadoc)
|
||||||
|
* @see org.eclipse.jface.text.IDocument#addPositionCategory(java.lang.String)
|
||||||
|
*/
|
||||||
|
public void addPositionCategory(String category) {
|
||||||
|
// defining interface method
|
||||||
|
}
|
||||||
|
|
||||||
|
/* (non-Javadoc)
|
||||||
|
* @see org.eclipse.jface.text.IDocument#removePositionCategory(java.lang.String)
|
||||||
|
*/
|
||||||
|
public void removePositionCategory(String category) {
|
||||||
|
// defining interface method
|
||||||
|
}
|
||||||
|
|
||||||
|
/* (non-Javadoc)
|
||||||
|
* @see org.eclipse.jface.text.IDocument#getPositionCategories()
|
||||||
|
*/
|
||||||
|
public String[] getPositionCategories() {
|
||||||
|
// defining interface method
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* (non-Javadoc)
|
||||||
|
* @see org.eclipse.jface.text.IDocument#containsPositionCategory(java.lang.String)
|
||||||
|
*/
|
||||||
|
public boolean containsPositionCategory(String category) {
|
||||||
|
// defining interface method
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* (non-Javadoc)
|
||||||
|
* @see org.eclipse.jface.text.IDocument#addPosition(org.eclipse.jface.text.Position)
|
||||||
|
*/
|
||||||
|
public void addPosition(Position position) {
|
||||||
|
// defining interface method
|
||||||
|
}
|
||||||
|
|
||||||
|
/* (non-Javadoc)
|
||||||
|
* @see org.eclipse.jface.text.IDocument#removePosition(org.eclipse.jface.text.Position)
|
||||||
|
*/
|
||||||
|
public void removePosition(Position position) {
|
||||||
|
// defining interface method
|
||||||
|
}
|
||||||
|
|
||||||
|
/* (non-Javadoc)
|
||||||
|
* @see org.eclipse.jface.text.IDocument#addPosition(java.lang.String, org.eclipse.jface.text.Position)
|
||||||
|
*/
|
||||||
|
public void addPosition(String category, Position position) {
|
||||||
|
// defining interface method
|
||||||
|
}
|
||||||
|
|
||||||
|
/* (non-Javadoc)
|
||||||
|
* @see org.eclipse.jface.text.IDocument#removePosition(java.lang.String, org.eclipse.jface.text.Position)
|
||||||
|
*/
|
||||||
|
public void removePosition(String category, Position position) {
|
||||||
|
// defining interface method
|
||||||
|
}
|
||||||
|
|
||||||
|
/* (non-Javadoc)
|
||||||
|
* @see org.eclipse.jface.text.IDocument#getPositions(java.lang.String)
|
||||||
|
*/
|
||||||
|
public Position[] getPositions(String category) {
|
||||||
|
// defining interface method
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* (non-Javadoc)
|
||||||
|
* @see org.eclipse.jface.text.IDocument#containsPosition(java.lang.String, int, int)
|
||||||
|
*/
|
||||||
|
public boolean containsPosition(String category, int offset, int length) {
|
||||||
|
// defining interface method
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* (non-Javadoc)
|
||||||
|
* @see org.eclipse.jface.text.IDocument#computeIndexInCategory(java.lang.String, int)
|
||||||
|
*/
|
||||||
|
public int computeIndexInCategory(String category, int offset) {
|
||||||
|
// defining interface method
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* (non-Javadoc)
|
||||||
|
* @see org.eclipse.jface.text.IDocument#addPositionUpdater(org.eclipse.jface.text.IPositionUpdater)
|
||||||
|
*/
|
||||||
|
public void addPositionUpdater(IPositionUpdater updater) {
|
||||||
|
// defining interface method
|
||||||
|
}
|
||||||
|
|
||||||
|
/* (non-Javadoc)
|
||||||
|
* @see org.eclipse.jface.text.IDocument#removePositionUpdater(org.eclipse.jface.text.IPositionUpdater)
|
||||||
|
*/
|
||||||
|
public void removePositionUpdater(IPositionUpdater updater) {
|
||||||
|
// defining interface method
|
||||||
|
}
|
||||||
|
|
||||||
|
/* (non-Javadoc)
|
||||||
|
* @see org.eclipse.jface.text.IDocument#insertPositionUpdater(org.eclipse.jface.text.IPositionUpdater, int)
|
||||||
|
*/
|
||||||
|
public void insertPositionUpdater(IPositionUpdater updater, int index) {
|
||||||
|
// defining interface method
|
||||||
|
}
|
||||||
|
|
||||||
|
/* (non-Javadoc)
|
||||||
|
* @see org.eclipse.jface.text.IDocument#getPositionUpdaters()
|
||||||
|
*/
|
||||||
|
public IPositionUpdater[] getPositionUpdaters() {
|
||||||
|
// defining interface method
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* (non-Javadoc)
|
||||||
|
* @see org.eclipse.jface.text.IDocument#getLegalContentTypes()
|
||||||
|
*/
|
||||||
|
public String[] getLegalContentTypes() {
|
||||||
|
// defining interface method
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* (non-Javadoc)
|
||||||
|
* @see org.eclipse.jface.text.IDocument#getContentType(int)
|
||||||
|
*/
|
||||||
|
public String getContentType(int offset) {
|
||||||
|
// defining interface method
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* (non-Javadoc)
|
||||||
|
* @see org.eclipse.jface.text.IDocument#getPartition(int)
|
||||||
|
*/
|
||||||
|
public ITypedRegion getPartition(int offset) {
|
||||||
|
// defining interface method
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* (non-Javadoc)
|
||||||
|
* @see org.eclipse.jface.text.IDocument#computePartitioning(int, int)
|
||||||
|
*/
|
||||||
|
public ITypedRegion[] computePartitioning(int offset, int length) {
|
||||||
|
// defining interface method
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* (non-Javadoc)
|
||||||
|
* @see org.eclipse.jface.text.IDocument#addDocumentPartitioningListener(org.eclipse.jface.text.IDocumentPartitioningListener)
|
||||||
|
*/
|
||||||
|
public void addDocumentPartitioningListener(IDocumentPartitioningListener listener) {
|
||||||
|
// defining interface method
|
||||||
|
}
|
||||||
|
|
||||||
|
/* (non-Javadoc)
|
||||||
|
* @see org.eclipse.jface.text.IDocument#removeDocumentPartitioningListener(org.eclipse.jface.text.IDocumentPartitioningListener)
|
||||||
|
*/
|
||||||
|
public void removeDocumentPartitioningListener(IDocumentPartitioningListener listener) {
|
||||||
|
// defining interface method
|
||||||
|
}
|
||||||
|
|
||||||
|
/* (non-Javadoc)
|
||||||
|
* @see org.eclipse.jface.text.IDocument#setDocumentPartitioner(org.eclipse.jface.text.IDocumentPartitioner)
|
||||||
|
*/
|
||||||
|
public void setDocumentPartitioner(IDocumentPartitioner partitioner) {
|
||||||
|
// defining interface method
|
||||||
|
}
|
||||||
|
|
||||||
|
/* (non-Javadoc)
|
||||||
|
* @see org.eclipse.jface.text.IDocument#getDocumentPartitioner()
|
||||||
|
*/
|
||||||
|
public IDocumentPartitioner getDocumentPartitioner() {
|
||||||
|
// defining interface method
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* (non-Javadoc)
|
||||||
|
* @see org.eclipse.jface.text.IDocument#getLineLength(int)
|
||||||
|
*/
|
||||||
|
public int getLineLength(int line) {
|
||||||
|
// defining interface method
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* (non-Javadoc)
|
||||||
|
* @see org.eclipse.jface.text.IDocument#getLineOfOffset(int)
|
||||||
|
*/
|
||||||
|
public int getLineOfOffset(int offset) {
|
||||||
|
// defining interface method
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* (non-Javadoc)
|
||||||
|
* @see org.eclipse.jface.text.IDocument#getLineOffset(int)
|
||||||
|
*/
|
||||||
|
public int getLineOffset(int line) {
|
||||||
|
// defining interface method
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* (non-Javadoc)
|
||||||
|
* @see org.eclipse.jface.text.IDocument#getLineInformation(int)
|
||||||
|
*/
|
||||||
|
public IRegion getLineInformation(int line) {
|
||||||
|
// defining interface method
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* (non-Javadoc)
|
||||||
|
* @see org.eclipse.jface.text.IDocument#getLineInformationOfOffset(int)
|
||||||
|
*/
|
||||||
|
public IRegion getLineInformationOfOffset(int offset) {
|
||||||
|
// defining interface method
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* (non-Javadoc)
|
||||||
|
* @see org.eclipse.jface.text.IDocument#getNumberOfLines()
|
||||||
|
*/
|
||||||
|
public int getNumberOfLines() {
|
||||||
|
// defining interface method
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* (non-Javadoc)
|
||||||
|
* @see org.eclipse.jface.text.IDocument#getNumberOfLines(int, int)
|
||||||
|
*/
|
||||||
|
public int getNumberOfLines(int offset, int length) {
|
||||||
|
// defining interface method
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* (non-Javadoc)
|
||||||
|
* @see org.eclipse.jface.text.IDocument#computeNumberOfLines(java.lang.String)
|
||||||
|
*/
|
||||||
|
public int computeNumberOfLines(String text) {
|
||||||
|
// defining interface method
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* (non-Javadoc)
|
||||||
|
* @see org.eclipse.jface.text.IDocument#getLegalLineDelimiters()
|
||||||
|
*/
|
||||||
|
public String[] getLegalLineDelimiters() {
|
||||||
|
// defining interface method
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* (non-Javadoc)
|
||||||
|
* @see org.eclipse.jface.text.IDocument#getLineDelimiter(int)
|
||||||
|
*/
|
||||||
|
public String getLineDelimiter(int line) {
|
||||||
|
// defining interface method
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @see org.eclipse.jface.text.IDocument#search(int, java.lang.String, boolean, boolean, boolean)
|
||||||
|
* @deprecated
|
||||||
|
*/
|
||||||
|
public int search(
|
||||||
|
int startOffset,
|
||||||
|
String findString,
|
||||||
|
boolean forwardSearch,
|
||||||
|
boolean caseSensitive,
|
||||||
|
boolean wholeWord) {
|
||||||
|
// defining interface method
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,53 @@
|
||||||
|
/*******************************************************************************
|
||||||
|
* Copyright (c) 2000, 2005 IBM Corporation and others.
|
||||||
|
* All rights reserved. This program and the accompanying materials
|
||||||
|
* are made available under the terms of the Eclipse Public License v1.0
|
||||||
|
* which accompanies this distribution, and is available at
|
||||||
|
* http://www.eclipse.org/legal/epl-v10.html
|
||||||
|
*
|
||||||
|
* Contributors:
|
||||||
|
* IBM Corporation - initial API and implementation
|
||||||
|
*******************************************************************************/
|
||||||
|
package org.eclipse.cdt.internal.ui.text;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Symbols for the heuristic C/C++ scanner.
|
||||||
|
*/
|
||||||
|
public interface Symbols {
|
||||||
|
int TokenEOF= -1;
|
||||||
|
int TokenLBRACE= 1;
|
||||||
|
int TokenRBRACE= 2;
|
||||||
|
int TokenLBRACKET= 3;
|
||||||
|
int TokenRBRACKET= 4;
|
||||||
|
int TokenLPAREN= 5;
|
||||||
|
int TokenRPAREN= 6;
|
||||||
|
int TokenSEMICOLON= 7;
|
||||||
|
int TokenOTHER= 8;
|
||||||
|
int TokenCOLON= 9;
|
||||||
|
int TokenQUESTIONMARK= 10;
|
||||||
|
int TokenCOMMA= 11;
|
||||||
|
int TokenEQUAL= 12;
|
||||||
|
int TokenLESSTHAN= 13;
|
||||||
|
int TokenGREATERTHAN= 14;
|
||||||
|
int TokenIF= 109;
|
||||||
|
int TokenDO= 1010;
|
||||||
|
int TokenFOR= 1011;
|
||||||
|
int TokenTRY= 1012;
|
||||||
|
int TokenCASE= 1013;
|
||||||
|
int TokenELSE= 1014;
|
||||||
|
int TokenBREAK= 1015;
|
||||||
|
int TokenCATCH= 1016;
|
||||||
|
int TokenWHILE= 1017;
|
||||||
|
int TokenRETURN= 1018;
|
||||||
|
int TokenSTATIC= 1019;
|
||||||
|
int TokenSWITCH= 1020;
|
||||||
|
// int TokenFINALLY= 1021;
|
||||||
|
// int TokenSYNCHRONIZED= 1022;
|
||||||
|
int TokenGOTO= 1023;
|
||||||
|
int TokenDEFAULT= 1024;
|
||||||
|
int TokenNEW= 1025;
|
||||||
|
int TokenCLASS= 1026;
|
||||||
|
// int TokenINTERFACE= 1027;
|
||||||
|
int TokenENUM= 1028;
|
||||||
|
int TokenIDENT= 2000;
|
||||||
|
}
|
|
@ -160,6 +160,51 @@ public class PreferenceConstants {
|
||||||
*/
|
*/
|
||||||
public static final String EDITOR_TEXT_HOVER_MODIFIER_MASKS= "hoverModifierMasks"; //$NON-NLS-1$
|
public static final String EDITOR_TEXT_HOVER_MODIFIER_MASKS= "hoverModifierMasks"; //$NON-NLS-1$
|
||||||
|
|
||||||
|
/**
|
||||||
|
* A named preference that controls whether the 'close strings' feature
|
||||||
|
* is enabled.
|
||||||
|
* <p>
|
||||||
|
* Value is of type <code>Boolean</code>.
|
||||||
|
* </p>
|
||||||
|
*/
|
||||||
|
public final static String EDITOR_CLOSE_STRINGS= "closeStrings"; //$NON-NLS-1$
|
||||||
|
|
||||||
|
/**
|
||||||
|
* A named preference that controls whether the 'wrap strings' feature is
|
||||||
|
* enabled.
|
||||||
|
* <p>
|
||||||
|
* Value is of type <code>Boolean</code>.
|
||||||
|
* </p>
|
||||||
|
*/
|
||||||
|
public final static String EDITOR_WRAP_STRINGS= "wrapStrings"; //$NON-NLS-1$
|
||||||
|
|
||||||
|
/**
|
||||||
|
* A named preference that controls whether the 'escape strings' feature is
|
||||||
|
* enabled.
|
||||||
|
* <p>
|
||||||
|
* Value is of type <code>Boolean</code>.
|
||||||
|
* </p>
|
||||||
|
*/
|
||||||
|
public final static String EDITOR_ESCAPE_STRINGS= "escapeStrings"; //$NON-NLS-1$
|
||||||
|
|
||||||
|
/**
|
||||||
|
* A named preference that controls whether the 'close brackets' feature is
|
||||||
|
* enabled.
|
||||||
|
* <p>
|
||||||
|
* Value is of type <code>Boolean</code>.
|
||||||
|
* </p>
|
||||||
|
*/
|
||||||
|
public final static String EDITOR_CLOSE_BRACKETS= "closeBrackets"; //$NON-NLS-1$
|
||||||
|
|
||||||
|
/**
|
||||||
|
* A named preference that controls whether the 'close braces' feature is
|
||||||
|
* enabled.
|
||||||
|
* <p>
|
||||||
|
* Value is of type <code>Boolean</code>.
|
||||||
|
* </p>
|
||||||
|
*/
|
||||||
|
public final static String EDITOR_CLOSE_BRACES= "closeBraces"; //$NON-NLS-1$
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* The id of the best match hover contributed for extension point
|
* The id of the best match hover contributed for extension point
|
||||||
* <code>javaEditorTextHovers</code>.
|
* <code>javaEditorTextHovers</code>.
|
||||||
|
@ -412,6 +457,10 @@ public class PreferenceConstants {
|
||||||
store.setDefault(PreferenceConstants.EDITOR_FOLDING_METHODS, false);
|
store.setDefault(PreferenceConstants.EDITOR_FOLDING_METHODS, false);
|
||||||
store.setDefault(PreferenceConstants.EDITOR_FOLDING_MACROS, true);
|
store.setDefault(PreferenceConstants.EDITOR_FOLDING_MACROS, true);
|
||||||
|
|
||||||
|
store.setDefault(PreferenceConstants.EDITOR_CLOSE_STRINGS, true);
|
||||||
|
store.setDefault(PreferenceConstants.EDITOR_CLOSE_BRACKETS, true);
|
||||||
|
store.setDefault(PreferenceConstants.EDITOR_CLOSE_BRACES, true);
|
||||||
|
store.setDefault(PreferenceConstants.EDITOR_WRAP_STRINGS, true);
|
||||||
|
store.setDefault(PreferenceConstants.EDITOR_ESCAPE_STRINGS, false);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,49 +1,42 @@
|
||||||
/*******************************************************************************
|
/*******************************************************************************
|
||||||
* Copyright (c) 2000, 2006 QNX Software Systems and others.
|
* Copyright (c) 2000, 2006 IBM Corporation 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:
|
||||||
* QNX Software Systems - Initial API and implementation
|
* IBM Corporation - initial API and implementation
|
||||||
* IBM Corporation
|
|
||||||
*******************************************************************************/
|
*******************************************************************************/
|
||||||
|
package org.eclipse.cdt.ui.text;
|
||||||
package org.eclipse.cdt.internal.ui.text;
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
*
|
* Definition of C partitioning and its partitions.
|
||||||
* The name of the C partitioning.
|
|
||||||
* @since 3.0
|
|
||||||
*/
|
*/
|
||||||
public interface ICPartitions {
|
public interface ICPartitions {
|
||||||
|
|
||||||
String SKIP= "__skip"; //$NON-NLS-1$
|
|
||||||
/**
|
|
||||||
* The identifier multi-line (JLS2: TraditionalComment) comment partition content type.
|
|
||||||
*/
|
|
||||||
String C_MULTILINE_COMMENT= "c_multi_line_comment"; //$NON-NLS-1$
|
|
||||||
|
|
||||||
/**
|
|
||||||
* The identifier of the single-line (JLS2: EndOfLineComment) end comment partition content type.
|
|
||||||
*/
|
|
||||||
String C_SINGLE_LINE_COMMENT= "c_single_line_comment"; //$NON-NLS-1$
|
|
||||||
|
|
||||||
/**
|
|
||||||
* The identifier of the C string partition content type.
|
|
||||||
*/
|
|
||||||
String C_STRING= "c_string"; //$NON-NLS-1$
|
|
||||||
|
|
||||||
/**
|
|
||||||
* The identifier of the C character partition content type.
|
|
||||||
*/
|
|
||||||
String C_CHARACTER= "c_character"; //$NON-NLS-1$
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* The identifier of the C partitioning.
|
* The identifier of the C partitioning.
|
||||||
*/
|
*/
|
||||||
String C_PARTITIONING= "___c_partitioning"; //$NON-NLS-1$
|
String C_PARTITIONING= "___c_partitioning"; //$NON-NLS-1$
|
||||||
|
|
||||||
|
/**
|
||||||
|
* The identifier of the single-line end comment partition content type.
|
||||||
|
*/
|
||||||
|
String C_SINGLE_LINE_COMMENT= "__c_singleline_comment"; //$NON-NLS-1$
|
||||||
|
|
||||||
|
/**
|
||||||
|
* The identifier multi-line comment partition content type.
|
||||||
|
*/
|
||||||
|
String C_MULTI_LINE_COMMENT= "__c_multiline_comment"; //$NON-NLS-1$
|
||||||
|
|
||||||
|
/**
|
||||||
|
* The identifier of the C string partition content type.
|
||||||
|
*/
|
||||||
|
String C_STRING= "__c_string"; //$NON-NLS-1$
|
||||||
|
|
||||||
|
/**
|
||||||
|
* The identifier of the C character partition content type.
|
||||||
|
*/
|
||||||
|
String C_CHARACTER= "__c_character"; //$NON-NLS-1$
|
||||||
}
|
}
|
Loading…
Add table
Reference in a new issue