mirror of
https://github.com/eclipse-cdt/cdt
synced 2025-08-11 02:05:39 +02:00
Bug 165090 - Leading spaces are not preserved when pasting comments
This commit is contained in:
parent
a83a57c3ba
commit
f52791b8cb
7 changed files with 161 additions and 115 deletions
|
@ -652,6 +652,17 @@ public class DefaultCodeFormatterConstants {
|
||||||
* @see #FALSE
|
* @see #FALSE
|
||||||
*/
|
*/
|
||||||
public static final String FORMATTER_INDENT_EMPTY_LINES = CCorePlugin.PLUGIN_ID + ".formatter.indent_empty_lines"; //$NON-NLS-1$
|
public static final String FORMATTER_INDENT_EMPTY_LINES = CCorePlugin.PLUGIN_ID + ".formatter.indent_empty_lines"; //$NON-NLS-1$
|
||||||
|
/**
|
||||||
|
* <pre>
|
||||||
|
* FORMATTER / Option to indent inside line comments at column 0
|
||||||
|
* - option id: "org.eclipse.cdt.core.formatter.indent_inside_line_comments"
|
||||||
|
* - possible values: { TRUE, FALSE }
|
||||||
|
* - default: FALSE
|
||||||
|
* </pre>
|
||||||
|
* @see #TRUE
|
||||||
|
* @see #FALSE
|
||||||
|
*/
|
||||||
|
public static final String FORMATTER_INDENT_INSIDE_LINE_COMMENTS = CCorePlugin.PLUGIN_ID + ".formatter.indent_inside_line_comments"; //$NON-NLS-1$
|
||||||
/**
|
/**
|
||||||
* <pre>
|
* <pre>
|
||||||
* FORMATTER / Option to indent statements inside a block
|
* FORMATTER / Option to indent statements inside a block
|
||||||
|
|
|
@ -36,6 +36,7 @@ const OtherStruct array[] =
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
// single line outside scope
|
||||||
|
|
||||||
void SimpleStruct_construct(
|
void SimpleStruct_construct(
|
||||||
struct SimpleStruct * const this )
|
struct SimpleStruct * const this )
|
||||||
|
|
|
@ -36,6 +36,7 @@ const OtherStruct array[] =
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
// single line outside scope
|
||||||
|
|
||||||
void SimpleStruct_construct(
|
void SimpleStruct_construct(
|
||||||
struct SimpleStruct * const this )
|
struct SimpleStruct * const this )
|
||||||
|
|
|
@ -374,4 +374,26 @@ public class CAutoIndentTest extends TestCase {
|
||||||
assertEquals("\t}", tester.getLine(1));
|
assertEquals("\t}", tester.getLine(1));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public void testPasteBlockCommentAutoIndent() throws BadLocationException {
|
||||||
|
AutoEditTester tester = createAutoEditTester(); //$NON-NLS-1$
|
||||||
|
tester.type("class A {\n};"); //$NON-NLS-1$
|
||||||
|
tester.goTo(1, 0);
|
||||||
|
tester.paste("/*\n" +
|
||||||
|
" * block comment\n" +
|
||||||
|
" */\n");
|
||||||
|
tester.goTo(1, 0);
|
||||||
|
assertEquals("\t/*", tester.getLine(0)); //$NON-NLS-1$
|
||||||
|
assertEquals("\t * block comment", tester.getLine(1)); //$NON-NLS-1$
|
||||||
|
assertEquals("\t */", tester.getLine(2)); //$NON-NLS-1$
|
||||||
|
}
|
||||||
|
|
||||||
|
public void testPasteLineCommentAutoIndent() throws BadLocationException {
|
||||||
|
AutoEditTester tester = createAutoEditTester(); //$NON-NLS-1$
|
||||||
|
tester.type("class A {\n};"); //$NON-NLS-1$
|
||||||
|
tester.goTo(1, 0);
|
||||||
|
tester.paste("// int f;\n");
|
||||||
|
tester.goTo(1, 0);
|
||||||
|
assertEquals("\t// int f;", tester.getLine(0)); //$NON-NLS-1$
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -213,6 +213,7 @@ public class IndentAction extends TextEditorAction {
|
||||||
indent= computePreprocessorIndent(document, line, startingPartition);
|
indent= computePreprocessorIndent(document, line, startingPartition);
|
||||||
} else if (!fIsTabAction && startingPartition.getOffset() == offset && startingPartition.getType().equals(ICPartitions.C_SINGLE_LINE_COMMENT)) {
|
} else if (!fIsTabAction && startingPartition.getOffset() == offset && startingPartition.getType().equals(ICPartitions.C_SINGLE_LINE_COMMENT)) {
|
||||||
// line comment starting at position 0 -> indent inside
|
// line comment starting at position 0 -> indent inside
|
||||||
|
if (indentInsideLineComments()) {
|
||||||
int max= document.getLength() - offset;
|
int max= document.getLength() - offset;
|
||||||
int slashes= 2;
|
int slashes= 2;
|
||||||
while (slashes < max - 1 && document.get(offset + slashes, 2).equals("//")) //$NON-NLS-1$
|
while (slashes < max - 1 && document.get(offset + slashes, 2).equals("//")) //$NON-NLS-1$
|
||||||
|
@ -243,6 +244,7 @@ public class IndentAction extends TextEditorAction {
|
||||||
indent= document.get(offset, wsStart - offset) + computed;
|
indent= document.get(offset, wsStart - offset) + computed;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
// standard C code indentation
|
// standard C code indentation
|
||||||
if (indent == null) {
|
if (indent == null) {
|
||||||
|
@ -291,7 +293,7 @@ public class IndentAction extends TextEditorAction {
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Computes and returns the indentation for a comment line.
|
* Computes and returns the indentation for a block comment line.
|
||||||
*
|
*
|
||||||
* @param document the document
|
* @param document the document
|
||||||
* @param line the line in document
|
* @param line the line in document
|
||||||
|
@ -370,14 +372,23 @@ public class IndentAction extends TextEditorAction {
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Returns <code>true</code> if empty lines should be indented, false otherwise.
|
* Returns <code>true</code> if empty lines should be indented, <code>false</code> otherwise.
|
||||||
*
|
*
|
||||||
* @return <code>true</code> if empty lines should be indented, false otherwise
|
* @return <code>true</code> if empty lines should be indented, <code>false</code> otherwise
|
||||||
*/
|
*/
|
||||||
private boolean indentEmptyLines() {
|
private boolean indentEmptyLines() {
|
||||||
return DefaultCodeFormatterConstants.TRUE.equals(getCoreFormatterOption(DefaultCodeFormatterConstants.FORMATTER_INDENT_EMPTY_LINES));
|
return DefaultCodeFormatterConstants.TRUE.equals(getCoreFormatterOption(DefaultCodeFormatterConstants.FORMATTER_INDENT_EMPTY_LINES));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Returns <code>true</code> if line comments at column 0 should be indented inside, <code>false</code> otherwise.
|
||||||
|
*
|
||||||
|
* @return <code>true</code> if line comments at column 0 should be indented inside, <code>false</code> otherwise.
|
||||||
|
*/
|
||||||
|
private boolean indentInsideLineComments() {
|
||||||
|
return DefaultCodeFormatterConstants.TRUE.equals(getCoreFormatterOption(DefaultCodeFormatterConstants.FORMATTER_INDENT_INSIDE_LINE_COMMENTS));
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Returns the possibly project-specific core preference defined under <code>key</code>.
|
* Returns the possibly project-specific core preference defined under <code>key</code>.
|
||||||
*
|
*
|
||||||
|
|
|
@ -18,6 +18,8 @@ import org.eclipse.jface.text.ITypedRegion;
|
||||||
import org.eclipse.jface.text.TextUtilities;
|
import org.eclipse.jface.text.TextUtilities;
|
||||||
import org.eclipse.jface.text.source.ILineRange;
|
import org.eclipse.jface.text.source.ILineRange;
|
||||||
|
|
||||||
|
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.ICProject;
|
||||||
import org.eclipse.cdt.ui.text.ICPartitions;
|
import org.eclipse.cdt.ui.text.ICPartitions;
|
||||||
|
|
||||||
|
@ -91,14 +93,40 @@ public final class IndentUtil {
|
||||||
CIndenter indenter= new CIndenter(document, scanner, project);
|
CIndenter indenter= new CIndenter(document, scanner, project);
|
||||||
boolean changed= false;
|
boolean changed= false;
|
||||||
int tabSize= CodeFormatterUtil.getTabWidth(project);
|
int tabSize= CodeFormatterUtil.getTabWidth(project);
|
||||||
|
boolean indentInsideLineComments= indentInsideLineComments(project);
|
||||||
for (int line= lines.getStartLine(), last= line + numberOfLines, i= 0; line < last; line++) {
|
for (int line= lines.getStartLine(), last= line + numberOfLines, i= 0; line < last; line++) {
|
||||||
changed |= indentLine(document, line, indenter, scanner, result.commentLinesAtColumnZero, i++, tabSize);
|
changed |= indentLine(document, line, indenter, scanner, result.commentLinesAtColumnZero, i++, tabSize, indentInsideLineComments);
|
||||||
}
|
}
|
||||||
result.hasChanged= changed;
|
result.hasChanged= changed;
|
||||||
|
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Returns <code>true</code> if line comments at column 0 should be indented inside, <code>false</code> otherwise.
|
||||||
|
*
|
||||||
|
* @param project the project to get project specific options from
|
||||||
|
* @return <code>true</code> if line comments at column 0 should be indented inside, <code>false</code> otherwise.
|
||||||
|
*/
|
||||||
|
public static boolean indentInsideLineComments(ICProject project) {
|
||||||
|
return DefaultCodeFormatterConstants.TRUE.equals(getCoreOption(project, DefaultCodeFormatterConstants.FORMATTER_INDENT_INSIDE_LINE_COMMENTS));
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 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);
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Shifts the line range specified by <code>lines</code> in
|
* Shifts the line range specified by <code>lines</code> in
|
||||||
* <code>document</code>. The amount that the lines get shifted
|
* <code>document</code>. The amount that the lines get shifted
|
||||||
|
@ -133,7 +161,8 @@ public final class IndentUtil {
|
||||||
CHeuristicScanner scanner= new CHeuristicScanner(document);
|
CHeuristicScanner scanner= new CHeuristicScanner(document);
|
||||||
CIndenter indenter= new CIndenter(document, scanner, project);
|
CIndenter indenter= new CIndenter(document, scanner, project);
|
||||||
|
|
||||||
String current= getCurrentIndent(document, lines.getStartLine());
|
boolean indentInsideLineComments= indentInsideLineComments(project);
|
||||||
|
String current= getCurrentIndent(document, lines.getStartLine(), indentInsideLineComments);
|
||||||
StringBuffer correct= new StringBuffer(computeIndent(document, lines.getStartLine(), indenter, scanner));
|
StringBuffer correct= new StringBuffer(computeIndent(document, lines.getStartLine(), indenter, scanner));
|
||||||
if (correct == null)
|
if (correct == null)
|
||||||
return result; // bail out
|
return result; // bail out
|
||||||
|
@ -146,17 +175,17 @@ public final class IndentUtil {
|
||||||
return result;
|
return result;
|
||||||
|
|
||||||
if (result.leftmostLine == -1)
|
if (result.leftmostLine == -1)
|
||||||
result.leftmostLine= getLeftMostLine(document, lines, tabSize);
|
result.leftmostLine= getLeftMostLine(document, lines, tabSize, indentInsideLineComments);
|
||||||
|
|
||||||
int maxReduction= computeVisualLength(getCurrentIndent(document, result.leftmostLine + lines.getStartLine()), tabSize);
|
int maxReduction= computeVisualLength(getCurrentIndent(document, result.leftmostLine + lines.getStartLine(), indentInsideLineComments), tabSize);
|
||||||
|
|
||||||
if (difference > 0) {
|
if (difference > 0) {
|
||||||
for (int line= lines.getStartLine(), last= line + numberOfLines, i= 0; line < last; line++)
|
for (int line= lines.getStartLine(), last= line + numberOfLines, i= 0; line < last; line++)
|
||||||
addIndent(document, line, addition, result.commentLinesAtColumnZero, i++);
|
addIndent(document, line, addition, result.commentLinesAtColumnZero, i++, indentInsideLineComments);
|
||||||
} else {
|
} else {
|
||||||
int reduction= Math.min(-difference, maxReduction);
|
int reduction= Math.min(-difference, maxReduction);
|
||||||
for (int line= lines.getStartLine(), last= line + numberOfLines, i= 0; line < last; line++)
|
for (int line= lines.getStartLine(), last= line + numberOfLines, i= 0; line < last; line++)
|
||||||
cutIndent(document, line, reduction, tabSize, result.commentLinesAtColumnZero, i++);
|
cutIndent(document, line, reduction, tabSize, result.commentLinesAtColumnZero, i++, indentInsideLineComments);
|
||||||
}
|
}
|
||||||
|
|
||||||
result.hasChanged= true;
|
result.hasChanged= true;
|
||||||
|
@ -173,18 +202,21 @@ public final class IndentUtil {
|
||||||
* @param line the line
|
* @param line the line
|
||||||
* @param indent the indentation to insert
|
* @param indent the indentation to insert
|
||||||
* @param commentlines
|
* @param commentlines
|
||||||
|
* @param indentInsideLineComments option whether to indent inside line comments starting at column 0
|
||||||
* @throws BadLocationException on concurrent document modification
|
* @throws BadLocationException on concurrent document modification
|
||||||
*/
|
*/
|
||||||
private static void addIndent(IDocument document, int line, CharSequence indent, boolean[] commentlines, int relative) throws BadLocationException {
|
private static void addIndent(IDocument document, int line, CharSequence indent, boolean[] commentlines, int relative, boolean indentInsideLineComments) throws BadLocationException {
|
||||||
IRegion region= document.getLineInformation(line);
|
IRegion region= document.getLineInformation(line);
|
||||||
int insert= region.getOffset();
|
int insert= region.getOffset();
|
||||||
int endOffset= region.getOffset() + region.getLength();
|
int endOffset= region.getOffset() + region.getLength();
|
||||||
|
|
||||||
|
if (indentInsideLineComments) {
|
||||||
// go behind line comments
|
// go behind line comments
|
||||||
if (!commentlines[relative]) {
|
if (!commentlines[relative]) {
|
||||||
while (insert < endOffset - 2 && document.get(insert, 2).equals(SLASHES))
|
while (insert < endOffset - 2 && document.get(insert, 2).equals(SLASHES))
|
||||||
insert += 2;
|
insert += 2;
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
// insert indent
|
// insert indent
|
||||||
document.replace(insert, 0, indent.toString());
|
document.replace(insert, 0, indent.toString());
|
||||||
|
@ -198,16 +230,19 @@ public final class IndentUtil {
|
||||||
* @param document the document
|
* @param document the document
|
||||||
* @param line the line
|
* @param line the line
|
||||||
* @param toDelete the number of space equivalents to delete.
|
* @param toDelete the number of space equivalents to delete.
|
||||||
|
* @param indentInsideLineComments option whether to indent inside line comments starting at column 0
|
||||||
* @throws BadLocationException on concurrent document modification
|
* @throws BadLocationException on concurrent document modification
|
||||||
*/
|
*/
|
||||||
private static void cutIndent(IDocument document, int line, int toDelete, int tabSize, boolean[] commentLines, int relative) throws BadLocationException {
|
private static void cutIndent(IDocument document, int line, int toDelete, int tabSize, boolean[] commentLines, int relative, boolean indentInsideLineComments) throws BadLocationException {
|
||||||
IRegion region= document.getLineInformation(line);
|
IRegion region= document.getLineInformation(line);
|
||||||
int from= region.getOffset();
|
int from= region.getOffset();
|
||||||
int endOffset= region.getOffset() + region.getLength();
|
int endOffset= region.getOffset() + region.getLength();
|
||||||
|
|
||||||
|
if (indentInsideLineComments) {
|
||||||
// go behind line comments
|
// go behind line comments
|
||||||
while (from < endOffset - 2 && document.get(from, 2).equals(SLASHES))
|
while (from < endOffset - 2 && document.get(from, 2).equals(SLASHES))
|
||||||
from += 2;
|
from += 2;
|
||||||
|
}
|
||||||
|
|
||||||
int to= from;
|
int to= from;
|
||||||
while (toDelete > 0 && to < endOffset) {
|
while (toDelete > 0 && to < endOffset) {
|
||||||
|
@ -289,23 +324,25 @@ public final class IndentUtil {
|
||||||
/**
|
/**
|
||||||
* Returns the indentation of the line <code>line</code> in <code>document</code>.
|
* Returns the indentation of the line <code>line</code> in <code>document</code>.
|
||||||
* The returned string may contain pairs of leading slashes that are considered
|
* The returned string may contain pairs of leading slashes that are considered
|
||||||
* part of the indentation. The space before the asterix in a block
|
* part of the indentation.
|
||||||
* comment is not considered part of the indentation.
|
|
||||||
*
|
*
|
||||||
* @param document the document
|
* @param document the document
|
||||||
* @param line the line
|
* @param line the line
|
||||||
|
* @param indentInsideLineComments option whether to indent inside line comments starting at column 0
|
||||||
* @return the indentation of <code>line</code> in <code>document</code>
|
* @return the indentation of <code>line</code> in <code>document</code>
|
||||||
* @throws BadLocationException if the document is changed concurrently
|
* @throws BadLocationException if the document is changed concurrently
|
||||||
*/
|
*/
|
||||||
private static String getCurrentIndent(IDocument document, int line) throws BadLocationException {
|
public static String getCurrentIndent(IDocument document, int line, boolean indentInsideLineComments) throws BadLocationException {
|
||||||
IRegion region= document.getLineInformation(line);
|
IRegion region= document.getLineInformation(line);
|
||||||
int from= region.getOffset();
|
int from= region.getOffset();
|
||||||
int endOffset= region.getOffset() + region.getLength();
|
int endOffset= region.getOffset() + region.getLength();
|
||||||
|
|
||||||
// go behind line comments
|
|
||||||
int to= from;
|
int to= from;
|
||||||
|
if (indentInsideLineComments) {
|
||||||
|
// go behind line comments
|
||||||
while (to < endOffset - 2 && document.get(to, 2).equals(SLASHES))
|
while (to < endOffset - 2 && document.get(to, 2).equals(SLASHES))
|
||||||
to += 2;
|
to += 2;
|
||||||
|
}
|
||||||
|
|
||||||
while (to < endOffset) {
|
while (to < endOffset) {
|
||||||
char ch= document.getChar(to);
|
char ch= document.getChar(to);
|
||||||
|
@ -314,23 +351,16 @@ public final class IndentUtil {
|
||||||
to++;
|
to++;
|
||||||
}
|
}
|
||||||
|
|
||||||
// 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))
|
|
||||||
to--;
|
|
||||||
}
|
|
||||||
|
|
||||||
return document.get(from, to - from);
|
return document.get(from, to - from);
|
||||||
}
|
}
|
||||||
|
|
||||||
private static int getLeftMostLine(IDocument document, ILineRange lines, int tabSize) throws BadLocationException {
|
private static int getLeftMostLine(IDocument document, ILineRange lines, int tabSize, boolean indentInsideLineComments) throws BadLocationException {
|
||||||
int numberOfLines= lines.getNumberOfLines();
|
int numberOfLines= lines.getNumberOfLines();
|
||||||
int first= lines.getStartLine();
|
int first= lines.getStartLine();
|
||||||
int minLine= -1;
|
int minLine= -1;
|
||||||
int minIndent= Integer.MAX_VALUE;
|
int minIndent= Integer.MAX_VALUE;
|
||||||
for (int line= 0; line < numberOfLines; line++) {
|
for (int line= 0; line < numberOfLines; line++) {
|
||||||
int length= computeVisualLength(getCurrentIndent(document, line + first), tabSize);
|
int length= computeVisualLength(getCurrentIndent(document, line + first, indentInsideLineComments), tabSize);
|
||||||
if (length < minIndent) {
|
if (length < minIndent) {
|
||||||
minIndent= length;
|
minIndent= length;
|
||||||
minLine= line;
|
minLine= line;
|
||||||
|
@ -362,11 +392,13 @@ public final class IndentUtil {
|
||||||
* @param scanner the heuristic scanner
|
* @param scanner the heuristic scanner
|
||||||
* @param commentLines the indent token comment booleans
|
* @param commentLines the indent token comment booleans
|
||||||
* @param lineIndex the zero-based line index
|
* @param lineIndex the zero-based line index
|
||||||
|
* @param indentInsideLineComments option whether to indent inside line comments
|
||||||
|
* starting at column 0
|
||||||
* @return <code>true</code> if the document was modified,
|
* @return <code>true</code> if the document was modified,
|
||||||
* <code>false</code> if not
|
* <code>false</code> if not
|
||||||
* @throws BadLocationException if the document got changed concurrently
|
* @throws BadLocationException if the document got changed concurrently
|
||||||
*/
|
*/
|
||||||
private static boolean indentLine(IDocument document, int line, CIndenter indenter, CHeuristicScanner scanner, boolean[] commentLines, int lineIndex, int tabSize) throws BadLocationException {
|
private static boolean indentLine(IDocument document, int line, CIndenter indenter, CHeuristicScanner scanner, boolean[] commentLines, int lineIndex, int tabSize, boolean indentInsideLineComments) throws BadLocationException {
|
||||||
IRegion currentLine= document.getLineInformation(line);
|
IRegion currentLine= document.getLineInformation(line);
|
||||||
final int offset= currentLine.getOffset();
|
final int offset= currentLine.getOffset();
|
||||||
int wsStart= offset; // where we start searching for non-WS; after the "//" in single line comments
|
int wsStart= offset; // where we start searching for non-WS; after the "//" in single line comments
|
||||||
|
@ -405,7 +437,8 @@ public final class IndentUtil {
|
||||||
|
|
||||||
// memorize the fact that a line is a single line comment (but not at column 0) and should be treated like code
|
// memorize the fact that a line is a single line comment (but not at column 0) and should be treated like code
|
||||||
// as opposed to commented out code, which should keep its slashes at column 0
|
// as opposed to commented out code, which should keep its slashes at column 0
|
||||||
if (length > 0) {
|
// if 'indentInsideLineComments' is false, all comment lines are indented with the code
|
||||||
|
if (length > 0 || !indentInsideLineComments) {
|
||||||
ITypedRegion partition= TextUtilities.getPartition(document, ICPartitions.C_PARTITIONING, end, false);
|
ITypedRegion partition= TextUtilities.getPartition(document, ICPartitions.C_PARTITIONING, end, false);
|
||||||
if (partition.getOffset() == end && ICPartitions.C_SINGLE_LINE_COMMENT.equals(partition.getType())) {
|
if (partition.getOffset() == end && ICPartitions.C_SINGLE_LINE_COMMENT.equals(partition.getType())) {
|
||||||
commentLines[lineIndex]= true;
|
commentLines[lineIndex]= true;
|
||||||
|
@ -444,8 +477,6 @@ public final class IndentUtil {
|
||||||
indent= computeCommentIndent(document, line, scanner, startingPartition);
|
indent= computeCommentIndent(document, line, scanner, startingPartition);
|
||||||
} else if (startingPartition.getType().equals(ICPartitions.C_PREPROCESSOR)) {
|
} else if (startingPartition.getType().equals(ICPartitions.C_PREPROCESSOR)) {
|
||||||
indent= computePreprocessorIndent(document, line, startingPartition);
|
indent= computePreprocessorIndent(document, line, startingPartition);
|
||||||
} else if (startingPartition.getOffset() == offset && startingPartition.getType().equals(ICPartitions.C_SINGLE_LINE_COMMENT)) {
|
|
||||||
indent= new String();
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -461,7 +492,7 @@ public final class IndentUtil {
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Computes and returns the indentation for a comment line.
|
* Computes and returns the indentation for a block comment line.
|
||||||
*
|
*
|
||||||
* @param document the document
|
* @param document the document
|
||||||
* @param line the line in document
|
* @param line the line in document
|
||||||
|
|
|
@ -570,6 +570,7 @@ public class CAutoIndentStrategy extends DefaultIndentLineAutoEditStrategy {
|
||||||
int first= document.computeNumberOfLines(prefix) + firstLine; // don't format first line
|
int first= document.computeNumberOfLines(prefix) + firstLine; // don't format first line
|
||||||
int lines= temp.getNumberOfLines();
|
int lines= temp.getNumberOfLines();
|
||||||
boolean changed= false;
|
boolean changed= false;
|
||||||
|
boolean indentInsideLineComments= IndentUtil.indentInsideLineComments(fProject);
|
||||||
|
|
||||||
for (int l= first; l < lines; l++) { // we don't change the number of lines while adding indents
|
for (int l= first; l < lines; l++) { // we don't change the number of lines while adding indents
|
||||||
IRegion r= temp.getLineInformation(l);
|
IRegion r= temp.getLineInformation(l);
|
||||||
|
@ -581,7 +582,7 @@ public class CAutoIndentStrategy extends DefaultIndentLineAutoEditStrategy {
|
||||||
|
|
||||||
if (!isIndentDetected) {
|
if (!isIndentDetected) {
|
||||||
// indent the first pasted line
|
// indent the first pasted line
|
||||||
String current= getCurrentIndent(temp, l);
|
String current= IndentUtil.getCurrentIndent(temp, l, indentInsideLineComments);
|
||||||
StringBuffer correct= new StringBuffer(IndentUtil.computeIndent(temp, l, indenter, scanner));
|
StringBuffer correct= new StringBuffer(IndentUtil.computeIndent(temp, l, indenter, scanner));
|
||||||
if (correct == null)
|
if (correct == null)
|
||||||
return; // bail out
|
return; // bail out
|
||||||
|
@ -608,9 +609,9 @@ public class CAutoIndentStrategy extends DefaultIndentLineAutoEditStrategy {
|
||||||
|
|
||||||
// relatively indent all pasted lines
|
// relatively indent all pasted lines
|
||||||
if (insertLength > 0)
|
if (insertLength > 0)
|
||||||
addIndent(temp, l, addition);
|
addIndent(temp, l, addition, indentInsideLineComments);
|
||||||
else if (insertLength < 0)
|
else if (insertLength < 0)
|
||||||
cutIndent(temp, l, -insertLength);
|
cutIndent(temp, l, -insertLength, indentInsideLineComments);
|
||||||
}
|
}
|
||||||
|
|
||||||
temp.stopRewriteSession(session);
|
temp.stopRewriteSession(session);
|
||||||
|
@ -624,44 +625,6 @@ public class CAutoIndentStrategy extends DefaultIndentLineAutoEditStrategy {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
|
||||||
* Returns the indentation of the line <code>line</code> in <code>document</code>.
|
|
||||||
* 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
|
|
||||||
* comment is not considered part of the indentation.
|
|
||||||
*
|
|
||||||
* @param document the document
|
|
||||||
* @param line the line
|
|
||||||
* @return the indentation of <code>line</code> in <code>document</code>
|
|
||||||
* @throws BadLocationException if the document is changed concurrently
|
|
||||||
*/
|
|
||||||
private static String getCurrentIndent(Document document, int line) throws BadLocationException {
|
|
||||||
IRegion region= document.getLineInformation(line);
|
|
||||||
int from= region.getOffset();
|
|
||||||
int endOffset= region.getOffset() + region.getLength();
|
|
||||||
|
|
||||||
// go behind line comments
|
|
||||||
int to= from;
|
|
||||||
while (to < endOffset - 2 && document.get(to, 2).equals(LINE_COMMENT))
|
|
||||||
to += 2;
|
|
||||||
|
|
||||||
while (to < endOffset) {
|
|
||||||
char ch= document.getChar(to);
|
|
||||||
if (!Character.isWhitespace(ch))
|
|
||||||
break;
|
|
||||||
to++;
|
|
||||||
}
|
|
||||||
|
|
||||||
// don't count the space before javadoc like, asterix-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))
|
|
||||||
to--;
|
|
||||||
}
|
|
||||||
|
|
||||||
return document.get(from, to - from);
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Computes the difference of two indentations and returns the difference in
|
* Computes the difference of two indentations and returns the difference in
|
||||||
* length of current and correct. If the return value is positive, <code>addition</code>
|
* length of current and correct. If the return value is positive, <code>addition</code>
|
||||||
|
@ -697,16 +660,19 @@ public class CAutoIndentStrategy extends DefaultIndentLineAutoEditStrategy {
|
||||||
* @param document the document
|
* @param document the document
|
||||||
* @param line the line
|
* @param line the line
|
||||||
* @param indent the indentation to insert
|
* @param indent the indentation to insert
|
||||||
|
* @param indentInsideLineComments option whether to indent inside line comments starting at column 0
|
||||||
* @throws BadLocationException on concurrent document modification
|
* @throws BadLocationException on concurrent document modification
|
||||||
*/
|
*/
|
||||||
private static void addIndent(Document document, int line, CharSequence indent) throws BadLocationException {
|
private static void addIndent(Document document, int line, CharSequence indent, boolean indentInsideLineComments) throws BadLocationException {
|
||||||
IRegion region= document.getLineInformation(line);
|
IRegion region= document.getLineInformation(line);
|
||||||
int insert= region.getOffset();
|
int insert= region.getOffset();
|
||||||
int endOffset= region.getOffset() + region.getLength();
|
int endOffset= region.getOffset() + region.getLength();
|
||||||
|
|
||||||
|
if (indentInsideLineComments) {
|
||||||
// go behind line comments
|
// go behind line comments
|
||||||
while (insert < endOffset - 2 && document.get(insert, 2).equals(LINE_COMMENT))
|
while (insert < endOffset - 2 && document.get(insert, 2).equals(LINE_COMMENT))
|
||||||
insert += 2;
|
insert += 2;
|
||||||
|
}
|
||||||
|
|
||||||
// insert indent
|
// insert indent
|
||||||
document.replace(insert, 0, indent.toString());
|
document.replace(insert, 0, indent.toString());
|
||||||
|
@ -720,16 +686,19 @@ public class CAutoIndentStrategy extends DefaultIndentLineAutoEditStrategy {
|
||||||
* @param document the document
|
* @param document the document
|
||||||
* @param line the line
|
* @param line the line
|
||||||
* @param toDelete the number of space equivalents to delete.
|
* @param toDelete the number of space equivalents to delete.
|
||||||
|
* @param indentInsideLineComments option whether to indent inside line comments starting at column 0
|
||||||
* @throws BadLocationException on concurrent document modification
|
* @throws BadLocationException on concurrent document modification
|
||||||
*/
|
*/
|
||||||
private void cutIndent(Document document, int line, int toDelete) throws BadLocationException {
|
private void cutIndent(Document document, int line, int toDelete, boolean indentInsideLineComments) throws BadLocationException {
|
||||||
IRegion region= document.getLineInformation(line);
|
IRegion region= document.getLineInformation(line);
|
||||||
int from= region.getOffset();
|
int from= region.getOffset();
|
||||||
int endOffset= region.getOffset() + region.getLength();
|
int endOffset= region.getOffset() + region.getLength();
|
||||||
|
|
||||||
|
if (indentInsideLineComments) {
|
||||||
// go behind line comments
|
// go behind line comments
|
||||||
while (from < endOffset - 2 && document.get(from, 2).equals(LINE_COMMENT))
|
while (from < endOffset - 2 && document.get(from, 2).equals(LINE_COMMENT))
|
||||||
from += 2;
|
from += 2;
|
||||||
|
}
|
||||||
|
|
||||||
int to= from;
|
int to= from;
|
||||||
while (toDelete > 0 && to < endOffset) {
|
while (toDelete > 0 && to < endOffset) {
|
||||||
|
|
Loading…
Add table
Reference in a new issue