mirror of
https://github.com/kovidgoyal/kitty
synced 2026-07-24 01:08:10 +02:00
Handle aliased flags
This commit is contained in:
35
gen-rc-go.py
35
gen-rc-go.py
@@ -4,7 +4,7 @@
|
|||||||
import os
|
import os
|
||||||
import subprocess
|
import subprocess
|
||||||
import sys
|
import sys
|
||||||
from typing import List
|
from typing import Dict, List, Tuple
|
||||||
|
|
||||||
import kitty.constants as kc
|
import kitty.constants as kc
|
||||||
from kitty.cli import OptionDict, OptionSpecSeq, parse_option_spec
|
from kitty.cli import OptionDict, OptionSpecSeq, parse_option_spec
|
||||||
@@ -21,22 +21,29 @@ def replace(template: str, **kw: str) -> str:
|
|||||||
return template
|
return template
|
||||||
|
|
||||||
|
|
||||||
|
go_type_map = {'bool-set': 'bool', 'int': 'int', 'float': 'float64', '': 'string', 'list': '[]string', 'choices': 'string'}
|
||||||
|
|
||||||
|
|
||||||
class Option:
|
class Option:
|
||||||
|
|
||||||
def __init__(self, x: OptionDict) -> None:
|
def __init__(self, x: OptionDict) -> None:
|
||||||
flags = sorted(x['aliases'], key=len)
|
flags = sorted(x['aliases'], key=len)
|
||||||
short = ''
|
short = ''
|
||||||
|
self.aliases = []
|
||||||
if len(flags) > 1 and not flags[0].startswith("--"):
|
if len(flags) > 1 and not flags[0].startswith("--"):
|
||||||
short = flags[0][1:]
|
short = flags[0][1:]
|
||||||
long = flags[-1][2:]
|
del flags[0]
|
||||||
if not long:
|
self.short, self.long = short, x['name'].replace('_', '-')
|
||||||
raise TypeError(f'No long flag for {x} with flags {flags}')
|
for f in flags:
|
||||||
self.short, self.long = short, long
|
q = f[2:]
|
||||||
|
if q != self.long:
|
||||||
|
self.aliases.append(q)
|
||||||
self.usage = serialize_as_go_string(x['help'].strip())
|
self.usage = serialize_as_go_string(x['help'].strip())
|
||||||
self.type = x['type']
|
self.type = x['type']
|
||||||
self.dest = x['dest']
|
self.dest = x['dest']
|
||||||
self.default = x['default']
|
self.default = x['default']
|
||||||
self.obj_dict = x
|
self.obj_dict = x
|
||||||
|
self.go_type = go_type_map[self.type]
|
||||||
|
|
||||||
def to_flag_definition(self, base: str = 'ans.Flags()') -> str:
|
def to_flag_definition(self, base: str = 'ans.Flags()') -> str:
|
||||||
if self.type == 'bool-set':
|
if self.type == 'bool-set':
|
||||||
@@ -73,18 +80,33 @@ class Option:
|
|||||||
raise TypeError(f'Unknown type of CLI option: {self.type} for {self.long}')
|
raise TypeError(f'Unknown type of CLI option: {self.type} for {self.long}')
|
||||||
|
|
||||||
|
|
||||||
|
def render_alias_map(alias_map: Dict[str, Tuple[str, ...]]) -> str:
|
||||||
|
if not alias_map:
|
||||||
|
return ''
|
||||||
|
amap = 'switch name {\n'
|
||||||
|
for name, aliases in alias_map.items():
|
||||||
|
for alias in aliases:
|
||||||
|
amap += f'\ncase "{alias}":\nname = "{name}"\n'
|
||||||
|
amap += '}'
|
||||||
|
return amap
|
||||||
|
|
||||||
|
|
||||||
def build_go_code(name: str, cmd: RemoteCommand, seq: OptionSpecSeq, template: str) -> str:
|
def build_go_code(name: str, cmd: RemoteCommand, seq: OptionSpecSeq, template: str) -> str:
|
||||||
template = '\n' + template[len('//go:build exclude'):]
|
template = '\n' + template[len('//go:build exclude'):]
|
||||||
NO_RESPONSE_BASE = 'true' if cmd.no_response else 'false'
|
NO_RESPONSE_BASE = 'true' if cmd.no_response else 'false'
|
||||||
af: List[str] = []
|
af: List[str] = []
|
||||||
a = af.append
|
a = af.append
|
||||||
|
alias_map = {}
|
||||||
for x in seq:
|
for x in seq:
|
||||||
if isinstance(x, str):
|
if isinstance(x, str):
|
||||||
continue
|
continue
|
||||||
o = Option(x)
|
o = Option(x)
|
||||||
|
if o.aliases:
|
||||||
|
alias_map[o.long] = tuple(o.aliases)
|
||||||
a(o.to_flag_definition())
|
a(o.to_flag_definition())
|
||||||
if o.dest == 'no_response':
|
if o.dest == 'no_response':
|
||||||
continue
|
continue
|
||||||
|
|
||||||
ans = replace(
|
ans = replace(
|
||||||
template,
|
template,
|
||||||
CMD_NAME=name, __FILE__=__file__, CLI_NAME=name.replace('_', '-'),
|
CMD_NAME=name, __FILE__=__file__, CLI_NAME=name.replace('_', '-'),
|
||||||
@@ -92,6 +114,7 @@ def build_go_code(name: str, cmd: RemoteCommand, seq: OptionSpecSeq, template: s
|
|||||||
LONG_DESC=serialize_as_go_string(cmd.desc.strip()),
|
LONG_DESC=serialize_as_go_string(cmd.desc.strip()),
|
||||||
NO_RESPONSE_BASE=NO_RESPONSE_BASE, ADD_FLAGS_CODE='\n'.join(af),
|
NO_RESPONSE_BASE=NO_RESPONSE_BASE, ADD_FLAGS_CODE='\n'.join(af),
|
||||||
WAIT_TIMEOUT=str(cmd.response_timeout),
|
WAIT_TIMEOUT=str(cmd.response_timeout),
|
||||||
|
ALIAS_NORMALIZE_CODE=render_alias_map(alias_map)
|
||||||
)
|
)
|
||||||
return ans
|
return ans
|
||||||
|
|
||||||
@@ -122,7 +145,7 @@ var IsFrozenBuild bool = false
|
|||||||
template = f.read()
|
template = f.read()
|
||||||
for name in all_command_names():
|
for name in all_command_names():
|
||||||
cmd = command_for_name(name)
|
cmd = command_for_name(name)
|
||||||
opts = parse_option_spec(cmd.options_spec)[0]
|
opts = parse_option_spec(cmd.options_spec or '\n\n')[0]
|
||||||
code = build_go_code(name, cmd, opts, template)
|
code = build_go_code(name, cmd, opts, template)
|
||||||
dest = f'tools/cmd/at/{name}_generated.go'
|
dest = f'tools/cmd/at/{name}_generated.go'
|
||||||
if os.path.exists(dest):
|
if os.path.exists(dest):
|
||||||
|
|||||||
@@ -26,6 +26,7 @@ from .typing import BadLineType, TypedDict
|
|||||||
|
|
||||||
class OptionDict(TypedDict):
|
class OptionDict(TypedDict):
|
||||||
dest: str
|
dest: str
|
||||||
|
name: str
|
||||||
aliases: FrozenSet[str]
|
aliases: FrozenSet[str]
|
||||||
help: str
|
help: str
|
||||||
choices: FrozenSet[str]
|
choices: FrozenSet[str]
|
||||||
@@ -244,7 +245,7 @@ def parse_option_spec(spec: Optional[str] = None) -> Tuple[OptionSpecSeq, Option
|
|||||||
mpat = re.compile('([a-z]+)=(.+)')
|
mpat = re.compile('([a-z]+)=(.+)')
|
||||||
current_cmd: OptionDict = {
|
current_cmd: OptionDict = {
|
||||||
'dest': '', 'aliases': frozenset(), 'help': '', 'choices': frozenset(),
|
'dest': '', 'aliases': frozenset(), 'help': '', 'choices': frozenset(),
|
||||||
'type': '', 'condition': False, 'default': None, 'completion': {},
|
'type': '', 'condition': False, 'default': None, 'completion': {}, 'name': ''
|
||||||
}
|
}
|
||||||
empty_cmd = current_cmd
|
empty_cmd = current_cmd
|
||||||
|
|
||||||
@@ -261,9 +262,10 @@ def parse_option_spec(spec: Optional[str] = None) -> Tuple[OptionSpecSeq, Option
|
|||||||
continue
|
continue
|
||||||
if line.startswith('--'):
|
if line.startswith('--'):
|
||||||
parts = line.split(' ')
|
parts = line.split(' ')
|
||||||
|
defdest = parts[0][2:].replace('-', '_')
|
||||||
current_cmd = {
|
current_cmd = {
|
||||||
'dest': parts[0][2:].replace('-', '_'), 'aliases': frozenset(parts), 'help': '',
|
'dest': defdest, 'aliases': frozenset(parts), 'help': '',
|
||||||
'choices': frozenset(), 'type': '',
|
'choices': frozenset(), 'type': '', 'name': defdest,
|
||||||
'default': None, 'condition': True, 'completion': {}
|
'default': None, 'condition': True, 'completion': {}
|
||||||
}
|
}
|
||||||
state = METADATA
|
state = METADATA
|
||||||
|
|||||||
@@ -362,6 +362,10 @@ func show_usage(cmd *cobra.Command, use_pager bool) error {
|
|||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func FlagNormalizer(name string) string {
|
||||||
|
return strings.ReplaceAll(name, "_", "-")
|
||||||
|
}
|
||||||
|
|
||||||
func CreateCommand(cmd *cobra.Command) *cobra.Command {
|
func CreateCommand(cmd *cobra.Command) *cobra.Command {
|
||||||
cmd.Annotations = make(map[string]string)
|
cmd.Annotations = make(map[string]string)
|
||||||
if cmd.Run == nil && cmd.RunE == nil {
|
if cmd.Run == nil && cmd.RunE == nil {
|
||||||
@@ -379,6 +383,10 @@ func CreateCommand(cmd *cobra.Command) *cobra.Command {
|
|||||||
cmd.SilenceUsage = true
|
cmd.SilenceUsage = true
|
||||||
cmd.PersistentFlags().SortFlags = false
|
cmd.PersistentFlags().SortFlags = false
|
||||||
cmd.Flags().SortFlags = false
|
cmd.Flags().SortFlags = false
|
||||||
|
cmd.Flags().SetNormalizeFunc(func(fs *pflag.FlagSet, name string) pflag.NormalizedName {
|
||||||
|
return pflag.NormalizedName(FlagNormalizer(name))
|
||||||
|
})
|
||||||
|
cmd.PersistentFlags().SetNormalizeFunc(cmd.Flags().GetNormalizeFunc())
|
||||||
return cmd
|
return cmd
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -402,9 +410,6 @@ func Init(root *cobra.Command) {
|
|||||||
root.SetHelpFunc(show_help)
|
root.SetHelpFunc(show_help)
|
||||||
root.SetHelpCommand(&cobra.Command{Hidden: true})
|
root.SetHelpCommand(&cobra.Command{Hidden: true})
|
||||||
root.CompletionOptions.DisableDefaultCmd = true
|
root.CompletionOptions.DisableDefaultCmd = true
|
||||||
root.SetGlobalNormalizationFunc(func(fs *pflag.FlagSet, name string) pflag.NormalizedName {
|
|
||||||
return pflag.NormalizedName(strings.ReplaceAll(name, "_", "-"))
|
|
||||||
})
|
|
||||||
}
|
}
|
||||||
|
|
||||||
func Execute(root *cobra.Command) error {
|
func Execute(root *cobra.Command) error {
|
||||||
|
|||||||
@@ -6,6 +6,7 @@ package at
|
|||||||
|
|
||||||
import (
|
import (
|
||||||
"github.com/spf13/cobra"
|
"github.com/spf13/cobra"
|
||||||
|
"github.com/spf13/pflag"
|
||||||
|
|
||||||
"kitty/tools/cli"
|
"kitty/tools/cli"
|
||||||
"kitty/tools/utils"
|
"kitty/tools/utils"
|
||||||
@@ -25,6 +26,12 @@ func run_CMD_NAME(cmd *cobra.Command, args []string) (err error) {
|
|||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func aliasNormalizeFunc_CMD_NAME(f *pflag.FlagSet, name string) pflag.NormalizedName {
|
||||||
|
name = cli.FlagNormalizer(name)
|
||||||
|
ALIAS_NORMALIZE_CODE
|
||||||
|
return pflag.NormalizedName(name)
|
||||||
|
}
|
||||||
|
|
||||||
func setup_CMD_NAME(root *cobra.Command) *cobra.Command {
|
func setup_CMD_NAME(root *cobra.Command) *cobra.Command {
|
||||||
ans := cli.CreateCommand(&cobra.Command{
|
ans := cli.CreateCommand(&cobra.Command{
|
||||||
Use: "CLI_NAME [options]",
|
Use: "CLI_NAME [options]",
|
||||||
@@ -33,6 +40,7 @@ func setup_CMD_NAME(root *cobra.Command) *cobra.Command {
|
|||||||
RunE: run_CMD_NAME,
|
RunE: run_CMD_NAME,
|
||||||
})
|
})
|
||||||
ADD_FLAGS_CODE
|
ADD_FLAGS_CODE
|
||||||
|
ans.Flags().SetNormalizeFunc(aliasNormalizeFunc_CMD_NAME)
|
||||||
|
|
||||||
return ans
|
return ans
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user