a python argcomplete inspired shell completion engine for zig argument parsers.
Traditionally, bash-completion
works by command line programs shipping their own bash code to handle
suggestions when users type the command and hit <TAB> on the keyboard.
Since these scripts are:
bashspecific- maintained separately from the binary and might not match the behaviour of it.
Zcomplete instead works like this:
- Generate a separate
.wasmversion of your program's argument parser - embed the
.wasmin a specialzcomplete.wasmELF section using a linker script - provides a generic tool called
zcompthat needs to be installed inPATHonce, along with a simplezcomplete.bashcompletion script. - when pressing
<TAB>in bash,zcompwill try to extract and instanciate thezcomplete.wasmsection with a Webassembly Runtime, then pass in the current command line and the current arg to be completed. - evaluate the response and generate bash completion
- SUCCESS!
Python's argcomplete works
by running the actual python script until the argparse instance is created,
and uses the contained info to generate the completion suggestions.
It's main shortcomings are:
- needs to run the actual python script. We cannot do that on a native binary
safely. It uses a
PYTHON_ARGCOMPLETE_OKmagic string to determine a script's eligibility for completion. - May take longer than bearable by users on each
<TAB>press, since starting python and reading all source code is slow.
This project is in a Proof-of-concept stage. It barely generates useful completion for itself.
- Offer a way for
.wasmto query filesystem files? - report back valid extensions or magic numbers from
.wasmtozcomp?
- Embedded Windows Resource files?
- MachO?
- Support
.wasmseparate from the binary? This needs a reasonably fast way of associating a binary and the.wasm. Optionally, a single.wasmcore could serve completions for multiple binaries, like andzcompletecould use the.wasmfiles like a plugin system.
at the moment we set an explicit generic target (which means only mvp
wasm features are on):
.target = b.resolveTargetQuery(.{
.cpu_arch = .wasm32,
.os_tag = .freestanding,
.abi = .none,
.cpu_model = .{
.explicit = std.Target.Cpu.Model.generic(.wasm32),
},
}),zware works always with 0.14.0, on master with only wasm32-freestanding
it fails. Maybe only mvp wasm32 should be supported, but this is the
error:
error: ValidatorCallIndirectNoTable
/home/dasimmet/.cache/zig/p/zware-0.0.1-ZA7j6X3jBABhBIltmAF9N6OP7VTsgFP3O1xPkgiaCY_t/src/module/parser.zig:384:68: 0x11c7aec in next (zcomp)
if (tableidx >= self.module.tables.list.items.len) return error.ValidatorCallIndirectNoTable;
^
/home/dasimmet/.cache/zig/p/zware-0.0.1-ZA7j6X3jBABhBIltmAF9N6OP7VTsgFP3O1xPkgiaCY_t/src/module/parser.zig:63:16: 0x11d9292 in parseFunction (zcomp)
while (try self.next()) |instr| {
^
/home/dasimmet/.cache/zig/p/zware-0.0.1-ZA7j6X3jBABhBIltmAF9N6OP7VTsgFP3O1xPkgiaCY_t/src/module.zig:798:9: 0x11d973a in readFunction (zcomp)
return parser.parseFunction(funcidx, locals, code);
^
/home/dasimmet/.cache/zig/p/zware-0.0.1-ZA7j6X3jBABhBIltmAF9N6OP7VTsgFP3O1xPkgiaCY_t/src/module.zig:686:33: 0x11d9e27 in decodeCodeSection (zcomp)
const parsed_code = try self.readFunction(module, locals, function_index_start + i);
^
/home/dasimmet/.cache/zig/p/zware-0.0.1-ZA7j6X3jBABhBIltmAF9N6OP7VTsgFP3O1xPkgiaCY_t/src/module.zig:174:22: 0x11dade0 in decodeSection (zcomp)
.Code => try self.decodeCodeSection(module),
^
/home/dasimmet/.cache/zig/p/zware-0.0.1-ZA7j6X3jBABhBIltmAF9N6OP7VTsgFP3O1xPkgiaCY_t/src/module.zig:106:25: 0x11dba05 in decode (zcomp)
else => return err,
^
/home/dasimmet/repos/zig/zcomplete/src/zcomp.zig:69:5: 0x11fc840 in complete (zcomp)
try module.decode();
^