From cb74996679fe6ea1ce8a98fb82460e97b5160358 Mon Sep 17 00:00:00 2001 From: bananeweizen Date: Sat, 11 Feb 2006 21:18:19 +0000 Subject: [PATCH] bugfix 1423269, http://sourceforge.net/tracker/index.php?func=detail&aid=1423269&group_id=57621&atid=484801 indentation in brace completion respects tab versus space option --- .../phpdt/internal/ui/text/JavaIndenter.java | 224 ++++++++++---------- .../phpeclipse/phpeditor/PHPUnitEditor.java | 6 +- 2 files changed, 117 insertions(+), 113 deletions(-) diff --git a/net.sourceforge.phpeclipse/src/net/sourceforge/phpdt/internal/ui/text/JavaIndenter.java b/net.sourceforge.phpeclipse/src/net/sourceforge/phpdt/internal/ui/text/JavaIndenter.java index 39a3b29..bf374ff 100644 --- a/net.sourceforge.phpeclipse/src/net/sourceforge/phpdt/internal/ui/text/JavaIndenter.java +++ b/net.sourceforge.phpeclipse/src/net/sourceforge/phpdt/internal/ui/text/JavaIndenter.java @@ -57,7 +57,7 @@ public class JavaIndenter { * on the same document as the one we get. */ private JavaHeuristicScanner fScanner; - + /** * Creates a new instance. * @@ -71,7 +71,7 @@ public class JavaIndenter { fDocument= document; fScanner= scanner; } - + /** * Computes the indentation at the reference point of position. * @@ -83,7 +83,7 @@ public class JavaIndenter { public StringBuffer getReferenceIndentation(int offset) { return getReferenceIndentation(offset, false); } - + /** * Computes the indentation at the reference point of position. * @@ -100,15 +100,15 @@ public class JavaIndenter { unit= findReferencePosition(offset, Symbols.TokenLBRACE); else unit= findReferencePosition(offset, peekChar(offset)); - + // if we were unable to find anything, return null if (unit == JavaHeuristicScanner.NOT_FOUND) return null; - + return getLeadingWhitespace(unit); - + } - + /** * Computes the indentation at offset. * @@ -120,7 +120,7 @@ public class JavaIndenter { public StringBuffer computeIndentation(int offset) { return computeIndentation(offset, false); } - + /** * Computes the indentation at offset. * @@ -131,9 +131,9 @@ public class JavaIndenter { * determined */ public StringBuffer computeIndentation(int offset, boolean assumeOpeningBrace) { - + StringBuffer indent= getReferenceIndentation(offset, assumeOpeningBrace); - + // handle special alignment if (fAlign != JavaHeuristicScanner.NOT_FOUND) { try { @@ -145,15 +145,15 @@ public class JavaIndenter { return null; } } - + if (indent == null) return null; - + // add additional indent indent.append(createIndent(fIndent)); if (fIndent < 0) unindent(indent); - + return indent; } @@ -189,7 +189,7 @@ public class JavaIndenter { int i= indent.lastIndexOf(oneIndent.toString()); //$NON-NLS-1$ if (i != -1) { indent.delete(i, i + oneIndent.length()); - } + } } /** @@ -205,12 +205,12 @@ public class JavaIndenter { * by start and indent */ private StringBuffer createIndent(int start, int indent) { - final int tabLen= prefTabLength(); + final int tabLen= prefTabLength(); StringBuffer ret= new StringBuffer(); try { int spaces= 0; while (start < indent) { - + char ch= fDocument.getChar(start); if (ch == '\t') { ret.append('\t'); @@ -224,7 +224,7 @@ public class JavaIndenter { spaces= 0; } } - + start++; } // remainder @@ -233,10 +233,10 @@ public class JavaIndenter { else while (spaces-- > 0) ret.append(' '); - + } catch (BadLocationException e) { } - + return ret; } @@ -248,16 +248,16 @@ public class JavaIndenter { * * @return the indentation specified by indent */ - private StringBuffer createIndent(int indent) { - StringBuffer oneIndent= createIndent(); + public StringBuffer createIndent(int indent) { + StringBuffer oneIndent= createIndent(); StringBuffer ret= new StringBuffer(); while (indent-- > 0) ret.append(oneIndent); - + return ret; } - + /** * Creates a string that represents one indent (can be * spaces or tabs..) @@ -297,7 +297,7 @@ public class JavaIndenter { public int findReferencePosition(int offset) { return findReferencePosition(offset, peekChar(offset)); } - + /** * Peeks the next char in the document that comes after offset * on the same line as offset. @@ -317,7 +317,7 @@ public class JavaIndenter { } return Symbols.TokenEOF; } - + /** * Returns the reference position regarding to indentation for position, * or NOT_FOUND. @@ -351,12 +351,12 @@ public class JavaIndenter { boolean matchBrace= false; boolean matchParen= false; boolean matchCase= false; - + // account for unindenation characters already typed in, but after position // if they are on a line by themselves, the indentation gets adjusted // accordingly // - // also account for a dangling else + // also account for a dangling else if (offset < fDocument.getLength()) { try { IRegion line= fDocument.getLineInformationOfOffset(offset); @@ -365,7 +365,7 @@ public class JavaIndenter { boolean isFirstTokenOnLine= fDocument.get(lineOffset, prevPos + 1 - lineOffset).trim().length() == 0; int prevToken= fScanner.previousToken(prevPos, JavaHeuristicScanner.UNBOUND); boolean bracelessBlockStart= fScanner.isBracelessBlockStart(prevPos, JavaHeuristicScanner.UNBOUND); - + switch (nextToken) { case Symbols.TokenEOF: case Symbols.TokenELSE: @@ -404,9 +404,9 @@ public class JavaIndenter { } } else { // assume an else could come if we are at the end of file - danglingElse= true; + danglingElse= true; } - + int ref= findReferencePosition(offset, danglingElse, matchBrace, matchParen, matchCase); if (unindent) fIndent--; @@ -414,7 +414,7 @@ public class JavaIndenter { fIndent++; return ref; } - + /** * Returns the reference position regarding to indentation for position, * or NOT_FOUND.fIndent will contain the @@ -440,7 +440,7 @@ public class JavaIndenter { fIndent= 0; // the indentation modification fAlign= JavaHeuristicScanner.NOT_FOUND; fPosition= offset; - + // forward cases // an unindentation happens sometimes if the next token is special, namely on braces, parens and case labels // align braces, but handle the case where we align with the method declaration start instead of @@ -467,7 +467,7 @@ public class JavaIndenter { // return pos; // } // } - + // align parenthesis' if (matchParen) { if (skipScope(Symbols.TokenLPAREN, Symbols.TokenRPAREN)) @@ -480,13 +480,13 @@ public class JavaIndenter { return pos; } } - + // the only reliable way to get case labels aligned (due to many different styles of using braces in a block) // is to go for another case statement, or the scope opening brace // if (matchCase) { // return matchCaseAlignment(); // } - + nextToken(); switch (fToken) { case Symbols.TokenRBRACE: @@ -496,31 +496,31 @@ public class JavaIndenter { if (!skipScope()) fPosition= pos; case Symbols.TokenSEMICOLON: - // this is the 90% case: after a statement block + // this is the 90% case: after a statement block // the end of the previous statement / block previous.end // search to the end of the statement / block before the previous; the token just after that is previous.start return skipToStatementStart(danglingElse, false); - + // scope introduction: special treat who special is case Symbols.TokenLPAREN: case Symbols.TokenLBRACE: case Symbols.TokenLBRACKET: return handleScopeIntroduction(offset + 1); - + case Symbols.TokenEOF: // trap when hitting start of document return 0; - + case Symbols.TokenEQUAL: // indent assignments fIndent= prefAssignmentIndent(); return fPosition; - + case Symbols.TokenCOLON: // TODO handle ternary deep indentation fIndent= prefCaseBlockIndent(); return fPosition; - + case Symbols.TokenQUESTIONMARK: if (prefTernaryDeepAlign()) { setFirstElementAlignment(fPosition, offset + 1); @@ -529,7 +529,7 @@ public class JavaIndenter { fIndent= prefTernaryIndent(); return fPosition; } - + // indentation for blockless introducers: case Symbols.TokenDO: case Symbols.TokenWHILE: @@ -554,7 +554,7 @@ public class JavaIndenter { fPosition= offset; fLine= line; // else: fall through to default - + case Symbols.TokenCOMMA: // inside a list of some type // easy if there is already a list item before with its own indentation - we just align @@ -565,7 +565,7 @@ public class JavaIndenter { // if we are inside a continued expression, then either align with a previous line that has indentation // or indent from the expression start line (either a scope introducer or the start of the expr). return skipToPreviousListItemOrListStart(); - + } } @@ -579,7 +579,7 @@ public class JavaIndenter { private int skipToStatementStart(boolean danglingElse, boolean isInBlock) { while (true) { nextToken(); - + if (isInBlock) { switch (fToken) { // exit on all block introducers @@ -595,13 +595,13 @@ public class JavaIndenter { case Symbols.TokenFOR: case Symbols.TokenTRY: return fPosition; - + case Symbols.TokenSWITCH: fIndent= prefCaseIndent(); return fPosition; } } - + switch (fToken) { // scope introduction through: LPAREN, LBRACE, LBRACKET // search stop on SEMICOLON, RBRACE, COLON, EOF @@ -612,13 +612,13 @@ public class JavaIndenter { case Symbols.TokenSEMICOLON: case Symbols.TokenEOF: return fPreviousPos; - + case Symbols.TokenCOLON: int pos= fPreviousPos; if (!isConditional()) return pos; break; - + case Symbols.TokenRBRACE: // RBRACE is a little tricky: it can be the end of an array definition, but // usually it is the end of a previous block @@ -627,7 +627,7 @@ public class JavaIndenter { continue; // it's an array else return pos; // it's not - do as with all the above - + // scopes: skip them case Symbols.TokenRPAREN: case Symbols.TokenRBRACKET: @@ -635,8 +635,8 @@ public class JavaIndenter { if (skipScope()) break; else - return pos; - + return pos; + // IF / ELSE: align the position after the conditional block with the if // so we are ready for an else, except if danglingElse is false // in order for this to work, we must skip an else to its if @@ -652,17 +652,17 @@ public class JavaIndenter { break; else return pos; - + case Symbols.TokenDO: // align the WHILE position with its do return fPosition; - + case Symbols.TokenWHILE: // this one is tricky: while can be the start of a while loop - // or the end of a do - while + // or the end of a do - while pos= fPosition; if (hasMatchingDo()) { - // continue searching from the DO on + // continue searching from the DO on break; } else { // continue searching from the WHILE on @@ -671,12 +671,12 @@ public class JavaIndenter { } default: // keep searching - + } } } - + /** * Returns true if the colon at the current position is part of a conditional * (ternary) expression, false otherwise. @@ -687,13 +687,13 @@ public class JavaIndenter { while (true) { nextToken(); switch (fToken) { - + // search for case, otherwise return true case Symbols.TokenIDENT: continue; case Symbols.TokenCASE: return false; - + default: return true; } @@ -727,18 +727,18 @@ public class JavaIndenter { // // align with previous label // fIndent= 0; // return fPosition; -// +// // // scopes: skip them // case Symbols.TokenRPAREN: // case Symbols.TokenRBRACKET: // case Symbols.TokenRBRACE: // skipScope(); // break; -// +// // default: // // keep searching // continue; -// +// // } // } // } @@ -759,7 +759,7 @@ public class JavaIndenter { int startPosition= fPosition; while (true) { nextToken(); - + // if any line item comes with its own indentation, adapt to it if (fLine < startLine) { try { @@ -771,7 +771,7 @@ public class JavaIndenter { } return startPosition; } - + switch (fToken) { // scopes: skip them case Symbols.TokenRPAREN: @@ -779,13 +779,13 @@ public class JavaIndenter { case Symbols.TokenRBRACE: skipScope(); break; - + // scope introduction: special treat who special is case Symbols.TokenLPAREN: case Symbols.TokenLBRACE: case Symbols.TokenLBRACKET: return handleScopeIntroduction(startPosition + 1); - + case Symbols.TokenSEMICOLON: return fPosition; case Symbols.TokenQUESTIONMARK: @@ -798,11 +798,11 @@ public class JavaIndenter { } case Symbols.TokenEOF: return 0; - + } } } - + /** * Skips a scope and positions the cursor (fPosition) on the * token that opens the scope. Returns true if a matching peer @@ -848,7 +848,7 @@ public class JavaIndenter { // scope introduction: special treat who special is case Symbols.TokenLPAREN: int pos= fPosition; // store - + // special: method declaration deep indentation if (looksLikeMethodDecl()) { if (prefMethodDeclDeepIndent()) @@ -869,14 +869,14 @@ public class JavaIndenter { } else if (prefParenthesisDeepIndent()) return setFirstElementAlignment(pos, bound); } - + // normal: return the parenthesis as reference fIndent= prefParenthesisIndent(); return pos; - + case Symbols.TokenLBRACE: pos= fPosition; // store - + // special: array initializer if (looksLikeArrayInitializerIntro()) if (prefArrayDeepIndent()) @@ -885,24 +885,24 @@ public class JavaIndenter { fIndent= prefArrayIndent(); else fIndent= prefBlockIndent(); - + // normal: skip to the statement start before the scope introducer // opening braces are often on differently ending indents than e.g. a method definition fPosition= pos; // restore return skipToStatementStart(true, true); // set to true to match the first if - + case Symbols.TokenLBRACKET: pos= fPosition; // store - + // special: method declaration deep indentation if (prefArrayDimensionsDeepIndent()) { return setFirstElementAlignment(pos, bound); } - + // normal: return the bracket as reference fIndent= prefBracketIndent(); return pos; // restore - + default: Assert.isTrue(false); return -1; // dummy @@ -953,7 +953,7 @@ public class JavaIndenter { */ private boolean skipNextIF() { Assert.isTrue(fToken == Symbols.TokenELSE); - + while (true) { nextToken(); switch (fToken) { @@ -963,7 +963,7 @@ public class JavaIndenter { case Symbols.TokenRBRACE: skipScope(); break; - + case Symbols.TokenIF: // found it, return return true; @@ -971,7 +971,7 @@ public class JavaIndenter { // recursively skip else-if blocks skipNextIF(); break; - + // shortcut scope starts case Symbols.TokenLPAREN: case Symbols.TokenLBRACE: @@ -1004,7 +1004,7 @@ public class JavaIndenter { } return false; } - + /** * Skips brackets if the current token is a RBRACKET. There can be nothing * but whitespace in between, this is only to be used for [] elements. @@ -1021,7 +1021,7 @@ public class JavaIndenter { } return false; } - + /** * Reads the next token in backward direction from the heuristic scanner * and sets the fields fToken, fPreviousPosition and fPosition @@ -1030,7 +1030,7 @@ public class JavaIndenter { private void nextToken() { nextToken(fPosition); } - + /** * Reads the next token in backward direction of start from * the heuristic scanner and sets the fields fToken, fPreviousPosition @@ -1046,7 +1046,7 @@ public class JavaIndenter { fLine= -1; } } - + /** * Returns true if the current tokens look like a method * declaration header (i.e. only the return type and method name). The @@ -1065,17 +1065,17 @@ public class JavaIndenter { * One option would be to go over the parameter list, but that might * be empty as well - hard to do without an AST... */ - + nextToken(); if (fToken == Symbols.TokenIDENT) { // method name do nextToken(); while (skipBrackets()); // optional brackets for array valued return types return fToken == Symbols.TokenIDENT; // type name - + } return false; } - + /** * Returns true if the current tokens look like a method * call header (i.e. an identifier as opposed to a keyword taking parenthesized @@ -1090,7 +1090,7 @@ public class JavaIndenter { nextToken(); return fToken == Symbols.TokenIDENT; // method name } - + /** * Scans tokens for the matching opening peer. The internal cursor * (fPosition) is set to the offset of the opening peer if found. @@ -1099,12 +1099,12 @@ public class JavaIndenter { * otherwise */ private boolean skipScope(int openToken, int closeToken) { - + int depth= 1; while (true) { nextToken(); - + if (fToken == closeToken) { depth++; } else if (fToken == openToken) { @@ -1118,7 +1118,7 @@ public class JavaIndenter { } // TODO adjust once there are per-project settings - + private int prefTabLength() { int tabLen; // JavaCore core= JavaCore.getJavaCore(); @@ -1129,7 +1129,7 @@ public class JavaIndenter { // if the formatter uses chars to mark indentation, then don't substitute any chars tabLen= -1; // results in no tabs being substituted for space runs else - // if the formatter uses tabs to mark indentations, use the visual setting from the editor + // if the formatter uses tabs to mark indentations, use the visual setting from the editor // to get nicely aligned indentations tabLen= plugin.getPreferenceStore().getInt(AbstractDecoratedTextEditorPreferenceConstants.EDITOR_TAB_WIDTH); else @@ -1137,7 +1137,7 @@ public class JavaIndenter { return tabLen; } - + private boolean prefArrayDimensionsDeepIndent() { return true; // sensible default } @@ -1153,7 +1153,7 @@ public class JavaIndenter { // ignore and return default } } - + return prefContinuationIndent(); // default } @@ -1167,7 +1167,7 @@ public class JavaIndenter { // ignore and return default } } - + return true; } @@ -1197,7 +1197,7 @@ public class JavaIndenter { // ignore and return default } } - + return prefContinuationIndent(); } @@ -1209,7 +1209,7 @@ public class JavaIndenter { else return 0; } - + return 0; // sun standard } @@ -1220,7 +1220,7 @@ public class JavaIndenter { private int prefCaseBlockIndent() { if (true) return prefBlockIndent(); - + Plugin plugin= JavaCore.getPlugin(); if (plugin != null) { if (DefaultCodeFormatterConstants.TRUE.equals(JavaCore.getOption(DefaultCodeFormatterConstants.FORMATTER_INDENT_SWITCHSTATEMENTS_COMPARE_TO_CASES))) @@ -1249,7 +1249,7 @@ public class JavaIndenter { // ignore and return default } } - + return true; } @@ -1295,15 +1295,15 @@ public class JavaIndenter { // ignore and return default } } - + return 1; // sensible default } private boolean prefParenthesisDeepIndent() { - + if (true) // don't do parenthesis deep indentation return false; - + Plugin plugin= JavaCore.getPlugin(); if (plugin != null) { String option= JavaCore.getOption(DefaultCodeFormatterConstants.FORMATTER_CONTINUATION_INDENTATION); @@ -1313,7 +1313,7 @@ public class JavaIndenter { // ignore and return default } } - + return false; // sensible default } @@ -1324,37 +1324,37 @@ public class JavaIndenter { private int prefBlockIndent() { return 1; // sensible default } - + private boolean prefIndentBracesForBlocks() { Plugin plugin= JavaCore.getPlugin(); if (plugin != null) { String option= JavaCore.getOption(DefaultCodeFormatterConstants.FORMATTER_BRACE_POSITION_FOR_BLOCK); return option.equals(DefaultCodeFormatterConstants.NEXT_LINE_SHIFTED); } - + return false; // sensible default } - + private boolean prefIndentBracesForArrays() { Plugin plugin= JavaCore.getPlugin(); if (plugin != null) { String option= JavaCore.getOption(DefaultCodeFormatterConstants.FORMATTER_BRACE_POSITION_FOR_ARRAY_INITIALIZER); return option.equals(DefaultCodeFormatterConstants.NEXT_LINE_SHIFTED); } - + return false; // sensible default } - + private boolean prefIndentBracesForMethods() { Plugin plugin= JavaCore.getPlugin(); if (plugin != null) { String option= JavaCore.getOption(DefaultCodeFormatterConstants.FORMATTER_BRACE_POSITION_FOR_METHOD_DECLARATION); return option.equals(DefaultCodeFormatterConstants.NEXT_LINE_SHIFTED); } - + return false; // sensible default } - + private int prefContinuationIndent() { Plugin plugin= JavaCore.getPlugin(); if (plugin != null) { @@ -1365,7 +1365,7 @@ public class JavaIndenter { // ignore and return default } } - + return 2; // sensible default } diff --git a/net.sourceforge.phpeclipse/src/net/sourceforge/phpeclipse/phpeditor/PHPUnitEditor.java b/net.sourceforge.phpeclipse/src/net/sourceforge/phpeclipse/phpeditor/PHPUnitEditor.java index 41387fe..f421323 100644 --- a/net.sourceforge.phpeclipse/src/net/sourceforge/phpeclipse/phpeditor/PHPUnitEditor.java +++ b/net.sourceforge.phpeclipse/src/net/sourceforge/phpeclipse/phpeditor/PHPUnitEditor.java @@ -24,6 +24,8 @@ import net.sourceforge.phpdt.internal.ui.actions.IndentAction; import net.sourceforge.phpdt.internal.ui.actions.RemoveBlockCommentAction; import net.sourceforge.phpdt.internal.ui.text.ContentAssistPreference; import net.sourceforge.phpdt.internal.ui.text.IPHPPartitions; +import net.sourceforge.phpdt.internal.ui.text.JavaHeuristicScanner; +import net.sourceforge.phpdt.internal.ui.text.JavaIndenter; import net.sourceforge.phpdt.internal.ui.text.PHPPairMatcher; import net.sourceforge.phpdt.internal.ui.text.SmartBackspaceManager; import net.sourceforge.phpdt.internal.ui.text.SmartSemicolonAutoEditStrategy; @@ -1106,7 +1108,9 @@ public class PHPUnitEditor extends PHPEditor { //implements index++; } buffer.append(indent); - buffer.append("\t"); + JavaHeuristicScanner scanner= new JavaHeuristicScanner(document); + JavaIndenter indenter= new JavaIndenter(document, scanner); + buffer.append(indenter.createIndent(1)); int cursorPos=buffer.length(); buffer.append(lineDelimiter); buffer.append(indent); -- 1.7.1