Sublime Forum

Preserve top/bottom lines on PageUp/PageDown (v2)

#1

I have created a plugin to add 1-2 lines from the previous viewport to the next one on PageUp / PageDown key presses. Feel free to test and improve.

(Corresponding GitHub issue: https://github.com/SublimeTextIssues/Core/issues/2843)

import sublime
import sublime_plugin

class ScrollUpCommand(sublime_plugin.TextCommand):
    def run(self, edit, amount):
        view = self.view

        physical_lines_per_viewport = float(view.rowcol(view.visible_region().end())[0] -
                                            view.rowcol(view.visible_region().begin())[0])
        viewport_height = view.viewport_extent()[1]
        line_height = view.line_height()
        visual_lines_per_viewport = round(viewport_height / line_height)
        x = visual_lines_per_viewport + amount
        cursor_position = view.rowcol(view.sel()[0].begin())[0]

        # print(cursor_position, physical_lines_per_viewport)
        if cursor_position > physical_lines_per_viewport:
            view.run_command("scroll_lines", {"amount": x})
            view.run_command("move", {"by": "lines", "forward": False})
            # print("a")
        else:
            view.run_command("move_to", {"to": "bof", "extend": False})
            # print("b")

class ScrollDownCommand(sublime_plugin.TextCommand):
    def run(self, edit, amount):
        view = self.view

        physical_lines_per_viewport = float(view.rowcol(view.visible_region().end())[0] -
                                            view.rowcol(view.visible_region().begin())[0])
        viewport_height = view.viewport_extent()[1]
        line_height = view.line_height()
        visual_lines_per_viewport = round(viewport_height / line_height)
        x = visual_lines_per_viewport + amount
        cursor_position = view.rowcol(view.sel()[0].begin())[0]
        physical_lines_per_layout = view.rowcol(view.size())[0]

        # print(cursor_position, physical_lines_per_layout, physical_lines_per_viewport)
        if cursor_position < physical_lines_per_layout - physical_lines_per_viewport:
            view.run_command("scroll_lines", {"amount": -x})
            view.run_command("move", {"by": "lines", "forward": True})
            # print("a2")
        else:
            view.run_command("move_to", {"to": "eof", "extend": False})
            # print("b2")
[
    { "keys": ["pageup"], "command": "scroll_up", "args": {"amount": -2.0} },
    { "keys": ["pagedown"], "command": "scroll_down", "args": {"amount": -2.0} },
]

scroll_past_end and word_wrap can have any values.

0 Likes