Skip to content

Commit

Permalink
Merge pull request #231 from citizenmatt/feature/smooth-scrolling
Browse files Browse the repository at this point in the history
Support smooth scrolling
  • Loading branch information
AlexPl292 authored May 8, 2020
2 parents ab8be2c + 98349a4 commit 0dc236c
Show file tree
Hide file tree
Showing 3 changed files with 38 additions and 41 deletions.
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 @@ -232,7 +230,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 @@ -246,7 +243,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 @@ -255,7 +251,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 @@ -237,7 +237,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 @@ -868,7 +868,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 @@ -1084,8 +1084,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 @@ -1106,7 +1105,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

0 comments on commit 0dc236c

Please sign in to comment.