Пример #1
0
 @Override
 protected int getPreservedLineInitialIndentation(JoinedTokenSequence<JspTokenId> ts)
     throws BadLocationException {
   int[] index = ts.index();
   boolean found = false;
   do {
     if (ts.token().id() == JspTokenId.COMMENT) {
       String comment = ts.token().text().toString().trim();
       if (comment.startsWith("<%--")) {
         found = true;
         break;
       }
     } else {
       break;
     }
   } while (ts.movePrevious());
   int indent = 0;
   if (found) {
     int lineStart = Utilities.getRowStart(getDocument(), ts.offset());
     // TODO: can comment token start with spaces?? if yes then adjust
     // column to point to first non-whitespace
     int column = ts.offset();
     indent = column - lineStart;
   }
   ts.moveIndex(index);
   ts.moveNext();
   return indent;
 }
Пример #2
0
  private void addFolds(
      BaseDocument doc,
      List<? extends ASTElement> elements,
      Map<String, List<OffsetRange>> folds,
      List<OffsetRange> codeblocks)
      throws BadLocationException {
    for (ASTElement element : elements) {
      ElementKind kind = element.getKind();
      switch (kind) {
        case FIELD:
        case METHOD:
        case CONSTRUCTOR:
        case CLASS:
        case MODULE:
          ASTNode node = element.getNode();
          OffsetRange range = ASTUtils.getRangeFull(node, doc);

          // beware of synthetic elements
          if ((kind == ElementKind.METHOD && !((MethodNode) node).isSynthetic())
              || (kind == ElementKind.CONSTRUCTOR && !((ConstructorNode) node).isSynthetic())
              || (kind == ElementKind.FIELD
                  && ((FieldNode) node).getInitialExpression() instanceof ClosureExpression)
              // Only make nested classes/modules foldable, similar to what the java editor is doing
              || (range.getStart() > Utilities.getRowStart(doc, range.getStart()))
                  && kind != ElementKind.FIELD) {

            int start = range.getStart();
            // Start the fold at the END of the line behind last non-whitespace, remove curly brace,
            // if any
            start = Utilities.getRowLastNonWhite(doc, start);
            if (start >= 0 && doc.getChars(start, 1)[0] != '{') {
              start++;
            }
            int end = range.getEnd();
            if (start != (-1) && end != (-1) && start < end && end <= doc.getLength()) {
              range = new OffsetRange(start, end);
              codeblocks.add(range);
            }
          }
          break;
      }

      List<? extends ASTElement> children = element.getChildren();

      if (children != null && children.size() > 0) {
        addFolds(doc, children, folds, codeblocks);
      }
    }
  }
