Example #1
0
 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);
    }
  }
Example #3
0
  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());
  }
Example #5
0
  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);
    }
  }
Example #7
0
 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);
    }
  }