Add a new `neighboring_window` function to switch to neighboring windows in the current layout, similar to window movement in vim

Fixes #916
This commit is contained in:
Kovid Goyal 2018-09-08 08:59:11 +05:30
parent 9329b2c202
commit e39635ea16
No known key found for this signature in database
GPG Key ID: 06BC317B515ACE7C
5 changed files with 34 additions and 3 deletions

View File

@ -9,6 +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`)
0.12.1 [2018-09-08]
------------------------------

View File

@ -151,6 +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)::
map ctrl+left neighboring_window left
map ctrl+down neighboring_window bottom
...
Other keyboard shortcuts
----------------------------------

View File

@ -140,6 +140,16 @@ def clear_terminal(func, rest):
return func, args
@func_with_args('neighboring_window')
def neighboring_window(func, rest):
rest = rest.lower()
rest = {'up': 'top', 'down': 'bottom'}.get(rest, rest)
if rest not in ('left', 'right', 'top', 'bottom'):
log_error('Invalid neighbor specification: {}'.format(rest))
rest = 'right'
return func, [rest]
def parse_key_action(action):
parts = action.split(' ', 1)
func = parts[0]

View File

@ -231,7 +231,10 @@ class Layout: # {{{
def neighbors(self, all_windows, active_window_idx):
w = all_windows[active_window_idx]
windows = process_overlaid_windows(all_windows)[1]
self.neighbors_for_window(w, windows)
ans = self.neighbors_for_window(w, windows)
for values in ans.values():
values[:] = [idx_for_id(w.id, windows) for w in values]
return ans
def move_window(self, all_windows, active_window_idx, delta=1):
w = all_windows[active_window_idx]
@ -481,7 +484,7 @@ class Tall(Layout): # {{{
if window is windows[0]:
return {'left': [], 'right': windows[1:], 'top': [], 'bottom': []}
idx = windows.index(window)
return {'left': windows[0], 'right': [], 'top': [] if idx <= 1 else [windows[idx-1]],
return {'left': [windows[0]], 'right': [], 'top': [] if idx <= 1 else [windows[idx-1]],
'bottom': [] if window is windows[-1] else [windows[idx+1]]}
def minimal_borders(self, windows, active_window, needs_borders_map):
@ -540,7 +543,7 @@ class Fat(Tall): # {{{
if window is windows[0]:
return {'left': [], 'bottom': windows[1:], 'top': [], 'right': []}
idx = windows.index(window)
return {'top': windows[0], 'bottom': [], 'left': [] if idx <= 1 else [windows[idx-1]],
return {'top': [windows[0]], 'bottom': [], 'left': [] if idx <= 1 else [windows[idx-1]],
'right': [] if window is windows[-1] else [windows[idx+1]]}
# }}}

View File

@ -271,6 +271,14 @@ class Tab: # {{{
def previous_window(self):
self._next_window(-1)
def neighboring_window(self, which):
neighbors = self.current_layout.neighbors(self.windows, self.active_window_idx)
candidates = neighbors.get(which)
if candidates:
self.active_window_idx = self.current_layout.set_active_window(self.windows, candidates[0])
self.relayout_borders()
glfw_post_empty_event()
def move_window(self, delta=1):
self.active_window_idx = self.current_layout.move_window(self.windows, self.active_window_idx, delta)
self.relayout()