# jarq
An interactive jq-like JSON query tool with a TUI.
Should you use this instead of `jq`? Definitely not, this was just an experiment using a TUI and live filtering.
## Usage
```bash
# Interactive TUI mode
jarq data.json
# Non-interactive mode (like jq)
# Non-interactive with flags (jq drop-in)
echo -e '1\n2\n3' | jarq -s '.' # slurp into array
echo '{"a":1}' | jarq -crs '.' # combine flags
```
### Command-line Options
| `-c` | Compact output (no pretty-printing) |
| `-r` | Raw output (strings without quotes) |
| `-s` | Slurp (read all inputs into array) |
In interactive mode, type filter expressions and see results in real-time.
## Keyboard Controls
### Navigation Mode
| `i`, `/` | Enter filter edit mode |
| `j`, `↓` | Scroll down |
| `k`, `↑` | Scroll up |
| `h`, `←` | Scroll left (when wrap off) |
| `l`, `→` | Scroll right (when wrap off) |
| `g` | Go to top |
| `G` | Go to bottom |
| `0` | Reset horizontal scroll |
| `Ctrl-D` | Page down (half screen) |
| `Ctrl-U` | Page up (half screen) |
| `w` | Toggle line wrap |
| `s` | Toggle slurp mode |
| `r` | Toggle raw output |
| `o` | Toggle compact output |
| `y` | Copy filter as jq command |
| `q`, `Esc` | Quit |
| `Ctrl-H` | Show help |
### Filter Edit Mode
| `Esc`, `Ctrl-D` | Exit filter edit mode |
| `Tab` | Toggle partial eval mode |
| `Ctrl-P` | Toggle pause/resume evaluation |
| `Ctrl-C` | Cancel running evaluation |
| `Enter` | Evaluate now (when paused) |
| `Ctrl-S` | Toggle slurp mode |
| `Ctrl-R` | Toggle raw output |
| `Ctrl-O` | Toggle compact output |
| `Ctrl-Y` | Copy filter as jq command |
| `Ctrl-H` | Show help |
### Background Evaluation
jarq evaluates filters in the background as you type. For large files, you can:
- **Pause evaluation** (`Ctrl-P`): Stop auto-evaluation while you compose a complex filter
- **Cancel evaluation** (`Ctrl-C`): Stop a long-running evaluation and enter pause mode
- **Evaluate on demand** (`Enter`): When paused, manually trigger evaluation
When paused, the filter is still validated for syntax errors in real-time.
### Partial Eval Mode
Press `Tab` to toggle partial eval mode. This evaluates the filter up to your cursor position, which is useful for debugging complex filters step by step.
When inside array construction brackets like `[.[] | .name]`, partial eval automatically "unwraps" to show what values will be collected into the array.
## Filter Syntax
```
. # identity
.foo # field access
.foo? # optional (suppress errors)
.[0] # array index
.[-1] # negative index (from end)
.[2:5] # array slice
.[:-1] # slice (all but last)
.[] # iterate all elements
.[]? # optional iterate
.foo.bar # chaining
# Literals
42, 3.14 # numbers
"hello" # strings
true, false # booleans
null # null
# Comparisons
.x == 5 # equal
.x != "foo" # not equal
.x < 10 # less than
.x <= 10 # less or equal
.x > 0 # greater than
.x >= 0 # greater or equal
# Boolean operators
.a and .b # logical and
.a or .b # logical or
.x > 0 and .x < 10 # compound conditions
# Arithmetic
2 + 3 # addition
10 - 3 # subtraction
4 * 5 # multiplication
10 / 3 # division
add / length # average (combine with builtins)
(2 + 3) * 4 # parentheses for grouping
# Conditionals
if .x > 0 then "pos" else "neg" end
.name // "default" # alternative (if null/false)
# Construction
[.a, .b] # array
{name: .foo} # object
{(.key): .val} # dynamic key
```
## Builtins
| `length` | Length of string, array, or object |
| `keys` | Object keys or array indices |
| `values` | Object or array values |
| `type` | Type name as string |
| `first` | First element of array |
| `last` | Last element of array |
| `reverse` | Reverse array |
| `sort` | Sort array |
| `min` | Minimum value in array |
| `max` | Maximum value in array |
| `unique` | Remove duplicates from array |
| `flatten` | Flatten nested arrays |
| `add` | Sum numbers, concat strings/arrays, merge objects |
| `empty` | Produce no output |
| `not` | Boolean negation |
| `to_entries` | Object to `[{key, value}, ...]` |
| `from_entries` | `[{key, value}, ...]` to object |
| `@csv` | Convert array to CSV string |
| `@tsv` | Convert array to TSV string |
## Functions
| `map(f)` | Apply filter to each array element |
| `select(f)` | Keep values where `f` is truthy |
| `sort_by(f)` | Sort array by extracted key |
| `group_by(f)` | Group array elements by key |
| `unique_by(f)` | Remove duplicates by key |
| `min_by(f)` | Element with minimum key |
| `max_by(f)` | Element with maximum key |
| `has("key")` | Check if object has key |
| `split("delim")` | Split string into array |
| `join("sep")` | Join array into string |
| `startswith("s")` | Check if string starts with prefix |
| `endswith("s")` | Check if string ends with suffix |
| `contains(value)` | Check if value contains another |
| `with_entries(f)` | Transform object entries |
## Building
```bash
cargo build --release
```
## License
MIT