From d276317e3a78f2536ecaa34ecff4847b144423db Mon Sep 17 00:00:00 2001 From: Kovid Goyal Date: Thu, 30 Aug 2018 10:23:20 +0530 Subject: [PATCH] Remote control: Allow changing the current window layout with a new goto-layout command Fixes #845 --- docs/changelog.rst | 3 +++ kitty/cmds.py | 40 ++++++++++++++++++++++++++++++++++++++++ kitty/tabs.py | 4 +++- 3 files changed, 46 insertions(+), 1 deletion(-) diff --git a/docs/changelog.rst b/docs/changelog.rst index 1dd6bdd47..01126bd2a 100644 --- a/docs/changelog.rst +++ b/docs/changelog.rst @@ -29,6 +29,9 @@ Changelog - macOS: Allow scrolling window contents using mouse wheel/trackpad even when the window is not the active window (:iss:`729`) +- Remote control: Allow changing the current window layout with a new + :ref:`at_goto-layout` command (:iss:`845`) + - Remote control: Allow matching windows by the environment variables of their child process as well diff --git a/kitty/cmds.py b/kitty/cmds.py index 2e63cd4d5..ae35aabd7 100644 --- a/kitty/cmds.py +++ b/kitty/cmds.py @@ -27,6 +27,11 @@ class OpacityError(ValueError): hide_traceback = True +class UnknownLayout(ValueError): + + hide_traceback = True + + def cmd(short_desc, desc=None, options_spec=None, no_response=False, argspec='...', string_return_is_error=False, args_count=None): def w(func): @@ -273,6 +278,41 @@ def set_tab_title(boss, window, payload): # }}} +# set_layout {{{ +@cmd( + 'Set the window layout', + 'Set the window layout in the specified tab (or the active tab if not specified).' + ' You can use special match value :italic:`all` to set the layout in all tabs.', + options_spec=MATCH_TAB_OPTION, + argspec='LAYOUT_NAME' +) +def cmd_goto_layout(global_opts, opts, args): + try: + return {'layout': args[0], 'match': opts.match} + except IndexError: + raise SystemExit('No layout specified') + + +def goto_layout(boss, window, payload): + match = payload['match'] + if match: + if match == 'all': + tabs = tuple(boss.all_tabs) + else: + tabs = tuple(boss.match_tabs(match)) + if not tabs: + raise MatchError(match, 'tabs') + else: + tabs = [boss.tab_for_window(window) if window else boss.active_tab] + for tab in tabs: + if tab: + try: + tab.goto_layout(payload['layout'], raise_exception=True) + except ValueError: + raise UnknownLayout('The layout {} is unknown or disabled'.format(payload['layout'])) +# }}} + + # close_window {{{ @cmd( 'Close the specified window(s)', diff --git a/kitty/tabs.py b/kitty/tabs.py index 7bcbfac11..5fc147b86 100644 --- a/kitty/tabs.py +++ b/kitty/tabs.py @@ -157,9 +157,11 @@ class Tab: # {{{ self.current_layout = self.create_layout_object(nl) self.relayout() - def goto_layout(self, layout_name): + def goto_layout(self, layout_name, raise_exception=False): layout_name = layout_name.lower() if layout_name not in self.enabled_layouts: + if raise_exception: + raise ValueError(layout_name) log_error('Unknown or disabled layout: {}'.format(layout_name)) return self.current_layout = self.create_layout_object(layout_name)