예제 #1
0
  private void moveSelectionNow(boolean up) {
    int start = _gsEditor.getEditor().getSelectionStart();
    int end = _gsEditor.getEditor().getSelectionEnd();
    String script = _gsEditor.getEditor().getText();

    // If the caret is positioned at the first point in a new line, treat it as if it is on the
    // previous line only
    if (start != end && end > 0 && script.charAt(end - 1) == '\n') {
      end = end - 1;
    }

    // Handle raw whitespace moves
    int rawStart = TextComponentUtil.getLineStart(script, start);
    int rawEnd = TextComponentUtil.getLineEnd(script, end);
    String line = script.substring(rawStart, rawEnd);
    if (GosuStringUtil.isWhitespace(line) || line.trim().startsWith("//")) {
      if (up) {
        if (rawStart == 0) {
          return;
        }
        int lineStartBefore = TextComponentUtil.getLineStart(script, rawStart - 1);
        GosuRefactorUtil.MoveInstruction moveInstruction =
            new GosuRefactorUtil.MoveInstruction(false, false, lineStartBefore);
        handleMoveInstruction(script, moveInstruction, rawStart, rawEnd, up);
        return;
      } else {
        if (rawEnd >= script.length()) {
          return;
        }
        int lineStartBefore = rawEnd + 1;
        GosuRefactorUtil.MoveInstruction moveInstruction =
            new GosuRefactorUtil.MoveInstruction(false, false, lineStartBefore);
        handleMoveInstruction(script, moveInstruction, rawStart, rawEnd, up);
        return;
      }
    }

    int peStart = TextComponentUtil.findNonWhitespacePositionAfter(script, rawStart);
    int peEnd = TextComponentUtil.findNonWhitespacePositionBefore(script, rawEnd);

    peStart = Math.min(peStart, script.length() - 1);
    peEnd = Math.min(peEnd, script.length() - 1);

    // Find the first statement at the selection start
    IParseTree firstStatement =
        GosuRefactorUtil.findFirstStatementAtLine(
            TextComponentUtil.getLineAtPosition(_gsEditor.getEditor(), peStart),
            peStart,
            _gsEditor.getParser().getLocations());

    // Find the last statement at the selection end
    IParseTree lastStatement =
        GosuRefactorUtil.findLastStatementAtLine(
            TextComponentUtil.getLineAtPosition(_gsEditor.getEditor(), peEnd),
            peEnd,
            _gsEditor.getParser().getLocations());

    // Find the spanning range of those two statements
    IParseTree[] boundingPair =
        GosuRefactorUtil.findSpanningLogicalRange(firstStatement, lastStatement);

    // If a bounding pair exists, do the move
    if (boundingPair != null) {
      int clipStart =
          Math.min(rawStart, TextComponentUtil.getLineStart(script, boundingPair[0].getOffset()));
      int clipEnd =
          Math.max(rawEnd, TextComponentUtil.getLineEnd(script, boundingPair[1].getExtent()));

      // if this is not a class element (that is, we are in an impl), handle moving into a white
      // space line
      if (!GosuRefactorUtil.isClassElement(boundingPair[0])) {
        int lineStart =
            up
                ? TextComponentUtil.getWhiteSpaceOrCommentLineStartBefore(script, clipStart)
                : TextComponentUtil.getWhiteSpaceOrCommentLineStartAfter(script, clipEnd);
        if (lineStart != -1) {
          GosuRefactorUtil.MoveInstruction moveInstruction =
              new GosuRefactorUtil.MoveInstruction(false, false, lineStart);
          handleMoveInstruction(script, moveInstruction, clipStart, clipEnd, up);
          return;
        }
      }

      // Not handling an into whitespace move, so do a syntax aware move
      GosuRefactorUtil.MoveInstruction moveInstruction =
          up
              ? GosuRefactorUtil.getMoveUpInstruction(boundingPair[0])
              : GosuRefactorUtil.getMoveDownInstruction(boundingPair[1]);

      if (moveInstruction != null) {
        if (GosuRefactorUtil.isClassElement(boundingPair[1])) {
          IParseTree nextSibling = boundingPair[1].getNextSibling();
          if (nextSibling != null) {
            clipEnd = TextComponentUtil.getLineStart(script, nextSibling.getOffset()) - 1;
            if (!up) {
              moveInstruction.position =
                  TextComponentUtil.getDeepestWhiteSpaceLineStartAfter(
                      script, moveInstruction.position);
            }
          }
        }

        handleMoveInstruction(script, moveInstruction, clipStart, clipEnd, up);
      }
    }
  }
