Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Support smooth scrolling #231

Merged
merged 2 commits into from
May 8, 2020
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
5 changes: 0 additions & 5 deletions src/com/maddyhome/idea/vim/group/EditorGroup.java
Original file line number Diff line number Diff line change
Expand Up @@ -52,12 +52,10 @@
*/
@State(name = "VimEditorSettings", storages = {@Storage(value = "$APP_CONFIG$/vim_settings.xml")})
public class EditorGroup implements PersistentStateComponent<Element> {
private static final boolean ANIMATED_SCROLLING_VIM_VALUE = false;
private static final boolean REFRAIN_FROM_SCROLLING_VIM_VALUE = true;
public static final String EDITOR_STORE_ELEMENT = "editor";

private boolean isBlockCursor = false;
private boolean isAnimatedScrolling = false;
private boolean isRefrainFromScrolling = false;
private Boolean isKeyRepeat = null;

Expand Down Expand Up @@ -244,7 +242,6 @@ public void closeEditorSearchSession(@NotNull Editor editor) {

public void editorCreated(@NotNull Editor editor) {
isBlockCursor = editor.getSettings().isBlockCursor();
isAnimatedScrolling = editor.getSettings().isAnimatedScrolling();
isRefrainFromScrolling = editor.getSettings().isRefrainFromScrolling();
DocumentManager.INSTANCE.addListeners(editor.getDocument());
VimPlugin.getKey().registerRequiredShortcutKeys(editor);
Expand All @@ -258,7 +255,6 @@ public void editorCreated(@NotNull Editor editor) {
KeyHandler.getInstance().reset(editor);
}
editor.getSettings().setBlockCursor(!CommandStateHelper.inInsertMode(editor));
editor.getSettings().setAnimatedScrolling(ANIMATED_SCROLLING_VIM_VALUE);
editor.getSettings().setRefrainFromScrolling(REFRAIN_FROM_SCROLLING_VIM_VALUE);
}

Expand All @@ -267,7 +263,6 @@ public void editorDeinit(@NotNull Editor editor, boolean isReleased) {
UserDataManager.unInitializeEditor(editor);
VimPlugin.getKey().unregisterShortcutKeys(editor);
editor.getSettings().setBlockCursor(isBlockCursor);
editor.getSettings().setAnimatedScrolling(isAnimatedScrolling);
editor.getSettings().setRefrainFromScrolling(isRefrainFromScrolling);
DocumentManager.INSTANCE.removeListeners(editor.getDocument());
}
Expand Down
9 changes: 4 additions & 5 deletions src/com/maddyhome/idea/vim/group/MotionGroup.java
Original file line number Diff line number Diff line change
Expand Up @@ -259,7 +259,7 @@ else if (caretColumn >= visualColumn + width - sideScrollOffset) {
}

private static int getScrollScreenTargetCaretVisualLine(final @NotNull Editor editor, int rawCount, boolean down) {
final Rectangle visibleArea = editor.getScrollingModel().getVisibleArea();
final Rectangle visibleArea = EditorHelper.getVisibleArea(editor);
final int caretVisualLine = editor.getCaretModel().getVisualPosition().line;
final int scrollOption = getScrollOption(rawCount);

Expand Down Expand Up @@ -890,7 +890,7 @@ private void scrollColumnToScreenColumn(@NotNull Editor editor, int column) {
}

private static void scrollColumnToLeftOfScreen(@NotNull Editor editor, int column) {
editor.getScrollingModel().scrollHorizontally(column * EditorHelper.getColumnWidth(editor));
EditorHelper.scrollHorizontally(editor, column * EditorHelper.getColumnWidth(editor));
}

public int moveCaretToMiddleColumn(@NotNull Editor editor, @NotNull Caret caret) {
Expand Down Expand Up @@ -1106,8 +1106,7 @@ public boolean scrollScreen(final @NotNull Editor editor, int rawCount, boolean
return false;
}

final ScrollingModel scrollingModel = editor.getScrollingModel();
final Rectangle visibleArea = scrollingModel.getVisibleArea();
final Rectangle visibleArea = EditorHelper.getVisibleArea(editor);

int targetCaretVisualLine = getScrollScreenTargetCaretVisualLine(editor, rawCount, down);

Expand All @@ -1128,7 +1127,7 @@ public boolean scrollScreen(final @NotNull Editor editor, int rawCount, boolean
}
if (moved) {
// We'll keep the caret at the same position, although that might not be the same line offset as previously
targetCaretVisualLine = editor.yToVisualLine(yInitialCaret + scrollingModel.getVisibleArea().y - yPrevious);
targetCaretVisualLine = editor.yToVisualLine(yInitialCaret + EditorHelper.getVisibleArea(editor).y - yPrevious);
}
}
else {
Expand Down
65 changes: 34 additions & 31 deletions src/com/maddyhome/idea/vim/helper/EditorHelper.java
Original file line number Diff line number Diff line change
Expand Up @@ -42,19 +42,35 @@
* This is a set of helper methods for working with editors. All line and column values are zero based.
*/
public class EditorHelper {
public static @NotNull Rectangle getVisibleArea(final @NotNull Editor editor) {
return editor.getScrollingModel().getVisibleAreaOnScrollingFinished();
}

public static boolean scrollVertically(@NotNull Editor editor, int verticalOffset) {
final ScrollingModel scrollingModel = editor.getScrollingModel();
final Rectangle area = scrollingModel.getVisibleAreaOnScrollingFinished();
scrollingModel.scroll(area.x, verticalOffset);
return scrollingModel.getVisibleAreaOnScrollingFinished().y != area.y;
}

public static void scrollHorizontally(@NotNull Editor editor, int horizontalOffset) {
final ScrollingModel scrollingModel = editor.getScrollingModel();
final Rectangle area = scrollingModel.getVisibleAreaOnScrollingFinished();
scrollingModel.scroll(horizontalOffset, area.y);
}

public static int getVisualLineAtTopOfScreen(final @NotNull Editor editor) {
final Rectangle visibleArea = editor.getScrollingModel().getVisibleArea();
final Rectangle visibleArea = getVisibleArea(editor);
return getFullVisualLine(editor, visibleArea.y, visibleArea.y, visibleArea.y + visibleArea.height);
}

public static int getVisualLineAtMiddleOfScreen(final @NotNull Editor editor) {
final ScrollingModel scrollingModel = editor.getScrollingModel();
final Rectangle visibleArea = scrollingModel.getVisibleArea();
final Rectangle visibleArea = getVisibleArea(editor);
return editor.yToVisualLine(visibleArea.y + (visibleArea.height / 2));
}

public static int getVisualLineAtBottomOfScreen(final @NotNull Editor editor) {
final Rectangle visibleArea = editor.getScrollingModel().getVisibleArea();
final Rectangle visibleArea = getVisibleArea(editor);
return getFullVisualLine(editor, visibleArea.y + visibleArea.height, visibleArea.y, visibleArea.y + visibleArea.height);
}

Expand Down Expand Up @@ -178,9 +194,8 @@ public static int normalizeScrollOffset(final @NotNull Editor editor, int scroll
*/
private static int getApproximateScreenHeight(final @NotNull Editor editor) {
int lh = editor.getLineHeight();
int height = editor.getScrollingModel().getVisibleArea().y +
editor.getScrollingModel().getVisibleArea().height -
getVisualLineAtTopOfScreen(editor) * lh;
Rectangle area = getVisibleArea(editor);
int height = area.y + area.height - getVisualLineAtTopOfScreen(editor) * lh;
return height / lh;
}

Expand All @@ -191,7 +206,7 @@ private static int getApproximateScreenHeight(final @NotNull Editor editor) {
* @return The number of screen columns
*/
public static int getScreenWidth(final @NotNull Editor editor) {
Rectangle rect = editor.getScrollingModel().getVisibleArea();
Rectangle rect = getVisibleArea(editor);
Point pt = new Point(rect.width, 0);
VisualPosition vp = editor.xyToVisualPosition(pt);

Expand All @@ -205,7 +220,7 @@ public static int getScreenWidth(final @NotNull Editor editor) {
* @return The number of pixels
*/
public static int getColumnWidth(final @NotNull Editor editor) {
Rectangle rect = editor.getScrollingModel().getVisibleArea();
Rectangle rect = getVisibleArea(editor);
if (rect.width == 0) return 0;
Point pt = new Point(rect.width, 0);
VisualPosition vp = editor.xyToVisualPosition(pt);
Expand All @@ -223,7 +238,7 @@ public static int getColumnWidth(final @NotNull Editor editor) {
public static int getVisualColumnAtLeftOfScreen(final @NotNull Editor editor) {
int cw = getColumnWidth(editor);
if (cw == 0) return 0;
return (editor.getScrollingModel().getHorizontalScrollOffset() + cw - 1) / cw;
return (getVisibleArea(editor).x + cw - 1) / cw;
}

/**
Expand Down Expand Up @@ -596,8 +611,7 @@ else if (!Character.isWhitespace(chars.charAt(offset))) {
* @param visualLine The visual line to scroll to the current caret location
*/
public static void scrollVisualLineToCaretLocation(final @NotNull Editor editor, int visualLine) {
final ScrollingModel scrollingModel = editor.getScrollingModel();
final Rectangle visibleArea = scrollingModel.getVisibleArea();
final Rectangle visibleArea = getVisibleArea(editor);
final int caretScreenOffset = editor.visualLineToY(editor.getCaretModel().getVisualPosition().line) - visibleArea.y;

final int yVisualLine = editor.visualLineToY(visualLine);
Expand All @@ -615,7 +629,7 @@ public static void scrollVisualLineToCaretLocation(final @NotNull Editor editor,
inlayOffset = -bottomInlayHeight;
}

scrollingModel.scrollVertically(yVisualLine - caretScreenOffset - inlayOffset);
scrollVertically(editor, yVisualLine - caretScreenOffset - inlayOffset);
}

/**
Expand All @@ -627,13 +641,9 @@ public static void scrollVisualLineToCaretLocation(final @NotNull Editor editor,
* @return Returns true if the window was moved
*/
public static boolean scrollVisualLineToTopOfScreen(final @NotNull Editor editor, int visualLine) {
final ScrollingModel scrollingModel = editor.getScrollingModel();
int inlayHeight = getHeightOfVisualLineInlays(editor, visualLine, true);
int y = editor.visualLineToY(visualLine) - inlayHeight;
int verticalPos = scrollingModel.getVerticalScrollOffset();
scrollingModel.scrollVertically(y);

return verticalPos != scrollingModel.getVerticalScrollOffset();
return scrollVertically(editor, y);
}

/**
Expand All @@ -643,11 +653,10 @@ public static boolean scrollVisualLineToTopOfScreen(final @NotNull Editor editor
* @param visualLine The visual line to place in the middle of the current window
*/
public static void scrollVisualLineToMiddleOfScreen(@NotNull Editor editor, int visualLine) {
final ScrollingModel scrollingModel = editor.getScrollingModel();
int y = editor.visualLineToY(visualLine);
int lineHeight = editor.getLineHeight();
int height = scrollingModel.getVisibleArea().height;
scrollingModel.scrollVertically(y - ((height - lineHeight) / 2));
int height = getVisibleArea(editor).height;
scrollVertically(editor, y - ((height - lineHeight) / 2));
}

/**
Expand All @@ -661,7 +670,6 @@ public static void scrollVisualLineToMiddleOfScreen(@NotNull Editor editor, int
* @return True if the editor was scrolled
*/
public static boolean scrollVisualLineToBottomOfScreen(@NotNull Editor editor, int visualLine) {
final ScrollingModel scrollingModel = editor.getScrollingModel();
int inlayHeight = getHeightOfVisualLineInlays(editor, visualLine, false);
int exPanelHeight = 0;
int exPanelWithoutShortcutsHeight = 0;
Expand All @@ -672,14 +680,9 @@ public static boolean scrollVisualLineToBottomOfScreen(@NotNull Editor editor, i
exPanelWithoutShortcutsHeight = ExEntryPanel.getInstanceWithoutShortcuts().getHeight();
}
int y = editor.visualLineToY(visualLine);
int verticalPos = scrollingModel.getVerticalScrollOffset();
int height = inlayHeight + editor.getLineHeight() + exPanelHeight + exPanelWithoutShortcutsHeight;

Rectangle visibleArea = scrollingModel.getVisibleArea();

scrollingModel.scrollVertically(y - visibleArea.height + height);

return verticalPos != scrollingModel.getVerticalScrollOffset();
Rectangle visibleArea = getVisibleArea(editor);
return scrollVertically(editor, y - visibleArea.height + height);
}

/**
Expand Down Expand Up @@ -734,7 +737,7 @@ public static void updateLastColumn(@NotNull Editor editor, @NotNull Caret caret
}

private static int scrollFullPageDown(final @NotNull Editor editor, int pages) {
final Rectangle visibleArea = editor.getScrollingModel().getVisibleArea();
final Rectangle visibleArea = getVisibleArea(editor);
final int lineCount = getVisualLineCount(editor);

if (editor.getCaretModel().getVisualPosition().line == lineCount - 1)
Expand Down Expand Up @@ -777,7 +780,7 @@ private static int scrollFullPageDown(final @NotNull Editor editor, int pages) {
}

private static int scrollFullPageUp(final @NotNull Editor editor, int pages) {
final Rectangle visibleArea = editor.getScrollingModel().getVisibleArea();
final Rectangle visibleArea = getVisibleArea(editor);
final int lineHeight = editor.getLineHeight();

int y = visibleArea.y;
Expand Down