mirror of
https://github.com/onyx-and-iris/vban-cli.git
synced 2026-04-16 02:23:30 +00:00
Compare commits
14 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
| c535ae5571 | |||
| 7b5d2150c7 | |||
| 28ec67839a | |||
| dd0d150202 | |||
| 78952aa3ff | |||
| c4d67527f5 | |||
| b3cfc6bc4a | |||
| c642bbc1f2 | |||
| 61a37bcd0f | |||
| b62ee185c3 | |||
| c7365bfe4e | |||
| c660778698 | |||
| 5460965945 | |||
| d03049e713 |
90
README.md
90
README.md
@@ -5,6 +5,8 @@
|
|||||||
|
|
||||||
---
|
---
|
||||||
|
|
||||||
|
This CLI is still in an early stage of development with many more things that could be implemented. However, the commands that are implemented should be working without issues.
|
||||||
|
|
||||||
## Install
|
## Install
|
||||||
|
|
||||||
#### With uv
|
#### With uv
|
||||||
@@ -47,40 +49,96 @@ export VBAN_CLI_STREAMNAME=Command1
|
|||||||
|
|
||||||
## Use
|
## Use
|
||||||
|
|
||||||
```console
|
### Strip Command
|
||||||
Usage: vban-cli COMMAND
|
|
||||||
|
|
||||||
╭─ Commands ───────────────────────────────────────────────────────────────────────────────────────╮
|
Usage: vban-cli strip \<index> COMMAND [ARGS]
|
||||||
│ bus Control the bus parameters. │
|
|
||||||
│ strip Control the strip parameters. │
|
examples:
|
||||||
│ --help (-h) Display this message and exit. │
|
|
||||||
│ --version Display application version. │
|
```console
|
||||||
╰──────────────────────────────────────────────────────────────────────────────────────────────────╯
|
vban-cli strip 0 mute true
|
||||||
╭─ Parameters ─────────────────────────────────────────────────────────────────────────────────────╮
|
|
||||||
│ --kind Kind of Voicemeeter [env var: VBAN_CLI_KIND] [default: potato] │
|
vban-cli strip 1 A1 true
|
||||||
│ --host VBAN host [env var: VBAN_CLI_HOST] [default: localhost] │
|
|
||||||
│ --port VBAN port [env var: VBAN_CLI_PORT] [default: 6980] │
|
vban-cli strip 2 gain -18.7
|
||||||
│ --streamname VBAN stream name [env var: VBAN_CLI_STREAMNAME] [default: Command1] │
|
|
||||||
╰──────────────────────────────────────────────────────────────────────────────────────────────────╯
|
|
||||||
```
|
```
|
||||||
|
|
||||||
For every command and subcommand there exists a `--help` flag for further usage information.
|
see `vban-cli strip --help` for more info.
|
||||||
|
|
||||||
|
#### Strip EQ
|
||||||
|
|
||||||
|
Usage: vban-cli strip \<index> eq COMMAND [OPTIONS]
|
||||||
|
|
||||||
|
examples:
|
||||||
|
|
||||||
|
```console
|
||||||
|
vban-cli strip 0 eq on true
|
||||||
|
```
|
||||||
|
|
||||||
|
see `vban-cli strip eq --help` for more info.
|
||||||
|
|
||||||
|
#### Strip EQ Cell Command
|
||||||
|
|
||||||
|
Usage: vban-cli strip \<index> eq cell \<band> COMMAND [ARGS]
|
||||||
|
|
||||||
|
examples:
|
||||||
|
|
||||||
|
```console
|
||||||
|
vban-cli strip 0 eq cell 0 on false
|
||||||
|
```
|
||||||
|
|
||||||
|
see `vban-cli strip eq cell --help` for more info.
|
||||||
|
|
||||||
|
### Bus Command
|
||||||
|
|
||||||
|
Usage: vban-cli bus \<index> COMMAND [ARGS]
|
||||||
|
|
||||||
|
examples:
|
||||||
|
|
||||||
|
```console
|
||||||
|
vban-cli bus 0 mode tvmix
|
||||||
|
|
||||||
|
vban-cli bus 1 mute true
|
||||||
|
```
|
||||||
|
|
||||||
|
see `vban-cli bus --help` for more info.
|
||||||
|
|
||||||
---
|
---
|
||||||
|
|
||||||
|
### Sendtext Command
|
||||||
|
|
||||||
|
Usage: vban-cli sendtext TEXT
|
||||||
|
|
||||||
|
*To Voicemeeter*
|
||||||
|
|
||||||
|
examples:
|
||||||
|
|
||||||
|
```console
|
||||||
|
vban-cli sendtext 'Strip[0].Mute=1;Bus[0].Mono=2'
|
||||||
|
```
|
||||||
|
|
||||||
|
*To Matrix*
|
||||||
|
|
||||||
|
```console
|
||||||
|
vban-cli sendtext 'Command.Version = ?'
|
||||||
|
|
||||||
|
vban-cli sendtext 'Point(ASIO128.IN[1..4],ASIO128.OUT[1]).dBGain = -3.0'
|
||||||
|
```
|
||||||
|
|
||||||
## Implementation Notes
|
## Implementation Notes
|
||||||
|
|
||||||
1. The VBAN TEXT subprotocol defines two packet structures [ident:0][ident-0] and [ident:1][ident-1]. Neither of them contain the data for Bus EQ parameters.
|
1. The VBAN TEXT subprotocol defines two packet structures [ident:0][ident-0] and [ident:1][ident-1]. Neither of them contain the data for Bus EQ parameters.
|
||||||
2. Packet structure with [ident:1][ident-1] is emitted by the VBAN server only on pdirty events. This means we do not receive the initial state of those parameters on initial subscription. Therefore any commands which are intended to fetch the value of parameters defined in packet [ident:1][ident-1] will not work in this CLI.
|
2. Packet structure with [ident:1][ident-1] is emitted by the VBAN server only on pdirty events. This means we do not receive the initial state of those parameters on initial subscription. Therefore any commands which are intended to fetch the value of parameters defined in packet [ident:1][ident-1] will not work in this CLI.
|
||||||
3. Packet structure with [ident:1][ident-1] defines parameteric EQ data only for the [first channel][ident-1-peq].
|
3. Packet structure with [ident:1][ident-1] defines parameteric EQ data only for the [first channel][ident-1-peq].
|
||||||
|
|
||||||
|
|
||||||
---
|
---
|
||||||
|
|
||||||
## Further Notes
|
## Further Notes
|
||||||
|
|
||||||
I've made the effort to set up the basic skeletal structure of the CLI as well as demonstrate how to combine subcommand groups with subcommand groups so more can be implemented, it just needs doing. There may be restrictions on some things however, for example, retrieving values is only possible for parameters [defined in the protocol](https://github.com/onyx-and-iris/Voicemeeter-SDK/blob/3be2c1c36563afbd6df3da8436406c77d2cc1f10/VoicemeeterRemote.h#L787). Setting parameters can be done for anything possible by a string request.
|
I've made the effort to set up the basic skeletal structure of the CLI as well as demonstrate how to combine subcommand groups with subcommand groups so more can be implemented, it just needs doing. There may be restrictions on some things however, for example, retrieving values is only possible for parameters [defined in the protocol](https://github.com/onyx-and-iris/Voicemeeter-SDK/blob/3be2c1c36563afbd6df3da8436406c77d2cc1f10/VoicemeeterRemote.h#L787). Setting parameters can be done for anything possible by a string request.
|
||||||
|
|
||||||
|
Shell completion scripts are available (for zsh, bash and fish) but they haven't been thoroughly tested.
|
||||||
|
|
||||||
If there's something missing that you would like to see added the best bet is to submit a PR. You may raise an issue and if it's quick and simple to do I may (or may not) do it.
|
If there's something missing that you would like to see added the best bet is to submit a PR. You may raise an issue and if it's quick and simple to do I may (or may not) do it.
|
||||||
|
|
||||||
---
|
---
|
||||||
|
|||||||
@@ -1,15 +1,11 @@
|
|||||||
[project]
|
[project]
|
||||||
name = "vban-cli"
|
name = "vban-cli"
|
||||||
version = "0.4.0"
|
version = "0.5.0"
|
||||||
description = "A command-line interface for Voicemeeter leveraging VBAN."
|
description = "A command-line interface for Voicemeeter leveraging VBAN."
|
||||||
readme = "README.md"
|
readme = "README.md"
|
||||||
license = { text = "LICENSE" }
|
license = { text = "LICENSE" }
|
||||||
requires-python = ">=3.13"
|
requires-python = ">=3.13"
|
||||||
dependencies = [
|
dependencies = ["cyclopts>=4.6.0", "loguru>=0.7.3", "vban-cmd>=2.7.1"]
|
||||||
"cyclopts>=4.6.0",
|
|
||||||
"loguru>=0.7.3",
|
|
||||||
"vban-cmd>=2.6.0",
|
|
||||||
]
|
|
||||||
classifiers = [
|
classifiers = [
|
||||||
"Development Status :: 3 - Alpha",
|
"Development Status :: 3 - Alpha",
|
||||||
"Programming Language :: Python",
|
"Programming Language :: Python",
|
||||||
@@ -28,4 +24,4 @@ vban-cli = "vban_cli.app:run"
|
|||||||
package = true
|
package = true
|
||||||
|
|
||||||
[tool.uv.sources]
|
[tool.uv.sources]
|
||||||
vban-cmd = { path = "../vban-cmd-python" }
|
vban-cmd = { path = "../vban-cmd-python", editable = true }
|
||||||
|
|||||||
@@ -2,7 +2,7 @@ from dataclasses import dataclass
|
|||||||
from typing import Annotated
|
from typing import Annotated
|
||||||
|
|
||||||
import vban_cmd
|
import vban_cmd
|
||||||
from cyclopts import App, Parameter, config
|
from cyclopts import App, Argument, Parameter, config
|
||||||
|
|
||||||
from . import __version__ as version
|
from . import __version__ as version
|
||||||
from . import bus, console, strip
|
from . import bus, console, strip
|
||||||
@@ -16,6 +16,7 @@ app = App(
|
|||||||
)
|
)
|
||||||
app.command(strip.app.meta, name='strip')
|
app.command(strip.app.meta, name='strip')
|
||||||
app.command(bus.app.meta, name='bus')
|
app.command(bus.app.meta, name='bus')
|
||||||
|
app.register_install_completion_command()
|
||||||
|
|
||||||
|
|
||||||
@Parameter(name='*')
|
@Parameter(name='*')
|
||||||
@@ -32,17 +33,34 @@ def launcher(
|
|||||||
*tokens: Annotated[str, Parameter(show=False, allow_leading_hyphen=True)],
|
*tokens: Annotated[str, Parameter(show=False, allow_leading_hyphen=True)],
|
||||||
vban_config: Annotated[VBANConfig, Parameter()] = VBANConfig(),
|
vban_config: Annotated[VBANConfig, Parameter()] = VBANConfig(),
|
||||||
):
|
):
|
||||||
|
command, bound, _ = app.parse_args(tokens)
|
||||||
|
if tokens[0] == '--install-completion':
|
||||||
|
return command(*bound.args, **bound.kwargs)
|
||||||
|
|
||||||
|
disable_rt_listeners = False
|
||||||
|
if command.__name__ == 'sendtext':
|
||||||
|
disable_rt_listeners = True
|
||||||
|
|
||||||
with vban_cmd.api(
|
with vban_cmd.api(
|
||||||
vban_config.kind,
|
vban_config.kind,
|
||||||
ip=vban_config.host,
|
ip=vban_config.host,
|
||||||
port=vban_config.port,
|
port=vban_config.port,
|
||||||
streamname=vban_config.streamname,
|
streamname=vban_config.streamname,
|
||||||
|
disable_rt_listeners=disable_rt_listeners,
|
||||||
) as client:
|
) as client:
|
||||||
additional_kwargs = {}
|
return command(*bound.args, **bound.kwargs, ctx=Context(client=client))
|
||||||
command, bound, _ = app.parse_args(tokens)
|
|
||||||
additional_kwargs['ctx'] = Context(client=client)
|
|
||||||
|
|
||||||
return command(*bound.args, **bound.kwargs, **additional_kwargs)
|
|
||||||
|
@app.command(name='sendtext')
|
||||||
|
def sendtext(
|
||||||
|
text: Annotated[str, Argument()],
|
||||||
|
/,
|
||||||
|
*,
|
||||||
|
ctx: Annotated[Context, Parameter(show=False)] = None,
|
||||||
|
):
|
||||||
|
"""Send a text command to the current Voicemeeter/Matrix instance."""
|
||||||
|
if resp := ctx.client.sendtext(text):
|
||||||
|
console.out.print(resp)
|
||||||
|
|
||||||
|
|
||||||
def run():
|
def run():
|
||||||
|
|||||||
@@ -4,9 +4,9 @@ from cyclopts import App, Argument, Parameter
|
|||||||
|
|
||||||
from . import console
|
from . import console
|
||||||
from .context import Context
|
from .context import Context
|
||||||
from .help import CustomHelpFormatter
|
from .help import BusHelpFormatter
|
||||||
|
|
||||||
app = App(name='bus', help_formatter=CustomHelpFormatter())
|
app = App(name='bus', help_formatter=BusHelpFormatter())
|
||||||
# See https://github.com/onyx-and-iris/vban-cli?tab=readme-ov-file#implementation-notes - 1.
|
# See https://github.com/onyx-and-iris/vban-cli?tab=readme-ov-file#implementation-notes - 1.
|
||||||
# app.command(eq.app.meta, name='eq')
|
# app.command(eq.app.meta, name='eq')
|
||||||
|
|
||||||
@@ -32,7 +32,9 @@ def launcher(
|
|||||||
|
|
||||||
@app.command(name='mono')
|
@app.command(name='mono')
|
||||||
def mono(
|
def mono(
|
||||||
new_value: Annotated[Optional[bool], Argument()] = None,
|
new_value: Annotated[
|
||||||
|
Optional[Literal['off', 'mono', 'stereoreverse']], Argument()
|
||||||
|
] = None,
|
||||||
*,
|
*,
|
||||||
index: Annotated[int, Parameter(show=False)] = None,
|
index: Annotated[int, Parameter(show=False)] = None,
|
||||||
ctx: Annotated[Context, Parameter(show=False)] = None,
|
ctx: Annotated[Context, Parameter(show=False)] = None,
|
||||||
@@ -41,13 +43,13 @@ def mono(
|
|||||||
|
|
||||||
Parameters
|
Parameters
|
||||||
----------
|
----------
|
||||||
new_value : bool, optional
|
new_value : {'off', 'mono', 'stereoreverse'}, optional
|
||||||
If provided, sets the mono state to this value. If not provided, the current mono state is printed.
|
If provided, sets the mono state to this value. If not provided, the current mono state is printed.
|
||||||
"""
|
"""
|
||||||
if new_value is None:
|
if new_value is None:
|
||||||
console.out.print(ctx.client.bus[index].mono)
|
console.out.print(['off', 'mono', 'stereoreverse'][ctx.client.bus[index].mono])
|
||||||
return
|
return
|
||||||
ctx.client.bus[index].mono = new_value
|
ctx.client.bus[index].mono = ['off', 'mono', 'stereoreverse'].index(new_value)
|
||||||
|
|
||||||
|
|
||||||
@app.command(name='mute')
|
@app.command(name='mute')
|
||||||
|
|||||||
@@ -3,9 +3,9 @@ from typing import Annotated
|
|||||||
from cyclopts import App, Argument, Parameter
|
from cyclopts import App, Argument, Parameter
|
||||||
|
|
||||||
from .context import Context
|
from .context import Context
|
||||||
from .help import CustomHelpFormatter
|
from .help import StripHelpFormatter
|
||||||
|
|
||||||
app = App(name='comp', help_formatter=CustomHelpFormatter())
|
app = App(name='comp', help_formatter=StripHelpFormatter())
|
||||||
|
|
||||||
|
|
||||||
@app.meta.default
|
@app.meta.default
|
||||||
|
|||||||
@@ -3,9 +3,9 @@ from typing import Annotated
|
|||||||
from cyclopts import App, Argument, Parameter
|
from cyclopts import App, Argument, Parameter
|
||||||
|
|
||||||
from .context import Context
|
from .context import Context
|
||||||
from .help import CustomHelpFormatter
|
from .help import StripHelpFormatter
|
||||||
|
|
||||||
app = App(name='denoiser', help_formatter=CustomHelpFormatter())
|
app = App(name='denoiser', help_formatter=StripHelpFormatter())
|
||||||
|
|
||||||
|
|
||||||
@app.meta.default
|
@app.meta.default
|
||||||
|
|||||||
@@ -3,11 +3,11 @@ from typing import Annotated
|
|||||||
from cyclopts import App, Argument, Parameter
|
from cyclopts import App, Argument, Parameter
|
||||||
|
|
||||||
from .context import Context
|
from .context import Context
|
||||||
from .help import CustomHelpFormatter
|
from .help import CellHelpFormatter, EqHelpFormatter
|
||||||
|
|
||||||
cell_app = App(name='cell', help_formatter=CustomHelpFormatter())
|
cell_app = App(name='cell', help_formatter=CellHelpFormatter())
|
||||||
|
|
||||||
app = App(name='eq', help_formatter=CustomHelpFormatter())
|
app = App(name='eq', help_formatter=EqHelpFormatter())
|
||||||
app.command(cell_app.meta, name='cell')
|
app.command(cell_app.meta, name='cell')
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
@@ -3,9 +3,9 @@ from typing import Annotated
|
|||||||
from cyclopts import App, Argument, Parameter
|
from cyclopts import App, Argument, Parameter
|
||||||
|
|
||||||
from .context import Context
|
from .context import Context
|
||||||
from .help import CustomHelpFormatter
|
from .help import StripHelpFormatter
|
||||||
|
|
||||||
app = App(name='gate', help_formatter=CustomHelpFormatter())
|
app = App(name='gate', help_formatter=StripHelpFormatter())
|
||||||
|
|
||||||
|
|
||||||
@app.meta.default
|
@app.meta.default
|
||||||
|
|||||||
@@ -4,31 +4,24 @@ from cyclopts.help import DefaultFormatter, HelpPanel
|
|||||||
from rich.console import Console, ConsoleOptions
|
from rich.console import Console, ConsoleOptions
|
||||||
|
|
||||||
|
|
||||||
class CustomHelpFormatter(DefaultFormatter):
|
class BaseHelpFormatter(DefaultFormatter):
|
||||||
"""Custom help formatter that injects an index argument into the usage line and filters it out from the parameters list.
|
"""Base help formatter that provides common functionality."""
|
||||||
|
|
||||||
This formatter modifies the usage line to include an <index> argument after the 'strip' command,
|
|
||||||
and filters out any parameters related to 'index' from the Parameters section of the help output.
|
|
||||||
"""
|
|
||||||
|
|
||||||
def render_usage(self, console: Console, options: ConsoleOptions, usage) -> None:
|
|
||||||
"""Render the usage line with index argument injected."""
|
|
||||||
if usage:
|
|
||||||
modified_usage = re.sub(
|
|
||||||
r'(\S+\s+[a-z]+)\s+(COMMAND)', r'\1 <index> \2', str(usage)
|
|
||||||
)
|
|
||||||
console.print(f'[bold]Usage:[/bold] {modified_usage}')
|
|
||||||
|
|
||||||
def __call__(
|
def __call__(
|
||||||
self, console: Console, options: ConsoleOptions, panel: HelpPanel
|
self, console: Console, options: ConsoleOptions, panel: HelpPanel
|
||||||
) -> None:
|
) -> None:
|
||||||
"""Render a help panel, filtering out the index parameter from Parameters sections."""
|
"""Render a help panel, filtering out hidden parameters from Parameters sections."""
|
||||||
if panel.title == 'Parameters':
|
if panel.title == 'Parameters':
|
||||||
filtered_entries = [
|
filtered_entries = [
|
||||||
entry
|
entry
|
||||||
for entry in panel.entries
|
for entry in panel.entries
|
||||||
if not (
|
if not (
|
||||||
entry.names and any('index' in name.lower() for name in entry.names)
|
entry.names
|
||||||
|
and any(
|
||||||
|
param in name.lower()
|
||||||
|
for name in entry.names
|
||||||
|
for param in self.get_filtered_params()
|
||||||
|
)
|
||||||
)
|
)
|
||||||
]
|
]
|
||||||
|
|
||||||
@@ -41,3 +34,78 @@ class CustomHelpFormatter(DefaultFormatter):
|
|||||||
super().__call__(console, options, filtered_panel)
|
super().__call__(console, options, filtered_panel)
|
||||||
else:
|
else:
|
||||||
super().__call__(console, options, panel)
|
super().__call__(console, options, panel)
|
||||||
|
|
||||||
|
def get_filtered_params(self):
|
||||||
|
"""Return list of parameter names to filter out of help output."""
|
||||||
|
return ['index', 'band', 'ctx', 'target', 'eq_kind']
|
||||||
|
|
||||||
|
|
||||||
|
class StripHelpFormatter(BaseHelpFormatter):
|
||||||
|
"""Help formatter for strip commands that injects <index> after 'strip'."""
|
||||||
|
|
||||||
|
def render_usage(self, console: Console, options: ConsoleOptions, usage) -> None:
|
||||||
|
"""Render the usage line with index argument injected after 'strip'.
|
||||||
|
|
||||||
|
Handles both command groups (COMMAND) and individual commands (commandname [ARGS/OPTIONS]).
|
||||||
|
"""
|
||||||
|
if usage:
|
||||||
|
modified_usage = re.sub(
|
||||||
|
r'(\S+\s+strip)\s+(\w+\s+\[[^\]]+\]|\w+\s+\[[^\]]+\]|\w+(?:\s+\[[^\]]+\])*|COMMAND)',
|
||||||
|
r'\1 <index> \2',
|
||||||
|
str(usage),
|
||||||
|
)
|
||||||
|
if modified_usage == str(usage):
|
||||||
|
modified_usage = re.sub(
|
||||||
|
r'(\S+\s+strip)\s+(\w+)', r'\1 <index> \2', str(usage)
|
||||||
|
)
|
||||||
|
console.print(f'[bold]Usage:[/bold] {modified_usage}')
|
||||||
|
|
||||||
|
|
||||||
|
class BusHelpFormatter(BaseHelpFormatter):
|
||||||
|
"""Help formatter for bus commands that injects <index> after 'bus'."""
|
||||||
|
|
||||||
|
def render_usage(self, console: Console, options: ConsoleOptions, usage) -> None:
|
||||||
|
"""Render the usage line with index argument injected after 'bus'.
|
||||||
|
|
||||||
|
Handles both command groups (COMMAND) and individual commands (commandname [ARGS/OPTIONS])."""
|
||||||
|
if usage:
|
||||||
|
modified_usage = re.sub(
|
||||||
|
r'(\S+\s+bus)\s+(\w+\s+\[[^\]]+\]|\w+\s+\[[^\]]+\]|\w+(?:\s+\[[^\]]+\])*|COMMAND)',
|
||||||
|
r'\1 <index> \2',
|
||||||
|
str(usage),
|
||||||
|
)
|
||||||
|
if modified_usage == str(usage):
|
||||||
|
modified_usage = re.sub(
|
||||||
|
r'(\S+\s+bus)\s+(\w+)', r'\1 <index> \2', str(usage)
|
||||||
|
)
|
||||||
|
console.print(f'[bold]Usage:[/bold] {modified_usage}')
|
||||||
|
|
||||||
|
|
||||||
|
class EqHelpFormatter(BaseHelpFormatter):
|
||||||
|
"""Help formatter for eq commands that works with both strip and bus commands.
|
||||||
|
|
||||||
|
Injects <index> after 'strip' or 'bus' and <band> after 'cell'."""
|
||||||
|
|
||||||
|
def render_usage(self, console: Console, options: ConsoleOptions, usage) -> None:
|
||||||
|
"""Render the usage line with proper <index> placement for both strip and bus commands."""
|
||||||
|
if usage:
|
||||||
|
modified_usage = re.sub(
|
||||||
|
r'(\S+\s+)(\w+)(\s+eq\s+)(COMMAND)', r'\1\2 <index>\3\4', str(usage)
|
||||||
|
)
|
||||||
|
console.print(f'[bold]Usage:[/bold] {modified_usage}')
|
||||||
|
|
||||||
|
|
||||||
|
class CellHelpFormatter(BaseHelpFormatter):
|
||||||
|
"""Help formatter for cell commands that works with both strip and bus commands.
|
||||||
|
|
||||||
|
Injects <index> after 'strip' or 'bus' and <band> after 'cell'."""
|
||||||
|
|
||||||
|
def render_usage(self, console: Console, options: ConsoleOptions, usage) -> None:
|
||||||
|
"""Render the usage line with proper <index> and <band> placement."""
|
||||||
|
if usage:
|
||||||
|
modified_usage = re.sub(
|
||||||
|
r'(\S+\s+)(\w+)(\s+eq\s+cell\s+)(COMMAND)',
|
||||||
|
r'\1\2 <index>\3<band> \4',
|
||||||
|
str(usage),
|
||||||
|
)
|
||||||
|
console.print(f'[bold]Usage:[/bold] {modified_usage}')
|
||||||
|
|||||||
@@ -4,9 +4,9 @@ from cyclopts import App, Argument, Parameter
|
|||||||
|
|
||||||
from . import comp, console, denoiser, eq, gate
|
from . import comp, console, denoiser, eq, gate
|
||||||
from .context import Context
|
from .context import Context
|
||||||
from .help import CustomHelpFormatter
|
from .help import StripHelpFormatter
|
||||||
|
|
||||||
app = App(name='strip', help_formatter=CustomHelpFormatter())
|
app = App(name='strip', help_formatter=StripHelpFormatter())
|
||||||
app.command(eq.app.meta, name='eq')
|
app.command(eq.app.meta, name='eq')
|
||||||
app.command(comp.app.meta, name='comp')
|
app.command(comp.app.meta, name='comp')
|
||||||
app.command(gate.app.meta, name='gate')
|
app.command(gate.app.meta, name='gate')
|
||||||
|
|||||||
8
uv.lock
generated
8
uv.lock
generated
@@ -124,7 +124,7 @@ wheels = [
|
|||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "vban-cli"
|
name = "vban-cli"
|
||||||
version = "0.4.0"
|
version = "0.5.0"
|
||||||
source = { editable = "." }
|
source = { editable = "." }
|
||||||
dependencies = [
|
dependencies = [
|
||||||
{ name = "cyclopts" },
|
{ name = "cyclopts" },
|
||||||
@@ -136,13 +136,13 @@ dependencies = [
|
|||||||
requires-dist = [
|
requires-dist = [
|
||||||
{ name = "cyclopts", specifier = ">=4.6.0" },
|
{ name = "cyclopts", specifier = ">=4.6.0" },
|
||||||
{ name = "loguru", specifier = ">=0.7.3" },
|
{ name = "loguru", specifier = ">=0.7.3" },
|
||||||
{ name = "vban-cmd", directory = "../vban-cmd-python" },
|
{ name = "vban-cmd", editable = "../vban-cmd-python" },
|
||||||
]
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "vban-cmd"
|
name = "vban-cmd"
|
||||||
version = "2.6.0"
|
version = "2.7.1"
|
||||||
source = { directory = "../vban-cmd-python" }
|
source = { editable = "../vban-cmd-python" }
|
||||||
|
|
||||||
[package.metadata]
|
[package.metadata]
|
||||||
requires-dist = [{ name = "tomli", marker = "python_full_version < '3.11'", specifier = ">=2.0.1,<3.0" }]
|
requires-dist = [{ name = "tomli", marker = "python_full_version < '3.11'", specifier = ">=2.0.1,<3.0" }]
|
||||||
|
|||||||
Reference in New Issue
Block a user