mirror of
https://github.com/wader/fq.git
synced 2024-11-23 09:56:07 +03:00
41551de331
repl now rewrites query to do implicit display inside the sub eval. This makes it possible to interrupt eval and output in a better and faster way. Make JSON encoder fail early on errors. Add more interrupt tests.
200 lines
5.2 KiB
Plaintext
200 lines
5.2 KiB
Plaintext
include "internal";
|
|
include "query";
|
|
include "eval";
|
|
include "repl";
|
|
include "decode";
|
|
include "funcs";
|
|
include "options";
|
|
include "args";
|
|
|
|
# TODO: variants, values, keywords?
|
|
# TODO: store some other way?
|
|
def _help_functions:
|
|
{ length: {
|
|
summary: "Length of string, array, object, etc",
|
|
doc:
|
|
"- For string number of unicode codepoints
|
|
- For array number of elements in array
|
|
- For object number of key-value pairs
|
|
- For null zero
|
|
- For number the number itself
|
|
- For boolean is an error
|
|
",
|
|
examples:
|
|
[ [[1,2,3], "length"]
|
|
, ["abc", "length"]
|
|
, [{a: 1, b: 2}, "length"]
|
|
, [null, "length"]
|
|
, [123, "length"]
|
|
, [true, "length"]
|
|
]
|
|
},
|
|
"..": {
|
|
summary: "Recursive descent of .",
|
|
doc:
|
|
"Recursively descend . and output each value.
|
|
Same as recurse without argument.
|
|
",
|
|
examples:
|
|
[ ["a", ".."]
|
|
, [[1,2,3], ".."]
|
|
, [{a: 1, b: {c: 3}}, ".."]
|
|
]
|
|
},
|
|
empty: {
|
|
summary: "Output nothing",
|
|
doc:
|
|
"Output no value, not even null, and cause backtrack.
|
|
",
|
|
examples:
|
|
[ ["empty"]
|
|
, ["[1,empty,2]"]
|
|
]
|
|
}
|
|
};
|
|
|
|
def help($_): error("help must be alone or last in pipeline. ex: help(length) or ... | help");
|
|
def help: help(null);
|
|
|
|
def _help($arg0; $topic):
|
|
( $topic
|
|
| if . == "usage" then
|
|
"Usage: \($arg0) [OPTIONS] [--] [EXPR] [FILE...]"
|
|
elif . == "example_usage" then
|
|
( "Example usages:"
|
|
, " fq . file"
|
|
, " fq d file"
|
|
, " fq tovalue file"
|
|
, " cat file.cbor | fq -d cbor torepr"
|
|
, " fq 'grep(\"^main$\") | parent' /bin/ls"
|
|
, " fq 'grep_by(format == \"exif\") | d' *.png *.jpeg"
|
|
)
|
|
elif . == "banner" then
|
|
( "fq - jq for binary formats"
|
|
, "Tool, language and decoders for inspecting binary data."
|
|
, "For more information see https://github.com/wader/fq"
|
|
)
|
|
elif . == "args" then
|
|
args_help_text(_opt_cli_opts)
|
|
elif . == "options" then
|
|
( [ ( options
|
|
| _opt_cli_arg_fromoptions
|
|
)
|
|
| to_entries[]
|
|
| [(.key+" "), .value | tostring]
|
|
]
|
|
| table(
|
|
.;
|
|
map(
|
|
( . as $rc
|
|
# right pad format name to align description
|
|
| if .column == 0 then .string | rpad(" "; $rc.maxwidth)
|
|
else $rc.string
|
|
end
|
|
)
|
|
) | join("")
|
|
)
|
|
)
|
|
elif . == "formats" then
|
|
( [ formats
|
|
| to_entries[]
|
|
| [(.key+" "), .value.description]
|
|
]
|
|
| table(
|
|
.;
|
|
map(
|
|
( . as $rc
|
|
# right pad format name to align description
|
|
| if .column == 0 then .string | rpad(" "; $rc.maxwidth)
|
|
else $rc.string
|
|
end
|
|
)
|
|
) | join("")
|
|
)
|
|
)
|
|
else
|
|
error("unknown topic: \($topic)")
|
|
end
|
|
);
|
|
|
|
# TODO: refactor
|
|
def _help_slurp($query):
|
|
def _name:
|
|
if _query_is_func then _query_func_name
|
|
else _query_tostring
|
|
end;
|
|
if $query.orig | _query_is_func then
|
|
( ($query.orig | _query_func_args) as $args
|
|
| ($args | length) as $argc
|
|
| if $args == null then
|
|
# help
|
|
( "Type expression to evaluate"
|
|
, "\\t Completion"
|
|
, "Up/Down History"
|
|
, "^C Interrupt execution"
|
|
, "... | repl Start a new REPL"
|
|
, "^D Exit REPL"
|
|
) | println
|
|
elif $argc == 1 then
|
|
# help(...)
|
|
( ($args[0] | _name) as $name
|
|
| _help_functions[$name] as $hf
|
|
| if $hf then
|
|
# help(name)
|
|
( "\($name): \($hf.summary)"
|
|
, $hf.doc
|
|
, if $hf.examples then
|
|
( "Examples:"
|
|
, ( $hf.examples[]
|
|
| . as $e
|
|
| if length == 1 then
|
|
( "> \($e[0])"
|
|
, (null | try (_eval($e[0]) | tojson) catch "error: \(.)")
|
|
)
|
|
else
|
|
( "> \($e[0] | tojson) | \($e[1])"
|
|
, ($e[0] | try (_eval($e[1]) | tojson) catch "error: \(.)")
|
|
)
|
|
end
|
|
)
|
|
)
|
|
end
|
|
) | println
|
|
else
|
|
# help(unknown)
|
|
# TODO: check builtin
|
|
( ( . # TODO: extract
|
|
| builtins
|
|
| map(split("/") | {key: .[0], value: true})
|
|
| from_entries
|
|
) as $builtins
|
|
| ( . # TODO: extract
|
|
| scope
|
|
| map({key: ., value: true})
|
|
| from_entries
|
|
) as $scope
|
|
| if $builtins | has($name) then
|
|
"\($name) is builtin function"
|
|
elif $scope | has($name) then
|
|
"\($name) is a function or variable"
|
|
else
|
|
"don't know what \($name) is "
|
|
end
|
|
| println
|
|
)
|
|
end
|
|
)
|
|
else
|
|
_eval_error("compile"; "help must be last in pipeline. ex: help(length) or ... | help")
|
|
end
|
|
)
|
|
else
|
|
# ... | help
|
|
# TODO: check builtin
|
|
( _repl_slurp_eval($query.rewrite) as $outputs
|
|
| "value help"
|
|
, $outputs
|
|
| display
|
|
)
|
|
end;
|