diff --git a/gen-go-code.py b/gen-go-code.py index 105f94d61..3a2ea9332 100755 --- a/gen-go-code.py +++ b/gen-go-code.py @@ -4,13 +4,15 @@ import io import json import os +import sys from contextlib import contextmanager, suppress from typing import Dict, Iterator, List, Tuple, Union import kitty.constants as kc from kittens.tui.operations import Mode from kitty.cli import ( - GoOption, OptionSpecSeq, parse_option_spec, serialize_as_go_string + GoOption, OptionSpecSeq, go_options_for_seq, parse_option_spec, + serialize_as_go_string ) from kitty.key_encoding import config_mod_map from kitty.key_names import ( @@ -98,24 +100,34 @@ def build_go_code(name: str, cmd: RemoteCommand, seq: OptionSpecSeq, template: s alias_map = {} od: List[str] = [] ov: List[str] = [] - for x in seq: - if isinstance(x, str): - continue - o = GoOption(name, x) + option_map: Dict[str, GoOption] = {} + for o in go_options_for_seq(seq): + field_dest = o.go_var_name.rstrip('_') + option_map[field_dest] = o if o.aliases: alias_map[o.long] = tuple(o.aliases) a(o.to_flag_definition()) if o.dest in ('no_response', 'response_timeout'): continue od.append(f'{o.go_var_name} {o.go_type}') - ov.append(o.set_flag_value()) + ov.append(o.set_flag_value(f'options_{name}')) jd: List[str] = [] + json_fields = [] for line in cmd.protocol_spec.splitlines(): line = line.strip() if ':' not in line: continue f = JSONField(line) + json_fields.append(f) jd.append(f.go_declaration()) + jc: List[str] = [] + for field in json_fields: + if field.field in option_map: + o = option_map[field.field] + jc.append(f'payload.{field.struct_field_name} = options_{name}.{o.go_var_name}') + else: + print(f'Cant map field: {field.field} for cmd: {name}', file=sys.stderr) + continue ans = replace( template, @@ -129,6 +141,7 @@ def build_go_code(name: str, cmd: RemoteCommand, seq: OptionSpecSeq, template: s OPTIONS_DECLARATION_CODE='\n'.join(od), SET_OPTION_VALUES_CODE='\n'.join(ov), JSON_DECLARATION_CODE='\n'.join(jd), + JSON_INIT_CODE='\n'.join(jc), STRING_RESPONSE_IS_ERROR='true' if cmd.string_return_is_error else 'false', ) return ans diff --git a/kitty/cli.py b/kitty/cli.py index 7bdf35982..3eebc859e 100644 --- a/kitty/cli.py +++ b/kitty/cli.py @@ -49,8 +49,7 @@ go_getter_map = { class GoOption: - def __init__(self, cmd_name: str, x: OptionDict) -> None: - self.cmd_name = cmd_name + def __init__(self, x: OptionDict) -> None: flags = sorted(x['aliases'], key=len) short = '' self.aliases = [] @@ -107,13 +106,19 @@ class GoOption: else: raise TypeError(f'Unknown type of CLI option: {self.type} for {self.long}') - def set_flag_value(self, cmd: str = 'cmd') -> str: + def set_flag_value(self, struct_name: str, cmd: str = 'cmd') -> str: func = go_getter_map[self.type] ans = f'{self.go_var_name}_temp, err := {cmd}.Flags().{func}("{self.long}")\n if err != nil {{ return err }}' - ans += f'\noptions_{self.cmd_name}.{self.go_var_name} = {self.go_var_name}_temp' + ans += f'\n{struct_name}.{self.go_var_name} = {self.go_var_name}_temp' return ans +def go_options_for_seq(seq: 'OptionSpecSeq') -> Iterator[GoOption]: + for x in seq: + if not isinstance(x, str): + yield GoOption(x) + + CONFIG_HELP = '''\ Specify a path to the configuration file(s) to use. All configuration files are merged onto the builtin :file:`{conf_name}.conf`, overriding the builtin values. diff --git a/kitty/rc/close_tab.py b/kitty/rc/close_tab.py index f21a4e5ba..f606d1e13 100644 --- a/kitty/rc/close_tab.py +++ b/kitty/rc/close_tab.py @@ -17,7 +17,6 @@ class CloseTab(RemoteCommand): protocol_spec = __doc__ = ''' match/str: Which tab to close - no_response/bool: Boolean indicating whether to wait for a response 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 ''' diff --git a/kitty/rc/close_window.py b/kitty/rc/close_window.py index e87cf4cb6..ab5ab764a 100644 --- a/kitty/rc/close_window.py +++ b/kitty/rc/close_window.py @@ -16,7 +16,6 @@ if TYPE_CHECKING: class CloseWindow(RemoteCommand): protocol_spec = __doc__ = ''' match/str: Which window to close - no_response/bool: Boolean indicating whether to wait for a response 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 ''' diff --git a/kitty/rc/get_text.py b/kitty/rc/get_text.py index af18ccd53..887bd8096 100644 --- a/kitty/rc/get_text.py +++ b/kitty/rc/get_text.py @@ -60,6 +60,7 @@ screen edges). --clear-selection +type=bool-set Clear the selection in the matched window, if any. diff --git a/kitty/rc/launch.py b/kitty/rc/launch.py index c56bb439e..15558c7b4 100644 --- a/kitty/rc/launch.py +++ b/kitty/rc/launch.py @@ -42,7 +42,6 @@ class Launch(RemoteCommand): stdin_add_formatting/bool: Boolean indicating whether to add formatting codes to stdin stdin_add_line_wrap_markers/bool: Boolean indicating whether to add line wrap markers to stdin spacing/list.str: A list of spacing specifications, see the docs for the set-spacing command - no_response/bool: Boolean indicating whether to send back the window id marker/str: Specification for marker for new window, for example: "text 1 ERROR" logo/str: Path to window logo logo_position/str: Window logo position as string or empty string to use default diff --git a/kitty/rc/new_window.py b/kitty/rc/new_window.py index 89146c03f..943056c8f 100644 --- a/kitty/rc/new_window.py +++ b/kitty/rc/new_window.py @@ -23,7 +23,6 @@ class NewWindow(RemoteCommand): window_type/choices.kitty.os: One of :code:`kitty` or :code:`os` new_tab/bool: Boolean indicating whether to open a new tab tab_title/str: Title for the new tab - no_response/bool: Boolean indicating whether to send back the window id ''' short_desc = 'Open new window' diff --git a/kitty/rc/scroll_window.py b/kitty/rc/scroll_window.py index b8d0f26bd..1917807f0 100644 --- a/kitty/rc/scroll_window.py +++ b/kitty/rc/scroll_window.py @@ -21,7 +21,6 @@ class ScrollWindow(RemoteCommand): And the second item being either 'p' for pages or 'l' for lines or 'u' for unscrolling by lines. match/str: The window to scroll - no_response/bool: Boolean indicating whether to wait for a response ''' short_desc = 'Scroll the specified windows' diff --git a/kitty/rc/signal_child.py b/kitty/rc/signal_child.py index a99daa532..02a4ae950 100644 --- a/kitty/rc/signal_child.py +++ b/kitty/rc/signal_child.py @@ -17,7 +17,6 @@ class SignalChild(RemoteCommand): protocol_spec = __doc__ = ''' signals/list.str: The signals, a list of names, such as :code:`SIGTERM`, :code:`SIGKILL`, :code:`SIGUSR1`, etc. match/str: Which windows to send the signals to - no_response/bool: Boolean indicating whether to wait for a response ''' short_desc = 'Send a signal to the foreground process in the specified windows' diff --git a/tools/cmd/at/template.go b/tools/cmd/at/template.go index 280787413..3b4381a39 100644 --- a/tools/cmd/at/template.go +++ b/tools/cmd/at/template.go @@ -26,9 +26,10 @@ type CMD_NAME_json_type struct { JSON_DECLARATION_CODE } -var CMD_NAME_json CMD_NAME_json_type - -func create_payload_CMD_NAME(io_data *rc_io_data, args []string) (err error) { +func create_payload_CMD_NAME(io_data *rc_io_data, flags *pflag.FlagSet, args []string) (err error) { + payload := CMD_NAME_json_type{} + JSON_INIT_CODE + io_data.rc.Payload = payload return } @@ -70,7 +71,7 @@ func run_CMD_NAME(cmd *cobra.Command, args []string) (err error) { timeout: time.Duration(timeout * float64(time.Second)), string_response_is_err: STRING_RESPONSE_IS_ERROR, } - err = create_payload_CMD_NAME(&io_data, args) + err = create_payload_CMD_NAME(&io_data, cmd.Flags(), args) if err != nil { return err } diff --git a/tools/utils/types.go b/tools/utils/types.go index fea896d4f..2240c8923 100644 --- a/tools/utils/types.go +++ b/tools/utils/types.go @@ -3,14 +3,14 @@ package utils type RemoteControlCmd struct { - Cmd string `json:"cmd"` - Version [3]int `json:"version"` - NoResponse bool `json:"no_response,omitempty"` - Payload *interface{} `json:"payload,omitempty"` - Timestamp int64 `json:"timestamp,omitempty"` - Password string `json:"password,omitempty"` - Async string `json:"async,omitempty"` - CancelAsync bool `json:"cancel_async,omitempty"` + Cmd string `json:"cmd"` + Version [3]int `json:"version"` + NoResponse bool `json:"no_response,omitempty"` + Payload interface{} `json:"payload,omitempty"` + Timestamp int64 `json:"timestamp,omitempty"` + Password string `json:"password,omitempty"` + Async string `json:"async,omitempty"` + CancelAsync bool `json:"cancel_async,omitempty"` } type EncryptedRemoteControlCmd struct {