Add updated HELP.md
This commit is contained in:
356
HELP.md
Normal file
356
HELP.md
Normal file
@@ -0,0 +1,356 @@
|
||||
`str` : An interactive string manipulation environment
|
||||
|
||||
Copyright (C) 2026 Garrett Mills <shout@garrettmills.dev>
|
||||
|
||||
## Syntax Overview
|
||||
|
||||
String manipulation operations are performed on a "subject" -- a given string you are working on.
|
||||
|
||||
Most of the time, you do this by pasting a string into the interpreter, then running a series of
|
||||
statements that make some changes to the string. Here's an example where a few lines of a TSV file
|
||||
have been pasted in as the subject:
|
||||
|
||||
```text
|
||||
str %> paste
|
||||
┌───────────────
|
||||
│ 0 │Mazda RX4 21 6 160 110 3.9 2.62 16.46 0 1 4 4
|
||||
│ 1 │Mazda RX4 Wag 21 6 160 110 3.9 2.875 17.02 0 1 4 4
|
||||
│ 2 │Datsun 710 22.8 4 108 93 3.85 2.32 18.61 1 1 4 1
|
||||
│ 3 │Hornet 4 Drive 21.4 6 258 110 3.08 3.215 19.44 1 0 3 1
|
||||
│ 4 │Hornet Sportabout 18.7 8 360 175 3.15 3.44 17.02 0 0 3 2
|
||||
├───────────────
|
||||
│ :: string
|
||||
└───────────────
|
||||
str %>
|
||||
```
|
||||
|
||||
Statements in `str` take the form of `<command> [...args]`. For a trivial example, here we use a
|
||||
command to replace all instances of `Hornet` with `Foobar`:
|
||||
|
||||
```text
|
||||
str %> replace Hornet Foobar
|
||||
┌───────────────
|
||||
│ 0 │Mazda RX4 21 6 160 110 3.9 2.62 16.46 0 1 4 4
|
||||
│ 1 │Mazda RX4 Wag 21 6 160 110 3.9 2.875 17.02 0 1 4 4
|
||||
│ 2 │Datsun 710 22.8 4 108 93 3.85 2.32 18.61 1 1 4 1
|
||||
│ 3 │Foobar 4 Drive 21.4 6 258 110 3.08 3.215 19.44 1 0 3 1
|
||||
│ 4 │Foobar Sportabout 18.7 8 360 175 3.15 3.44 17.02 0 0 3 2
|
||||
├───────────────
|
||||
│ :: string
|
||||
└───────────────
|
||||
str %>
|
||||
```
|
||||
|
||||
Notice that I did not have to quote the strings `Hornet` and `Foobar` because they do not contain any
|
||||
special syntax characters. The only special syntax characters in `str` are single quotes themselves (`'`),
|
||||
whitespace, and opening parens (`(`).
|
||||
|
||||
Commands are separated either by newlines (pressing enter), or using the `;` separator. For example:
|
||||
|
||||
```text
|
||||
┌───────────────
|
||||
│ 0 │foo bar baz
|
||||
├───────────────
|
||||
│ :: string
|
||||
└───────────────
|
||||
str %> replace oo OO; replace ba BA
|
||||
┌───────────────
|
||||
│ 0 │fOO BAr BAz
|
||||
├───────────────
|
||||
│ :: string
|
||||
└───────────────
|
||||
str %>
|
||||
```
|
||||
|
||||
|
||||
## Data Types
|
||||
|
||||
- `:: string` - Strings. Does what it says on the tin.
|
||||
- `:: int` - Base-10 integers (e.g. for use as offsets).
|
||||
- `:: destructured` - A list split by some value (e.g. `foo::bar` split on `::`).
|
||||
- These differ from normal lists in that they keep track of their "connective tissue".
|
||||
- For example, `foo::bar` split on `::` will give you `[foo, bar]`, but will remember that `bar` is prefixed with `::`
|
||||
- This allows you to `join` the destructured back together later on
|
||||
- `:: ... :: ()` - Lambdas. Multi-parameter functions. See "Working with Lambdas" below.
|
||||
|
||||
|
||||
## Available Commands
|
||||
|
||||
### I/O & Editor Control
|
||||
|
||||
#### `exit`
|
||||
Stop `str` and exit. This can also be done with `^C`.
|
||||
|
||||
#### `paste`
|
||||
Replace the current subject with the current contents of your clipboard.
|
||||
|
||||
#### `copy`
|
||||
Copy the current subject to your clipboard.
|
||||
|
||||
#### `infile <path>`
|
||||
Replace the current subject with the contents of the given file.
|
||||
Example: `infile ~/foo.txt`
|
||||
|
||||
#### `outfile <path>`
|
||||
Write the current subject to the given file (replacing its current contents).
|
||||
Example: `outfile ~/foo.txt`
|
||||
|
||||
#### `assign <value>` / `= <value>`
|
||||
Replace the current context with the given value.
|
||||
Example: `= 'foo bar'` -> `foo bar`
|
||||
Example: `= $a` -> (value of `$a`)
|
||||
|
||||
#### `clear`
|
||||
Clear the current subject (replace it with an empty string).
|
||||
|
||||
#### `show`
|
||||
Print the current subject. This is done by default after every operation.
|
||||
|
||||
#### `undo`
|
||||
Undo the last statement/operation.
|
||||
|
||||
#### `redo`
|
||||
Redo the last undone statement/operation.
|
||||
|
||||
#### `history`
|
||||
Show a log of recent statements/operations.
|
||||
|
||||
#### `edit`
|
||||
Open the current subject in an external text editor (specified by `$EDITOR`).
|
||||
Once you save and close the editor, the modified contents will be loaded back into `str`.
|
||||
A crutch.
|
||||
|
||||
#### `save [<statefile>]`
|
||||
Save the current state of the `str` session to the given statefile (default `~/.str.json`).
|
||||
|
||||
#### `load [<statefile>]`
|
||||
Restore a `str` session from a saved state file (default `~/.str.json`).
|
||||
|
||||
#### `runfile <path>`
|
||||
Execute the contents of the given file as a series of `str` commands.
|
||||
|
||||
|
||||
### Basic String Operations
|
||||
|
||||
#### `enclose [<with>]`
|
||||
Wrap the string on either side with the given string (default = `(`).
|
||||
If the string is one half of a matching pair (e.g. `(`, `[`, `{`, &c), surround with the matching pair.
|
||||
Example: `foo` -> `enclose [` -> `[foo]`
|
||||
|
||||
#### `lower`
|
||||
Convert the string to lower-case.
|
||||
Example: `FoO` -> `lower` -> `foo`
|
||||
|
||||
#### `upper`
|
||||
Convert the string to upper-case.
|
||||
Example: `FoO` -> `upper` -> `FOO`
|
||||
|
||||
#### `lsub <offset> [<length>]`
|
||||
Take a left-substring starting at the given `offset`. Stop after the given `length`, if provided.
|
||||
Example: `abcdef` -> `lsub 1 3` -> `bcd`
|
||||
|
||||
#### `rsub <offset> [<length>]`
|
||||
Take a right-substring starting at the given `offset`. Stop after the given `length`, if provided.
|
||||
Example: `abcdef` -> `rsub 1 3` -> `cde`
|
||||
|
||||
#### `prefix <with>`
|
||||
Prefix the current subject with the given string.
|
||||
Example: `bar` -> `prefix foo` -> `foobar`
|
||||
|
||||
#### `suffix <with>`
|
||||
Suffix the current subject with the given string.
|
||||
Example: `foo` -> `suffix bar` -> `foobar`
|
||||
|
||||
#### `quote [<with>]`
|
||||
Quote the string with the given quotemark (default `'`).
|
||||
If the string is already quoted with a standard quotemark, strip it off first.
|
||||
Example: `'bar'` -> `quote "` -> `"bar"`
|
||||
|
||||
#### `unquote [<with>]`
|
||||
Unquote the string if it is quoted with a standard quotemark (or `with`, if provided explicitly).
|
||||
Example: `"foo"` -> `unquote` -> `foo`
|
||||
|
||||
#### `replace <find> <with>`
|
||||
Replace all instances of `find` with the given `with`.
|
||||
Example: `foobaz` -> `replace baz bar` -> `foobar`
|
||||
|
||||
#### `rev`
|
||||
Reverse the given string (or destructured list).
|
||||
Example: `abcdef` -> `rev` -> `fedcba`
|
||||
|
||||
#### `trim [<type>] [<char>]`
|
||||
Trim leading/trailing instances of `char` from the subject (by default, any whitespace).
|
||||
By default, `trim` uses the `both` type, but supports the following modes:
|
||||
|
||||
- `start`/`left` - only from the start of the string
|
||||
- `end`/`right` - only from the end of the string
|
||||
- `both` - from both start and end of the string
|
||||
- `lines` - remove any empty lines
|
||||
|
||||
Example: ` foo ` -> `trim left` -> `foo `
|
||||
Example: `fffubarfff` -> `trim both f` -> `ubar`
|
||||
|
||||
#### `indent <space|tab> [<level>]`
|
||||
Reindent the current subject with tabs or spaces.
|
||||
If a `level` is provided, adjust the indentation to that level.
|
||||
Example: ` word` -> `indent tab` -> `\tword`
|
||||
|
||||
#### `concat [...<strings>]`
|
||||
Replace the current subject with the result of concatenating the provided strings together.
|
||||
Mostly useful in conjunction with variables.
|
||||
Example: `concat foo bar` -> `foobar`
|
||||
|
||||
|
||||
### Multi-part Manipulation (line-wise, word-wise, destructured)
|
||||
|
||||
#### `line ...<subcommand>`
|
||||
Execute the given `subcommand` on every line of the subject.
|
||||
Example: `foo\nbar` -> `line prefix --` -> `--foo\n--bar`
|
||||
|
||||
#### `word ...<subcommand>`
|
||||
Execute the given `subcommand` on every word of the subject, preserving whitespace.
|
||||
Example: `foo bar baz` -> `word prefix --` -> `--foo --bar --baz`
|
||||
|
||||
#### `each ...<subcommand>`
|
||||
Execute the given `subcommand` on every part of a destructured subject.
|
||||
Example: `[foo, bar, baz]` -> `each prefix A` -> `[Afoo, Abar, Abaz]`
|
||||
|
||||
#### `on <word|line|index> <index> ...<subcommand>`
|
||||
Execute the given subcommand on the specified word/line/index from the current subject.
|
||||
`word` and `line` apply to strings that have not been destructured.
|
||||
`index` is applied for destructured subjects. For destructured subjects you may omit the type (e.g. `on 4 ...`).
|
||||
Example: `foo bar baz` -> `on word 1 rsub 1` -> `foo ba baz`
|
||||
|
||||
#### `drop <word|line|index> <index>`
|
||||
Delete the specified word/line/index from the current subject.
|
||||
`word` and `line` apply to strings that have not been destructured.
|
||||
`index` is applied for destructured subjects. For destructured subjects you may omit the type (e.g. `drop 4`).
|
||||
Example: `foo bar baz` -> `drop word 1` -> `foo baz`
|
||||
|
||||
#### `contains <find>`
|
||||
If the subject contains the given substring, keep it. Otherwise, replace it with an empty string.
|
||||
Most often used in conjunction with `line`, `word`, or `each` for filtering.
|
||||
Example: `afoo \n bfoo \n cbar` -> `line contains foo` -> `afoo \n bfoo \n `
|
||||
|
||||
#### `missing <find>`
|
||||
If the subject contains the given substring, replace it with an empty string. Otherwise, keep it.
|
||||
Most often used in conjunction with `line`, `word`, or `each` for filtering.
|
||||
Example: `afoo \n bfoo \n cbar` -> `line missing foo` -> `\n \n cbar`
|
||||
|
||||
#### `lines`
|
||||
Destructure the current subject into individual lines.
|
||||
Example: `foo \n bar` -> `lines` -> `[foo, bar]`
|
||||
|
||||
#### `words`
|
||||
Destructure the current subject into individual words.
|
||||
Example: `foo bar \n baz` -> `words` -> `[foo, bar, baz]`
|
||||
|
||||
#### `split <on> [<limit>]`
|
||||
Destructure the current subject based on the given delimiter.
|
||||
If a `limit` is provided, split the subject no more than the given number of times.
|
||||
Example: `foo::bar::baz::ban` -> `split :: 2` -> `[foo, bar, baz::ban]`
|
||||
|
||||
#### `chunk <every> <line|word|char>`
|
||||
Destructure the current subject into chunks based on `every` Nth line/word/character.
|
||||
Example: `a b c d e f` -> `chunk 2 word` -> `[a b, c d, e f]`
|
||||
|
||||
#### `join [<on>]`
|
||||
Join the current destructured subject back together using the given delimiter.
|
||||
If no delimiter is provided, it will preserve the existing delimiters between substrings.
|
||||
If string is not destructured, joins the lines in the string.
|
||||
Example: `[foo, bar]` -> `join ::` -> `foo::bar`
|
||||
|
||||
#### `sort [<asc|desc>]`
|
||||
Sort the items in the destructured subject alphabetically either `asc`ending (default) or `desc`ending.
|
||||
If string is not destructured, sorts the lines in the string.
|
||||
Example: `[foo, bar]` -> `sort` -> `[bar, foo]`
|
||||
|
||||
#### `unique`
|
||||
Filter out duplicate values from the destructured subject.
|
||||
If string is not destructured, filters out duplicate lines in the string.
|
||||
Example: `[foo, bar, foo]` -> `unique` -> `[foo, bar]`
|
||||
|
||||
#### `zip <with>`
|
||||
Interleave the current destructured subject with the given other destructured subject.
|
||||
Example: Say `$a` is `[1, 2, 3]` and subject is `[a, b, c]` -> `zip $a` -> `[a, 1, b, 2, c, 3]`
|
||||
|
||||
|
||||
### Working with Variables
|
||||
|
||||
Variables in `str` start with a dollar sign and may be alphanumeric with underscores (e.g. `$my_var`).
|
||||
|
||||
Assign a variable using the standard syntax: `$a = 'mystr'`
|
||||
|
||||
You can then use them anywhere you may use a string: `split $a`
|
||||
|
||||
There are also several commands for interactive with variables, defined below.
|
||||
|
||||
#### `to <var>`
|
||||
Store the current subject into the given variable.
|
||||
Example: `foo bar` -> `to $a`
|
||||
|
||||
#### `from <var>`
|
||||
Replace the current subject with the value of the given variable.
|
||||
Example: `from $a`
|
||||
|
||||
#### `set <var> <value>`
|
||||
Alternative syntax for variable assignment.
|
||||
Example: `set $a 'mystr'` is equivalent to `$a = 'mystr'`
|
||||
|
||||
#### `over <var> ...<subcommand>`
|
||||
Execute the given `subcommand` against the contents of `var` instead of the current subject.
|
||||
Example: `over $a replace foo bar`
|
||||
|
||||
|
||||
### Working with Lambdas (functions, closures, &c)
|
||||
|
||||
`str` supports Lambda functions. These are defined as a series of commands which may optionally
|
||||
have some number of parameters. For example:
|
||||
|
||||
```text
|
||||
$myReplacer = (|$a $b| split $a; join $b)
|
||||
```
|
||||
|
||||
This trivial lambda takes two parameters, splits the subject on `$a` and joins it back together on `$b` (effectively, `replace`).
|
||||
|
||||
You may omit the parameter list if the lambda takes no parameters. For example, this basic TSV parser:
|
||||
|
||||
```text
|
||||
$myTSVParser = (
|
||||
trim;
|
||||
trim lines;
|
||||
lines;
|
||||
each split \t
|
||||
)
|
||||
```
|
||||
|
||||
#### `call <lambda> [...<params>]`
|
||||
Execute the given lambda with the provided parameters, replacing the current context with the result.
|
||||
Example: `call $myReplacer foo bar`
|
||||
|
||||
`call` operates over the current context. However, you can execute lambdas over the contents of a variable using `over`:
|
||||
|
||||
```text
|
||||
str %> $a = 'foo bar'
|
||||
str %> over $a call $myReplacer foo bar
|
||||
```
|
||||
|
||||
`call` also supports partial application. For example:
|
||||
|
||||
```text
|
||||
str %> over $myFooReplacer call $myReplacer foo
|
||||
```
|
||||
|
||||
You can then call the partially-applied lambda with the remaining parameter(s):
|
||||
|
||||
```text
|
||||
str %> call $myFooReplacer bar
|
||||
```
|
||||
|
||||
|
||||
### Misc
|
||||
|
||||
#### `lipsum <num> <word|line|para>`
|
||||
Replace the current subject with "Lorem ipsum..." placeholder text.
|
||||
Can generate individual words, lines, or paragraphs.
|
||||
Example: `lipsum 4 word` -> `lorem ipsum dolor sit`
|
||||
209
HELP.txt
209
HELP.txt
@@ -1,209 +0,0 @@
|
||||
str : An interactive string manipulation environment
|
||||
Copyright (C) 2025 Garrett Mills <shout@garrettmills.dev>
|
||||
|
||||
----------------------------------------
|
||||
Input / Output
|
||||
----------------------------------------
|
||||
copy
|
||||
Copy the current string to the clipboard. (Requires wl-clipboard.)
|
||||
|
||||
paste
|
||||
Paste the contents of the clipboard to replace the current string. (Requires wl-clipboard.)
|
||||
|
||||
infile <file path>
|
||||
Replace the current string with the contents of <file path>.
|
||||
|
||||
outfile <file path>
|
||||
Write the current string as the contents of <file path>.
|
||||
|
||||
edit
|
||||
Open the current string in EDITOR.
|
||||
|
||||
history
|
||||
Print the undo/redo history
|
||||
|
||||
runfile <file path>
|
||||
Parse a file as a set of str commands and execute them.
|
||||
|
||||
from <var>
|
||||
Replace the current string with the contents of the <var> variable.
|
||||
|
||||
to <var>
|
||||
Store the current string contents into the <var> variable.
|
||||
|
||||
----------------------------------------
|
||||
String Manipulation
|
||||
----------------------------------------
|
||||
indent <spaces|tabs> [<level>]
|
||||
Indent the string with the specified number of spaces or tabs.
|
||||
Default is a single standard indentation level.
|
||||
|
||||
trim [<start|end|both|lines>] [<char>]
|
||||
Remove instances of the given character from either the start/end or both sides of the string.
|
||||
Default is to trim whitespace from both ends.
|
||||
|
||||
quote [<char>]
|
||||
Surround the current string in the given quote character.
|
||||
Default is to use the current "quote" setting, which defaults to a single-quote.
|
||||
|
||||
unquote [<char>]
|
||||
Try to strip surrounding quotes of the given character from the string.
|
||||
Will only proceed if the string has the quote mark on both ends.
|
||||
Default is to try common quote schemes (single/double quotes, backtick).
|
||||
|
||||
enclose [<char>]
|
||||
Wrap the string in the given character. Tries to match pairs when possible.
|
||||
Example: Using `(` will wrap with a closing `)`
|
||||
Default is to wrap with parentheses.
|
||||
|
||||
prefix <string>
|
||||
Prepend <string> to the current string.
|
||||
|
||||
suffix <string>
|
||||
Append <string> to the current string.
|
||||
|
||||
split <on> [<join>]
|
||||
Split the current string using the given <on> separator, and rejoin it using the given <join> separator.
|
||||
Default is to rejoin on newlines.
|
||||
|
||||
lines [<on>] [<join>]
|
||||
Like `split`, but defaults to splitting on chunks of whitespace.
|
||||
|
||||
join [<with>]
|
||||
Join separate lines in the string using the given <with> separator.
|
||||
|
||||
replace <find> <replace> [<range>]
|
||||
Replace all instances of <find> with <replace>.
|
||||
Optionally, define a "range pattern" to replace. Range patterns define
|
||||
the nth occurrences of <find> that should be replaced. The last number
|
||||
in a range will be repeated as necessary.
|
||||
Example:
|
||||
"First Name Last Name Salutation Age Height"
|
||||
replace ' ' , [2, 2, 1]
|
||||
"First Name,Last Name,Salutation,Age,Height"
|
||||
|
||||
lsub <offset> [<length>]
|
||||
Replace the current string with a substring from the left, starting at <offset>.
|
||||
Optionally, limit to <length> characters.
|
||||
|
||||
rsub <offset> [<length>]
|
||||
Like `lsub`, but works on the string from right-to-left.
|
||||
|
||||
reparse <fromlang> <tolang>
|
||||
Assuming the string is a valid <fromlang> expression, parse it and convert it to <tolang> encoding.
|
||||
Example: reparse json php
|
||||
|
||||
----------------------------------------
|
||||
Advanced Manipulation
|
||||
----------------------------------------
|
||||
line <command...>
|
||||
Runs the given command for every line in the string (separated by \n).
|
||||
|
||||
word <command...>
|
||||
Runs the given command for every word in the string (separated by whitespace).
|
||||
|
||||
contains <search>
|
||||
Check if the current string contains <search>. If not, replace it with an empty string.
|
||||
|
||||
on <line|word> <index> <command...>
|
||||
Run the given command on the nth line or word.
|
||||
Example: on line 2 prefix +
|
||||
|
||||
drop <line|word|index> <index>
|
||||
Drops the nth line, word, or element from the subject.
|
||||
|
||||
map <line|word> <start index> [to <end index>] [by <nth lines>] <command...>
|
||||
Map the subject line-wise or word-wise for the given range.
|
||||
Default is to map until the end of the string if `to` is not provided,
|
||||
and to apply to every single line/word.
|
||||
Example: map line 1 to 5 by 2 prefix +
|
||||
|
||||
over <var> <command...>
|
||||
Apply a command to the given <var> and save it back in <var>.
|
||||
Example: over $a line prefix +
|
||||
|
||||
----------------------------------------
|
||||
State Management
|
||||
----------------------------------------
|
||||
show
|
||||
Print out the current string.
|
||||
|
||||
clear
|
||||
Replace the current string with an empty string.
|
||||
|
||||
undo [<steps>]
|
||||
Undo the past <steps> operations on the string. Defaults to a single operation.
|
||||
|
||||
redo
|
||||
Redo the past <steps> operations that were undone. Defaults to a single operation.
|
||||
|
||||
save [<file>]
|
||||
Store the current state of the interpreter to the given file path.
|
||||
Defaults to ~/.str.json
|
||||
|
||||
load [<file>]
|
||||
Restore a saved state from the given file path to the interpreter.
|
||||
Defaults to ~/.str.json
|
||||
exit
|
||||
Exit the interpreter.
|
||||
|
||||
set <setting> [<value>]
|
||||
Change the given interpreter <setting> to the given <value>.
|
||||
If no value is given, will reset it back to the default.
|
||||
Supported settings:
|
||||
quote (default: ') - What character is used to parse quoted strings.
|
||||
Also sets the default for the `quote` command.
|
||||
escape (default: \) - What character is used to parse escape sequences.
|
||||
session (default: ~/.str.json) - Default file used by `save`/`load` commands.
|
||||
debug (default: 0) - Set to 1 to enable debug mode
|
||||
terminator (default: \n) - What character is used to parse sequential commands.
|
||||
Example: `set terminator ;` will begin parsing commands
|
||||
separated by a ; instead of when enter is pressed.
|
||||
|
||||
----------------------------------------
|
||||
Variables
|
||||
----------------------------------------
|
||||
Define/set a variable
|
||||
$varname = <string>
|
||||
Example: $foo = example
|
||||
$baz = 'another example'
|
||||
|
||||
Use variables as arguments to commands
|
||||
Example: line prefix $foo
|
||||
|
||||
Use quotes to escape variable names
|
||||
Example: line prefix '$foo'
|
||||
|
||||
vars
|
||||
Print the value of all defined variables
|
||||
|
||||
varUnset <var>
|
||||
Unset a variable.
|
||||
Example: varUnset $foo
|
||||
|
||||
----------------------------------------
|
||||
Functions
|
||||
----------------------------------------
|
||||
function <name>
|
||||
Start a function definition. Subsequent commands will be parsed
|
||||
as part of the function body until `end function` is encountered.
|
||||
|
||||
Functions may not be nested.
|
||||
|
||||
end <block>
|
||||
End a block of the given type. Only supports `function` currently.
|
||||
|
||||
call <name>
|
||||
Execute the given function.
|
||||
|
||||
Example:
|
||||
```
|
||||
function format_sql_in_clause
|
||||
line lines
|
||||
line trim
|
||||
trim
|
||||
line quote "
|
||||
join ,
|
||||
enclose (
|
||||
end function
|
||||
```
|
||||
@@ -5,7 +5,7 @@ import {fileURLToPath} from "node:url";
|
||||
import {StrVM} from "../vm.js";
|
||||
import fs from "node:fs";
|
||||
|
||||
const helpFile = () => `${dirname(fileURLToPath(import.meta.url))}/../../../HELP.txt`
|
||||
const helpFile = () => `${dirname(fileURLToPath(import.meta.url))}/../../../HELP.md`
|
||||
const helpContents = () => fs.readFileSync(helpFile(), 'utf8')
|
||||
|
||||
export class Help extends Command<{}> {
|
||||
|
||||
Reference in New Issue
Block a user