예제 #2
0
  private void handleMoveInstruction(
      String script,
      GosuRefactorUtil.MoveInstruction moveInstruction,
      int startClip,
      int endClip,
      boolean up) {
    // Do nothing if we are moving down beyond the last position in the script
    if (endClip == script.length() - 1 && !up) {
      return;
    }

    if (endClip < script.length()) {
      endClip = endClip + 1;
    }

    String movedCodeAsString = script.substring(startClip, endClip);
    if (!movedCodeAsString.endsWith("\n")) {
      movedCodeAsString += "\n";
    }
    int offset = moveInstruction.position;

    if (up) {
      offset = TextComponentUtil.getLineStart(script, offset);
    } else {
      offset = TextComponentUtil.getLineEnd(script, offset) + 1 - movedCodeAsString.length();
    }

    StringBuilder movedCode = new StringBuilder();

    int caretPosition = _gsEditor.getEditor().getCaretPosition();
    int selectionStart = _gsEditor.getEditor().getSelectionStart();
    int selectionEnd = _gsEditor.getEditor().getSelectionEnd();

    int currentPosition = startClip;

    if (moveInstruction.indent) {
      String[] strings = movedCodeAsString.split("\n");
      for (String str : strings) {

        if (caretPosition > currentPosition) {
          caretPosition += 2;
        }
        if (selectionStart > currentPosition) {
          selectionStart += 2;
        }
        if (selectionEnd > currentPosition) {
          selectionEnd += 2;
        }

        movedCode.append("  ");
        movedCode.append(str);
        movedCode.append("\n");
        currentPosition += str.length() + 1;
      }
    } else if (moveInstruction.outdent && movedCodeAsString.startsWith("  ")) {
      String[] strings = movedCodeAsString.split("\n");
      for (String str : strings) {
        if (str.startsWith("  ")) {
          if (caretPosition > currentPosition) {
            caretPosition -= 2;
          }
          if (selectionStart > currentPosition) {
            selectionStart -= 2;
          }
          if (selectionEnd > currentPosition) {
            selectionEnd -= 2;
          }
          str = str.substring(2, str.length());
        }

        movedCode.append(str);
        movedCode.append("\n");
        currentPosition += str.length() + 1;
      }
    } else {
      movedCode.append(movedCodeAsString);
    }

    CompoundEdit undoAtom = _gsEditor.getUndoManager().getUndoAtom();
    if (undoAtom != null && undoAtom.getPresentationName().equals("Script Change")) {
      _gsEditor.getUndoManager().endUndoAtom();
    }
    _gsEditor.getUndoManager().beginUndoAtom("moveLine");
    try {

      _gsEditor.getEditor().getDocument().remove(startClip, endClip - startClip);
      _gsEditor.getEditor().getDocument().insertString(offset, movedCode.toString(), null);

      _gsEditor.getEditor().setSelectionStart(selectionStart - (startClip - offset));
      _gsEditor.getEditor().setSelectionEnd(selectionEnd - (startClip - offset));
      _gsEditor.getEditor().getCaret().moveDot(caretPosition - (startClip - offset));

    } catch (BadLocationException e) {
      throw new RuntimeException(e);
    } finally {
      _gsEditor.getUndoManager().endUndoAtom();
    }
  }