* Performs specified movement action.
*/
public void move(MoveAction action, boolean isShiftHeld) {
boolean shouldUpdatePreferredColumn = true;
int column = cursorAnchor.getColumn();
LineInfo lineInfo = cursorAnchor.getLineInfo();
String lineText = lineInfo.line().getText();
switch (action) {
case LEFT:
column = TextUtils.findPreviousNonMarkNorOtherCharacter(lineText, column);
break;
case RIGHT:
column = TextUtils.findNonMarkNorOtherCharacter(lineText, column);
break;
case WORD_LEFT:
column = TextUtils.findPreviousWord(lineText, column, false);
/**
* {@link TextUtils#findNextWord} can return line length indicating it's
* at the end of a word on the line. If this line ends in a* {@code \n}
* that will cause us to move to the next line when we check
* {@link LineUtils#getLastCursorColumn} which isn't what we want. So
* fix it now in case the lines ends in {@code \n}.
*/
if (column == lineInfo.line().length()) {
column = rubberbandColumn(lineInfo.line(), column);
}
break;
case WORD_RIGHT:
column = TextUtils.findNextWord(lineText, column, true);
/**
* {@link TextUtils#findNextWord} can return line length indicating it's
* at the end of a word on the line. If this line ends in a* {@code \n}
* that will cause us to move to the next line when we check
* {@link LineUtils#getLastCursorColumn} which isn't what we want. So
* fix it now in case the lines ends in {@code \n}.
*/
if (column == lineInfo.line().length()) {
column = rubberbandColumn(lineInfo.line(), column);
}
break;
case UP:
column = preferredCursorColumn;
if (lineInfo.line() == document.getFirstLine() && (isShiftHeld || UserAgent.isMac())) {
/*
* Pressing up on the first line should:
* - On Mac, always go to first column, or
* - On all platforms, shift+up should select to first column
*/
column = 0;
} else {
lineInfo.moveToPrevious();
}
column = rubberbandColumn(lineInfo.line(), column);
shouldUpdatePreferredColumn = false;
break;
case DOWN:
column = preferredCursorColumn;
if (lineInfo.line() == document.getLastLine() && (isShiftHeld || UserAgent.isMac())) {
// Consistent with up-arrowing on first line
column = LineUtils.getLastCursorColumn(lineInfo.line());
} else {
lineInfo.moveToNext();
}
column = rubberbandColumn(lineInfo.line(), column);
shouldUpdatePreferredColumn = false;
break;
case PAGE_UP:
for (int i = buffer.getFlooredHeightInLines(); i > 0; i--) {
lineInfo.moveToPrevious();
}
column = rubberbandColumn(lineInfo.line(), preferredCursorColumn);
shouldUpdatePreferredColumn = false;
break;
case PAGE_DOWN:
for (int i = buffer.getFlooredHeightInLines(); i > 0; i--) {
lineInfo.moveToNext();
}
column = rubberbandColumn(lineInfo.line(), preferredCursorColumn);
shouldUpdatePreferredColumn = false;
break;
case LINE_START:
int firstNonWhitespaceColumn = TextUtils.countWhitespacesAtTheBeginningOfLine(
lineInfo.line().getText());
column = (column != firstNonWhitespaceColumn) ? firstNonWhitespaceColumn : 0;
break;
case LINE_END:
column = LineUtils.getLastCursorColumn(lineInfo.line());
break;
case TEXT_START:
lineInfo = new LineInfo(document.getFirstLine(), 0);
column = 0;
break;
case TEXT_END:
lineInfo = new LineInfo(document.getLastLine(), document.getLineCount() - 1);
column = LineUtils.getLastCursorColumn(lineInfo.line());
break;
}
if (column < 0) {
if (lineInfo.moveToPrevious()) {
column = getLastCursorColumn(lineInfo.line());
} else {
column = 0;
}
} else if (column > getLastCursorColumn(lineInfo.line())) {
if (lineInfo.moveToNext()) {
column = LineUtils.getFirstCursorColumn(lineInfo.line());
} else {
column = rubberbandColumn(lineInfo.line(), column);
}
}
moveCursor(lineInfo, column, shouldUpdatePreferredColumn, isShiftHeld,
getSelectionRangeForCallback());