diff --git a/core/org.eclipse.cdt.ui.tests/resources/indentation/sample/After.cpp b/core/org.eclipse.cdt.ui.tests/resources/indentation/sample/After.cpp index bb1040abe7d..1d7eae8de46 100644 --- a/core/org.eclipse.cdt.ui.tests/resources/indentation/sample/After.cpp +++ b/core/org.eclipse.cdt.ui.tests/resources/indentation/sample/After.cpp @@ -9,12 +9,19 @@ const SimpleStruct simpleStruct = #define SIZEOF( A, B ) sizeof( A.B ) +#define FOREVER \ + for(;;)\ + {\ + \ + } +} + const OtherStruct array[] = { { #if FOO "foo" -#else +# else "bar" #endif , SIZEOF( simpleStruct, num ) diff --git a/core/org.eclipse.cdt.ui.tests/resources/indentation/sample/Before.cpp b/core/org.eclipse.cdt.ui.tests/resources/indentation/sample/Before.cpp index a0b3297f10d..dc77f8e7333 100644 --- a/core/org.eclipse.cdt.ui.tests/resources/indentation/sample/Before.cpp +++ b/core/org.eclipse.cdt.ui.tests/resources/indentation/sample/Before.cpp @@ -9,12 +9,19 @@ const SimpleStruct simpleStruct = #define SIZEOF( A, B ) sizeof( A.B ) + #define FOREVER \ + for(;;)\ +{\ + \ + } + } + const OtherStruct array[] = { { #if FOO - "foo" - #else + "foo" + # else "bar" #endif , SIZEOF( simpleStruct, num ) diff --git a/core/org.eclipse.cdt.ui.tests/ui/org/eclipse/cdt/ui/tests/text/CAutoIndentTest.java b/core/org.eclipse.cdt.ui.tests/ui/org/eclipse/cdt/ui/tests/text/CAutoIndentTest.java index 8b556c308c9..98e0cb660db 100644 --- a/core/org.eclipse.cdt.ui.tests/ui/org/eclipse/cdt/ui/tests/text/CAutoIndentTest.java +++ b/core/org.eclipse.cdt.ui.tests/ui/org/eclipse/cdt/ui/tests/text/CAutoIndentTest.java @@ -12,7 +12,6 @@ package org.eclipse.cdt.ui.tests.text; -import java.io.IOException; import java.util.HashMap; import java.util.Map; @@ -20,7 +19,6 @@ import junit.framework.Test; import junit.framework.TestCase; import junit.framework.TestSuite; -import org.eclipse.core.runtime.CoreException; import org.eclipse.jface.text.BadLocationException; import org.eclipse.jface.text.Document; import org.eclipse.jface.text.DocumentCommand; @@ -245,10 +243,12 @@ public class CAutoIndentTest extends TestCase { tester.setAutoEditStrategy(IDocument.DEFAULT_CONTENT_TYPE, new CAutoIndentStrategy(textTools.getDocumentPartitioning(), null)); tester.setAutoEditStrategy(ICPartitions.C_MULTI_LINE_COMMENT, new CCommentAutoIndentStrategy()); + tester.setAutoEditStrategy(ICPartitions.C_PREPROCESSOR, + new CAutoIndentStrategy(textTools.getDocumentPartitioning(), null)); return tester; } - public void testCAutoIndent() throws IOException, CoreException, BadLocationException { + public void testCAutoIndent() throws BadLocationException { AutoEditTester tester = createAutoEditTester(); //$NON-NLS-1$ tester.type("void main() {\n"); //$NON-NLS-1$ assertEquals(1, tester.getCaretLine()); @@ -286,7 +286,7 @@ public class CAutoIndentTest extends TestCase { assertEquals("\t\tint x = 5;", tester.getLine(1)); //$NON-NLS-1$ } - public void testPasteAutoIndent() throws IOException, CoreException, BadLocationException { + public void testPasteAutoIndent() throws BadLocationException { AutoEditTester tester = createAutoEditTester(); //$NON-NLS-1$ tester.type("class A {\n"); //$NON-NLS-1$ tester.goTo(1, 0); @@ -313,7 +313,7 @@ public class CAutoIndentTest extends TestCase { assertEquals("\t};", tester.getLine(9)); //$NON-NLS-1$ } - public void testDefaultAutoIndent() throws IOException, CoreException, BadLocationException { + public void testDefaultAutoIndent() throws BadLocationException { AutoEditTester tester = createAutoEditTester(); //$NON-NLS-1$ tester.type(" initial indent=3\n"); //$NON-NLS-1$ assertEquals(1, tester.getCaretLine()); @@ -335,7 +335,7 @@ public class CAutoIndentTest extends TestCase { assertEquals(0, tester.getCaretColumn()); } - public void testCCommentAutoIndent() throws IOException, CoreException, BadLocationException { + public void testCCommentAutoIndent() throws BadLocationException { AutoEditTester tester = createAutoEditTester(); //$NON-NLS-1$ tester.type("/*\n"); //$NON-NLS-1$ assertEquals(ICPartitions.C_MULTI_LINE_COMMENT, tester.getContentType(-1)); @@ -352,4 +352,26 @@ public class CAutoIndentTest extends TestCase { assertEquals(0, tester.getCaretColumn()); } + public void testPreprocessorAutoIndent() throws BadLocationException { + AutoEditTester tester = createAutoEditTester(); //$NON-NLS-1$ + tester.type("void main() {\n"); //$NON-NLS-1$ + assertEquals(1, tester.getCaretLine()); + // Nested statement is indented by one. + assertEquals(1, tester.getCaretColumn()); + // The brace was closed automatically. + assertEquals("}", tester.getLine(1)); //$NON-NLS-1$ + tester.type("#define"); //$NON-NLS-1$ + assertEquals("#define", tester.getLine()); //$NON-NLS-1$ + tester.type(" FOREVER \\\n"); + assertEquals(1, tester.getCaretColumn()); + tester.type("for(;;) \\\n"); + assertEquals(1, tester.getCaretColumn()); + tester.type("\t{"); + assertEquals(2, tester.getCaretColumn()); + assertEquals("\t{", tester.getLine()); + tester.type("\\\n"); + assertEquals(2, tester.getCaretColumn()); + assertEquals("\t}", tester.getLine(1)); + } + } diff --git a/core/org.eclipse.cdt.ui/src/org/eclipse/cdt/internal/ui/actions/IndentAction.java b/core/org.eclipse.cdt.ui/src/org/eclipse/cdt/internal/ui/actions/IndentAction.java index 30dda96853c..73424d9cd8b 100644 --- a/core/org.eclipse.cdt.ui/src/org/eclipse/cdt/internal/ui/actions/IndentAction.java +++ b/core/org.eclipse.cdt.ui/src/org/eclipse/cdt/internal/ui/actions/IndentAction.java @@ -16,13 +16,6 @@ import java.util.ResourceBundle; import org.eclipse.core.runtime.IStatus; import org.eclipse.core.runtime.Status; - -import org.eclipse.swt.custom.BusyIndicator; -import org.eclipse.swt.widgets.Display; - -import org.eclipse.jface.viewers.ISelection; -import org.eclipse.jface.viewers.ISelectionProvider; - import org.eclipse.jface.text.Assert; import org.eclipse.jface.text.BadLocationException; import org.eclipse.jface.text.IDocument; @@ -34,7 +27,10 @@ import org.eclipse.jface.text.Position; import org.eclipse.jface.text.TextSelection; import org.eclipse.jface.text.TextUtilities; import org.eclipse.jface.text.source.ISourceViewer; - +import org.eclipse.jface.viewers.ISelection; +import org.eclipse.jface.viewers.ISelectionProvider; +import org.eclipse.swt.custom.BusyIndicator; +import org.eclipse.swt.widgets.Display; import org.eclipse.ui.IEditorInput; import org.eclipse.ui.texteditor.IDocumentProvider; import org.eclipse.ui.texteditor.ITextEditor; @@ -45,11 +41,11 @@ import org.eclipse.cdt.core.CCorePlugin; import org.eclipse.cdt.core.formatter.DefaultCodeFormatterConstants; import org.eclipse.cdt.core.model.ICProject; import org.eclipse.cdt.core.model.ITranslationUnit; - import org.eclipse.cdt.ui.CUIPlugin; import org.eclipse.cdt.ui.text.ICPartitions; import org.eclipse.cdt.internal.ui.editor.CEditor; +import org.eclipse.cdt.internal.ui.editor.IndentUtil; import org.eclipse.cdt.internal.ui.text.CHeuristicScanner; import org.eclipse.cdt.internal.ui.text.CIndenter; @@ -189,8 +185,8 @@ public class IndentAction extends TextEditorAction { } /** - * Indents a single line using the heuristic scanner. Cdoc and multiline comments are - * indented as specified by the CDocAutoIndentStrategy. + * Indents a single line using the heuristic scanner. Multiline comments are + * indented as specified by the CCommentAutoIndentStrategy. * * @param document the document * @param line the line to be indented @@ -214,7 +210,7 @@ public class IndentAction extends TextEditorAction { if (type.equals(ICPartitions.C_MULTI_LINE_COMMENT)) { indent= computeCommentIndent(document, line, scanner, startingPartition); } else if (startingPartition.getType().equals(ICPartitions.C_PREPROCESSOR)) { - indent= computePreprocessorIndent(document, line, scanner, startingPartition); + indent= computePreprocessorIndent(document, line, startingPartition); } else if (!fIsTabAction && startingPartition.getOffset() == offset && startingPartition.getType().equals(ICPartitions.C_SINGLE_LINE_COMMENT)) { // line comment starting at position 0 -> indent inside int max= document.getLength() - offset; @@ -248,7 +244,7 @@ public class IndentAction extends TextEditorAction { } } - // standard C indentation + // standard C code indentation if (indent == null) { StringBuffer computed= indenter.computeIndentation(offset); if (computed != null) @@ -305,48 +301,7 @@ public class IndentAction extends TextEditorAction { * @throws BadLocationException */ private String computeCommentIndent(IDocument document, int line, CHeuristicScanner scanner, ITypedRegion partition) throws BadLocationException { - if (line == 0) // impossible - the first line is never inside a comment comment - return null; - - // don't make any assumptions if the line does not start with \s*\* - it might be - // commented out code, for which we don't want to change the indent - final IRegion lineInfo= document.getLineInformation(line); - final int lineStart= lineInfo.getOffset(); - final int lineLength= lineInfo.getLength(); - final int lineEnd= lineStart + lineLength; - int nonWS= scanner.findNonWhitespaceForwardInAnyPartition(lineStart, lineEnd); - if (nonWS == CHeuristicScanner.NOT_FOUND || document.getChar(nonWS) != '*') { - if (nonWS == CHeuristicScanner.NOT_FOUND) - return document.get(lineStart, lineLength); - return document.get(lineStart, nonWS - lineStart); - } - - // take the indent from the previous line and reuse - IRegion previousLine= document.getLineInformation(line - 1); - int previousLineStart= previousLine.getOffset(); - int previousLineLength= previousLine.getLength(); - int previousLineEnd= previousLineStart + previousLineLength; - - StringBuffer buf= new StringBuffer(); - int previousLineNonWS= scanner.findNonWhitespaceForwardInAnyPartition(previousLineStart, previousLineEnd); - if (previousLineNonWS == CHeuristicScanner.NOT_FOUND || document.getChar(previousLineNonWS) != '*') { - // align with the comment start if the previous line is not an asterisked line - previousLine= document.getLineInformationOfOffset(partition.getOffset()); - previousLineStart= previousLine.getOffset(); - previousLineLength= previousLine.getLength(); - previousLineEnd= previousLineStart + previousLineLength; - previousLineNonWS= scanner.findNonWhitespaceForwardInAnyPartition(previousLineStart, previousLineEnd); - if (previousLineNonWS == CHeuristicScanner.NOT_FOUND) - previousLineNonWS= previousLineEnd; - - // add the initial space - // TODO this may be controlled by a formatter preference in the future - buf.append(' '); - } - - String indentation= document.get(previousLineStart, previousLineNonWS - previousLineStart); - buf.insert(0, indentation); - return buf.toString(); + return IndentUtil.computeCommentIndent(document, line, scanner, partition); } /** @@ -354,13 +309,12 @@ public class IndentAction extends TextEditorAction { * * @param document the document * @param line the line in document - * @param scanner the scanner * @param partition the comment partition * @return the indent, or null if not computable * @throws BadLocationException */ - private String computePreprocessorIndent(IDocument document, int line, CHeuristicScanner scanner, ITypedRegion partition) throws BadLocationException { - return ""; //$NON-NLS-1$ + private String computePreprocessorIndent(IDocument document, int line, ITypedRegion partition) throws BadLocationException { + return IndentUtil.computePreprocessorIndent(document, line, partition); } /** diff --git a/core/org.eclipse.cdt.ui/src/org/eclipse/cdt/internal/ui/editor/IndentUtil.java b/core/org.eclipse.cdt.ui/src/org/eclipse/cdt/internal/ui/editor/IndentUtil.java index 015d0d3400d..8b9b5b07a36 100644 --- a/core/org.eclipse.cdt.ui/src/org/eclipse/cdt/internal/ui/editor/IndentUtil.java +++ b/core/org.eclipse.cdt.ui/src/org/eclipse/cdt/internal/ui/editor/IndentUtil.java @@ -134,7 +134,7 @@ public final class IndentUtil { CIndenter indenter= new CIndenter(document, scanner, project); String current= getCurrentIndent(document, lines.getStartLine()); - StringBuffer correct= indenter.computeIndentation(document.getLineOffset(lines.getStartLine())); + StringBuffer correct= new StringBuffer(computeIndent(document, lines.getStartLine(), indenter, scanner)); if (correct == null) return result; // bail out @@ -289,7 +289,7 @@ public final class IndentUtil { /** * Returns the indentation of the line line in document. * The returned string may contain pairs of leading slashes that are considered - * part of the indentation. The space before the asterix in a javadoc-like + * part of the indentation. The space before the asterix in a block * comment is not considered part of the indentation. * * @param document the document @@ -314,7 +314,7 @@ public final class IndentUtil { to++; } - // don't count the space before javadoc like, asterix-style comment lines + // don't count the space before javadoc like, asterisk-style comment lines if (to > from && to < endOffset - 1 && document.get(to - 1, 2).equals(" *")) { //$NON-NLS-1$ String type= TextUtilities.getContentType(document, ICPartitions.C_PARTITIONING, to, true); if (type.equals(ICPartitions.C_MULTI_LINE_COMMENT)) @@ -353,12 +353,12 @@ public final class IndentUtil { } /** - * Indents a single line using the java heuristic scanner. Multi line comments - * are indented as specified by the CDocAutoIndentStrategy. + * Indents a single line using the heuristic scanner. Multiline comments are + * indented as specified by the CCommentAutoIndentStrategy. * * @param document the document * @param line the line to be indented - * @param indenter the java indenter + * @param indenter the C indenter * @param scanner the heuristic scanner * @param commentLines the indent token comment booleans * @param lineIndex the zero-based line index @@ -377,13 +377,15 @@ public final class IndentUtil { ITypedRegion startingPartition= TextUtilities.getPartition(document, ICPartitions.C_PARTITIONING, offset, false); String type= partition.getType(); if (type.equals(ICPartitions.C_MULTI_LINE_COMMENT)) { - indent= computeCdocIndent(document, line, scanner, startingPartition); + indent= computeCommentIndent(document, line, scanner, startingPartition); + } else if (startingPartition.getType().equals(ICPartitions.C_PREPROCESSOR)) { + indent= computePreprocessorIndent(document, line, startingPartition); } else if (!commentLines[lineIndex] && startingPartition.getOffset() == offset && startingPartition.getType().equals(ICPartitions.C_SINGLE_LINE_COMMENT)) { return false; } } - // standard java indentation + // standard C code indentation if (indent == null) { StringBuffer computed= indenter.computeIndentation(offset); if (computed != null) @@ -418,10 +420,48 @@ public final class IndentUtil { return false; } + + /** + * Computes and returns the indentation for a source line. + * + * @param document the document + * @param line the line in document + * @param indenter the C indenter + * @param scanner the scanner + * @return the indent, never null + * @throws BadLocationException + */ + public static String computeIndent(IDocument document, int line, CIndenter indenter, CHeuristicScanner scanner) throws BadLocationException { + IRegion currentLine= document.getLineInformation(line); + final int offset= currentLine.getOffset(); + + String indent= null; + if (offset < document.getLength()) { + ITypedRegion partition= TextUtilities.getPartition(document, ICPartitions.C_PARTITIONING, offset, true); + ITypedRegion startingPartition= TextUtilities.getPartition(document, ICPartitions.C_PARTITIONING, offset, false); + String type= partition.getType(); + if (type.equals(ICPartitions.C_MULTI_LINE_COMMENT)) { + indent= computeCommentIndent(document, line, scanner, startingPartition); + } else if (startingPartition.getType().equals(ICPartitions.C_PREPROCESSOR)) { + indent= computePreprocessorIndent(document, line, startingPartition); + } else if (startingPartition.getOffset() == offset && startingPartition.getType().equals(ICPartitions.C_SINGLE_LINE_COMMENT)) { + indent= new String(); + } + } + + // standard C code indentation + if (indent == null) { + StringBuffer computed= indenter.computeIndentation(offset); + if (computed != null) + indent= computed.toString(); + else + indent= new String(); + } + return indent; + } /** - * Computes and returns the indentation for a javadoc line. The line - * must be inside a javadoc comment. + * Computes and returns the indentation for a comment line. * * @param document the document * @param line the line in document @@ -430,8 +470,8 @@ public final class IndentUtil { * @return the indent, or null if not computable * @throws BadLocationException */ - private static String computeCdocIndent(IDocument document, int line, CHeuristicScanner scanner, ITypedRegion partition) throws BadLocationException { - if (line == 0) // impossible - the first line is never inside a javadoc comment + public static String computeCommentIndent(IDocument document, int line, CHeuristicScanner scanner, ITypedRegion partition) throws BadLocationException { + if (line == 0) // impossible - the first line is never inside a comment return null; // don't make any assumptions if the line does not start with \s*\* - it might be @@ -474,4 +514,40 @@ public final class IndentUtil { buf.insert(0, indentation); return buf.toString(); } + + /** + * Computes and returns the indentation for a preprocessor line. + * + * @param document the document + * @param line the line in document + * @param partition the comment partition + * @return the indent, or null if not computable + * @throws BadLocationException + */ + public static String computePreprocessorIndent(IDocument document, int line, ITypedRegion partition) throws BadLocationException { + int ppFirstLine= document.getLineOfOffset(partition.getOffset()); + if (line == ppFirstLine) { + return ""; //$NON-NLS-1$ + } + CHeuristicScanner ppScanner= new CHeuristicScanner(document, ICPartitions.C_PARTITIONING, partition.getType()); + CIndenter ppIndenter= new CIndenter(document, ppScanner); + if (line == ppFirstLine + 1) { + return ppIndenter.createReusingIndent(new StringBuffer(), 1).toString(); + } + StringBuffer computed= ppIndenter.computeIndentation(document.getLineOffset(line), false); + if (computed != null) { + return computed.toString(); + } + // take the indent from the previous line and reuse + IRegion previousLine= document.getLineInformation(line - 1); + int previousLineStart= previousLine.getOffset(); + int previousLineLength= previousLine.getLength(); + int previousLineEnd= previousLineStart + previousLineLength; + + int previousLineNonWS= ppScanner.findNonWhitespaceForwardInAnyPartition(previousLineStart, previousLineEnd); + String previousIndent= document.get(previousLineStart, previousLineNonWS - previousLineStart); + computed= new StringBuffer(previousIndent); + return computed.toString(); + } + } diff --git a/core/org.eclipse.cdt.ui/src/org/eclipse/cdt/internal/ui/text/CAutoIndentStrategy.java b/core/org.eclipse.cdt.ui/src/org/eclipse/cdt/internal/ui/text/CAutoIndentStrategy.java index 2c49eea8e6c..1fcfa278b1e 100644 --- a/core/org.eclipse.cdt.ui/src/org/eclipse/cdt/internal/ui/text/CAutoIndentStrategy.java +++ b/core/org.eclipse.cdt.ui/src/org/eclipse/cdt/internal/ui/text/CAutoIndentStrategy.java @@ -8,7 +8,7 @@ * Contributors: * IBM Corporation - initial API and implementation * QNX Software System - * Anton Leherbauer (Wind River Systems) - Fixed bug 48339 + * Anton Leherbauer (Wind River Systems) * Sergey Prigogin, Google *******************************************************************************/ package org.eclipse.cdt.internal.ui.text; @@ -23,6 +23,7 @@ import org.eclipse.jface.text.DocumentRewriteSession; import org.eclipse.jface.text.DocumentRewriteSessionType; import org.eclipse.jface.text.IDocument; import org.eclipse.jface.text.IRegion; +import org.eclipse.jface.text.ITypedRegion; import org.eclipse.jface.text.TextUtilities; import org.eclipse.jface.text.rules.FastPartitioner; import org.eclipse.ui.IEditorPart; @@ -36,6 +37,8 @@ import org.eclipse.cdt.ui.text.ICPartitions; import org.eclipse.cdt.internal.corext.util.CodeFormatterUtil; +import org.eclipse.cdt.internal.ui.editor.IndentUtil; + /** * Auto indent strategy sensitive to brackets. */ @@ -72,25 +75,6 @@ public class CAutoIndentStrategy extends DefaultIndentLineAutoEditStrategy { fProject = project; } - // 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 { - int start = d.getLineOffset(line); - int brackcount = getBracketCount(d, start, end, false) - closingBracketIncrease; - - // sum up the brackets counts of each line (closing brackets count negative, - // opening positive) until we find a line the brings the count to zero - while (brackcount < 0) { - line--; - if (line < 0) { - return -1; - } - start = d.getLineOffset(line); - end = start + d.getLineLength(line) - 1; - brackcount += getBracketCount(d, start, end, false); - } - return line; - } - private int getBracketCount(IDocument d, int start, int end, boolean ignoreCloseBrackets) throws BadLocationException { int bracketcount = 0; while (start < end) { @@ -153,7 +137,7 @@ public class CAutoIndentStrategy extends DefaultIndentLineAutoEditStrategy { return end; } - protected String getIndentOfLine(IDocument d, int line) throws BadLocationException { + private String getIndentOfLine(IDocument d, int line) throws BadLocationException { if (line > -1) { int start = d.getLineOffset(line); int end = start + d.getLineLength(line) - 1; @@ -177,37 +161,6 @@ public class CAutoIndentStrategy extends DefaultIndentLineAutoEditStrategy { return end; } - protected void smartInsertAfterBracket(IDocument d, DocumentCommand c) { - 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); - - // 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 indLine = findMatchingOpenBracket(d, line, c.offset, 1); - 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 excp) { - CUIPlugin.getDefault().log(excp); - } - } - private void smartIndentAfterClosingBracket(IDocument d, DocumentCommand c) { if (c.offset == -1 || d.getLength() == 0) return; @@ -218,7 +171,11 @@ public class CAutoIndentStrategy extends DefaultIndentLineAutoEditStrategy { int start = d.getLineOffset(line); int whiteend = findEndOfWhiteSpace(d, start, c.offset); - CHeuristicScanner scanner = new CHeuristicScanner(d); + CHeuristicScanner scanner= new CHeuristicScanner(d); + ITypedRegion partition= TextUtilities.getPartition(d, fPartitioning, p, false); + if (ICPartitions.C_PREPROCESSOR.equals(partition.getType())) { + scanner = new CHeuristicScanner(d, fPartitioning, ICPartitions.C_PREPROCESSOR); + } CIndenter indenter = new CIndenter(d, scanner, fProject); // shift only when line does not contain any text up to the closing bracket @@ -247,11 +204,14 @@ public class CAutoIndentStrategy extends DefaultIndentLineAutoEditStrategy { 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 { + CHeuristicScanner scanner= new CHeuristicScanner(d); + ITypedRegion partition= TextUtilities.getPartition(d, fPartitioning, p, false); + if (ICPartitions.C_PREPROCESSOR.equals(partition.getType())) { + scanner = new CHeuristicScanner(d, fPartitioning, ICPartitions.C_PREPROCESSOR); + } // current line int line = d.getLineOfOffset(p); int lineOffset = d.getLineOffset(line); @@ -284,12 +244,23 @@ public class CAutoIndentStrategy extends DefaultIndentLineAutoEditStrategy { } private void smartIndentAfterNewLine(IDocument d, DocumentCommand c) { - CHeuristicScanner scanner = new CHeuristicScanner(d); + int addIndent= 0; + CHeuristicScanner scanner= new CHeuristicScanner(d); + try { + ITypedRegion partition= TextUtilities.getPartition(d, fPartitioning, c.offset, false); + if (ICPartitions.C_PREPROCESSOR.equals(partition.getType()) && d.get(c.offset-1, 1).charAt(0) == '\\') { + scanner = new CHeuristicScanner(d, fPartitioning, ICPartitions.C_PREPROCESSOR); + addIndent= 1; + } + } catch (BadLocationException exc) { + } CIndenter indenter = new CIndenter(d, scanner, fProject); StringBuffer indent = indenter.computeIndentation(c.offset); if (indent == null) indent = new StringBuffer(); - + if (addIndent > 0 && indent.length() == 0) { + indent= indenter.createReusingIndent(indent, addIndent); + } int docLength = d.getLength(); if (c.offset == -1 || docLength == 0) return; @@ -533,6 +504,7 @@ public class CAutoIndentStrategy extends DefaultIndentLineAutoEditStrategy { ICPartitions.C_SINGLE_LINE_COMMENT, ICPartitions.C_STRING, ICPartitions.C_CHARACTER, + ICPartitions.C_PREPROCESSOR, IDocument.DEFAULT_CONTENT_TYPE }; FastPartitioner partitioner= new FastPartitioner(new FastCPartitionScanner(), types); @@ -610,7 +582,7 @@ public class CAutoIndentStrategy extends DefaultIndentLineAutoEditStrategy { if (!isIndentDetected) { // indent the first pasted line String current= getCurrentIndent(temp, l); - StringBuffer correct= indenter.computeIndentation(lineOffset); + StringBuffer correct= new StringBuffer(IndentUtil.computeIndent(temp, l, indenter, scanner)); if (correct == null) return; // bail out @@ -978,6 +950,9 @@ public class CAutoIndentStrategy extends DefaultIndentLineAutoEditStrategy { case ':': smartIndentAfterColumn(document, command); break; + case '#': + smartIndentAfterHash(document, command); + break; } } @@ -1136,6 +1111,22 @@ public class CAutoIndentStrategy extends DefaultIndentLineAutoEditStrategy { } } + private void smartIndentAfterHash(IDocument doc, DocumentCommand c) { + try { + ITypedRegion partition= TextUtilities.getPartition(doc, fPartitioning, c.offset, false); + if (IDocument.DEFAULT_CONTENT_TYPE.equals(partition.getType())) { + IRegion startLine= doc.getLineInformationOfOffset(c.offset); + String indent= (doc.get(startLine.getOffset(), c.offset - startLine.getOffset())); + if (indent.trim().length() == 0) { + c.offset -= indent.length(); + c.length += indent.length(); + } + } + } catch (BadLocationException e) { + CUIPlugin.getDefault().log(e); + } + } + /* * @see org.eclipse.jface.text.IAutoEditStrategy#customizeDocumentCommand(IDocument, DocumentCommand) */ @@ -1175,7 +1166,7 @@ public class CAutoIndentStrategy extends DefaultIndentLineAutoEditStrategy { private boolean isAppendToOpenMultilineComment(IDocument d, DocumentCommand c) { if (d.getLength() >= 2 && c.offset == d.getLength()) { try { - String contentType = org.eclipse.jface.text.TextUtilities.getContentType(d, fPartitioning, c.offset - 1, false); + String contentType = TextUtilities.getContentType(d, fPartitioning, c.offset - 1, false); if (ICPartitions.C_MULTI_LINE_COMMENT.equals(contentType)) { return !d.get(c.offset - 2, 2).equals(MULTILINE_COMMENT_CLOSE); }