From cb3671343e7b15f9099fc2200a0f0273e3b7fb8d Mon Sep 17 00:00:00 2001 From: Kovid Goyal Date: Sat, 8 Sep 2018 23:51:09 +0530 Subject: [PATCH] Implement directional movement of windows --- docs/changelog.rst | 5 +++-- docs/index.rst | 8 +++++--- kitty/config.py | 13 +++++++++++++ kitty/layout.py | 15 +++++++++++++-- 4 files changed, 34 insertions(+), 7 deletions(-) diff --git a/docs/changelog.rst b/docs/changelog.rst index 4984c912f..8f2cc972a 100644 --- a/docs/changelog.rst +++ b/docs/changelog.rst @@ -9,8 +9,9 @@ Changelog - Add a new ``last_used_layout`` function that can be mapped to a shortcut to switch to the previously used window layout (:iss:`870`) -- Add a new ``neighboring_window`` function to switch to neighboring - windows in the current layout, similar to window movement in vim (:iss:`916`) +- Add new ``neighboring_window`` and ``move_window`` functions to switch to + neighboring windows in the current layout, and move them around, similar to + window movement in vim (:iss:`916`) - Linux: Ensure that the python embedded in the kitty binary build always uses UTF-8 mode (:iss:`924`) diff --git a/docs/index.rst b/docs/index.rst index e9654cc65..5c0d77593 100644 --- a/docs/index.rst +++ b/docs/index.rst @@ -151,11 +151,13 @@ Focus specific window :sc:`first_window`, :sc:`second_window` ... :sc:`ten (clockwise from the top-left) ======================== ======================= -Additionally, you can define shortcuts in :file:`kitty.conf` to go to neighboring -windows (similar to window movement in vim):: +Additionally, you can define shortcuts in :file:`kitty.conf` to focus neighboring +windows and move windows around (similar to window movement in vim):: map ctrl+left neighboring_window left - map ctrl+down neighboring_window bottom + map shift+left move_window right + map ctrl+down neighboring_window down + map shift+down move_window up ... diff --git a/kitty/config.py b/kitty/config.py index 07ff29b9d..b1a0eb1cd 100644 --- a/kitty/config.py +++ b/kitty/config.py @@ -150,6 +150,19 @@ def neighboring_window(func, rest): return func, [rest] +@func_with_args('move_window') +def move_window(func, rest): + rest = rest.lower() + rest = {'up': 'top', 'down': 'bottom'}.get(rest, rest) + try: + rest = int(rest) + except Exception: + if rest not in ('left', 'right', 'top', 'bottom'): + log_error('Invalid move_window specification: {}'.format(rest)) + rest = 0 + return func, [rest] + + def parse_key_action(action): parts = action.split(' ', 1) func = parts[0] diff --git a/kitty/layout.py b/kitty/layout.py index e040a265a..aa522efb0 100644 --- a/kitty/layout.py +++ b/kitty/layout.py @@ -237,14 +237,25 @@ class Layout: # {{{ return ans def move_window(self, all_windows, active_window_idx, delta=1): + # delta can be either a number or a string such as 'left', 'top', etc + # for neighborhood moves w = all_windows[active_window_idx] windows = process_overlaid_windows(all_windows)[1] - if len(windows) < 2 or abs(delta) == 0: + if len(windows) < 2 or not delta: return active_window_idx idx = idx_for_id(w.id, windows) if idx is None: idx = idx_for_id(w.overlay_window_id, windows) - nidx = (idx + len(windows) + delta) % len(windows) + if isinstance(delta, int): + nidx = (idx + len(windows) + delta) % len(windows) + else: + delta = delta.lower() + delta = {'up': 'top', 'down': 'bottom'}.get(delta, delta) + neighbors = self.neighbors_for_window(w, windows) + if not neighbors.get(delta): + return active_window_idx + nidx = idx_for_id(neighbors[delta][0].id, windows) + nw = windows[nidx] nidx = idx_for_id(nw.id, all_windows) idx = active_window_idx