private static IndentResult reuseOrCreateToken(IndentResult token, int numberOfLines) { if (token == null) token = new IndentResult(new boolean[numberOfLines]); else if (token.commentLinesAtColumnZero == null) token.commentLinesAtColumnZero = new boolean[numberOfLines]; else if (token.commentLinesAtColumnZero.length != numberOfLines) { boolean[] commentBooleans = new boolean[numberOfLines]; System.arraycopy( token.commentLinesAtColumnZero, 0, commentBooleans, 0, Math.min(numberOfLines, token.commentLinesAtColumnZero.length)); token.commentLinesAtColumnZero = commentBooleans; } return token; }
/** * Shifts the line range specified by <code>lines</code> in <code>document</code>. The amount that * the lines get shifted are determined by the first line in the range, all subsequent lines are * adjusted accordingly. The passed Java project may be <code>null</code>, it is used solely to * obtain formatter preferences. * * @param document the document to be changed * @param lines the line range to be shifted * @param project the Java project to get the formatter preferences from, or <code>null</code> if * global preferences should be used * @param result the result from a previous call to <code>shiftLines</code>, in order to maintain * comment line properties, or <code>null</code>. Note that the passed result may be changed * by the call. * @return an indent result that may be queried for changes and can be reused in subsequent * indentation operations * @throws BadLocationException if <code>lines</code> is not a valid line range on <code>document * </code> */ public static IndentResult shiftLines( IDocument document, ILineRange lines, IJavaProject project, IndentResult result) throws BadLocationException { int numberOfLines = lines.getNumberOfLines(); if (numberOfLines < 1) return new IndentResult(null); result = reuseOrCreateToken(result, numberOfLines); result.hasChanged = false; JavaHeuristicScanner scanner = new JavaHeuristicScanner(document); JavaIndenter indenter = new JavaIndenter(document, scanner, project); String current = getCurrentIndent(document, lines.getStartLine()); StringBuffer correct = indenter.computeIndentation(document.getLineOffset(lines.getStartLine())); if (correct == null) return result; // bail out int tabSize = CodeFormatterUtil.getTabWidth(project); StringBuffer addition = new StringBuffer(); int difference = subtractIndent(correct, current, addition, tabSize); if (difference == 0) return result; if (result.leftmostLine == -1) result.leftmostLine = getLeftMostLine(document, lines, tabSize); int maxReduction = computeVisualLength( getCurrentIndent(document, result.leftmostLine + lines.getStartLine()), tabSize); if (difference > 0) { for (int line = lines.getStartLine(), last = line + numberOfLines, i = 0; line < last; line++) addIndent(document, line, addition, result.commentLinesAtColumnZero, i++); } else { int reduction = Math.min(-difference, maxReduction); for (int line = lines.getStartLine(), last = line + numberOfLines, i = 0; line < last; line++) cutIndent(document, line, reduction, tabSize, result.commentLinesAtColumnZero, i++); } result.hasChanged = true; return result; }
/** * Indents the line range specified by <code>lines</code> in <code>document</code>. The passed * Java project may be <code>null</code>, it is used solely to obtain formatter preferences. * * @param document the document to be changed * @param lines the line range to be indented * @param project the Java project to get the formatter preferences from, or <code>null</code> if * global preferences should be used * @param result the result from a previous call to <code>indentLines</code>, in order to maintain * comment line properties, or <code>null</code>. Note that the passed result may be changed * by the call. * @return an indent result that may be queried for changes and can be reused in subsequent * indentation operations * @throws BadLocationException if <code>lines</code> is not a valid line range on <code>document * </code> */ public static IndentResult indentLines( IDocument document, ILineRange lines, IJavaProject project, IndentResult result) throws BadLocationException { int numberOfLines = lines.getNumberOfLines(); if (numberOfLines < 1) return new IndentResult(null); result = reuseOrCreateToken(result, numberOfLines); JavaHeuristicScanner scanner = new JavaHeuristicScanner(document); JavaIndenter indenter = new JavaIndenter(document, scanner, project); boolean changed = false; int tabSize = CodeFormatterUtil.getTabWidth(project); for (int line = lines.getStartLine(), last = line + numberOfLines, i = 0; line < last; line++) { changed |= indentLine( document, line, indenter, scanner, result.commentLinesAtColumnZero, i++, tabSize); } result.hasChanged = changed; return result; }