Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Output Formats, Raw REPL #14

Merged
merged 11 commits into from
Sep 5, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 4 additions & 0 deletions CREDITS.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
# Credits

- Implementation of `reshape` by anaseto, shared [on Matrix](https://matrix.to/#/#aplfarm-k:matrix.org)
- Implementation of `shape` by John Earnest, shared [in the k tree StackExchange chat](https://chat.stackexchange.com/transcript/message/54070438#54070438)
16 changes: 10 additions & 6 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@

Ari stands for **A**rray **R**elational **I**nteractive programming environment.

Ari is a set of extensions to the [Goal] programming language, also providing an extensible CLI with dedicated SQL mode.
Ari is a set of extensions to the [Goal] programming language with an extensible CLI and dedicated SQL mode.

## Installation

Expand All @@ -26,6 +26,7 @@ Then run `ari` for a REPL or `ari --help` to see CLI options.
- Runtime configuration:
- Configure the REPL prompt by setting string values for the `ari.prompt` and `ari.nextprompt` (for multiline input) globals
- Replace default REPL printing by setting a function value for the `ari.print` global (function receives a single Goal value to print)
- Configure the output format with `--output-format` or using one of the `)output.` system commands at the REPL. Formats include CSV/TSV, JSON, Markdown, and LaTeX.
- `ari.p` is bound to the previous result (value from last evaluation at the REPL)
- Extensible help system
- `help"help"` for an overview
Expand All @@ -37,7 +38,10 @@ Then run `ari` for a REPL or `ari --help` to see CLI options.
- New Goal functions:
- `http.` functions for HTTP requests using [Resty]
- `sql.` functions for SQL queries and commands
- Dedicated SQL mode for DuckDB
- _(WIP)_ `time.` functions for more extensive date/time handling
- `tui.` functions for basic terminal UI styling (colors, padding/margin, borders)
- Dedicated SQL mode
- The ari CLI uses DuckDB, but the `github.com/semperos/ari` Go package doesn't directly depend on a specific SQL database driver, so you can BYODB.
- Activate with `)sql` for read-only, `)sql!` for read/write modes. Execute `)goal` to return to the default Goal mode.
- Auto-completion of SQL keywords
- Help entries for SQL keywords (shown during auto-complete, still WIP)
Expand All @@ -50,19 +54,19 @@ Non-exhaustive list:
- TODO: Test coverage.
- TODO: Correct usage of `goal.NewError` vs. `goal.NewPanicError`
- TODO: Option for raw REPL (modeled on Goal's) with better input performance, no auto-complete etc.
- TODO: Goal function to return auto-complete results (esp. if raw REPL is being used).
- TODO: Looser auto-complete, not just prefix-based
- TODO: Functions to conveniently populate SQL tables with Goal values.
- TODO: Support plots/charts (consider https://github.com/wcharczuk/go-chart)
- TODO: User commands (as found in [APL](https://aplwiki.com/wiki/User_command)), executable from Goal or SQL modes

I plan to support the above items. The following are stretch goals or nice-to-have's:

- TODO: Use custom table functions via replacement scan to query Goal tables from DuckDB.
- TODO: Looser auto-complete, not just prefix-based
- TODO: `)help`
- TODO: Functions leveraging [time.Time](https://pkg.go.dev/[email protected])
- TODO: `tui.` functions in CLI mode using https://github.com/charmbracelet/lipgloss (already a transitive dependency) for colored output, etc.
- IN PROGRESS: `tui.` functions in CLI mode using https://github.com/charmbracelet/lipgloss (already a transitive dependency) for colored output, etc.
- TODO: Implement a subset of [q](https://code.kx.com/q/) functions to extend what Goal already has.
- Specific user commands:
- TODO: Choosing output format (e.g., as JSON, perhaps all the ones DuckDB supports)
- TODO: Toggle pretty-printing
- TODO: Toggle paging at the REPL (as found in [PicoLisp](https://picolisp.com/wiki/?home))
- TODO: Toggle colored output
Expand Down
35 changes: 35 additions & 0 deletions ari.goal
Original file line number Diff line number Diff line change
@@ -0,0 +1,35 @@
istbl:{and["d"=@x;&/"s"=@'!x;&/{(@'x)¿"ANSI"}x;&/(*ls)=ls:#'x]} / is x a dictionary-as-table
reshape:{((*/x)#y){(-y)$x}/|1_x} / Implementation by anaseto, shared on Matrix
shape:{-1_#:'*:\x} / Implementation by John Earnest, shared on k-tree
depths:{[l;ind] ,/(..?[(@x)¿"ANSI";p.o[x;p.ind+1];p.ind])'l} / list depths
md.tbl:{[t;fmt] / helper
k:!t; v:(..?[(@x)¿"nN";p.fmt$x;$'x])'.t; w:(-1+""#k)|(|/-1+""#)'v
(k;v):(-w)!'´(k;v); "|"+("|\n|"/,/"|"/(k;"-"*w;+v))+"|"}
md.lst:{[l;fmt] / helper
ds:depths[l;0]; v:(..?["n"=@x;p.fmt$x;$'x])',//l
ind:..x*" "; pfx:(ind'ds)+"- "
"\n"/v;"\n"/pfx+v}
sprintf.md:{[x;fmt]?[istbl x;md.tbl[x;fmt]; (@x)¿"ANSI";md.lst[x;fmt]; "n"=@x;fmt$x; $x]} / String print to Markdown
ltx.lq:{sub[rq/ "/;" ``"]sub[rx/(?m)^"/;"``"]x} / helper
ltx.rq:{sub[rq/" /;"'' "]sub[rx/(?m)"$/;"''"]x} / helper
ltx.tbl:{[t;fmt] / helper
algn:!"r l"; algns:""/algn["S"=@'t]
k:!t; v:(..?[(@x)¿"nN";p.fmt$x;$'x])'.t; w:(-1+""#k)|(|/-1+""#)'v
(k;v):(-w)!'´(k;v); rs:" \\\\\n"/,/" & "/(k;"\\hline %";+v)
[email protected]@qq`\\begin{tabular}{|$algns|}\n\\hline
$rs \\\\\n\\hline\n\\end{tabular}`
}
ltx.be:"\\begin{enumerate}"; ltx.ee:"\\end{enumerate}" / helpers
ltx.lstenv:{ / helper
(n;sig):(abs x;sign x);
?[sig=-1;"\n"+(""/(n-1)#"$ltx.be\n\\item\n")+"$ltx.be\n\\item %v\n"
sig=0;"\\item %v\n"
"\n"+(""/n#"$ltx.ee\n")+"\n\\item %v\n"]}
ltx.lst:{[l;fmt] / helper
v:(..?["n"=@x;p.fmt$x;$'x])',//l;
ds:depths[l;0]; cs:(»ds)-ds; fs:,/ltx.lstenv'cs
"$ltx.be\n"+(""/fs$'v)+"$ltx.ee"}
sprintf.ltx:{[x;fmt]?[istbl x;ltx.tbl[x;fmt]; (@x)¿"ANSI";ltx.lst[x;fmt]; "n"=@x;fmt$x; $x]} / LaTeX output
csv.tbl:{(*'x)!(1_'x)} / table from csv parsing, assumes header
json.tbl:{ks:!*x; vs:@[;ks]'x; ks!+vs} / table from parsing json array of like objects
1
13 changes: 12 additions & 1 deletion cmd/ari/input.go
Original file line number Diff line number Diff line change
Expand Up @@ -397,7 +397,18 @@ func (autoCompleter *AutoCompleter) cacheSystemCommands() {

func systemCommands() (map[string]string, []string) {
m := map[string]string{
")goal": "Goal array language mode", ")sql": "Read-only SQL mode (querying)", ")sql!": "Read/write SQL mode",
")goal": "Goal array language mode",
// TODO Output formats: https://duckdb.org/docs/api/cli/output_formats.html
// In particular csv, json, markdown, latex, and one of the boxed ones
")output.csv": "Print results as CSV",
")output.goal": "Print results as Goal values (default)",
")output.json": "Print results as JSON",
")output.json+pretty": "Print results as JSON with indentation",
")output.latex": "Print results as LaTeX",
")output.markdown": "Print results as Markdown",
")output.tsv": "Print results as TSV",
")sql": "Read-only SQL mode (querying)",
")sql!": "Read/write SQL mode",
}
// Prepare sorted keys ahead of time
keys := make([]string, 0, len(m))
Expand Down
Loading
Loading