private void reduceIndentOfCurrentLine() throws BadLocationException { int spaces = getIndentSpaces(); String text = document.get(command.offset - spaces, spaces); if (endsWithSpaces(text, spaces)) { command.offset = command.offset - spaces; command.length = spaces; } else if (document.get(command.offset - 1, 1).equals("\t")) { command.offset = command.offset - 1; command.length = 1; } }
private void smartIndentAfterClosingBracket(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); JavaHeuristicScanner scanner = new JavaHeuristicScanner(d); JavaIndenter indenter = new JavaIndenter(d, scanner, fProject); // 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 reference = indenter.findReferencePosition(c.offset, false, true, false, false); int indLine = d.getLineOfOffset(reference); 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 e) { JavaPlugin.log(e); } }
private void fixIndentOfCurrentLine() throws BadLocationException { int start = getStartOfCurrentLine(); int end = getEndOfCurrentLine(); int endOfWs = firstEndOfWhitespace(start, end); // we want this to happen in three cases: // 1. the user types a tab in the whitespace // at the start of the line // 2. the user types { or ( at the start of // the line // 3. Correct Indentation is calling us // test for Correct Indentation action boolean correctingIndentation = command.offset == start && !command.shiftsCaret; boolean opening = command.text.equals("{") || command.text.equals("("); if (command.offset < endOfWs || // we want strictly < since we don't want to prevent the caret advancing when a space is // typed command.offset == endOfWs && endOfWs == end && opening || // this can cause the caret to jump *backwards* when a { or ( is typed! correctingIndentation) { int endOfPrev = getEndOfPreviousLine(); int startOfPrev = getStartOfPreviousLine(); char startOfCurrentLineChar = opening ? command.text.charAt(0) : // the typed character is now the first character in the line getNextNonHiddenCharacterInLine(start); char endOfLastLineChar = getPreviousNonHiddenCharacterInLine(endOfPrev); StringBuilder buf = new StringBuilder(); appendIndent( start, end, startOfPrev, endOfPrev, startOfCurrentLineChar, endOfLastLineChar, false, buf); int len = endOfWs - start; String text = buf.toString(); if (text.length() != len || !document.get(start, len).equals(text)) { if (opening) { text += command.text; } command.text = text; command.offset = start; command.length = len; } else if (!opening) { command.caretOffset = start + len; command.shiftsCaret = false; command.text = null; } } }
private void handleSmartTrigger(IDocument document, char trigger, int referenceOffset) throws BadLocationException { DocumentCommand cmd = new DocumentCommand() {}; cmd.offset = referenceOffset; cmd.length = 0; cmd.text = Character.toString(trigger); cmd.doit = true; cmd.shiftsCaret = true; cmd.caretOffset = getReplacementOffset() + getCursorPosition(); SmartSemicolonAutoEditStrategy strategy = new SmartSemicolonAutoEditStrategy(DartPartitions.DART_PARTITIONING); strategy.customizeDocumentCommand(document, cmd); replace(document, cmd.offset, cmd.length, cmd.text); setCursorPosition(cmd.caretOffset - getReplacementOffset() + cmd.text.length()); }
private void indentNewLine() throws BadLocationException { int stringIndent = getStringOrCommentIndent(command.offset); int start = getStartOfCurrentLine(); if (stringIndent >= 0) { // we're in a string or multiline comment StringBuilder sb = new StringBuilder(); for (int i = 0; i < stringIndent; i++) { char ws = document.getChar(start + i) == '\t' ? '\t' : ' '; sb.append(ws); } command.text = command.text + sb.toString() + getRelativeIndent(command.offset); } else { char endOfLastLineChar = getPreviousNonHiddenCharacterInLine(command.offset); char startOfNewLineChar = getNextNonHiddenCharacterInNewline(command.offset); StringBuilder buf = new StringBuilder(command.text); IPreferenceStore store = getPreferences(); boolean closeBrace = store == null || store.getBoolean(CLOSE_BRACES); int end = getEndOfCurrentLine(); appendIndent( command.offset, end, start, command.offset, startOfNewLineChar, endOfLastLineChar, closeBrace, buf); if (buf.length() > 2) { char ch = buf.charAt(buf.length() - 1); if (ch == '}' || ch == ')') { String hanging = document.get( command.offset, end - command.offset); // stuff after the { on the current line buf.insert(command.caretOffset - command.offset, hanging); command.length = hanging.length(); } } command.text = buf.toString(); } closeUnterminatedMultlineComment(); }
protected void indentAfterNewLine(final IDocument d, final DocumentCommand c) throws BadLocationException { final int offset = c.offset; String txt = null; editor.reconcileNow(); final IErlElement element = editor.getElementAt(offset, false); final IErlMember member = (IErlMember) element; if (member != null) { final int start = member.getSourceRange().getOffset(); if (offset >= start) { txt = d.get(start, offset - start); } } if (txt == null) { txt = ""; } final int lineN = d.getLineOfOffset(offset); final int lineOffset = d.getLineOffset(lineN); final int lineLength = d.getLineLength(lineN); final String oldLine = d.get(offset, lineLength + lineOffset - offset); try { final IRpcSite b = BackendCore.getBackendManager().getIdeBackend().getRpcSite(); final int tabw = getTabWidthFromPreferences(); final Map<String, String> prefs = new TreeMap<String, String>(); IndentationPreferencePage.addKeysAndPrefs(prefs); SmartTypingPreferencePage.addAutoNLKeysAndPrefs(prefs); final boolean useTabs = getUseTabsFromPreferences(); final IndentResult res = ErlideIndent.indentLine(b, oldLine, txt, c.text, tabw, useTabs, prefs); if (res.isAddNewLine()) { c.text += "\n"; } c.text += res.getText(); c.length += res.getRemoveNext(); } catch (final Exception e) { ErlLogger.warn(e); } }
private void fixIndentOfStringOrCommentContinuation() throws BadLocationException { int endOfWs = firstEndOfWhitespace(command.offset, getEndOfCurrentLine()); if (endOfWs < 0) return; CommonToken tokenContainingOffset = getTokenStrictlyContainingOffset(command.offset); CommonToken token = getStartOfStringToken(tokenContainingOffset); int pos = command.offset - getStartOfCurrentLine(); int tokenIndent = token.getCharPositionInLine(); if (pos > tokenIndent) return; StringBuilder indent = new StringBuilder(); int startOfTokenLine = document.getLineOffset(token.getLine() - 1); String prefix = document.get(startOfTokenLine + pos, tokenIndent - pos); for (int i = 0; i < prefix.length(); i++) { char ch = prefix.charAt(i); indent.append(ch == '\t' ? '\t' : ' '); } indent.append(getExtraIndent(token)); indent.append(getRelativeIndent(command.offset)); if (indent.length() > 0) { command.length = endOfWs - command.offset; command.text = indent.toString(); } }
/** * Set the indent of a bracket based on the command provided in the supplied document. * * @param document - the document being parsed * @param command - the command being performed */ protected void smartInsertAfterBracket(final IDocument document, final DocumentCommand command) { if (command.offset == -1 || document.getLength() == 0) { return; } try { int p = (command.offset == document.getLength() ? command.offset - 1 : command.offset); int line = document.getLineOfOffset(p); int start = document.getLineOffset(line); int whiteend = findEndOfWhiteSpace(document, start, command.offset); // shift only when line does not contain any text up to // the closing // bracket if (whiteend == command.offset) { // evaluate the line with the opening bracket // that matches out // closing bracket int indLine = findMatchingOpenBracket(document, command.offset); if (indLine != -1 && indLine != line) { // take the indent of the found line StringBuffer replaceText = new StringBuffer(getIndentOfLine(document, indLine, command)); // add the rest of the current line // including the just added // close bracket // replaceText.append(document.get(whiteend, // command.offset // - whiteend)); replaceText.append(command.text); // modify document command command.length = command.offset - start; command.offset = start; command.text = replaceText.toString(); } } } catch (BadLocationException e) { ErrorReporter.logExceptionStackTrace(e); } }
private void smartIndentAfterOpeningBracket(IDocument d, DocumentCommand c) { if (c.offset < 1 || d.getLength() == 0) return; JavaHeuristicScanner scanner = new JavaHeuristicScanner(d); int p = (c.offset == d.getLength() ? c.offset - 1 : c.offset); try { // current line int line = d.getLineOfOffset(p); int lineOffset = d.getLineOffset(line); // make sure we don't have any leading comments etc. if (d.get(lineOffset, p - lineOffset).trim().length() != 0) return; // line of last Java code int pos = scanner.findNonWhitespaceBackward(p, JavaHeuristicScanner.UNBOUND); if (pos == -1) return; int lastLine = d.getLineOfOffset(pos); // only shift if the last java line is further up and is a braceless block candidate if (lastLine < line) { JavaIndenter indenter = new JavaIndenter(d, scanner, fProject); StringBuffer indent = indenter.computeIndentation(p, true); String toDelete = d.get(lineOffset, c.offset - lineOffset); if (indent != null && !indent.toString().equals(toDelete)) { c.text = indent.append(c.text).toString(); c.length += c.offset - lineOffset; c.offset = lineOffset; } } } catch (BadLocationException e) { JavaPlugin.log(e); } }
private void smartPaste(IDocument document, DocumentCommand command) { int newOffset = command.offset; int newLength = command.length; String newText = command.text; try { JavaHeuristicScanner scanner = new JavaHeuristicScanner(document); JavaIndenter indenter = new JavaIndenter(document, scanner, fProject); int offset = newOffset; // reference position to get the indent from int refOffset = indenter.findReferencePosition(offset); if (refOffset == JavaHeuristicScanner.NOT_FOUND) return; int peerOffset = getPeerPosition(document, command); peerOffset = indenter.findReferencePosition(peerOffset); if (peerOffset != JavaHeuristicScanner.NOT_FOUND) refOffset = Math.min(refOffset, peerOffset); // eat any WS before the insertion to the beginning of the line int firstLine = 1; // don't format the first line per default, as it has other content before it IRegion line = document.getLineInformationOfOffset(offset); String notSelected = document.get(line.getOffset(), offset - line.getOffset()); if (notSelected.trim().length() == 0) { newLength += notSelected.length(); newOffset = line.getOffset(); firstLine = 0; } // prefix: the part we need for formatting but won't paste IRegion refLine = document.getLineInformationOfOffset(refOffset); String prefix = document.get(refLine.getOffset(), newOffset - refLine.getOffset()); // handle the indentation computation inside a temporary document Document temp = new Document(prefix + newText); DocumentRewriteSession session = temp.startRewriteSession(DocumentRewriteSessionType.STRICTLY_SEQUENTIAL); scanner = new JavaHeuristicScanner(temp); indenter = new JavaIndenter(temp, scanner, fProject); installJavaStuff(temp); // indent the first and second line // compute the relative indentation difference from the second line // (as the first might be partially selected) and use the value to // indent all other lines. boolean isIndentDetected = false; StringBuffer addition = new StringBuffer(); int insertLength = 0; int firstLineInsertLength = 0; int firstLineIndent = 0; int first = document.computeNumberOfLines(prefix) + firstLine; // don't format first line int lines = temp.getNumberOfLines(); int tabLength = getVisualTabLengthPreference(); boolean changed = false; for (int l = first; l < lines; l++) { // we don't change the number of lines while adding indents IRegion r = temp.getLineInformation(l); int lineOffset = r.getOffset(); int lineLength = r.getLength(); if (lineLength == 0) // don't modify empty lines continue; if (!isIndentDetected) { // indent the first pasted line String current = getCurrentIndent(temp, l); StringBuffer correct = indenter.computeIndentation(lineOffset); if (correct == null) return; // bail out insertLength = subtractIndent(correct, current, addition, tabLength); if (l == first) { firstLineInsertLength = insertLength; firstLineIndent = current.length(); } if (l != first && temp.get(lineOffset, lineLength).trim().length() != 0) { isIndentDetected = true; if (firstLineIndent >= current.length()) insertLength = firstLineInsertLength; if (insertLength == 0) { // no adjustment needed, bail out if (firstLine == 0) { // but we still need to adjust the first line command.offset = newOffset; command.length = newLength; if (changed) break; // still need to get the leading indent of the first line } return; } } else { changed = insertLength != 0; } } // relatively indent all pasted lines if (insertLength > 0) addIndent(temp, l, addition, tabLength); else if (insertLength < 0) cutIndent(temp, l, -insertLength, tabLength); } removeJavaStuff(temp); temp.stopRewriteSession(session); newText = temp.get(prefix.length(), temp.getLength() - prefix.length()); command.offset = newOffset; command.length = newLength; command.text = newText; } catch (BadLocationException e) { JavaPlugin.log(e); } }
private void smartIndentAfterNewLine(IDocument d, DocumentCommand c) { JavaHeuristicScanner scanner = new JavaHeuristicScanner(d); JavaIndenter indenter = new JavaIndenter(d, scanner, fProject); StringBuffer indent = indenter.computeIndentation(c.offset); if (indent == null) indent = new StringBuffer(); int docLength = d.getLength(); if (c.offset == -1 || docLength == 0) return; try { int p = (c.offset == docLength ? c.offset - 1 : c.offset); int line = d.getLineOfOffset(p); StringBuffer buf = new StringBuffer(c.text + indent); IRegion reg = d.getLineInformation(line); int lineEnd = reg.getOffset() + reg.getLength(); int contentStart = findEndOfWhiteSpace(d, c.offset, lineEnd); c.length = Math.max(contentStart - c.offset, 0); int start = reg.getOffset(); ITypedRegion region = TextUtilities.getPartition(d, fPartitioning, start, true); if (IJavaPartitions.JAVA_DOC.equals(region.getType())) start = d.getLineInformationOfOffset(region.getOffset()).getOffset(); // insert closing brace on new line after an unclosed opening brace if (getBracketCount(d, start, c.offset, true) > 0 && closeBrace() && !isClosed(d, c.offset, c.length)) { c.caretOffset = c.offset + buf.length(); c.shiftsCaret = false; // copy old content of line behind insertion point to new line // unless we think we are inserting an anonymous type definition if (c.offset == 0 || computeAnonymousPosition(d, c.offset - 1, fPartitioning, lineEnd) == -1) { if (lineEnd - contentStart > 0) { c.length = lineEnd - c.offset; buf.append(d.get(contentStart, lineEnd - contentStart).toCharArray()); } } buf.append(TextUtilities.getDefaultLineDelimiter(d)); StringBuffer reference = null; int nonWS = findEndOfWhiteSpace(d, start, lineEnd); if (nonWS < c.offset && d.getChar(nonWS) == '{') reference = new StringBuffer(d.get(start, nonWS - start)); else reference = indenter.getReferenceIndentation(c.offset); if (reference != null) buf.append(reference); buf.append('}'); } // insert extra line upon new line between two braces else if (c.offset > start && contentStart < lineEnd && d.getChar(contentStart) == '}') { int firstCharPos = scanner.findNonWhitespaceBackward(c.offset - 1, start); if (firstCharPos != JavaHeuristicScanner.NOT_FOUND && d.getChar(firstCharPos) == '{') { c.caretOffset = c.offset + buf.length(); c.shiftsCaret = false; StringBuffer reference = null; int nonWS = findEndOfWhiteSpace(d, start, lineEnd); if (nonWS < c.offset && d.getChar(nonWS) == '{') reference = new StringBuffer(d.get(start, nonWS - start)); else reference = indenter.getReferenceIndentation(c.offset); buf.append(TextUtilities.getDefaultLineDelimiter(d)); if (reference != null) buf.append(reference); } } c.text = buf.toString(); } catch (BadLocationException e) { JavaPlugin.log(e); } }
private void smartIndentUponE(IDocument d, DocumentCommand c) { if (c.offset < 4 || d.getLength() == 0) return; try { String content = d.get(c.offset - 3, 3); if (content.equals("els")) { // $NON-NLS-1$ JavaHeuristicScanner scanner = new JavaHeuristicScanner(d); int p = c.offset - 3; // current line int line = d.getLineOfOffset(p); int lineOffset = d.getLineOffset(line); // make sure we don't have any leading comments etc. if (d.get(lineOffset, p - lineOffset).trim().length() != 0) return; // line of last Java code int pos = scanner.findNonWhitespaceBackward(p - 1, JavaHeuristicScanner.UNBOUND); if (pos == -1) return; int lastLine = d.getLineOfOffset(pos); // only shift if the last java line is further up and is a braceless block candidate if (lastLine < line) { JavaIndenter indenter = new JavaIndenter(d, scanner, fProject); int ref = indenter.findReferencePosition(p, true, false, false, false); if (ref == JavaHeuristicScanner.NOT_FOUND) return; int refLine = d.getLineOfOffset(ref); String indent = getIndentOfLine(d, refLine); if (indent != null) { c.text = indent.toString() + "else"; // $NON-NLS-1$ c.length += c.offset - lineOffset; c.offset = lineOffset; } } return; } if (content.equals("cas")) { // $NON-NLS-1$ JavaHeuristicScanner scanner = new JavaHeuristicScanner(d); int p = c.offset - 3; // current line int line = d.getLineOfOffset(p); int lineOffset = d.getLineOffset(line); // make sure we don't have any leading comments etc. if (d.get(lineOffset, p - lineOffset).trim().length() != 0) return; // line of last Java code int pos = scanner.findNonWhitespaceBackward(p - 1, JavaHeuristicScanner.UNBOUND); if (pos == -1) return; int lastLine = d.getLineOfOffset(pos); // only shift if the last java line is further up and is a braceless block candidate if (lastLine < line) { JavaIndenter indenter = new JavaIndenter(d, scanner, fProject); int ref = indenter.findReferencePosition(p, false, false, false, true); if (ref == JavaHeuristicScanner.NOT_FOUND) return; int refLine = d.getLineOfOffset(ref); int nextToken = scanner.nextToken(ref, JavaHeuristicScanner.UNBOUND); String indent; if (nextToken == Symbols.TokenCASE || nextToken == Symbols.TokenDEFAULT) indent = getIndentOfLine(d, refLine); else // at the brace of the switch indent = indenter.computeIndentation(p).toString(); if (indent != null) { c.text = indent.toString() + "case"; // $NON-NLS-1$ c.length += c.offset - lineOffset; c.offset = lineOffset; } } return; } } catch (BadLocationException e) { JavaPlugin.log(e); } }