diff --git a/docs/changelog.rst b/docs/changelog.rst index ff8af6854..47250e892 100644 --- a/docs/changelog.rst +++ b/docs/changelog.rst @@ -46,6 +46,9 @@ To update |kitty|, :doc:`follow the instructions `. - Double clicking on empty tab bar area now opens a new tab (:iss:`3201`) +- kitty @ ls: Show only environment variables that are different for each + window, by default. + - When passing a directory or a non-executable file as the program to run to kitty opens it with the shell or by parsing the shebang, instead of just failing. diff --git a/kitty/rc/ls.py b/kitty/rc/ls.py index 85d51e387..d2b6f3ed2 100644 --- a/kitty/rc/ls.py +++ b/kitty/rc/ls.py @@ -3,7 +3,7 @@ # License: GPLv3 Copyright: 2020, Kovid Goyal import json -from typing import Any, Dict, Optional +from typing import Any, Dict, List, Optional, Set, Tuple from kitty.constants import appname @@ -15,7 +15,7 @@ from .base import ( class LS(RemoteCommand): ''' - No payload + all_env_vars: Whether to send all environment variables for ever window rather than just differing ones ''' short_desc = 'List all tabs/windows' @@ -28,10 +28,16 @@ class LS(RemoteCommand): ' running the command inside a kitty window, that window can be identified by the :italic:`is_self` parameter.\n\n' 'You can use these criteria to select windows/tabs for the other commands.' ) + options_spec = '''\ +--all-env-vars +type=bool-set +Show all environment variables in output not just differing ones. +''' + argspec = '' def message_to_kitty(self, global_opts: RCOptions, opts: Any, args: ArgsType) -> PayloadType: - pass + return {'all_env_vars': opts.all_env_vars} def response_from_kitty(self, boss: Boss, window: Optional[Window], payload_get: PayloadGetType) -> ResponseType: @@ -47,6 +53,24 @@ class LS(RemoteCommand): finally: if window is not None: window.serialize_callback = orig_callback + if not payload_get('all_env_vars'): + all_env_blocks: List[Dict[str, str]] = [] + common_env_vars: Set[Tuple[str, str]] = set() + for osw in data: + for tab in osw.get('tabs', ()): + for w in tab.get('windows', ()): + env: Dict[str, str] = w.get('env', {}) + frozen_env = set(env.items()) + if all_env_blocks: + common_env_vars &= frozen_env + else: + common_env_vars = frozen_env + all_env_blocks.append(env) + if common_env_vars and len(all_env_blocks) > 1: + remove_env_vars = {k for k, v in common_env_vars} + for env in all_env_blocks: + for r in remove_env_vars: + env.pop(r, None) return json.dumps(data, indent=2, sort_keys=True)