deathau / cm-typewriter-scroll-obsidian

Typewriter Scroll Obsidian Plugin
169 stars 15 forks source link

[Feature] Set number of visible lines before/after current line, like vim's scrolloff (Scroll offset) option #22

Open horriblename opened 2 years ago

horriblename commented 2 years ago

I'd like to add a feature where the number of visible lines above or below the current line always present during scrolling, here is a demo of the expected behaviour if a scrolloff option is set to 5:

simplescreenrecorder-2021-11-27_17 08 38

notice that the number of lines above the cursor is always 5 when scrolling up. The same effect for scrolling down is not yet implemented.

The following modification to typewriter-scrolling.js's CodeMirror.commands.scrollSelectionToCenter will implement this effect:

const ALWAYS_CENTRE = false; // turn off scroll offset, always centre the line // TODO add to settings
const SCROLL_OFFSET_LINES = 5; /* TODO add to settings */
CodeMirror.commands.scrollSelectionToCenter = function (cm) {
    var cursor = cm.getCursor('head');
    var charCoords = cm.charCoords(cursor, "local");
    var scrollInfo = cm.getScrollInfo();
    var top = charCoords.top;
    var halfLineHeight = (charCoords.bottom - top) / 2;
    var halfWindowHeight = cm.getWrapperElement().offsetHeight / 2;

    /* TODO define as global var on plugin load, cuz each line height is different and will lead to inconsistent offset sizes */
    var scrollOffset = 2 * halfLineHeight * SCROLL_OFFSET_LINES;

    var scrollTo = null;
    if (ALWAYS_CENTRE || scrollOffset >= halfWindowHeight - halfLineHeight) {
        scrollTo = Math.round((top - halfWindowHeight + halfLineHeight));
    }
    else if (top < scrollInfo.top + scrollOffset) {
        scrollTo = Math.round(top - scrollOffset);
    }
    else if (top + 2 * halfLineHeight > scrollInfo.top + scrollInfo.height - scrollOffset){
        /* this part is not working properly */
        scrollTo = Math.round(top + 2*halfLineHeight + scrollOffset - 2 * halfWindowHeight);
    }

    cm.scrollTo(null, scrollTo);
};

If it's okay, I will open a pull request and work on it.

TODO

  1. fix implementation for scrolling down
  2. add "Number of Lines always Visible above or below cursor during Scrolling" (SCROLL_OFFSET_LINES above) and "Always centre (current Typewriter scrolling behaviour)"
  3. calculate a fixed offset size based on line height in plugin onload()
kevinawoo commented 2 years ago

This seems like an alternative solution for #9