diff --git a/docs/changelog.rst b/docs/changelog.rst index 0c753f436..9f537ebdb 100644 --- a/docs/changelog.rst +++ b/docs/changelog.rst @@ -106,6 +106,8 @@ Detailed list of changes - macOS: Fix speaking selected text not working (:iss:`5357`) +- Allow ignoring failure to close windows/tabs via rc commands (:disc:`5406`) + 0.25.2 [2022-06-07] ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ diff --git a/kitty/rc/close_tab.py b/kitty/rc/close_tab.py index 52cd9612c..8389cc853 100644 --- a/kitty/rc/close_tab.py +++ b/kitty/rc/close_tab.py @@ -5,8 +5,8 @@ from typing import TYPE_CHECKING, Optional from .base import ( - MATCH_TAB_OPTION, ArgsType, Boss, PayloadGetType, PayloadType, RCOptions, - RemoteCommand, ResponseType, Window + MATCH_TAB_OPTION, ArgsType, Boss, MatchError, PayloadGetType, PayloadType, + RCOptions, RemoteCommand, ResponseType, Window ) if TYPE_CHECKING: @@ -18,6 +18,7 @@ class CloseTab(RemoteCommand): ''' match/str: Which tab to close self/bool: Boolean indicating whether to close the tab of the window the command is run in + ignore_no_match/bool: Boolean indicating whether no matches should be ignored or return an error ''' short_desc = 'Close the specified tabs' @@ -32,14 +33,25 @@ tabs in the currently focused OS window, use:: --self type=bool-set Close the tab of the window this command is run in, rather than the active tab. + + +--ignore-no-match +type=bool-set +Do not return an error if no tabs are matched to be closed. ''' argspec = '' def message_to_kitty(self, global_opts: RCOptions, opts: 'CLIOptions', args: ArgsType) -> PayloadType: - return {'match': opts.match, 'self': opts.self} + return {'match': opts.match, 'self': opts.self, 'ignore_no_match': opts.ignore_no_match} def response_from_kitty(self, boss: Boss, window: Optional[Window], payload_get: PayloadGetType) -> ResponseType: - for tab in self.tabs_for_match_payload(boss, window, payload_get): + try: + tabs = self.tabs_for_match_payload(boss, window, payload_get) + except MatchError: + if payload_get('ignore_no_match'): + return None + raise + for tab in tabs: if tab: boss.close_tab_no_confirm(tab) return None diff --git a/kitty/rc/close_window.py b/kitty/rc/close_window.py index e57564d07..c358b936b 100644 --- a/kitty/rc/close_window.py +++ b/kitty/rc/close_window.py @@ -6,7 +6,7 @@ from typing import TYPE_CHECKING, Optional from .base import ( MATCH_WINDOW_OPTION, ArgsType, Boss, PayloadGetType, PayloadType, - RCOptions, RemoteCommand, ResponseType, Window + RCOptions, RemoteCommand, ResponseType, Window, MatchError ) if TYPE_CHECKING: @@ -17,6 +17,7 @@ class CloseWindow(RemoteCommand): ''' match/str: Which window to close self/bool: Boolean indicating whether to close the window the command is run in + ignore_no_match/bool: Boolean indicating whether no matches should be ignored or return an error ''' short_desc = 'Close the specified windows' @@ -24,14 +25,25 @@ class CloseWindow(RemoteCommand): --self type=bool-set Close the window this command is run in, rather than the active window. + + +--ignore-no-match +type=bool-set +Do not return an error if no windows are matched to be closed. ''' argspec = '' def message_to_kitty(self, global_opts: RCOptions, opts: 'CLIOptions', args: ArgsType) -> PayloadType: - return {'match': opts.match, 'self': opts.self} + return {'match': opts.match, 'self': opts.self, 'ignore_no_match': opts.ignore_no_match} def response_from_kitty(self, boss: Boss, window: Optional[Window], payload_get: PayloadGetType) -> ResponseType: - for window in self.windows_for_match_payload(boss, window, payload_get): + try: + windows = self.windows_for_match_payload(boss, window, payload_get) + except MatchError: + if payload_get('ignore_no_match'): + return None + raise + for window in windows: if window: boss.mark_window_for_close(window) return None