From ce2b3265beaa712dce831eff903f4ad2f8be5edb Mon Sep 17 00:00:00 2001 From: Kovid Goyal Date: Tue, 24 Jul 2018 12:40:59 +0530 Subject: [PATCH] Remote control: Allow matching windows by the environment variables of their child process as well --- docs/changelog.rst | 3 +++ kitty/boss.py | 13 ++++++++++--- kitty/cmds.py | 12 +++++++----- kitty/window.py | 10 +++++++++- 4 files changed, 29 insertions(+), 9 deletions(-) diff --git a/docs/changelog.rst b/docs/changelog.rst index fa55e64cc..b1b6e8827 100644 --- a/docs/changelog.rst +++ b/docs/changelog.rst @@ -19,6 +19,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 matching windows by the environment variables of their + child process as well + 0.11.3 [2018-07-10] ------------------------------ diff --git a/kitty/boss.py b/kitty/boss.py index da5f0d124..592e8e846 100644 --- a/kitty/boss.py +++ b/kitty/boss.py @@ -152,11 +152,18 @@ class Boss: return if w is not None: yield w + return + if field == 'env': + kp, vp = exp.partition('=')[::2] + if vp: + pat = tuple(map(re.compile, (kp, vp))) + else: + pat = re.compile(kp), None else: pat = re.compile(exp) - for window in self.all_windows: - if window.matches(field, pat): - yield window + for window in self.all_windows: + if window.matches(field, pat): + yield window def tab_for_window(self, window): for tab in self.all_tabs: diff --git a/kitty/cmds.py b/kitty/cmds.py index 08f504e6b..c77e52430 100644 --- a/kitty/cmds.py +++ b/kitty/cmds.py @@ -46,18 +46,20 @@ def cmd(short_desc, desc=None, options_spec=None, no_response=False, argspec='.. MATCH_WINDOW_OPTION = '''\ --match -m The window to match. Match specifications are of the form: -:italic:`field:regexp`. Where field can be one of: id, title, pid, cwd, cmdline, num. +:italic:`field:regexp`. Where field can be one of: id, title, pid, cwd, cmdline, num, env. You can use the :italic:`ls` command to get a list of windows. Note that for numeric fields such as id, pid and num the expression is interpreted as a number, not a regular expression. The field num refers to the window position in the current tab, starting from zero and counting clockwise (this is the same as the order in which the windows are reported by the :italic:`ls` command). The window id of the current window -is available as the KITTY_WINDOW_ID environment variable. +is available as the KITTY_WINDOW_ID environment variable. When using the :italic:`env` field +to match on environment variables you can specify only the environment variable name or a name +and value, for example, :italic:`env:MY_ENV_VAR=2` ''' MATCH_TAB_OPTION = '''\ --match -m The tab to match. Match specifications are of the form: -:italic:`field:regexp`. Where field can be one of: id, title, pid, cwd, cmdline. +:italic:`field:regexp`. Where field can be one of: id, title, pid, cwd, env, cmdline. You can use the :italic:`ls` command to get a list of tabs. Note that for numeric fields such as id and pid the expression is interpreted as a number, not a regular expression. When using title or id, first a matching tab is @@ -72,8 +74,8 @@ for that window is used. 'List all windows. The list is returned as JSON tree. The top-level is a list of' ' operating system {appname} windows. Each OS window has an :italic:`id` and a list' ' of :italic:`tabs`. Each tab has its own :italic:`id`, a :italic:`title` and a list of :italic:`windows`.' - ' Each window has an :italic:`id`, :italic:`title`, :italic:`current working directory`, :italic:`process id (PID)` and' - ' :italic:`command-line` of the process running in the window.\n\n' + ' Each window has an :italic:`id`, :italic:`title`, :italic:`current working directory`, :italic:`process id (PID)`, ' + ' :italic:`command-line` and :italic:`environment` of the process running in the window.\n\n' 'You can use these criteria to select windows/tabs for the other commands.'.format(appname=appname), argspec='' ) diff --git a/kitty/window.py b/kitty/window.py index 920175f4a..3a5c92556 100644 --- a/kitty/window.py +++ b/kitty/window.py @@ -140,7 +140,9 @@ class Window: id=self.id, title=self.override_title or self.title, pid=self.child.pid, - cwd=self.child.current_cwd or self.child.cwd, cmdline=self.child.cmdline + cwd=self.child.current_cwd or self.child.cwd, + cmdline=self.child.cmdline, + env=self.child.environ, ) @property @@ -161,6 +163,12 @@ class Window: if pat.search(x) is not None: return True return False + if field == 'env': + key_pat, val_pat = pat + for key, val in self.child.environ.items(): + if key_pat.search(key) is not None and ( + val_pat is None or val_pat.search(val) is not None): + return True return False def set_visible_in_layout(self, window_idx, val):