/** * Indents line <code>line</code> in <code>document</code> with <code>indent</code>. Leaves * leading comment signs alone. * * @param document the document * @param line the line * @param indent the indentation to insert * @param tabLength the length of a tab * @throws BadLocationException on concurrent document modification */ private void addIndent(Document document, int line, CharSequence indent, int tabLength) throws BadLocationException { IRegion region = document.getLineInformation(line); int insert = region.getOffset(); int endOffset = region.getOffset() + region.getLength(); // Compute insert after all leading line comment markers int newInsert = insert; while (newInsert < endOffset - 2 && document.get(newInsert, 2).equals(LINE_COMMENT)) newInsert += 2; // Heuristic to check whether it is commented code or just a comment if (newInsert > insert) { int whitespaceCount = 0; int i = newInsert; while (i < endOffset - 1) { char ch = document.get(i, 1).charAt(0); if (!Character.isWhitespace(ch)) break; whitespaceCount = whitespaceCount + computeVisualLength(ch, tabLength); i++; } if (whitespaceCount != 0 && whitespaceCount >= CodeFormatterUtil.getIndentWidth(fProject)) insert = newInsert; } // Insert indent document.replace(insert, 0, indent.toString()); }
/** * Cuts the visual equivalent of <code>toDelete</code> characters out of the indentation of line * <code>line</code> in <code>document</code>. Leaves leading comment signs alone. * * @param document the document * @param line the line * @param toDelete the number of space equivalents to delete * @param tabLength the length of a tab * @throws BadLocationException on concurrent document modification */ private void cutIndent(Document document, int line, int toDelete, int tabLength) throws BadLocationException { IRegion region = document.getLineInformation(line); int from = region.getOffset(); int endOffset = region.getOffset() + region.getLength(); // go behind line comments while (from < endOffset - 2 && document.get(from, 2).equals(LINE_COMMENT)) from += 2; int to = from; while (toDelete > 0 && to < endOffset) { char ch = document.getChar(to); if (!Character.isWhitespace(ch)) break; toDelete -= computeVisualLength(ch, tabLength); if (toDelete >= 0) to++; else break; } document.replace(from, to - from, ""); // $NON-NLS-1$ }
private final synchronized void eclipseReplace(int pos, int length, String text) throws BadLocationException { // changes.addChange(new Change(pos, length, text)); changed = true; super.replace(pos, length, text); }
/** * This is a new method, not known to the eclipse platform. It is used to handle document changes * that were not directly triggered by the user. These changes come from the according * DocumentText. We say this are changes "from below", in contradiction to changes "from above" * {@link #replace(int, int, String)}. */ public final void doReplace(int pos, int length, String text) throws BadLocationException { super.replace(pos, length, text); }
private int getPeerPosition(IDocument document, DocumentCommand command) { if (document.getLength() == 0) return 0; /* * Search for scope closers in the pasted text and find their opening peers * in the document. */ Document pasted = new Document(command.text); installJavaStuff(pasted); int firstPeer = command.offset; JavaHeuristicScanner pScanner = new JavaHeuristicScanner(pasted); JavaHeuristicScanner dScanner = new JavaHeuristicScanner(document); // add scope relevant after context to peer search int afterToken = dScanner.nextToken(command.offset + command.length, JavaHeuristicScanner.UNBOUND); try { switch (afterToken) { case Symbols.TokenRBRACE: pasted.replace(pasted.getLength(), 0, "}"); // $NON-NLS-1$ break; case Symbols.TokenRPAREN: pasted.replace(pasted.getLength(), 0, ")"); // $NON-NLS-1$ break; case Symbols.TokenRBRACKET: pasted.replace(pasted.getLength(), 0, "]"); // $NON-NLS-1$ break; } } catch (BadLocationException e) { // cannot happen Assert.isTrue(false); } int pPos = 0; // paste text position (increasing from 0) int dPos = Math.max(0, command.offset - 1); // document position (decreasing from paste offset) while (true) { int token = pScanner.nextToken(pPos, JavaHeuristicScanner.UNBOUND); pPos = pScanner.getPosition(); switch (token) { case Symbols.TokenLBRACE: case Symbols.TokenLBRACKET: case Symbols.TokenLPAREN: pPos = skipScope(pScanner, pPos, token); if (pPos == JavaHeuristicScanner.NOT_FOUND) return firstPeer; break; // closed scope -> keep searching case Symbols.TokenRBRACE: int peer = dScanner.findOpeningPeer(dPos, '{', '}'); dPos = peer - 1; if (peer == JavaHeuristicScanner.NOT_FOUND) return firstPeer; firstPeer = peer; break; // keep searching case Symbols.TokenRBRACKET: peer = dScanner.findOpeningPeer(dPos, '[', ']'); dPos = peer - 1; if (peer == JavaHeuristicScanner.NOT_FOUND) return firstPeer; firstPeer = peer; break; // keep searching case Symbols.TokenRPAREN: peer = dScanner.findOpeningPeer(dPos, '(', ')'); dPos = peer - 1; if (peer == JavaHeuristicScanner.NOT_FOUND) return firstPeer; firstPeer = peer; break; // keep searching case Symbols.TokenCASE: case Symbols.TokenDEFAULT: JavaIndenter indenter = new JavaIndenter(document, dScanner, fProject); peer = indenter.findReferencePosition(dPos, false, false, false, true); if (peer == JavaHeuristicScanner.NOT_FOUND) return firstPeer; firstPeer = peer; break; // keep searching case Symbols.TokenEOF: return firstPeer; default: // keep searching } } }