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
```