Пример #3
0
  @Override
  protected List<IndentCommand> getLineIndent(
      IndenterContextData<TplTopTokenId> context, List<IndentCommand> preliminaryNextLineIndent)
      throws BadLocationException {
    Stack<TplStackItem> blockStack = getStack();
    List<IndentCommand> iis = new ArrayList<IndentCommand>();
    getIndentFromState(iis, true, context.getLineStartOffset());

    JoinedTokenSequence<TplTopTokenId> ts = context.getJoinedTokenSequences();
    ts.move(context.getLineStartOffset());

    boolean isSmartyBodyCommand = false;
    boolean isSmartyElseCommand = false;
    boolean afterDelimiter = false;
    int embeddingLevel = 0;
    String lastTplCommand = "";
    // iterate over tokens on the line and push to stack any changes
    while (!context.isBlankLine()
        && ts.moveNext()
        && ((ts.isCurrentTokenSequenceVirtual() && ts.offset() < context.getLineEndOffset())
            || ts.offset() <= context.getLineEndOffset())) {
      Token<TplTopTokenId> token = ts.token();
      if (token == null) {
        continue;
      } else if (ts.embedded() != null) {
        // indent for smarty command of the zero embedding level
        if (embeddingLevel == 1 && afterDelimiter) {
          if (token.id() == TplTopTokenId.T_SMARTY && context.isIndentThisLine()) {
            String tplToken = getFunctionalTplTokenId(token);
            isSmartyBodyCommand = isBodyCommand(tplToken, context);
            if (isSmartyBodyCommand) {
              lastTplCommand = tplToken;
              isSmartyElseCommand = isElseCommand(tplToken);
            }
          } else {
            isSmartyBodyCommand = false;
            isSmartyElseCommand = false;
          }
        }
        continue;
      }

      if (token.id() == TplTopTokenId.T_SMARTY_OPEN_DELIMITER) {
        afterDelimiter = true;
        embeddingLevel++;
        TplStackItem state = new TplStackItem(StackItemState.IN_RULE);
        blockStack.push(state);
      } else if (token.id() == TplTopTokenId.T_SMARTY_CLOSE_DELIMITER) {
        afterDelimiter = false;
        if (isInState(blockStack, StackItemState.IN_RULE)) {
          // check that IN_RULE is the last state
          TplStackItem item = blockStack.pop();
          embeddingLevel--;
          if (embeddingLevel == 0) {
            assert item.state == StackItemState.IN_RULE;
            if (isSmartyBodyCommand) {
              if (!blockStack.isEmpty()
                  && isInRelatedCommand(lastTplCommand, blockStack.peek().getCommand())) {
                if (isSmartyElseCommand) {
                  String command = blockStack.pop().command;
                  blockStack.push(new TplStackItem(StackItemState.IN_BODY, command));
                } else {
                  blockStack.pop();
                }
                iis.add(new IndentCommand(IndentCommand.Type.RETURN, preservedLineIndentation));
              } else {
                blockStack.push(new TplStackItem(StackItemState.IN_BODY, lastTplCommand));
              }
            }
          }
        }
      } else if (isCommentToken(token)) {
        int start = context.getLineStartOffset();
        if (start < ts.offset()) {
          start = ts.offset();
        }
        int commentEndOffset = ts.offset() + ts.token().text().toString().trim().length() - 1;
        int end = context.getLineEndOffset();
        if (end > commentEndOffset) {
          end = commentEndOffset;
        }
        if (start > end) {
          // do nothing
        } else if (start == ts.offset()) {
          if (end < commentEndOffset) {
            // if comment ends on next line put formatter to IN_COMMENT state
            int lineStart = Utilities.getRowStart(getDocument(), ts.offset());
            preservedLineIndentation = start - lineStart;
          }
        } else if (end == commentEndOffset) {
          String text = getDocument().getText(start, end - start + 1).trim();
          if (!text.startsWith("*/")) {
            // if line does not start with '*/' then treat it as unformattable
            IndentCommand ic =
                new IndentCommand(
                    IndentCommand.Type.PRESERVE_INDENTATION, context.getLineStartOffset());
            ic.setFixedIndentSize(preservedLineIndentation);
            iis.add(ic);
          }
          preservedLineIndentation = -1;
        } else {
          IndentCommand ic =
              new IndentCommand(
                  IndentCommand.Type.PRESERVE_INDENTATION, context.getLineStartOffset());
          ic.setFixedIndentSize(preservedLineIndentation);
          iis.add(ic);
        }
      }
    }
    if (context.isBlankLine() && iis.isEmpty()) {
      IndentCommand ic =
          new IndentCommand(IndentCommand.Type.PRESERVE_INDENTATION, context.getLineStartOffset());
      ic.setFixedIndentSize(preservedLineIndentation);
      iis.add(ic);
    }

    if (iis.isEmpty()) {
      iis.add(new IndentCommand(IndentCommand.Type.NO_CHANGE, context.getLineStartOffset()));
    }

    if (context.getNextLineStartOffset() != -1) {
      getIndentFromState(preliminaryNextLineIndent, false, context.getNextLineStartOffset());
      if (preliminaryNextLineIndent.isEmpty()) {
        preliminaryNextLineIndent.add(
            new IndentCommand(IndentCommand.Type.NO_CHANGE, context.getNextLineStartOffset()));
      }
    }

    return iis;
  }