From d5abc84bea2b4f3d03dbef04da82a3ae0200fcd2 Mon Sep 17 00:00:00 2001 From: Kovid Goyal Date: Fri, 28 Jun 2019 17:07:31 +0530 Subject: [PATCH] Remote control: Add a command `kitty @ scroll-window` to scroll windows --- docs/changelog.rst | 2 ++ kitty/cmds.py | 55 +++++++++++++++++++++++++++++++++++++++++++++- 2 files changed, 56 insertions(+), 1 deletion(-) diff --git a/docs/changelog.rst b/docs/changelog.rst index 1ab480fbb..4c367b3db 100644 --- a/docs/changelog.rst +++ b/docs/changelog.rst @@ -7,6 +7,8 @@ To update |kitty|, :doc:`follow the instructions `. 0.14.3 [future] --------------------- +- Remote control: Add a command `kitty @ scroll-window` to scroll windows + - Fix an out of bounds read causing a crash when selecting text with the mouse in the alternate screen mode (:iss:`1578`) diff --git a/kitty/cmds.py b/kitty/cmds.py index 4ad1b5df3..4037d83a6 100644 --- a/kitty/cmds.py +++ b/kitty/cmds.py @@ -690,7 +690,7 @@ the command will exit with a success code. ) def cmd_focus_window(global_opts, opts, args): ''' - match: The tab to open the new window in + match: The window to focus ''' if opts.no_response: global_opts.no_command_response = True @@ -714,6 +714,59 @@ def focus_window(boss, window, payload): # }}} +# scroll_window {{{ +@cmd( + 'Scroll the specified window', + 'Scroll the specified window, if no window is specified, scroll the window this command is run inside.' + ' SCROLL_AMOUNT can be either the keywords :code:`start` or :code:`end` or an' + ' argument of the form [unit][+-]. For example, 30 will scroll down 30 lines and 2p- will' + ' scroll up 2 pages.', + argspec='SCROLL_AMOUNT', + options_spec=MATCH_WINDOW_OPTION +) +def cmd_scroll_window(global_opts, opts, args): + ''' + amount+: The amount to scroll, a two item list with the first item being \ + either a number or the keywords, start and end. \ + And the second item being either 'p' for pages or 'l' for lines. + match: The window to scroll + ''' + amt = args[0] + ans = {'match': opts.match} + if amt in ('start', 'end'): + ans['amount'] = amt, None + else: + pages = 'p' in amt + amt = amt.replace('p', '') + mult = -1 if amt.endswith('-') else 1 + amt = int(amt.replace('-', '')) + ans['amount'] = [amt * mult, 'p' if pages else 'l'] + return ans + + +def scroll_window(boss, window, payload): + pg = cmd_scroll_window.payload_get + windows = [window or boss.active_window] + match = pg(payload, 'match') + amt = pg(payload, 'amount') + if match: + windows = tuple(boss.match_windows(match)) + if not windows: + raise MatchError(match) + for window in windows: + if window: + if amt[0] in ('start', 'end'): + getattr(window, {'start': 'scroll_home'}.get(amt[0], 'scroll_end'))() + else: + amt, unit = amt + unit = 'page' if unit == 'p' else 'line' + direction = 'up' if amt < 0 else 'down' + func = getattr(window, 'scroll_{}_{}'.format(unit, direction)) + for i in range(abs(amt)): + func() +# }}} + + # focus_tab {{{ @cmd( 'Focus the specified tab',