diff --git a/kitty/layout/base.py b/kitty/layout/base.py index f97d87a8f..e7ef83f6e 100644 --- a/kitty/layout/base.py +++ b/kitty/layout/base.py @@ -6,7 +6,7 @@ from functools import partial from itertools import repeat from typing import ( Dict, Generator, Iterable, Iterator, List, NamedTuple, Optional, Sequence, - Tuple, Union, cast + Tuple ) from kitty.constants import Edges, WindowGeometry @@ -261,24 +261,14 @@ class Layout: assert w is not None return self.neighbors_for_window(w, all_windows) - def move_window(self, all_windows: WindowList, delta: Union[str, int] = 1) -> bool: - # delta can be either a number or a string such as 'left', 'top', etc - # for neighborhood moves + def move_window(self, all_windows: WindowList, delta: int = 1) -> bool: if all_windows.num_groups < 2 or not delta: return False - if isinstance(delta, int): - return all_windows.move_window_group(by=delta) - which = delta.lower() - which = {'up': 'top', 'down': 'bottom'}.get(which, which) - w = all_windows.active_window - if w is None: - return False - neighbors = self.neighbors_for_window(w, all_windows) - q: List[int] = cast(List[int], neighbors.get(which, [])) - if not q: - return False - return all_windows.move_window_group(to_group=q[0]) + return all_windows.move_window_group(by=delta) + + def move_window_to_group(self, all_windows: WindowList, group: int) -> bool: + return all_windows.move_window_group(to_group=group) def add_window(self, all_windows: WindowList, window: WindowType, location: Optional[str] = None, overlay_for: Optional[int] = None) -> None: if overlay_for is not None and overlay_for in all_windows: diff --git a/kitty/layout/splits.py b/kitty/layout/splits.py index 4a99fa2d5..293853882 100644 --- a/kitty/layout/splits.py +++ b/kitty/layout/splits.py @@ -435,12 +435,12 @@ class Splits(Layout): pair.neighbors_for_window(wg.id, ans, self, all_windows) return ans - def move_window(self, all_windows: WindowList, delta: Union[str, int] = 1) -> bool: + def move_window_to_group(self, all_windows: WindowList, group: int) -> bool: before = all_windows.active_group if before is None: return False before_idx = all_windows.active_group_idx - moved = super().move_window(all_windows, delta) + moved = super().move_window_to_group(all_windows, group) after = all_windows.groups[before_idx] if moved and before.id != after.id: self.pairs_root.swap_windows(before.id, after.id) diff --git a/kitty/tabs.py b/kitty/tabs.py index b582c42b9..e792f4048 100644 --- a/kitty/tabs.py +++ b/kitty/tabs.py @@ -410,15 +410,36 @@ class Tab: # {{{ prev_window = previous_window - def neighboring_window(self, which: str) -> None: + def most_recent_group(self, groups: List[int]) -> int: + groups_set = set(groups) + + for window_id in reversed(self.windows.active_window_history): + group = self.windows.group_for_window(window_id) + if group and group.id in groups_set: + return group.id + + return groups[0] + + def neighboring_group_id(self, which: str) -> Optional[int]: neighbors = self.current_layout.neighbors(self.windows) - candidates = cast(Optional[Tuple[int, ...]], neighbors.get(which)) + candidates = cast(Optional[List[int]], neighbors.get(which)) if candidates: - self.windows.set_active_group(candidates[0]) + return self.most_recent_group(candidates) + + def neighboring_window(self, which: str) -> None: + neighbor = self.neighboring_group_id(which) + if neighbor: + self.windows.set_active_group(neighbor) def move_window(self, delta: Union[str, int] = 1) -> None: - if self.current_layout.move_window(self.windows, delta): - self.relayout() + if isinstance(delta, int): + if self.current_layout.move_window(self.windows, delta): + self.relayout() + elif isinstance(delta, str): + neighbor = self.neighboring_group_id(delta) + if neighbor: + if self.current_layout.move_window_to_group(self.windows, neighbor): + self.relayout() def move_window_to_top(self) -> None: n = self.windows.num_groups