diff --git a/kitty/boss.py b/kitty/boss.py index 846d44ae1..93a15e3cd 100644 --- a/kitty/boss.py +++ b/kitty/boss.py @@ -118,10 +118,13 @@ class Boss: return os_window_id def list_os_windows(self): + active_tab, active_window = self.active_tab, self.active_window + active_tab_manager = self.active_tab_manager for os_window_id, tm in self.os_window_map.items(): yield { 'id': os_window_id, - 'tabs': list(tm.list_tabs()), + 'is_focused': tm is active_tab_manager, + 'tabs': list(tm.list_tabs(active_tab, active_window)), } @property diff --git a/kitty/complete.py b/kitty/complete.py index 88ca27e31..a33051036 100644 --- a/kitty/complete.py +++ b/kitty/complete.py @@ -2,6 +2,7 @@ # vim:fileencoding=utf-8 # License: GPLv3 Copyright: 2018, Kovid Goyal +import os import shlex import sys @@ -64,6 +65,25 @@ def kitty_cli_opts(ans, prefix=None): ans.match_groups['Options'] = matches +def executables(ans, prefix=None): + matches = {} + prefix = prefix or '' + for src in os.environ.get('PATH', '').split(os.pathsep): + if src: + try: + it = os.scandir(src) + except EnvironmentError: + continue + for entry in it: + try: + if entry.name.startswith(prefix) and entry.is_file() and os.access(entry.path, os.X_OK): + matches[entry.name] = None + except EnvironmentError: + pass + if matches: + ans.match_groups['Executables'] = matches + + def find_completions(words, new_word, entry_points, namespaced_entry_points): ans = Completions() if not words or words[0] != 'kitty': @@ -73,6 +93,7 @@ def find_completions(words, new_word, entry_points, namespaced_entry_points): prefix = words[0] if words else '' completions_for_first_word(ans, prefix, entry_points, namespaced_entry_points) kitty_cli_opts(ans, prefix) + executables(ans, prefix) return ans return ans diff --git a/kitty/tabs.py b/kitty/tabs.py index c35be8623..7bcbfac11 100644 --- a/kitty/tabs.py +++ b/kitty/tabs.py @@ -272,9 +272,9 @@ class Tab: # {{{ def move_window_backward(self): self.move_window(-1) - def list_windows(self): + def list_windows(self, active_window): for w in self: - yield w.as_dict() + yield w.as_dict(is_focused=w is active_window) def matches(self, field, pat): if field == 'id': @@ -410,12 +410,13 @@ class TabManager: # {{{ def __len__(self): return len(self.tabs) - def list_tabs(self): + def list_tabs(self, active_tab, active_window): for tab in self: yield { 'id': tab.id, + 'is_focused': tab is active_tab, 'title': tab.name or tab.title, - 'windows': list(tab.list_windows()), + 'windows': list(tab.list_windows(active_window)), } @property diff --git a/kitty/window.py b/kitty/window.py index 80c8a95fb..bc3751d68 100644 --- a/kitty/window.py +++ b/kitty/window.py @@ -136,9 +136,10 @@ class Window: return 'Window(title={}, id={}, overlay_for={}, overlay_window_id={})'.format( self.title, self.id, self.overlay_for, self.overlay_window_id) - def as_dict(self): + def as_dict(self, is_focused=False): return dict( id=self.id, + is_focused=is_focused, title=self.override_title or self.title, pid=self.child.pid, cwd=self.child.current_cwd or self.child.cwd,