diff --git a/.github/workflows/rust.yml b/.github/workflows/rust.yml index 8234431..35210fa 100644 --- a/.github/workflows/rust.yml +++ b/.github/workflows/rust.yml @@ -45,7 +45,8 @@ jobs: needs: test runs-on: ${{ matrix.OS }} env: - NAME: a2kit + CLI: ("a2kit") + SERVERS: ("server-applesoft" "server-integerbasic" "server-merlin") TARGET: ${{ matrix.TARGET }} OS: ${{ matrix.OS }} steps: @@ -69,19 +70,26 @@ jobs: - name: Compress run: | mkdir -p ./artifacts - # windows is the only OS using a different convention for executable file name if [[ $OS =~ ^windows.*$ ]]; then - EXEC=$NAME.exe + EXE=".exe" else - EXEC=$NAME + EXE="" fi if [[ $GITHUB_REF_TYPE =~ ^tag$ ]]; then TAG=$GITHUB_REF_NAME else TAG=$GITHUB_SHA fi - mv ./target/$TARGET/release/$EXEC ./$EXEC - tar -czf ./artifacts/$NAME-$TARGET-$TAG.tar.gz $EXEC completions + cli_list="completions" + for i in ${CLI[@]}; do + cli_list+=" ./target/$TARGET/release/${i}$EXE" + done + tar -czf ./artifacts/a2kit-$TARGET-$TAG.tar.gz $cli_list + server_list="" + for i in ${SERVERS[@]}; do + server_list+=" ./target/$TARGET/release/${i}$EXE" + done + tar -czf ./artifacts/server-$TARGET-$TAG.tar.gz $server_list - name: Archive artifact uses: actions/upload-artifact@v3 with: diff --git a/Cargo.toml b/Cargo.toml index 6efbc52..d3b844a 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -24,8 +24,8 @@ env_logger = "0.11.3" hex = "0.4.3" a2-memory-map = "1.0.4" tree-sitter = "0.22.4" -tree-sitter-applesoft = "3.2.0" -tree-sitter-integerbasic = "1.1.1" +tree-sitter-applesoft = "4.0.0" +tree-sitter-integerbasic = "2.0.0" tree-sitter-merlin6502 = "3.0.0" lsp-types = "0.95.0" lsp-server = "0.7.6" diff --git a/completions/_a2kit b/completions/_a2kit index 2577677..10b5988 100644 --- a/completions/_a2kit +++ b/completions/_a2kit @@ -14,7 +14,7 @@ _a2kit() { fi local context curcontext="$curcontext" state line - _arguments "${_arguments_options[@]}" \ + _arguments "${_arguments_options[@]}" : \ '-h[Print help (see more with '\''--help'\'')]' \ '--help[Print help (see more with '\''--help'\'')]' \ '-V[Print version]' \ @@ -29,7 +29,7 @@ _a2kit() { curcontext="${curcontext%:*:*}:a2kit-command-$line[1]:" case $line[1] in (mkdsk) -_arguments "${_arguments_options[@]}" \ +_arguments "${_arguments_options[@]}" : \ '-v+[volume name or number]:VOLUME: ' \ '--volume+[volume name or number]:VOLUME: ' \ '-t+[type of disk image to create]:TYPE:(d13 do po woz1 woz2 imd img 2mg nib td0)' \ @@ -49,7 +49,7 @@ _arguments "${_arguments_options[@]}" \ && ret=0 ;; (mkdir) -_arguments "${_arguments_options[@]}" \ +_arguments "${_arguments_options[@]}" : \ '-f+[path inside disk image of new directory]:PATH: ' \ '--file+[path inside disk image of new directory]:PATH: ' \ '-d+[path to disk image itself]:PATH:_files' \ @@ -59,7 +59,7 @@ _arguments "${_arguments_options[@]}" \ && ret=0 ;; (delete) -_arguments "${_arguments_options[@]}" \ +_arguments "${_arguments_options[@]}" : \ '-f+[path inside disk image to delete]:PATH: ' \ '--file+[path inside disk image to delete]:PATH: ' \ '-d+[path to disk image itself]:PATH:_files' \ @@ -69,7 +69,7 @@ _arguments "${_arguments_options[@]}" \ && ret=0 ;; (del) -_arguments "${_arguments_options[@]}" \ +_arguments "${_arguments_options[@]}" : \ '-f+[path inside disk image to delete]:PATH: ' \ '--file+[path inside disk image to delete]:PATH: ' \ '-d+[path to disk image itself]:PATH:_files' \ @@ -79,7 +79,27 @@ _arguments "${_arguments_options[@]}" \ && ret=0 ;; (era) -_arguments "${_arguments_options[@]}" \ +_arguments "${_arguments_options[@]}" : \ +'-f+[path inside disk image to delete]:PATH: ' \ +'--file+[path inside disk image to delete]:PATH: ' \ +'-d+[path to disk image itself]:PATH:_files' \ +'--dimg+[path to disk image itself]:PATH:_files' \ +'-h[Print help]' \ +'--help[Print help]' \ +&& ret=0 +;; +(del) +_arguments "${_arguments_options[@]}" : \ +'-f+[path inside disk image to delete]:PATH: ' \ +'--file+[path inside disk image to delete]:PATH: ' \ +'-d+[path to disk image itself]:PATH:_files' \ +'--dimg+[path to disk image itself]:PATH:_files' \ +'-h[Print help]' \ +'--help[Print help]' \ +&& ret=0 +;; +(era) +_arguments "${_arguments_options[@]}" : \ '-f+[path inside disk image to delete]:PATH: ' \ '--file+[path inside disk image to delete]:PATH: ' \ '-d+[path to disk image itself]:PATH:_files' \ @@ -89,7 +109,7 @@ _arguments "${_arguments_options[@]}" \ && ret=0 ;; (protect) -_arguments "${_arguments_options[@]}" \ +_arguments "${_arguments_options[@]}" : \ '-f+[path inside disk image to protect]:PATH: ' \ '--file+[path inside disk image to protect]:PATH: ' \ '-d+[path to disk image itself]:PATH:_files' \ @@ -104,7 +124,7 @@ _arguments "${_arguments_options[@]}" \ && ret=0 ;; (unprotect) -_arguments "${_arguments_options[@]}" \ +_arguments "${_arguments_options[@]}" : \ '-f+[path inside disk image to unprotect]:PATH: ' \ '--file+[path inside disk image to unprotect]:PATH: ' \ '-d+[path to disk image itself]:PATH:_files' \ @@ -114,7 +134,7 @@ _arguments "${_arguments_options[@]}" \ && ret=0 ;; (lock) -_arguments "${_arguments_options[@]}" \ +_arguments "${_arguments_options[@]}" : \ '-f+[path inside disk image to lock]:PATH: ' \ '--file+[path inside disk image to lock]:PATH: ' \ '-d+[path to disk image itself]:PATH:_files' \ @@ -124,7 +144,7 @@ _arguments "${_arguments_options[@]}" \ && ret=0 ;; (unlock) -_arguments "${_arguments_options[@]}" \ +_arguments "${_arguments_options[@]}" : \ '-f+[path inside disk image to unlock]:PATH: ' \ '--file+[path inside disk image to unlock]:PATH: ' \ '-d+[path to disk image itself]:PATH:_files' \ @@ -134,7 +154,7 @@ _arguments "${_arguments_options[@]}" \ && ret=0 ;; (rename) -_arguments "${_arguments_options[@]}" \ +_arguments "${_arguments_options[@]}" : \ '-f+[path inside disk image to rename]:PATH: ' \ '--file+[path inside disk image to rename]:PATH: ' \ '-n+[new name]:NAME: ' \ @@ -146,7 +166,7 @@ _arguments "${_arguments_options[@]}" \ && ret=0 ;; (retype) -_arguments "${_arguments_options[@]}" \ +_arguments "${_arguments_options[@]}" : \ '-f+[path inside disk image to retype]:PATH: ' \ '--file+[path inside disk image to retype]:PATH: ' \ '-t+[file system type, code or mnemonic]:TYPE: ' \ @@ -160,7 +180,7 @@ _arguments "${_arguments_options[@]}" \ && ret=0 ;; (verify) -_arguments "${_arguments_options[@]}" \ +_arguments "${_arguments_options[@]}" : \ '-t+[type of the file]:TYPE:(atxt itxt mtxt)' \ '--type+[type of the file]:TYPE:(atxt itxt mtxt)' \ '-c+[modify diagnostic configuration]:JSON: ' \ @@ -174,7 +194,7 @@ _arguments "${_arguments_options[@]}" \ && ret=0 ;; (minify) -_arguments "${_arguments_options[@]}" \ +_arguments "${_arguments_options[@]}" : \ '-t+[type of the file]:TYPE:(atxt)' \ '--type+[type of the file]:TYPE:(atxt)' \ '--level+[set minification level]:LEVEL:(0 1 2 3)' \ @@ -184,7 +204,7 @@ _arguments "${_arguments_options[@]}" \ && ret=0 ;; (renumber) -_arguments "${_arguments_options[@]}" \ +_arguments "${_arguments_options[@]}" : \ '-t+[type of the file]:TYPE:(atxt itxt)' \ '--type+[type of the file]:TYPE:(atxt itxt)' \ '-b+[lowest number to renumber]:NUM: ' \ @@ -202,7 +222,7 @@ _arguments "${_arguments_options[@]}" \ && ret=0 ;; (get) -_arguments "${_arguments_options[@]}" \ +_arguments "${_arguments_options[@]}" : \ '-f+[path, key, or address, maybe inside disk image]:PATH:_files' \ '--file+[path, key, or address, maybe inside disk image]:PATH:_files' \ '-t+[type of the item]:TYPE:(any auto bin txt raw rec atok itok mtok block sec track raw_track meta)' \ @@ -217,7 +237,7 @@ _arguments "${_arguments_options[@]}" \ && ret=0 ;; (put) -_arguments "${_arguments_options[@]}" \ +_arguments "${_arguments_options[@]}" : \ '-f+[path, key, or address, maybe inside disk image]:PATH:_files' \ '--file+[path, key, or address, maybe inside disk image]:PATH:_files' \ '-t+[type of the item]:TYPE:(any auto bin txt raw rec atok itok mtok block sec track raw_track meta)' \ @@ -231,7 +251,7 @@ _arguments "${_arguments_options[@]}" \ && ret=0 ;; (catalog) -_arguments "${_arguments_options[@]}" \ +_arguments "${_arguments_options[@]}" : \ '-f+[path of directory inside disk image]:PATH: ' \ '--file+[path of directory inside disk image]:PATH: ' \ '-d+[path to disk image]:PATH:_files' \ @@ -242,7 +262,7 @@ _arguments "${_arguments_options[@]}" \ && ret=0 ;; (ls) -_arguments "${_arguments_options[@]}" \ +_arguments "${_arguments_options[@]}" : \ '-f+[path of directory inside disk image]:PATH: ' \ '--file+[path of directory inside disk image]:PATH: ' \ '-d+[path to disk image]:PATH:_files' \ @@ -253,7 +273,7 @@ _arguments "${_arguments_options[@]}" \ && ret=0 ;; (dir) -_arguments "${_arguments_options[@]}" \ +_arguments "${_arguments_options[@]}" : \ '-f+[path of directory inside disk image]:PATH: ' \ '--file+[path of directory inside disk image]:PATH: ' \ '-d+[path to disk image]:PATH:_files' \ @@ -264,7 +284,40 @@ _arguments "${_arguments_options[@]}" \ && ret=0 ;; (cat) -_arguments "${_arguments_options[@]}" \ +_arguments "${_arguments_options[@]}" : \ +'-f+[path of directory inside disk image]:PATH: ' \ +'--file+[path of directory inside disk image]:PATH: ' \ +'-d+[path to disk image]:PATH:_files' \ +'--dimg+[path to disk image]:PATH:_files' \ +'--generic[use generic output format]' \ +'-h[Print help]' \ +'--help[Print help]' \ +&& ret=0 +;; +(cat) +_arguments "${_arguments_options[@]}" : \ +'-f+[path of directory inside disk image]:PATH: ' \ +'--file+[path of directory inside disk image]:PATH: ' \ +'-d+[path to disk image]:PATH:_files' \ +'--dimg+[path to disk image]:PATH:_files' \ +'--generic[use generic output format]' \ +'-h[Print help]' \ +'--help[Print help]' \ +&& ret=0 +;; +(dir) +_arguments "${_arguments_options[@]}" : \ +'-f+[path of directory inside disk image]:PATH: ' \ +'--file+[path of directory inside disk image]:PATH: ' \ +'-d+[path to disk image]:PATH:_files' \ +'--dimg+[path to disk image]:PATH:_files' \ +'--generic[use generic output format]' \ +'-h[Print help]' \ +'--help[Print help]' \ +&& ret=0 +;; +(ls) +_arguments "${_arguments_options[@]}" : \ '-f+[path of directory inside disk image]:PATH: ' \ '--file+[path of directory inside disk image]:PATH: ' \ '-d+[path to disk image]:PATH:_files' \ @@ -275,7 +328,7 @@ _arguments "${_arguments_options[@]}" \ && ret=0 ;; (tree) -_arguments "${_arguments_options[@]}" \ +_arguments "${_arguments_options[@]}" : \ '-d+[path to disk image]:PATH:_files' \ '--dimg+[path to disk image]:PATH:_files' \ '--meta[include metadata]' \ @@ -284,7 +337,7 @@ _arguments "${_arguments_options[@]}" \ && ret=0 ;; (stat) -_arguments "${_arguments_options[@]}" \ +_arguments "${_arguments_options[@]}" : \ '-d+[path to disk image]:PATH:_files' \ '--dimg+[path to disk image]:PATH:_files' \ '-h[Print help]' \ @@ -292,7 +345,7 @@ _arguments "${_arguments_options[@]}" \ && ret=0 ;; (geometry) -_arguments "${_arguments_options[@]}" \ +_arguments "${_arguments_options[@]}" : \ '-d+[path to disk image]:PATH:_files' \ '--dimg+[path to disk image]:PATH:_files' \ '-h[Print help]' \ @@ -300,7 +353,17 @@ _arguments "${_arguments_options[@]}" \ && ret=0 ;; (tokenize) -_arguments "${_arguments_options[@]}" \ +_arguments "${_arguments_options[@]}" : \ +'-a+[address of tokenized code (Applesoft only)]:ADDRESS: ' \ +'--addr+[address of tokenized code (Applesoft only)]:ADDRESS: ' \ +'-t+[type of the file]:TYPE:(atxt itxt mtxt)' \ +'--type+[type of the file]:TYPE:(atxt itxt mtxt)' \ +'-h[Print help]' \ +'--help[Print help]' \ +&& ret=0 +;; +(tok) +_arguments "${_arguments_options[@]}" : \ '-a+[address of tokenized code (Applesoft only)]:ADDRESS: ' \ '--addr+[address of tokenized code (Applesoft only)]:ADDRESS: ' \ '-t+[type of the file]:TYPE:(atxt itxt mtxt)' \ @@ -310,7 +373,7 @@ _arguments "${_arguments_options[@]}" \ && ret=0 ;; (tok) -_arguments "${_arguments_options[@]}" \ +_arguments "${_arguments_options[@]}" : \ '-a+[address of tokenized code (Applesoft only)]:ADDRESS: ' \ '--addr+[address of tokenized code (Applesoft only)]:ADDRESS: ' \ '-t+[type of the file]:TYPE:(atxt itxt mtxt)' \ @@ -320,7 +383,7 @@ _arguments "${_arguments_options[@]}" \ && ret=0 ;; (detokenize) -_arguments "${_arguments_options[@]}" \ +_arguments "${_arguments_options[@]}" : \ '-t+[type of the file]:TYPE:(atok itok mtok)' \ '--type+[type of the file]:TYPE:(atok itok mtok)' \ '-h[Print help]' \ @@ -328,15 +391,44 @@ _arguments "${_arguments_options[@]}" \ && ret=0 ;; (dtok) -_arguments "${_arguments_options[@]}" \ +_arguments "${_arguments_options[@]}" : \ '-t+[type of the file]:TYPE:(atok itok mtok)' \ '--type+[type of the file]:TYPE:(atok itok mtok)' \ '-h[Print help]' \ '--help[Print help]' \ && ret=0 ;; +(dtok) +_arguments "${_arguments_options[@]}" : \ +'-t+[type of the file]:TYPE:(atok itok mtok)' \ +'--type+[type of the file]:TYPE:(atok itok mtok)' \ +'-h[Print help]' \ +'--help[Print help]' \ +&& ret=0 +;; +(asm) +_arguments "${_arguments_options[@]}" : \ +'-a+[assembler variant]:NAME:(m8 m16 m16+ m32)' \ +'--assembler+[assembler variant]:NAME:(m8 m16 m16+ m32)' \ +'-w+[workspace directory]:PATH: ' \ +'--workspace+[workspace directory]:PATH: ' \ +'-h[Print help]' \ +'--help[Print help]' \ +&& ret=0 +;; +(dasm) +_arguments "${_arguments_options[@]}" : \ +'-p+[processor target]:NAME:(6502 65c02 65802 65816)' \ +'--proc+[processor target]:NAME:(6502 65c02 65802 65816)' \ +'--mx+[MX status bits]:BINARY:(00 01 10 11)' \ +'-o+[starting address]:ADDRESS: ' \ +'--org+[starting address]:ADDRESS: ' \ +'-h[Print help]' \ +'--help[Print help]' \ +&& ret=0 +;; (help) -_arguments "${_arguments_options[@]}" \ +_arguments "${_arguments_options[@]}" : \ ":: :_a2kit__help_commands" \ "*::: :->help" \ && ret=0 @@ -348,115 +440,123 @@ _arguments "${_arguments_options[@]}" \ curcontext="${curcontext%:*:*}:a2kit-help-command-$line[1]:" case $line[1] in (mkdsk) -_arguments "${_arguments_options[@]}" \ +_arguments "${_arguments_options[@]}" : \ && ret=0 ;; (mkdir) -_arguments "${_arguments_options[@]}" \ +_arguments "${_arguments_options[@]}" : \ && ret=0 ;; (delete) -_arguments "${_arguments_options[@]}" \ +_arguments "${_arguments_options[@]}" : \ && ret=0 ;; (del) -_arguments "${_arguments_options[@]}" \ +_arguments "${_arguments_options[@]}" : \ && ret=0 ;; (era) -_arguments "${_arguments_options[@]}" \ +_arguments "${_arguments_options[@]}" : \ && ret=0 ;; (protect) -_arguments "${_arguments_options[@]}" \ +_arguments "${_arguments_options[@]}" : \ && ret=0 ;; (unprotect) -_arguments "${_arguments_options[@]}" \ +_arguments "${_arguments_options[@]}" : \ && ret=0 ;; (lock) -_arguments "${_arguments_options[@]}" \ +_arguments "${_arguments_options[@]}" : \ && ret=0 ;; (unlock) -_arguments "${_arguments_options[@]}" \ +_arguments "${_arguments_options[@]}" : \ && ret=0 ;; (rename) -_arguments "${_arguments_options[@]}" \ +_arguments "${_arguments_options[@]}" : \ && ret=0 ;; (retype) -_arguments "${_arguments_options[@]}" \ +_arguments "${_arguments_options[@]}" : \ && ret=0 ;; (verify) -_arguments "${_arguments_options[@]}" \ +_arguments "${_arguments_options[@]}" : \ && ret=0 ;; (minify) -_arguments "${_arguments_options[@]}" \ +_arguments "${_arguments_options[@]}" : \ && ret=0 ;; (renumber) -_arguments "${_arguments_options[@]}" \ +_arguments "${_arguments_options[@]}" : \ && ret=0 ;; (get) -_arguments "${_arguments_options[@]}" \ +_arguments "${_arguments_options[@]}" : \ && ret=0 ;; (put) -_arguments "${_arguments_options[@]}" \ +_arguments "${_arguments_options[@]}" : \ && ret=0 ;; (catalog) -_arguments "${_arguments_options[@]}" \ +_arguments "${_arguments_options[@]}" : \ && ret=0 ;; (ls) -_arguments "${_arguments_options[@]}" \ +_arguments "${_arguments_options[@]}" : \ && ret=0 ;; (dir) -_arguments "${_arguments_options[@]}" \ +_arguments "${_arguments_options[@]}" : \ && ret=0 ;; (cat) -_arguments "${_arguments_options[@]}" \ +_arguments "${_arguments_options[@]}" : \ && ret=0 ;; (tree) -_arguments "${_arguments_options[@]}" \ +_arguments "${_arguments_options[@]}" : \ && ret=0 ;; (stat) -_arguments "${_arguments_options[@]}" \ +_arguments "${_arguments_options[@]}" : \ && ret=0 ;; (geometry) -_arguments "${_arguments_options[@]}" \ +_arguments "${_arguments_options[@]}" : \ && ret=0 ;; (tokenize) -_arguments "${_arguments_options[@]}" \ +_arguments "${_arguments_options[@]}" : \ && ret=0 ;; (tok) -_arguments "${_arguments_options[@]}" \ +_arguments "${_arguments_options[@]}" : \ && ret=0 ;; (detokenize) -_arguments "${_arguments_options[@]}" \ +_arguments "${_arguments_options[@]}" : \ && ret=0 ;; (dtok) -_arguments "${_arguments_options[@]}" \ +_arguments "${_arguments_options[@]}" : \ +&& ret=0 +;; +(asm) +_arguments "${_arguments_options[@]}" : \ +&& ret=0 +;; +(dasm) +_arguments "${_arguments_options[@]}" : \ && ret=0 ;; (help) -_arguments "${_arguments_options[@]}" \ +_arguments "${_arguments_options[@]}" : \ && ret=0 ;; esac @@ -498,60 +598,47 @@ _a2kit_commands() { 'tok:read from stdin, tokenize, write to stdout' \ 'detokenize:read from stdin, detokenize, write to stdout' \ 'dtok:read from stdin, detokenize, write to stdout' \ +'asm:read from stdin, assemble, write to stdout' \ +'dasm:read from stdin, disassemble, write to stdout' \ 'help:Print this message or the help of the given subcommand(s)' \ ) _describe -t commands 'a2kit commands' commands "$@" } +(( $+functions[_a2kit__asm_commands] )) || +_a2kit__asm_commands() { + local commands; commands=() + _describe -t commands 'a2kit asm commands' commands "$@" +} (( $+functions[_a2kit__catalog_commands] )) || _a2kit__catalog_commands() { local commands; commands=() _describe -t commands 'a2kit catalog commands' commands "$@" } -(( $+functions[_a2kit__help__catalog_commands] )) || -_a2kit__help__catalog_commands() { +(( $+functions[_a2kit__dasm_commands] )) || +_a2kit__dasm_commands() { local commands; commands=() - _describe -t commands 'a2kit help catalog commands' commands "$@" + _describe -t commands 'a2kit dasm commands' commands "$@" } (( $+functions[_a2kit__delete_commands] )) || _a2kit__delete_commands() { local commands; commands=() _describe -t commands 'a2kit delete commands' commands "$@" } -(( $+functions[_a2kit__help__delete_commands] )) || -_a2kit__help__delete_commands() { - local commands; commands=() - _describe -t commands 'a2kit help delete commands' commands "$@" -} (( $+functions[_a2kit__detokenize_commands] )) || _a2kit__detokenize_commands() { local commands; commands=() _describe -t commands 'a2kit detokenize commands' commands "$@" } -(( $+functions[_a2kit__help__detokenize_commands] )) || -_a2kit__help__detokenize_commands() { - local commands; commands=() - _describe -t commands 'a2kit help detokenize commands' commands "$@" -} (( $+functions[_a2kit__geometry_commands] )) || _a2kit__geometry_commands() { local commands; commands=() _describe -t commands 'a2kit geometry commands' commands "$@" } -(( $+functions[_a2kit__help__geometry_commands] )) || -_a2kit__help__geometry_commands() { - local commands; commands=() - _describe -t commands 'a2kit help geometry commands' commands "$@" -} (( $+functions[_a2kit__get_commands] )) || _a2kit__get_commands() { local commands; commands=() _describe -t commands 'a2kit get commands' commands "$@" } -(( $+functions[_a2kit__help__get_commands] )) || -_a2kit__help__get_commands() { - local commands; commands=() - _describe -t commands 'a2kit help get commands' commands "$@" -} (( $+functions[_a2kit__help_commands] )) || _a2kit__help_commands() { local commands; commands=( @@ -575,10 +662,47 @@ _a2kit__help_commands() { 'geometry:write disk geometry as a JSON string to stdout' \ 'tokenize:read from stdin, tokenize, write to stdout' \ 'detokenize:read from stdin, detokenize, write to stdout' \ +'asm:read from stdin, assemble, write to stdout' \ +'dasm:read from stdin, disassemble, write to stdout' \ 'help:Print this message or the help of the given subcommand(s)' \ ) _describe -t commands 'a2kit help commands' commands "$@" } +(( $+functions[_a2kit__help__asm_commands] )) || +_a2kit__help__asm_commands() { + local commands; commands=() + _describe -t commands 'a2kit help asm commands' commands "$@" +} +(( $+functions[_a2kit__help__catalog_commands] )) || +_a2kit__help__catalog_commands() { + local commands; commands=() + _describe -t commands 'a2kit help catalog commands' commands "$@" +} +(( $+functions[_a2kit__help__dasm_commands] )) || +_a2kit__help__dasm_commands() { + local commands; commands=() + _describe -t commands 'a2kit help dasm commands' commands "$@" +} +(( $+functions[_a2kit__help__delete_commands] )) || +_a2kit__help__delete_commands() { + local commands; commands=() + _describe -t commands 'a2kit help delete commands' commands "$@" +} +(( $+functions[_a2kit__help__detokenize_commands] )) || +_a2kit__help__detokenize_commands() { + local commands; commands=() + _describe -t commands 'a2kit help detokenize commands' commands "$@" +} +(( $+functions[_a2kit__help__geometry_commands] )) || +_a2kit__help__geometry_commands() { + local commands; commands=() + _describe -t commands 'a2kit help geometry commands' commands "$@" +} +(( $+functions[_a2kit__help__get_commands] )) || +_a2kit__help__get_commands() { + local commands; commands=() + _describe -t commands 'a2kit help get commands' commands "$@" +} (( $+functions[_a2kit__help__help_commands] )) || _a2kit__help__help_commands() { local commands; commands=() @@ -589,146 +713,146 @@ _a2kit__help__lock_commands() { local commands; commands=() _describe -t commands 'a2kit help lock commands' commands "$@" } -(( $+functions[_a2kit__lock_commands] )) || -_a2kit__lock_commands() { - local commands; commands=() - _describe -t commands 'a2kit lock commands' commands "$@" -} (( $+functions[_a2kit__help__minify_commands] )) || _a2kit__help__minify_commands() { local commands; commands=() _describe -t commands 'a2kit help minify commands' commands "$@" } -(( $+functions[_a2kit__minify_commands] )) || -_a2kit__minify_commands() { - local commands; commands=() - _describe -t commands 'a2kit minify commands' commands "$@" -} (( $+functions[_a2kit__help__mkdir_commands] )) || _a2kit__help__mkdir_commands() { local commands; commands=() _describe -t commands 'a2kit help mkdir commands' commands "$@" } -(( $+functions[_a2kit__mkdir_commands] )) || -_a2kit__mkdir_commands() { - local commands; commands=() - _describe -t commands 'a2kit mkdir commands' commands "$@" -} (( $+functions[_a2kit__help__mkdsk_commands] )) || _a2kit__help__mkdsk_commands() { local commands; commands=() _describe -t commands 'a2kit help mkdsk commands' commands "$@" } -(( $+functions[_a2kit__mkdsk_commands] )) || -_a2kit__mkdsk_commands() { - local commands; commands=() - _describe -t commands 'a2kit mkdsk commands' commands "$@" -} (( $+functions[_a2kit__help__protect_commands] )) || _a2kit__help__protect_commands() { local commands; commands=() _describe -t commands 'a2kit help protect commands' commands "$@" } -(( $+functions[_a2kit__protect_commands] )) || -_a2kit__protect_commands() { - local commands; commands=() - _describe -t commands 'a2kit protect commands' commands "$@" -} (( $+functions[_a2kit__help__put_commands] )) || _a2kit__help__put_commands() { local commands; commands=() _describe -t commands 'a2kit help put commands' commands "$@" } -(( $+functions[_a2kit__put_commands] )) || -_a2kit__put_commands() { - local commands; commands=() - _describe -t commands 'a2kit put commands' commands "$@" -} (( $+functions[_a2kit__help__rename_commands] )) || _a2kit__help__rename_commands() { local commands; commands=() _describe -t commands 'a2kit help rename commands' commands "$@" } -(( $+functions[_a2kit__rename_commands] )) || -_a2kit__rename_commands() { - local commands; commands=() - _describe -t commands 'a2kit rename commands' commands "$@" -} (( $+functions[_a2kit__help__renumber_commands] )) || _a2kit__help__renumber_commands() { local commands; commands=() _describe -t commands 'a2kit help renumber commands' commands "$@" } -(( $+functions[_a2kit__renumber_commands] )) || -_a2kit__renumber_commands() { - local commands; commands=() - _describe -t commands 'a2kit renumber commands' commands "$@" -} (( $+functions[_a2kit__help__retype_commands] )) || _a2kit__help__retype_commands() { local commands; commands=() _describe -t commands 'a2kit help retype commands' commands "$@" } -(( $+functions[_a2kit__retype_commands] )) || -_a2kit__retype_commands() { - local commands; commands=() - _describe -t commands 'a2kit retype commands' commands "$@" -} (( $+functions[_a2kit__help__stat_commands] )) || _a2kit__help__stat_commands() { local commands; commands=() _describe -t commands 'a2kit help stat commands' commands "$@" } -(( $+functions[_a2kit__stat_commands] )) || -_a2kit__stat_commands() { - local commands; commands=() - _describe -t commands 'a2kit stat commands' commands "$@" -} (( $+functions[_a2kit__help__tokenize_commands] )) || _a2kit__help__tokenize_commands() { local commands; commands=() _describe -t commands 'a2kit help tokenize commands' commands "$@" } -(( $+functions[_a2kit__tokenize_commands] )) || -_a2kit__tokenize_commands() { - local commands; commands=() - _describe -t commands 'a2kit tokenize commands' commands "$@" -} (( $+functions[_a2kit__help__tree_commands] )) || _a2kit__help__tree_commands() { local commands; commands=() _describe -t commands 'a2kit help tree commands' commands "$@" } -(( $+functions[_a2kit__tree_commands] )) || -_a2kit__tree_commands() { - local commands; commands=() - _describe -t commands 'a2kit tree commands' commands "$@" -} (( $+functions[_a2kit__help__unlock_commands] )) || _a2kit__help__unlock_commands() { local commands; commands=() _describe -t commands 'a2kit help unlock commands' commands "$@" } -(( $+functions[_a2kit__unlock_commands] )) || -_a2kit__unlock_commands() { - local commands; commands=() - _describe -t commands 'a2kit unlock commands' commands "$@" -} (( $+functions[_a2kit__help__unprotect_commands] )) || _a2kit__help__unprotect_commands() { local commands; commands=() _describe -t commands 'a2kit help unprotect commands' commands "$@" } -(( $+functions[_a2kit__unprotect_commands] )) || -_a2kit__unprotect_commands() { - local commands; commands=() - _describe -t commands 'a2kit unprotect commands' commands "$@" -} (( $+functions[_a2kit__help__verify_commands] )) || _a2kit__help__verify_commands() { local commands; commands=() _describe -t commands 'a2kit help verify commands' commands "$@" } +(( $+functions[_a2kit__lock_commands] )) || +_a2kit__lock_commands() { + local commands; commands=() + _describe -t commands 'a2kit lock commands' commands "$@" +} +(( $+functions[_a2kit__minify_commands] )) || +_a2kit__minify_commands() { + local commands; commands=() + _describe -t commands 'a2kit minify commands' commands "$@" +} +(( $+functions[_a2kit__mkdir_commands] )) || +_a2kit__mkdir_commands() { + local commands; commands=() + _describe -t commands 'a2kit mkdir commands' commands "$@" +} +(( $+functions[_a2kit__mkdsk_commands] )) || +_a2kit__mkdsk_commands() { + local commands; commands=() + _describe -t commands 'a2kit mkdsk commands' commands "$@" +} +(( $+functions[_a2kit__protect_commands] )) || +_a2kit__protect_commands() { + local commands; commands=() + _describe -t commands 'a2kit protect commands' commands "$@" +} +(( $+functions[_a2kit__put_commands] )) || +_a2kit__put_commands() { + local commands; commands=() + _describe -t commands 'a2kit put commands' commands "$@" +} +(( $+functions[_a2kit__rename_commands] )) || +_a2kit__rename_commands() { + local commands; commands=() + _describe -t commands 'a2kit rename commands' commands "$@" +} +(( $+functions[_a2kit__renumber_commands] )) || +_a2kit__renumber_commands() { + local commands; commands=() + _describe -t commands 'a2kit renumber commands' commands "$@" +} +(( $+functions[_a2kit__retype_commands] )) || +_a2kit__retype_commands() { + local commands; commands=() + _describe -t commands 'a2kit retype commands' commands "$@" +} +(( $+functions[_a2kit__stat_commands] )) || +_a2kit__stat_commands() { + local commands; commands=() + _describe -t commands 'a2kit stat commands' commands "$@" +} +(( $+functions[_a2kit__tokenize_commands] )) || +_a2kit__tokenize_commands() { + local commands; commands=() + _describe -t commands 'a2kit tokenize commands' commands "$@" +} +(( $+functions[_a2kit__tree_commands] )) || +_a2kit__tree_commands() { + local commands; commands=() + _describe -t commands 'a2kit tree commands' commands "$@" +} +(( $+functions[_a2kit__unlock_commands] )) || +_a2kit__unlock_commands() { + local commands; commands=() + _describe -t commands 'a2kit unlock commands' commands "$@" +} +(( $+functions[_a2kit__unprotect_commands] )) || +_a2kit__unprotect_commands() { + local commands; commands=() + _describe -t commands 'a2kit unprotect commands' commands "$@" +} (( $+functions[_a2kit__verify_commands] )) || _a2kit__verify_commands() { local commands; commands=() diff --git a/completions/_a2kit.ps1 b/completions/_a2kit.ps1 index 58773e4..a4155a9 100644 --- a/completions/_a2kit.ps1 +++ b/completions/_a2kit.ps1 @@ -28,6 +28,8 @@ Register-ArgumentCompleter -Native -CommandName 'a2kit' -ScriptBlock { [CompletionResult]::new('mkdsk', 'mkdsk', [CompletionResultType]::ParameterValue, 'write a blank disk image to the given path') [CompletionResult]::new('mkdir', 'mkdir', [CompletionResultType]::ParameterValue, 'create a new directory inside a disk image') [CompletionResult]::new('delete', 'delete', [CompletionResultType]::ParameterValue, 'delete a file or directory inside a disk image') + [CompletionResult]::new('del', 'del', [CompletionResultType]::ParameterValue, 'delete a file or directory inside a disk image') + [CompletionResult]::new('era', 'era', [CompletionResultType]::ParameterValue, 'delete a file or directory inside a disk image') [CompletionResult]::new('protect', 'protect', [CompletionResultType]::ParameterValue, 'password protect a disk or file') [CompletionResult]::new('unprotect', 'unprotect', [CompletionResultType]::ParameterValue, 'remove password protection from a disk or file') [CompletionResult]::new('lock', 'lock', [CompletionResultType]::ParameterValue, 'write protect a file or directory inside a disk image') @@ -40,11 +42,18 @@ Register-ArgumentCompleter -Native -CommandName 'a2kit' -ScriptBlock { [CompletionResult]::new('get', 'get', [CompletionResultType]::ParameterValue, 'read from stdin, local, or disk image, write to stdout') [CompletionResult]::new('put', 'put', [CompletionResultType]::ParameterValue, 'read from stdin, write to local or disk image') [CompletionResult]::new('catalog', 'catalog', [CompletionResultType]::ParameterValue, 'write disk image catalog to stdout') + [CompletionResult]::new('cat', 'cat', [CompletionResultType]::ParameterValue, 'write disk image catalog to stdout') + [CompletionResult]::new('dir', 'dir', [CompletionResultType]::ParameterValue, 'write disk image catalog to stdout') + [CompletionResult]::new('ls', 'ls', [CompletionResultType]::ParameterValue, 'write disk image catalog to stdout') [CompletionResult]::new('tree', 'tree', [CompletionResultType]::ParameterValue, 'write directory tree as a JSON string to stdout') [CompletionResult]::new('stat', 'stat', [CompletionResultType]::ParameterValue, 'write FS statistics as a JSON string to stdout') [CompletionResult]::new('geometry', 'geometry', [CompletionResultType]::ParameterValue, 'write disk geometry as a JSON string to stdout') [CompletionResult]::new('tokenize', 'tokenize', [CompletionResultType]::ParameterValue, 'read from stdin, tokenize, write to stdout') + [CompletionResult]::new('tok', 'tok', [CompletionResultType]::ParameterValue, 'read from stdin, tokenize, write to stdout') [CompletionResult]::new('detokenize', 'detokenize', [CompletionResultType]::ParameterValue, 'read from stdin, detokenize, write to stdout') + [CompletionResult]::new('dtok', 'dtok', [CompletionResultType]::ParameterValue, 'read from stdin, detokenize, write to stdout') + [CompletionResult]::new('asm', 'asm', [CompletionResultType]::ParameterValue, 'read from stdin, assemble, write to stdout') + [CompletionResult]::new('dasm', 'dasm', [CompletionResultType]::ParameterValue, 'read from stdin, disassemble, write to stdout') [CompletionResult]::new('help', 'help', [CompletionResultType]::ParameterValue, 'Print this message or the help of the given subcommand(s)') break } @@ -85,6 +94,24 @@ Register-ArgumentCompleter -Native -CommandName 'a2kit' -ScriptBlock { [CompletionResult]::new('--help', 'help', [CompletionResultType]::ParameterName, 'Print help') break } + 'a2kit;del' { + [CompletionResult]::new('-f', 'f', [CompletionResultType]::ParameterName, 'path inside disk image to delete') + [CompletionResult]::new('--file', 'file', [CompletionResultType]::ParameterName, 'path inside disk image to delete') + [CompletionResult]::new('-d', 'd', [CompletionResultType]::ParameterName, 'path to disk image itself') + [CompletionResult]::new('--dimg', 'dimg', [CompletionResultType]::ParameterName, 'path to disk image itself') + [CompletionResult]::new('-h', 'h', [CompletionResultType]::ParameterName, 'Print help') + [CompletionResult]::new('--help', 'help', [CompletionResultType]::ParameterName, 'Print help') + break + } + 'a2kit;era' { + [CompletionResult]::new('-f', 'f', [CompletionResultType]::ParameterName, 'path inside disk image to delete') + [CompletionResult]::new('--file', 'file', [CompletionResultType]::ParameterName, 'path inside disk image to delete') + [CompletionResult]::new('-d', 'd', [CompletionResultType]::ParameterName, 'path to disk image itself') + [CompletionResult]::new('--dimg', 'dimg', [CompletionResultType]::ParameterName, 'path to disk image itself') + [CompletionResult]::new('-h', 'h', [CompletionResultType]::ParameterName, 'Print help') + [CompletionResult]::new('--help', 'help', [CompletionResultType]::ParameterName, 'Print help') + break + } 'a2kit;protect' { [CompletionResult]::new('-f', 'f', [CompletionResultType]::ParameterName, 'path inside disk image to protect') [CompletionResult]::new('--file', 'file', [CompletionResultType]::ParameterName, 'path inside disk image to protect') @@ -226,6 +253,36 @@ Register-ArgumentCompleter -Native -CommandName 'a2kit' -ScriptBlock { [CompletionResult]::new('--help', 'help', [CompletionResultType]::ParameterName, 'Print help') break } + 'a2kit;cat' { + [CompletionResult]::new('-f', 'f', [CompletionResultType]::ParameterName, 'path of directory inside disk image') + [CompletionResult]::new('--file', 'file', [CompletionResultType]::ParameterName, 'path of directory inside disk image') + [CompletionResult]::new('-d', 'd', [CompletionResultType]::ParameterName, 'path to disk image') + [CompletionResult]::new('--dimg', 'dimg', [CompletionResultType]::ParameterName, 'path to disk image') + [CompletionResult]::new('--generic', 'generic', [CompletionResultType]::ParameterName, 'use generic output format') + [CompletionResult]::new('-h', 'h', [CompletionResultType]::ParameterName, 'Print help') + [CompletionResult]::new('--help', 'help', [CompletionResultType]::ParameterName, 'Print help') + break + } + 'a2kit;dir' { + [CompletionResult]::new('-f', 'f', [CompletionResultType]::ParameterName, 'path of directory inside disk image') + [CompletionResult]::new('--file', 'file', [CompletionResultType]::ParameterName, 'path of directory inside disk image') + [CompletionResult]::new('-d', 'd', [CompletionResultType]::ParameterName, 'path to disk image') + [CompletionResult]::new('--dimg', 'dimg', [CompletionResultType]::ParameterName, 'path to disk image') + [CompletionResult]::new('--generic', 'generic', [CompletionResultType]::ParameterName, 'use generic output format') + [CompletionResult]::new('-h', 'h', [CompletionResultType]::ParameterName, 'Print help') + [CompletionResult]::new('--help', 'help', [CompletionResultType]::ParameterName, 'Print help') + break + } + 'a2kit;ls' { + [CompletionResult]::new('-f', 'f', [CompletionResultType]::ParameterName, 'path of directory inside disk image') + [CompletionResult]::new('--file', 'file', [CompletionResultType]::ParameterName, 'path of directory inside disk image') + [CompletionResult]::new('-d', 'd', [CompletionResultType]::ParameterName, 'path to disk image') + [CompletionResult]::new('--dimg', 'dimg', [CompletionResultType]::ParameterName, 'path to disk image') + [CompletionResult]::new('--generic', 'generic', [CompletionResultType]::ParameterName, 'use generic output format') + [CompletionResult]::new('-h', 'h', [CompletionResultType]::ParameterName, 'Print help') + [CompletionResult]::new('--help', 'help', [CompletionResultType]::ParameterName, 'Print help') + break + } 'a2kit;tree' { [CompletionResult]::new('-d', 'd', [CompletionResultType]::ParameterName, 'path to disk image') [CompletionResult]::new('--dimg', 'dimg', [CompletionResultType]::ParameterName, 'path to disk image') @@ -257,6 +314,15 @@ Register-ArgumentCompleter -Native -CommandName 'a2kit' -ScriptBlock { [CompletionResult]::new('--help', 'help', [CompletionResultType]::ParameterName, 'Print help') break } + 'a2kit;tok' { + [CompletionResult]::new('-a', 'a', [CompletionResultType]::ParameterName, 'address of tokenized code (Applesoft only)') + [CompletionResult]::new('--addr', 'addr', [CompletionResultType]::ParameterName, 'address of tokenized code (Applesoft only)') + [CompletionResult]::new('-t', 't', [CompletionResultType]::ParameterName, 'type of the file') + [CompletionResult]::new('--type', 'type', [CompletionResultType]::ParameterName, 'type of the file') + [CompletionResult]::new('-h', 'h', [CompletionResultType]::ParameterName, 'Print help') + [CompletionResult]::new('--help', 'help', [CompletionResultType]::ParameterName, 'Print help') + break + } 'a2kit;detokenize' { [CompletionResult]::new('-t', 't', [CompletionResultType]::ParameterName, 'type of the file') [CompletionResult]::new('--type', 'type', [CompletionResultType]::ParameterName, 'type of the file') @@ -264,6 +330,32 @@ Register-ArgumentCompleter -Native -CommandName 'a2kit' -ScriptBlock { [CompletionResult]::new('--help', 'help', [CompletionResultType]::ParameterName, 'Print help') break } + 'a2kit;dtok' { + [CompletionResult]::new('-t', 't', [CompletionResultType]::ParameterName, 'type of the file') + [CompletionResult]::new('--type', 'type', [CompletionResultType]::ParameterName, 'type of the file') + [CompletionResult]::new('-h', 'h', [CompletionResultType]::ParameterName, 'Print help') + [CompletionResult]::new('--help', 'help', [CompletionResultType]::ParameterName, 'Print help') + break + } + 'a2kit;asm' { + [CompletionResult]::new('-a', 'a', [CompletionResultType]::ParameterName, 'assembler variant') + [CompletionResult]::new('--assembler', 'assembler', [CompletionResultType]::ParameterName, 'assembler variant') + [CompletionResult]::new('-w', 'w', [CompletionResultType]::ParameterName, 'workspace directory') + [CompletionResult]::new('--workspace', 'workspace', [CompletionResultType]::ParameterName, 'workspace directory') + [CompletionResult]::new('-h', 'h', [CompletionResultType]::ParameterName, 'Print help') + [CompletionResult]::new('--help', 'help', [CompletionResultType]::ParameterName, 'Print help') + break + } + 'a2kit;dasm' { + [CompletionResult]::new('-p', 'p', [CompletionResultType]::ParameterName, 'processor target') + [CompletionResult]::new('--proc', 'proc', [CompletionResultType]::ParameterName, 'processor target') + [CompletionResult]::new('--mx', 'mx', [CompletionResultType]::ParameterName, 'MX status bits') + [CompletionResult]::new('-o', 'o', [CompletionResultType]::ParameterName, 'starting address') + [CompletionResult]::new('--org', 'org', [CompletionResultType]::ParameterName, 'starting address') + [CompletionResult]::new('-h', 'h', [CompletionResultType]::ParameterName, 'Print help') + [CompletionResult]::new('--help', 'help', [CompletionResultType]::ParameterName, 'Print help') + break + } 'a2kit;help' { [CompletionResult]::new('mkdsk', 'mkdsk', [CompletionResultType]::ParameterValue, 'write a blank disk image to the given path') [CompletionResult]::new('mkdir', 'mkdir', [CompletionResultType]::ParameterValue, 'create a new directory inside a disk image') @@ -285,6 +377,8 @@ Register-ArgumentCompleter -Native -CommandName 'a2kit' -ScriptBlock { [CompletionResult]::new('geometry', 'geometry', [CompletionResultType]::ParameterValue, 'write disk geometry as a JSON string to stdout') [CompletionResult]::new('tokenize', 'tokenize', [CompletionResultType]::ParameterValue, 'read from stdin, tokenize, write to stdout') [CompletionResult]::new('detokenize', 'detokenize', [CompletionResultType]::ParameterValue, 'read from stdin, detokenize, write to stdout') + [CompletionResult]::new('asm', 'asm', [CompletionResultType]::ParameterValue, 'read from stdin, assemble, write to stdout') + [CompletionResult]::new('dasm', 'dasm', [CompletionResultType]::ParameterValue, 'read from stdin, disassemble, write to stdout') [CompletionResult]::new('help', 'help', [CompletionResultType]::ParameterValue, 'Print this message or the help of the given subcommand(s)') break } @@ -348,6 +442,12 @@ Register-ArgumentCompleter -Native -CommandName 'a2kit' -ScriptBlock { 'a2kit;help;detokenize' { break } + 'a2kit;help;asm' { + break + } + 'a2kit;help;dasm' { + break + } 'a2kit;help;help' { break } diff --git a/completions/a2kit.bash b/completions/a2kit.bash index 4cca389..c52ca73 100644 --- a/completions/a2kit.bash +++ b/completions/a2kit.bash @@ -12,12 +12,18 @@ _a2kit() { ",$1") cmd="a2kit" ;; + a2kit,asm) + cmd="a2kit__asm" + ;; a2kit,cat) cmd="a2kit__catalog" ;; a2kit,catalog) cmd="a2kit__catalog" ;; + a2kit,dasm) + cmd="a2kit__dasm" + ;; a2kit,del) cmd="a2kit__delete" ;; @@ -96,9 +102,15 @@ _a2kit() { a2kit,verify) cmd="a2kit__verify" ;; + a2kit__help,asm) + cmd="a2kit__help__asm" + ;; a2kit__help,catalog) cmd="a2kit__help__catalog" ;; + a2kit__help,dasm) + cmd="a2kit__help__dasm" + ;; a2kit__help,delete) cmd="a2kit__help__delete" ;; @@ -166,7 +178,7 @@ _a2kit() { case "${cmd}" in a2kit) - opts="-h -V --help --version mkdsk mkdir delete protect unprotect lock unlock rename retype verify minify renumber get put catalog tree stat geometry tokenize detokenize help" + opts="-h -V --help --version mkdsk mkdir delete del era protect unprotect lock unlock rename retype verify minify renumber get put catalog cat dir ls tree stat geometry tokenize tok detokenize dtok asm dasm help" if [[ ${cur} == -* || ${COMP_CWORD} -eq 1 ]] ; then COMPREPLY=( $(compgen -W "${opts}" -- "${cur}") ) return 0 @@ -179,6 +191,36 @@ _a2kit() { COMPREPLY=( $(compgen -W "${opts}" -- "${cur}") ) return 0 ;; + a2kit__asm) + opts="-a -w -h --assembler --workspace --help" + if [[ ${cur} == -* || ${COMP_CWORD} -eq 2 ]] ; then + COMPREPLY=( $(compgen -W "${opts}" -- "${cur}") ) + return 0 + fi + case "${prev}" in + --assembler) + COMPREPLY=($(compgen -W "m8 m16 m16+ m32" -- "${cur}")) + return 0 + ;; + -a) + COMPREPLY=($(compgen -W "m8 m16 m16+ m32" -- "${cur}")) + return 0 + ;; + --workspace) + COMPREPLY=($(compgen -f "${cur}")) + return 0 + ;; + -w) + COMPREPLY=($(compgen -f "${cur}")) + return 0 + ;; + *) + COMPREPLY=() + ;; + esac + COMPREPLY=( $(compgen -W "${opts}" -- "${cur}") ) + return 0 + ;; a2kit__catalog) opts="-f -d -h --file --generic --dimg --help" if [[ ${cur} == -* || ${COMP_CWORD} -eq 2 ]] ; then @@ -231,6 +273,300 @@ _a2kit() { COMPREPLY=( $(compgen -W "${opts}" -- "${cur}") ) return 0 ;; + a2kit__catalog) + opts="-f -d -h --file --generic --dimg --help" + if [[ ${cur} == -* || ${COMP_CWORD} -eq 2 ]] ; then + COMPREPLY=( $(compgen -W "${opts}" -- "${cur}") ) + return 0 + fi + case "${prev}" in + --file) + COMPREPLY=($(compgen -f "${cur}")) + return 0 + ;; + -f) + COMPREPLY=($(compgen -f "${cur}")) + return 0 + ;; + --dimg) + local oldifs + if [ -n "${IFS+x}" ]; then + oldifs="$IFS" + fi + IFS=$'\n' + COMPREPLY=($(compgen -f "${cur}")) + if [ -n "${oldifs+x}" ]; then + IFS="$oldifs" + fi + if [[ "${BASH_VERSINFO[0]}" -ge 4 ]]; then + compopt -o filenames + fi + return 0 + ;; + -d) + local oldifs + if [ -n "${IFS+x}" ]; then + oldifs="$IFS" + fi + IFS=$'\n' + COMPREPLY=($(compgen -f "${cur}")) + if [ -n "${oldifs+x}" ]; then + IFS="$oldifs" + fi + if [[ "${BASH_VERSINFO[0]}" -ge 4 ]]; then + compopt -o filenames + fi + return 0 + ;; + *) + COMPREPLY=() + ;; + esac + COMPREPLY=( $(compgen -W "${opts}" -- "${cur}") ) + return 0 + ;; + a2kit__catalog) + opts="-f -d -h --file --generic --dimg --help" + if [[ ${cur} == -* || ${COMP_CWORD} -eq 2 ]] ; then + COMPREPLY=( $(compgen -W "${opts}" -- "${cur}") ) + return 0 + fi + case "${prev}" in + --file) + COMPREPLY=($(compgen -f "${cur}")) + return 0 + ;; + -f) + COMPREPLY=($(compgen -f "${cur}")) + return 0 + ;; + --dimg) + local oldifs + if [ -n "${IFS+x}" ]; then + oldifs="$IFS" + fi + IFS=$'\n' + COMPREPLY=($(compgen -f "${cur}")) + if [ -n "${oldifs+x}" ]; then + IFS="$oldifs" + fi + if [[ "${BASH_VERSINFO[0]}" -ge 4 ]]; then + compopt -o filenames + fi + return 0 + ;; + -d) + local oldifs + if [ -n "${IFS+x}" ]; then + oldifs="$IFS" + fi + IFS=$'\n' + COMPREPLY=($(compgen -f "${cur}")) + if [ -n "${oldifs+x}" ]; then + IFS="$oldifs" + fi + if [[ "${BASH_VERSINFO[0]}" -ge 4 ]]; then + compopt -o filenames + fi + return 0 + ;; + *) + COMPREPLY=() + ;; + esac + COMPREPLY=( $(compgen -W "${opts}" -- "${cur}") ) + return 0 + ;; + a2kit__catalog) + opts="-f -d -h --file --generic --dimg --help" + if [[ ${cur} == -* || ${COMP_CWORD} -eq 2 ]] ; then + COMPREPLY=( $(compgen -W "${opts}" -- "${cur}") ) + return 0 + fi + case "${prev}" in + --file) + COMPREPLY=($(compgen -f "${cur}")) + return 0 + ;; + -f) + COMPREPLY=($(compgen -f "${cur}")) + return 0 + ;; + --dimg) + local oldifs + if [ -n "${IFS+x}" ]; then + oldifs="$IFS" + fi + IFS=$'\n' + COMPREPLY=($(compgen -f "${cur}")) + if [ -n "${oldifs+x}" ]; then + IFS="$oldifs" + fi + if [[ "${BASH_VERSINFO[0]}" -ge 4 ]]; then + compopt -o filenames + fi + return 0 + ;; + -d) + local oldifs + if [ -n "${IFS+x}" ]; then + oldifs="$IFS" + fi + IFS=$'\n' + COMPREPLY=($(compgen -f "${cur}")) + if [ -n "${oldifs+x}" ]; then + IFS="$oldifs" + fi + if [[ "${BASH_VERSINFO[0]}" -ge 4 ]]; then + compopt -o filenames + fi + return 0 + ;; + *) + COMPREPLY=() + ;; + esac + COMPREPLY=( $(compgen -W "${opts}" -- "${cur}") ) + return 0 + ;; + a2kit__dasm) + opts="-p -o -h --proc --mx --org --help" + if [[ ${cur} == -* || ${COMP_CWORD} -eq 2 ]] ; then + COMPREPLY=( $(compgen -W "${opts}" -- "${cur}") ) + return 0 + fi + case "${prev}" in + --proc) + COMPREPLY=($(compgen -W "6502 65c02 65802 65816" -- "${cur}")) + return 0 + ;; + -p) + COMPREPLY=($(compgen -W "6502 65c02 65802 65816" -- "${cur}")) + return 0 + ;; + --mx) + COMPREPLY=($(compgen -W "00 01 10 11" -- "${cur}")) + return 0 + ;; + --org) + COMPREPLY=($(compgen -f "${cur}")) + return 0 + ;; + -o) + COMPREPLY=($(compgen -f "${cur}")) + return 0 + ;; + *) + COMPREPLY=() + ;; + esac + COMPREPLY=( $(compgen -W "${opts}" -- "${cur}") ) + return 0 + ;; + a2kit__delete) + opts="-f -d -h --file --dimg --help" + if [[ ${cur} == -* || ${COMP_CWORD} -eq 2 ]] ; then + COMPREPLY=( $(compgen -W "${opts}" -- "${cur}") ) + return 0 + fi + case "${prev}" in + --file) + COMPREPLY=($(compgen -f "${cur}")) + return 0 + ;; + -f) + COMPREPLY=($(compgen -f "${cur}")) + return 0 + ;; + --dimg) + local oldifs + if [ -n "${IFS+x}" ]; then + oldifs="$IFS" + fi + IFS=$'\n' + COMPREPLY=($(compgen -f "${cur}")) + if [ -n "${oldifs+x}" ]; then + IFS="$oldifs" + fi + if [[ "${BASH_VERSINFO[0]}" -ge 4 ]]; then + compopt -o filenames + fi + return 0 + ;; + -d) + local oldifs + if [ -n "${IFS+x}" ]; then + oldifs="$IFS" + fi + IFS=$'\n' + COMPREPLY=($(compgen -f "${cur}")) + if [ -n "${oldifs+x}" ]; then + IFS="$oldifs" + fi + if [[ "${BASH_VERSINFO[0]}" -ge 4 ]]; then + compopt -o filenames + fi + return 0 + ;; + *) + COMPREPLY=() + ;; + esac + COMPREPLY=( $(compgen -W "${opts}" -- "${cur}") ) + return 0 + ;; + a2kit__delete) + opts="-f -d -h --file --dimg --help" + if [[ ${cur} == -* || ${COMP_CWORD} -eq 2 ]] ; then + COMPREPLY=( $(compgen -W "${opts}" -- "${cur}") ) + return 0 + fi + case "${prev}" in + --file) + COMPREPLY=($(compgen -f "${cur}")) + return 0 + ;; + -f) + COMPREPLY=($(compgen -f "${cur}")) + return 0 + ;; + --dimg) + local oldifs + if [ -n "${IFS+x}" ]; then + oldifs="$IFS" + fi + IFS=$'\n' + COMPREPLY=($(compgen -f "${cur}")) + if [ -n "${oldifs+x}" ]; then + IFS="$oldifs" + fi + if [[ "${BASH_VERSINFO[0]}" -ge 4 ]]; then + compopt -o filenames + fi + return 0 + ;; + -d) + local oldifs + if [ -n "${IFS+x}" ]; then + oldifs="$IFS" + fi + IFS=$'\n' + COMPREPLY=($(compgen -f "${cur}")) + if [ -n "${oldifs+x}" ]; then + IFS="$oldifs" + fi + if [[ "${BASH_VERSINFO[0]}" -ge 4 ]]; then + compopt -o filenames + fi + return 0 + ;; + *) + COMPREPLY=() + ;; + esac + COMPREPLY=( $(compgen -W "${opts}" -- "${cur}") ) + return 0 + ;; a2kit__delete) opts="-f -d -h --file --dimg --help" if [[ ${cur} == -* || ${COMP_CWORD} -eq 2 ]] ; then @@ -305,6 +641,28 @@ _a2kit() { COMPREPLY=( $(compgen -W "${opts}" -- "${cur}") ) return 0 ;; + a2kit__detokenize) + opts="-t -h --type --help" + if [[ ${cur} == -* || ${COMP_CWORD} -eq 2 ]] ; then + COMPREPLY=( $(compgen -W "${opts}" -- "${cur}") ) + return 0 + fi + case "${prev}" in + --type) + COMPREPLY=($(compgen -W "atok itok mtok" -- "${cur}")) + return 0 + ;; + -t) + COMPREPLY=($(compgen -W "atok itok mtok" -- "${cur}")) + return 0 + ;; + *) + COMPREPLY=() + ;; + esac + COMPREPLY=( $(compgen -W "${opts}" -- "${cur}") ) + return 0 + ;; a2kit__geometry) opts="-d -h --dimg --help" if [[ ${cur} == -* || ${COMP_CWORD} -eq 2 ]] ; then @@ -440,7 +798,7 @@ _a2kit() { return 0 ;; a2kit__help) - opts="mkdsk mkdir delete protect unprotect lock unlock rename retype verify minify renumber get put catalog tree stat geometry tokenize detokenize help" + opts="mkdsk mkdir delete protect unprotect lock unlock rename retype verify minify renumber get put catalog tree stat geometry tokenize detokenize asm dasm help" if [[ ${cur} == -* || ${COMP_CWORD} -eq 2 ]] ; then COMPREPLY=( $(compgen -W "${opts}" -- "${cur}") ) return 0 @@ -453,6 +811,20 @@ _a2kit() { COMPREPLY=( $(compgen -W "${opts}" -- "${cur}") ) return 0 ;; + a2kit__help__asm) + opts="" + if [[ ${cur} == -* || ${COMP_CWORD} -eq 3 ]] ; then + COMPREPLY=( $(compgen -W "${opts}" -- "${cur}") ) + return 0 + fi + case "${prev}" in + *) + COMPREPLY=() + ;; + esac + COMPREPLY=( $(compgen -W "${opts}" -- "${cur}") ) + return 0 + ;; a2kit__help__catalog) opts="" if [[ ${cur} == -* || ${COMP_CWORD} -eq 3 ]] ; then @@ -467,6 +839,20 @@ _a2kit() { COMPREPLY=( $(compgen -W "${opts}" -- "${cur}") ) return 0 ;; + a2kit__help__dasm) + opts="" + if [[ ${cur} == -* || ${COMP_CWORD} -eq 3 ]] ; then + COMPREPLY=( $(compgen -W "${opts}" -- "${cur}") ) + return 0 + fi + case "${prev}" in + *) + COMPREPLY=() + ;; + esac + COMPREPLY=( $(compgen -W "${opts}" -- "${cur}") ) + return 0 + ;; a2kit__help__delete) opts="" if [[ ${cur} == -* || ${COMP_CWORD} -eq 3 ]] ; then @@ -1371,6 +1757,36 @@ _a2kit() { COMPREPLY=( $(compgen -W "${opts}" -- "${cur}") ) return 0 ;; + a2kit__tokenize) + opts="-a -t -h --addr --type --help" + if [[ ${cur} == -* || ${COMP_CWORD} -eq 2 ]] ; then + COMPREPLY=( $(compgen -W "${opts}" -- "${cur}") ) + return 0 + fi + case "${prev}" in + --addr) + COMPREPLY=($(compgen -f "${cur}")) + return 0 + ;; + -a) + COMPREPLY=($(compgen -f "${cur}")) + return 0 + ;; + --type) + COMPREPLY=($(compgen -W "atxt itxt mtxt" -- "${cur}")) + return 0 + ;; + -t) + COMPREPLY=($(compgen -W "atxt itxt mtxt" -- "${cur}")) + return 0 + ;; + *) + COMPREPLY=() + ;; + esac + COMPREPLY=( $(compgen -W "${opts}" -- "${cur}") ) + return 0 + ;; a2kit__tree) opts="-d -h --dimg --meta --help" if [[ ${cur} == -* || ${COMP_CWORD} -eq 2 ]] ; then diff --git a/completions/a2kit.elv b/completions/a2kit.elv index 00b507f..b2f691c 100644 --- a/completions/a2kit.elv +++ b/completions/a2kit.elv @@ -25,6 +25,8 @@ set edit:completion:arg-completer[a2kit] = {|@words| cand mkdsk 'write a blank disk image to the given path' cand mkdir 'create a new directory inside a disk image' cand delete 'delete a file or directory inside a disk image' + cand del 'delete a file or directory inside a disk image' + cand era 'delete a file or directory inside a disk image' cand protect 'password protect a disk or file' cand unprotect 'remove password protection from a disk or file' cand lock 'write protect a file or directory inside a disk image' @@ -37,11 +39,18 @@ set edit:completion:arg-completer[a2kit] = {|@words| cand get 'read from stdin, local, or disk image, write to stdout' cand put 'read from stdin, write to local or disk image' cand catalog 'write disk image catalog to stdout' + cand cat 'write disk image catalog to stdout' + cand dir 'write disk image catalog to stdout' + cand ls 'write disk image catalog to stdout' cand tree 'write directory tree as a JSON string to stdout' cand stat 'write FS statistics as a JSON string to stdout' cand geometry 'write disk geometry as a JSON string to stdout' cand tokenize 'read from stdin, tokenize, write to stdout' + cand tok 'read from stdin, tokenize, write to stdout' cand detokenize 'read from stdin, detokenize, write to stdout' + cand dtok 'read from stdin, detokenize, write to stdout' + cand asm 'read from stdin, assemble, write to stdout' + cand dasm 'read from stdin, disassemble, write to stdout' cand help 'Print this message or the help of the given subcommand(s)' } &'a2kit;mkdsk'= { @@ -78,6 +87,22 @@ set edit:completion:arg-completer[a2kit] = {|@words| cand -h 'Print help' cand --help 'Print help' } + &'a2kit;del'= { + cand -f 'path inside disk image to delete' + cand --file 'path inside disk image to delete' + cand -d 'path to disk image itself' + cand --dimg 'path to disk image itself' + cand -h 'Print help' + cand --help 'Print help' + } + &'a2kit;era'= { + cand -f 'path inside disk image to delete' + cand --file 'path inside disk image to delete' + cand -d 'path to disk image itself' + cand --dimg 'path to disk image itself' + cand -h 'Print help' + cand --help 'Print help' + } &'a2kit;protect'= { cand -f 'path inside disk image to protect' cand --file 'path inside disk image to protect' @@ -207,6 +232,33 @@ set edit:completion:arg-completer[a2kit] = {|@words| cand -h 'Print help' cand --help 'Print help' } + &'a2kit;cat'= { + cand -f 'path of directory inside disk image' + cand --file 'path of directory inside disk image' + cand -d 'path to disk image' + cand --dimg 'path to disk image' + cand --generic 'use generic output format' + cand -h 'Print help' + cand --help 'Print help' + } + &'a2kit;dir'= { + cand -f 'path of directory inside disk image' + cand --file 'path of directory inside disk image' + cand -d 'path to disk image' + cand --dimg 'path to disk image' + cand --generic 'use generic output format' + cand -h 'Print help' + cand --help 'Print help' + } + &'a2kit;ls'= { + cand -f 'path of directory inside disk image' + cand --file 'path of directory inside disk image' + cand -d 'path to disk image' + cand --dimg 'path to disk image' + cand --generic 'use generic output format' + cand -h 'Print help' + cand --help 'Print help' + } &'a2kit;tree'= { cand -d 'path to disk image' cand --dimg 'path to disk image' @@ -234,12 +286,43 @@ set edit:completion:arg-completer[a2kit] = {|@words| cand -h 'Print help' cand --help 'Print help' } + &'a2kit;tok'= { + cand -a 'address of tokenized code (Applesoft only)' + cand --addr 'address of tokenized code (Applesoft only)' + cand -t 'type of the file' + cand --type 'type of the file' + cand -h 'Print help' + cand --help 'Print help' + } &'a2kit;detokenize'= { cand -t 'type of the file' cand --type 'type of the file' cand -h 'Print help' cand --help 'Print help' } + &'a2kit;dtok'= { + cand -t 'type of the file' + cand --type 'type of the file' + cand -h 'Print help' + cand --help 'Print help' + } + &'a2kit;asm'= { + cand -a 'assembler variant' + cand --assembler 'assembler variant' + cand -w 'workspace directory' + cand --workspace 'workspace directory' + cand -h 'Print help' + cand --help 'Print help' + } + &'a2kit;dasm'= { + cand -p 'processor target' + cand --proc 'processor target' + cand --mx 'MX status bits' + cand -o 'starting address' + cand --org 'starting address' + cand -h 'Print help' + cand --help 'Print help' + } &'a2kit;help'= { cand mkdsk 'write a blank disk image to the given path' cand mkdir 'create a new directory inside a disk image' @@ -261,6 +344,8 @@ set edit:completion:arg-completer[a2kit] = {|@words| cand geometry 'write disk geometry as a JSON string to stdout' cand tokenize 'read from stdin, tokenize, write to stdout' cand detokenize 'read from stdin, detokenize, write to stdout' + cand asm 'read from stdin, assemble, write to stdout' + cand dasm 'read from stdin, disassemble, write to stdout' cand help 'Print this message or the help of the given subcommand(s)' } &'a2kit;help;mkdsk'= { @@ -303,6 +388,10 @@ set edit:completion:arg-completer[a2kit] = {|@words| } &'a2kit;help;detokenize'= { } + &'a2kit;help;asm'= { + } + &'a2kit;help;dasm'= { + } &'a2kit;help;help'= { } ] diff --git a/completions/a2kit.fish b/completions/a2kit.fish index fb64e93..a9e994a 100644 --- a/completions/a2kit.fish +++ b/completions/a2kit.fish @@ -1,126 +1,193 @@ -complete -c a2kit -n "__fish_use_subcommand" -s h -l help -d 'Print help (see more with \'--help\')' -complete -c a2kit -n "__fish_use_subcommand" -s V -l version -d 'Print version' -complete -c a2kit -n "__fish_use_subcommand" -f -a "mkdsk" -d 'write a blank disk image to the given path' -complete -c a2kit -n "__fish_use_subcommand" -f -a "mkdir" -d 'create a new directory inside a disk image' -complete -c a2kit -n "__fish_use_subcommand" -f -a "delete" -d 'delete a file or directory inside a disk image' -complete -c a2kit -n "__fish_use_subcommand" -f -a "protect" -d 'password protect a disk or file' -complete -c a2kit -n "__fish_use_subcommand" -f -a "unprotect" -d 'remove password protection from a disk or file' -complete -c a2kit -n "__fish_use_subcommand" -f -a "lock" -d 'write protect a file or directory inside a disk image' -complete -c a2kit -n "__fish_use_subcommand" -f -a "unlock" -d 'remove write protection from a file or directory inside a disk image' -complete -c a2kit -n "__fish_use_subcommand" -f -a "rename" -d 'rename a file or directory inside a disk image' -complete -c a2kit -n "__fish_use_subcommand" -f -a "retype" -d 'change file type inside a disk image' -complete -c a2kit -n "__fish_use_subcommand" -f -a "verify" -d 'read from stdin and error check' -complete -c a2kit -n "__fish_use_subcommand" -f -a "minify" -d 'reduce program size' -complete -c a2kit -n "__fish_use_subcommand" -f -a "renumber" -d 'renumber BASIC program lines' -complete -c a2kit -n "__fish_use_subcommand" -f -a "get" -d 'read from stdin, local, or disk image, write to stdout' -complete -c a2kit -n "__fish_use_subcommand" -f -a "put" -d 'read from stdin, write to local or disk image' -complete -c a2kit -n "__fish_use_subcommand" -f -a "catalog" -d 'write disk image catalog to stdout' -complete -c a2kit -n "__fish_use_subcommand" -f -a "tree" -d 'write directory tree as a JSON string to stdout' -complete -c a2kit -n "__fish_use_subcommand" -f -a "stat" -d 'write FS statistics as a JSON string to stdout' -complete -c a2kit -n "__fish_use_subcommand" -f -a "geometry" -d 'write disk geometry as a JSON string to stdout' -complete -c a2kit -n "__fish_use_subcommand" -f -a "tokenize" -d 'read from stdin, tokenize, write to stdout' -complete -c a2kit -n "__fish_use_subcommand" -f -a "detokenize" -d 'read from stdin, detokenize, write to stdout' -complete -c a2kit -n "__fish_use_subcommand" -f -a "help" -d 'Print this message or the help of the given subcommand(s)' -complete -c a2kit -n "__fish_seen_subcommand_from mkdsk" -s v -l volume -d 'volume name or number' -r -complete -c a2kit -n "__fish_seen_subcommand_from mkdsk" -s t -l type -d 'type of disk image to create' -r -f -a "{d13 '',do '',po '',woz1 '',woz2 '',imd '',img '',2mg '',nib '',td0 ''}" -complete -c a2kit -n "__fish_seen_subcommand_from mkdsk" -s o -l os -d 'operating system format' -r -f -a "{cpm2 '',cpm3 '',dos32 '',dos33 '',prodos '',pascal '',fat ''}" -complete -c a2kit -n "__fish_seen_subcommand_from mkdsk" -s k -l kind -d 'kind of disk' -r -f -a "{8in '',8in-trs80 '',8in-nabu '',5.25in '',5.25in-ibm-ssdd8 '',5.25in-ibm-ssdd9 '',5.25in-ibm-dsdd8 '',5.25in-ibm-dsdd9 '',5.25in-ibm-ssqd '',5.25in-ibm-dsqd '',5.25in-ibm-dshd '',5.25in-kayii '',5.25in-kay4 '',5.25in-osb-sd '',5.25in-osb-dd '',3.5in '',3.5in-ss '',3.5in-ds '',3.5in-ibm-720 '',3.5in-ibm-1440 '',3.5in-ibm-2880 '',3in-amstrad '',hdmax ''}" -complete -c a2kit -n "__fish_seen_subcommand_from mkdsk" -s d -l dimg -d 'disk image path to create' -r -F -complete -c a2kit -n "__fish_seen_subcommand_from mkdsk" -s w -l wrap -d 'type of disk image to wrap' -r -f -a "{do '',po '',nib ''}" -complete -c a2kit -n "__fish_seen_subcommand_from mkdsk" -s b -l bootable -d 'make disk bootable' -complete -c a2kit -n "__fish_seen_subcommand_from mkdsk" -s h -l help -d 'Print help' -complete -c a2kit -n "__fish_seen_subcommand_from mkdir" -s f -l file -d 'path inside disk image of new directory' -r -complete -c a2kit -n "__fish_seen_subcommand_from mkdir" -s d -l dimg -d 'path to disk image itself' -r -F -complete -c a2kit -n "__fish_seen_subcommand_from mkdir" -s h -l help -d 'Print help' -complete -c a2kit -n "__fish_seen_subcommand_from delete" -s f -l file -d 'path inside disk image to delete' -r -complete -c a2kit -n "__fish_seen_subcommand_from delete" -s d -l dimg -d 'path to disk image itself' -r -F -complete -c a2kit -n "__fish_seen_subcommand_from delete" -s h -l help -d 'Print help' -complete -c a2kit -n "__fish_seen_subcommand_from protect" -s f -l file -d 'path inside disk image to protect' -r -complete -c a2kit -n "__fish_seen_subcommand_from protect" -s d -l dimg -d 'path to disk image itself' -r -F -complete -c a2kit -n "__fish_seen_subcommand_from protect" -s p -l password -d 'password to assign' -r -complete -c a2kit -n "__fish_seen_subcommand_from protect" -l read -d 'protect read' -complete -c a2kit -n "__fish_seen_subcommand_from protect" -l write -d 'protect read' -complete -c a2kit -n "__fish_seen_subcommand_from protect" -l delete -d 'protect read' -complete -c a2kit -n "__fish_seen_subcommand_from protect" -s h -l help -d 'Print help' -complete -c a2kit -n "__fish_seen_subcommand_from unprotect" -s f -l file -d 'path inside disk image to unprotect' -r -complete -c a2kit -n "__fish_seen_subcommand_from unprotect" -s d -l dimg -d 'path to disk image itself' -r -F -complete -c a2kit -n "__fish_seen_subcommand_from unprotect" -s h -l help -d 'Print help' -complete -c a2kit -n "__fish_seen_subcommand_from lock" -s f -l file -d 'path inside disk image to lock' -r -complete -c a2kit -n "__fish_seen_subcommand_from lock" -s d -l dimg -d 'path to disk image itself' -r -F -complete -c a2kit -n "__fish_seen_subcommand_from lock" -s h -l help -d 'Print help' -complete -c a2kit -n "__fish_seen_subcommand_from unlock" -s f -l file -d 'path inside disk image to unlock' -r -complete -c a2kit -n "__fish_seen_subcommand_from unlock" -s d -l dimg -d 'path to disk image itself' -r -F -complete -c a2kit -n "__fish_seen_subcommand_from unlock" -s h -l help -d 'Print help' -complete -c a2kit -n "__fish_seen_subcommand_from rename" -s f -l file -d 'path inside disk image to rename' -r -complete -c a2kit -n "__fish_seen_subcommand_from rename" -s n -l name -d 'new name' -r -complete -c a2kit -n "__fish_seen_subcommand_from rename" -s d -l dimg -d 'path to disk image itself' -r -F -complete -c a2kit -n "__fish_seen_subcommand_from rename" -s h -l help -d 'Print help' -complete -c a2kit -n "__fish_seen_subcommand_from retype" -s f -l file -d 'path inside disk image to retype' -r -complete -c a2kit -n "__fish_seen_subcommand_from retype" -s t -l type -d 'file system type, code or mnemonic' -r -complete -c a2kit -n "__fish_seen_subcommand_from retype" -s a -l aux -d 'file system auxiliary metadata' -r -complete -c a2kit -n "__fish_seen_subcommand_from retype" -s d -l dimg -d 'path to disk image itself' -r -F -complete -c a2kit -n "__fish_seen_subcommand_from retype" -s h -l help -d 'Print help' -complete -c a2kit -n "__fish_seen_subcommand_from verify" -s t -l type -d 'type of the file' -r -f -a "{atxt '',itxt '',mtxt ''}" -complete -c a2kit -n "__fish_seen_subcommand_from verify" -s c -l config -d 'modify diagnostic configuration' -r -complete -c a2kit -n "__fish_seen_subcommand_from verify" -s w -l workspace -d 'workspace directory' -r -complete -c a2kit -n "__fish_seen_subcommand_from verify" -s s -l sexpr -d 'write S-expressions to stderr' -complete -c a2kit -n "__fish_seen_subcommand_from verify" -s h -l help -d 'Print help' -complete -c a2kit -n "__fish_seen_subcommand_from minify" -s t -l type -d 'type of the file' -r -f -a "{atxt ''}" -complete -c a2kit -n "__fish_seen_subcommand_from minify" -l level -d 'set minification level' -r -f -a "{0 '',1 '',2 '',3 ''}" -complete -c a2kit -n "__fish_seen_subcommand_from minify" -l flags -d 'set minification flags' -r -complete -c a2kit -n "__fish_seen_subcommand_from minify" -s h -l help -d 'Print help' -complete -c a2kit -n "__fish_seen_subcommand_from renumber" -s t -l type -d 'type of the file' -r -f -a "{atxt '',itxt ''}" -complete -c a2kit -n "__fish_seen_subcommand_from renumber" -s b -l beg -d 'lowest number to renumber' -r -complete -c a2kit -n "__fish_seen_subcommand_from renumber" -s e -l end -d 'highest number to renumber plus 1' -r -complete -c a2kit -n "__fish_seen_subcommand_from renumber" -s f -l first -d 'first number' -r -complete -c a2kit -n "__fish_seen_subcommand_from renumber" -s s -l step -d 'step between numbers' -r -complete -c a2kit -n "__fish_seen_subcommand_from renumber" -s r -l reorder -d 'allow reordering of lines' -complete -c a2kit -n "__fish_seen_subcommand_from renumber" -s h -l help -d 'Print help' -complete -c a2kit -n "__fish_seen_subcommand_from get" -s f -l file -d 'path, key, or address, maybe inside disk image' -r -F -complete -c a2kit -n "__fish_seen_subcommand_from get" -s t -l type -d 'type of the item' -r -f -a "{any '',auto '',bin '',txt '',raw '',rec '',atok '',itok '',mtok '',block '',sec '',track '',raw_track '',meta ''}" -complete -c a2kit -n "__fish_seen_subcommand_from get" -s d -l dimg -d 'path to disk image' -r -F -complete -c a2kit -n "__fish_seen_subcommand_from get" -s l -l len -d 'length of record in DOS 3.3 random access text file' -r -complete -c a2kit -n "__fish_seen_subcommand_from get" -l trunc -d 'truncate raw at EOF if possible' -complete -c a2kit -n "__fish_seen_subcommand_from get" -s h -l help -d 'Print help' -complete -c a2kit -n "__fish_seen_subcommand_from put" -s f -l file -d 'path, key, or address, maybe inside disk image' -r -F -complete -c a2kit -n "__fish_seen_subcommand_from put" -s t -l type -d 'type of the item' -r -f -a "{any '',auto '',bin '',txt '',raw '',rec '',atok '',itok '',mtok '',block '',sec '',track '',raw_track '',meta ''}" -complete -c a2kit -n "__fish_seen_subcommand_from put" -s d -l dimg -d 'path to disk image' -r -F -complete -c a2kit -n "__fish_seen_subcommand_from put" -s a -l addr -d 'address of binary file' -r -complete -c a2kit -n "__fish_seen_subcommand_from put" -s h -l help -d 'Print help' -complete -c a2kit -n "__fish_seen_subcommand_from catalog" -s f -l file -d 'path of directory inside disk image' -r -complete -c a2kit -n "__fish_seen_subcommand_from catalog" -s d -l dimg -d 'path to disk image' -r -F -complete -c a2kit -n "__fish_seen_subcommand_from catalog" -l generic -d 'use generic output format' -complete -c a2kit -n "__fish_seen_subcommand_from catalog" -s h -l help -d 'Print help' -complete -c a2kit -n "__fish_seen_subcommand_from tree" -s d -l dimg -d 'path to disk image' -r -F -complete -c a2kit -n "__fish_seen_subcommand_from tree" -l meta -d 'include metadata' -complete -c a2kit -n "__fish_seen_subcommand_from tree" -s h -l help -d 'Print help' -complete -c a2kit -n "__fish_seen_subcommand_from stat" -s d -l dimg -d 'path to disk image' -r -F -complete -c a2kit -n "__fish_seen_subcommand_from stat" -s h -l help -d 'Print help' -complete -c a2kit -n "__fish_seen_subcommand_from geometry" -s d -l dimg -d 'path to disk image' -r -F -complete -c a2kit -n "__fish_seen_subcommand_from geometry" -s h -l help -d 'Print help' -complete -c a2kit -n "__fish_seen_subcommand_from tokenize" -s a -l addr -d 'address of tokenized code (Applesoft only)' -r -complete -c a2kit -n "__fish_seen_subcommand_from tokenize" -s t -l type -d 'type of the file' -r -f -a "{atxt '',itxt '',mtxt ''}" -complete -c a2kit -n "__fish_seen_subcommand_from tokenize" -s h -l help -d 'Print help' -complete -c a2kit -n "__fish_seen_subcommand_from detokenize" -s t -l type -d 'type of the file' -r -f -a "{atok '',itok '',mtok ''}" -complete -c a2kit -n "__fish_seen_subcommand_from detokenize" -s h -l help -d 'Print help' -complete -c a2kit -n "__fish_seen_subcommand_from help; and not __fish_seen_subcommand_from mkdsk; and not __fish_seen_subcommand_from mkdir; and not __fish_seen_subcommand_from delete; and not __fish_seen_subcommand_from protect; and not __fish_seen_subcommand_from unprotect; and not __fish_seen_subcommand_from lock; and not __fish_seen_subcommand_from unlock; and not __fish_seen_subcommand_from rename; and not __fish_seen_subcommand_from retype; and not __fish_seen_subcommand_from verify; and not __fish_seen_subcommand_from minify; and not __fish_seen_subcommand_from renumber; and not __fish_seen_subcommand_from get; and not __fish_seen_subcommand_from put; and not __fish_seen_subcommand_from catalog; and not __fish_seen_subcommand_from tree; and not __fish_seen_subcommand_from stat; and not __fish_seen_subcommand_from geometry; and not __fish_seen_subcommand_from tokenize; and not __fish_seen_subcommand_from detokenize; and not __fish_seen_subcommand_from help" -f -a "mkdsk" -d 'write a blank disk image to the given path' -complete -c a2kit -n "__fish_seen_subcommand_from help; and not __fish_seen_subcommand_from mkdsk; and not __fish_seen_subcommand_from mkdir; and not __fish_seen_subcommand_from delete; and not __fish_seen_subcommand_from protect; and not __fish_seen_subcommand_from unprotect; and not __fish_seen_subcommand_from lock; and not __fish_seen_subcommand_from unlock; and not __fish_seen_subcommand_from rename; and not __fish_seen_subcommand_from retype; and not __fish_seen_subcommand_from verify; and not __fish_seen_subcommand_from minify; and not __fish_seen_subcommand_from renumber; and not __fish_seen_subcommand_from get; and not __fish_seen_subcommand_from put; and not __fish_seen_subcommand_from catalog; and not __fish_seen_subcommand_from tree; and not __fish_seen_subcommand_from stat; and not __fish_seen_subcommand_from geometry; and not __fish_seen_subcommand_from tokenize; and not __fish_seen_subcommand_from detokenize; and not __fish_seen_subcommand_from help" -f -a "mkdir" -d 'create a new directory inside a disk image' -complete -c a2kit -n "__fish_seen_subcommand_from help; and not __fish_seen_subcommand_from mkdsk; and not __fish_seen_subcommand_from mkdir; and not __fish_seen_subcommand_from delete; and not __fish_seen_subcommand_from protect; and not __fish_seen_subcommand_from unprotect; and not __fish_seen_subcommand_from lock; and not __fish_seen_subcommand_from unlock; and not __fish_seen_subcommand_from rename; and not __fish_seen_subcommand_from retype; and not __fish_seen_subcommand_from verify; and not __fish_seen_subcommand_from minify; and not __fish_seen_subcommand_from renumber; and not __fish_seen_subcommand_from get; and not __fish_seen_subcommand_from put; and not __fish_seen_subcommand_from catalog; and not __fish_seen_subcommand_from tree; and not __fish_seen_subcommand_from stat; and not __fish_seen_subcommand_from geometry; and not __fish_seen_subcommand_from tokenize; and not __fish_seen_subcommand_from detokenize; and not __fish_seen_subcommand_from help" -f -a "delete" -d 'delete a file or directory inside a disk image' -complete -c a2kit -n "__fish_seen_subcommand_from help; and not __fish_seen_subcommand_from mkdsk; and not __fish_seen_subcommand_from mkdir; and not __fish_seen_subcommand_from delete; and not __fish_seen_subcommand_from protect; and not __fish_seen_subcommand_from unprotect; and not __fish_seen_subcommand_from lock; and not __fish_seen_subcommand_from unlock; and not __fish_seen_subcommand_from rename; and not __fish_seen_subcommand_from retype; and not __fish_seen_subcommand_from verify; and not __fish_seen_subcommand_from minify; and not __fish_seen_subcommand_from renumber; and not __fish_seen_subcommand_from get; and not __fish_seen_subcommand_from put; and not __fish_seen_subcommand_from catalog; and not __fish_seen_subcommand_from tree; and not __fish_seen_subcommand_from stat; and not __fish_seen_subcommand_from geometry; and not __fish_seen_subcommand_from tokenize; and not __fish_seen_subcommand_from detokenize; and not __fish_seen_subcommand_from help" -f -a "protect" -d 'password protect a disk or file' -complete -c a2kit -n "__fish_seen_subcommand_from help; and not __fish_seen_subcommand_from mkdsk; and not __fish_seen_subcommand_from mkdir; and not __fish_seen_subcommand_from delete; and not __fish_seen_subcommand_from protect; and not __fish_seen_subcommand_from unprotect; and not __fish_seen_subcommand_from lock; and not __fish_seen_subcommand_from unlock; and not __fish_seen_subcommand_from rename; and not __fish_seen_subcommand_from retype; and not __fish_seen_subcommand_from verify; and not __fish_seen_subcommand_from minify; and not __fish_seen_subcommand_from renumber; and not __fish_seen_subcommand_from get; and not __fish_seen_subcommand_from put; and not __fish_seen_subcommand_from catalog; and not __fish_seen_subcommand_from tree; and not __fish_seen_subcommand_from stat; and not __fish_seen_subcommand_from geometry; and not __fish_seen_subcommand_from tokenize; and not __fish_seen_subcommand_from detokenize; and not __fish_seen_subcommand_from help" -f -a "unprotect" -d 'remove password protection from a disk or file' -complete -c a2kit -n "__fish_seen_subcommand_from help; and not __fish_seen_subcommand_from mkdsk; and not __fish_seen_subcommand_from mkdir; and not __fish_seen_subcommand_from delete; and not __fish_seen_subcommand_from protect; and not __fish_seen_subcommand_from unprotect; and not __fish_seen_subcommand_from lock; and not __fish_seen_subcommand_from unlock; and not __fish_seen_subcommand_from rename; and not __fish_seen_subcommand_from retype; and not __fish_seen_subcommand_from verify; and not __fish_seen_subcommand_from minify; and not __fish_seen_subcommand_from renumber; and not __fish_seen_subcommand_from get; and not __fish_seen_subcommand_from put; and not __fish_seen_subcommand_from catalog; and not __fish_seen_subcommand_from tree; and not __fish_seen_subcommand_from stat; and not __fish_seen_subcommand_from geometry; and not __fish_seen_subcommand_from tokenize; and not __fish_seen_subcommand_from detokenize; and not __fish_seen_subcommand_from help" -f -a "lock" -d 'write protect a file or directory inside a disk image' -complete -c a2kit -n "__fish_seen_subcommand_from help; and not __fish_seen_subcommand_from mkdsk; and not __fish_seen_subcommand_from mkdir; and not __fish_seen_subcommand_from delete; and not __fish_seen_subcommand_from protect; and not __fish_seen_subcommand_from unprotect; and not __fish_seen_subcommand_from lock; and not __fish_seen_subcommand_from unlock; and not __fish_seen_subcommand_from rename; and not __fish_seen_subcommand_from retype; and not __fish_seen_subcommand_from verify; and not __fish_seen_subcommand_from minify; and not __fish_seen_subcommand_from renumber; and not __fish_seen_subcommand_from get; and not __fish_seen_subcommand_from put; and not __fish_seen_subcommand_from catalog; and not __fish_seen_subcommand_from tree; and not __fish_seen_subcommand_from stat; and not __fish_seen_subcommand_from geometry; and not __fish_seen_subcommand_from tokenize; and not __fish_seen_subcommand_from detokenize; and not __fish_seen_subcommand_from help" -f -a "unlock" -d 'remove write protection from a file or directory inside a disk image' -complete -c a2kit -n "__fish_seen_subcommand_from help; and not __fish_seen_subcommand_from mkdsk; and not __fish_seen_subcommand_from mkdir; and not __fish_seen_subcommand_from delete; and not __fish_seen_subcommand_from protect; and not __fish_seen_subcommand_from unprotect; and not __fish_seen_subcommand_from lock; and not __fish_seen_subcommand_from unlock; and not __fish_seen_subcommand_from rename; and not __fish_seen_subcommand_from retype; and not __fish_seen_subcommand_from verify; and not __fish_seen_subcommand_from minify; and not __fish_seen_subcommand_from renumber; and not __fish_seen_subcommand_from get; and not __fish_seen_subcommand_from put; and not __fish_seen_subcommand_from catalog; and not __fish_seen_subcommand_from tree; and not __fish_seen_subcommand_from stat; and not __fish_seen_subcommand_from geometry; and not __fish_seen_subcommand_from tokenize; and not __fish_seen_subcommand_from detokenize; and not __fish_seen_subcommand_from help" -f -a "rename" -d 'rename a file or directory inside a disk image' -complete -c a2kit -n "__fish_seen_subcommand_from help; and not __fish_seen_subcommand_from mkdsk; and not __fish_seen_subcommand_from mkdir; and not __fish_seen_subcommand_from delete; and not __fish_seen_subcommand_from protect; and not __fish_seen_subcommand_from unprotect; and not __fish_seen_subcommand_from lock; and not __fish_seen_subcommand_from unlock; and not __fish_seen_subcommand_from rename; and not __fish_seen_subcommand_from retype; and not __fish_seen_subcommand_from verify; and not __fish_seen_subcommand_from minify; and not __fish_seen_subcommand_from renumber; and not __fish_seen_subcommand_from get; and not __fish_seen_subcommand_from put; and not __fish_seen_subcommand_from catalog; and not __fish_seen_subcommand_from tree; and not __fish_seen_subcommand_from stat; and not __fish_seen_subcommand_from geometry; and not __fish_seen_subcommand_from tokenize; and not __fish_seen_subcommand_from detokenize; and not __fish_seen_subcommand_from help" -f -a "retype" -d 'change file type inside a disk image' -complete -c a2kit -n "__fish_seen_subcommand_from help; and not __fish_seen_subcommand_from mkdsk; and not __fish_seen_subcommand_from mkdir; and not __fish_seen_subcommand_from delete; and not __fish_seen_subcommand_from protect; and not __fish_seen_subcommand_from unprotect; and not __fish_seen_subcommand_from lock; and not __fish_seen_subcommand_from unlock; and not __fish_seen_subcommand_from rename; and not __fish_seen_subcommand_from retype; and not __fish_seen_subcommand_from verify; and not __fish_seen_subcommand_from minify; and not __fish_seen_subcommand_from renumber; and not __fish_seen_subcommand_from get; and not __fish_seen_subcommand_from put; and not __fish_seen_subcommand_from catalog; and not __fish_seen_subcommand_from tree; and not __fish_seen_subcommand_from stat; and not __fish_seen_subcommand_from geometry; and not __fish_seen_subcommand_from tokenize; and not __fish_seen_subcommand_from detokenize; and not __fish_seen_subcommand_from help" -f -a "verify" -d 'read from stdin and error check' -complete -c a2kit -n "__fish_seen_subcommand_from help; and not __fish_seen_subcommand_from mkdsk; and not __fish_seen_subcommand_from mkdir; and not __fish_seen_subcommand_from delete; and not __fish_seen_subcommand_from protect; and not __fish_seen_subcommand_from unprotect; and not __fish_seen_subcommand_from lock; and not __fish_seen_subcommand_from unlock; and not __fish_seen_subcommand_from rename; and not __fish_seen_subcommand_from retype; and not __fish_seen_subcommand_from verify; and not __fish_seen_subcommand_from minify; and not __fish_seen_subcommand_from renumber; and not __fish_seen_subcommand_from get; and not __fish_seen_subcommand_from put; and not __fish_seen_subcommand_from catalog; and not __fish_seen_subcommand_from tree; and not __fish_seen_subcommand_from stat; and not __fish_seen_subcommand_from geometry; and not __fish_seen_subcommand_from tokenize; and not __fish_seen_subcommand_from detokenize; and not __fish_seen_subcommand_from help" -f -a "minify" -d 'reduce program size' -complete -c a2kit -n "__fish_seen_subcommand_from help; and not __fish_seen_subcommand_from mkdsk; and not __fish_seen_subcommand_from mkdir; and not __fish_seen_subcommand_from delete; and not __fish_seen_subcommand_from protect; and not __fish_seen_subcommand_from unprotect; and not __fish_seen_subcommand_from lock; and not __fish_seen_subcommand_from unlock; and not __fish_seen_subcommand_from rename; and not __fish_seen_subcommand_from retype; and not __fish_seen_subcommand_from verify; and not __fish_seen_subcommand_from minify; and not __fish_seen_subcommand_from renumber; and not __fish_seen_subcommand_from get; and not __fish_seen_subcommand_from put; and not __fish_seen_subcommand_from catalog; and not __fish_seen_subcommand_from tree; and not __fish_seen_subcommand_from stat; and not __fish_seen_subcommand_from geometry; and not __fish_seen_subcommand_from tokenize; and not __fish_seen_subcommand_from detokenize; and not __fish_seen_subcommand_from help" -f -a "renumber" -d 'renumber BASIC program lines' -complete -c a2kit -n "__fish_seen_subcommand_from help; and not __fish_seen_subcommand_from mkdsk; and not __fish_seen_subcommand_from mkdir; and not __fish_seen_subcommand_from delete; and not __fish_seen_subcommand_from protect; and not __fish_seen_subcommand_from unprotect; and not __fish_seen_subcommand_from lock; and not __fish_seen_subcommand_from unlock; and not __fish_seen_subcommand_from rename; and not __fish_seen_subcommand_from retype; and not __fish_seen_subcommand_from verify; and not __fish_seen_subcommand_from minify; and not __fish_seen_subcommand_from renumber; and not __fish_seen_subcommand_from get; and not __fish_seen_subcommand_from put; and not __fish_seen_subcommand_from catalog; and not __fish_seen_subcommand_from tree; and not __fish_seen_subcommand_from stat; and not __fish_seen_subcommand_from geometry; and not __fish_seen_subcommand_from tokenize; and not __fish_seen_subcommand_from detokenize; and not __fish_seen_subcommand_from help" -f -a "get" -d 'read from stdin, local, or disk image, write to stdout' -complete -c a2kit -n "__fish_seen_subcommand_from help; and not __fish_seen_subcommand_from mkdsk; and not __fish_seen_subcommand_from mkdir; and not __fish_seen_subcommand_from delete; and not __fish_seen_subcommand_from protect; and not __fish_seen_subcommand_from unprotect; and not __fish_seen_subcommand_from lock; and not __fish_seen_subcommand_from unlock; and not __fish_seen_subcommand_from rename; and not __fish_seen_subcommand_from retype; and not __fish_seen_subcommand_from verify; and not __fish_seen_subcommand_from minify; and not __fish_seen_subcommand_from renumber; and not __fish_seen_subcommand_from get; and not __fish_seen_subcommand_from put; and not __fish_seen_subcommand_from catalog; and not __fish_seen_subcommand_from tree; and not __fish_seen_subcommand_from stat; and not __fish_seen_subcommand_from geometry; and not __fish_seen_subcommand_from tokenize; and not __fish_seen_subcommand_from detokenize; and not __fish_seen_subcommand_from help" -f -a "put" -d 'read from stdin, write to local or disk image' -complete -c a2kit -n "__fish_seen_subcommand_from help; and not __fish_seen_subcommand_from mkdsk; and not __fish_seen_subcommand_from mkdir; and not __fish_seen_subcommand_from delete; and not __fish_seen_subcommand_from protect; and not __fish_seen_subcommand_from unprotect; and not __fish_seen_subcommand_from lock; and not __fish_seen_subcommand_from unlock; and not __fish_seen_subcommand_from rename; and not __fish_seen_subcommand_from retype; and not __fish_seen_subcommand_from verify; and not __fish_seen_subcommand_from minify; and not __fish_seen_subcommand_from renumber; and not __fish_seen_subcommand_from get; and not __fish_seen_subcommand_from put; and not __fish_seen_subcommand_from catalog; and not __fish_seen_subcommand_from tree; and not __fish_seen_subcommand_from stat; and not __fish_seen_subcommand_from geometry; and not __fish_seen_subcommand_from tokenize; and not __fish_seen_subcommand_from detokenize; and not __fish_seen_subcommand_from help" -f -a "catalog" -d 'write disk image catalog to stdout' -complete -c a2kit -n "__fish_seen_subcommand_from help; and not __fish_seen_subcommand_from mkdsk; and not __fish_seen_subcommand_from mkdir; and not __fish_seen_subcommand_from delete; and not __fish_seen_subcommand_from protect; and not __fish_seen_subcommand_from unprotect; and not __fish_seen_subcommand_from lock; and not __fish_seen_subcommand_from unlock; and not __fish_seen_subcommand_from rename; and not __fish_seen_subcommand_from retype; and not __fish_seen_subcommand_from verify; and not __fish_seen_subcommand_from minify; and not __fish_seen_subcommand_from renumber; and not __fish_seen_subcommand_from get; and not __fish_seen_subcommand_from put; and not __fish_seen_subcommand_from catalog; and not __fish_seen_subcommand_from tree; and not __fish_seen_subcommand_from stat; and not __fish_seen_subcommand_from geometry; and not __fish_seen_subcommand_from tokenize; and not __fish_seen_subcommand_from detokenize; and not __fish_seen_subcommand_from help" -f -a "tree" -d 'write directory tree as a JSON string to stdout' -complete -c a2kit -n "__fish_seen_subcommand_from help; and not __fish_seen_subcommand_from mkdsk; and not __fish_seen_subcommand_from mkdir; and not __fish_seen_subcommand_from delete; and not __fish_seen_subcommand_from protect; and not __fish_seen_subcommand_from unprotect; and not __fish_seen_subcommand_from lock; and not __fish_seen_subcommand_from unlock; and not __fish_seen_subcommand_from rename; and not __fish_seen_subcommand_from retype; and not __fish_seen_subcommand_from verify; and not __fish_seen_subcommand_from minify; and not __fish_seen_subcommand_from renumber; and not __fish_seen_subcommand_from get; and not __fish_seen_subcommand_from put; and not __fish_seen_subcommand_from catalog; and not __fish_seen_subcommand_from tree; and not __fish_seen_subcommand_from stat; and not __fish_seen_subcommand_from geometry; and not __fish_seen_subcommand_from tokenize; and not __fish_seen_subcommand_from detokenize; and not __fish_seen_subcommand_from help" -f -a "stat" -d 'write FS statistics as a JSON string to stdout' -complete -c a2kit -n "__fish_seen_subcommand_from help; and not __fish_seen_subcommand_from mkdsk; and not __fish_seen_subcommand_from mkdir; and not __fish_seen_subcommand_from delete; and not __fish_seen_subcommand_from protect; and not __fish_seen_subcommand_from unprotect; and not __fish_seen_subcommand_from lock; and not __fish_seen_subcommand_from unlock; and not __fish_seen_subcommand_from rename; and not __fish_seen_subcommand_from retype; and not __fish_seen_subcommand_from verify; and not __fish_seen_subcommand_from minify; and not __fish_seen_subcommand_from renumber; and not __fish_seen_subcommand_from get; and not __fish_seen_subcommand_from put; and not __fish_seen_subcommand_from catalog; and not __fish_seen_subcommand_from tree; and not __fish_seen_subcommand_from stat; and not __fish_seen_subcommand_from geometry; and not __fish_seen_subcommand_from tokenize; and not __fish_seen_subcommand_from detokenize; and not __fish_seen_subcommand_from help" -f -a "geometry" -d 'write disk geometry as a JSON string to stdout' -complete -c a2kit -n "__fish_seen_subcommand_from help; and not __fish_seen_subcommand_from mkdsk; and not __fish_seen_subcommand_from mkdir; and not __fish_seen_subcommand_from delete; and not __fish_seen_subcommand_from protect; and not __fish_seen_subcommand_from unprotect; and not __fish_seen_subcommand_from lock; and not __fish_seen_subcommand_from unlock; and not __fish_seen_subcommand_from rename; and not __fish_seen_subcommand_from retype; and not __fish_seen_subcommand_from verify; and not __fish_seen_subcommand_from minify; and not __fish_seen_subcommand_from renumber; and not __fish_seen_subcommand_from get; and not __fish_seen_subcommand_from put; and not __fish_seen_subcommand_from catalog; and not __fish_seen_subcommand_from tree; and not __fish_seen_subcommand_from stat; and not __fish_seen_subcommand_from geometry; and not __fish_seen_subcommand_from tokenize; and not __fish_seen_subcommand_from detokenize; and not __fish_seen_subcommand_from help" -f -a "tokenize" -d 'read from stdin, tokenize, write to stdout' -complete -c a2kit -n "__fish_seen_subcommand_from help; and not __fish_seen_subcommand_from mkdsk; and not __fish_seen_subcommand_from mkdir; and not __fish_seen_subcommand_from delete; and not __fish_seen_subcommand_from protect; and not __fish_seen_subcommand_from unprotect; and not __fish_seen_subcommand_from lock; and not __fish_seen_subcommand_from unlock; and not __fish_seen_subcommand_from rename; and not __fish_seen_subcommand_from retype; and not __fish_seen_subcommand_from verify; and not __fish_seen_subcommand_from minify; and not __fish_seen_subcommand_from renumber; and not __fish_seen_subcommand_from get; and not __fish_seen_subcommand_from put; and not __fish_seen_subcommand_from catalog; and not __fish_seen_subcommand_from tree; and not __fish_seen_subcommand_from stat; and not __fish_seen_subcommand_from geometry; and not __fish_seen_subcommand_from tokenize; and not __fish_seen_subcommand_from detokenize; and not __fish_seen_subcommand_from help" -f -a "detokenize" -d 'read from stdin, detokenize, write to stdout' -complete -c a2kit -n "__fish_seen_subcommand_from help; and not __fish_seen_subcommand_from mkdsk; and not __fish_seen_subcommand_from mkdir; and not __fish_seen_subcommand_from delete; and not __fish_seen_subcommand_from protect; and not __fish_seen_subcommand_from unprotect; and not __fish_seen_subcommand_from lock; and not __fish_seen_subcommand_from unlock; and not __fish_seen_subcommand_from rename; and not __fish_seen_subcommand_from retype; and not __fish_seen_subcommand_from verify; and not __fish_seen_subcommand_from minify; and not __fish_seen_subcommand_from renumber; and not __fish_seen_subcommand_from get; and not __fish_seen_subcommand_from put; and not __fish_seen_subcommand_from catalog; and not __fish_seen_subcommand_from tree; and not __fish_seen_subcommand_from stat; and not __fish_seen_subcommand_from geometry; and not __fish_seen_subcommand_from tokenize; and not __fish_seen_subcommand_from detokenize; and not __fish_seen_subcommand_from help" -f -a "help" -d 'Print this message or the help of the given subcommand(s)' +# Print an optspec for argparse to handle cmd's options that are independent of any subcommand. +function __fish_a2kit_global_optspecs + string join \n h/help V/version +end + +function __fish_a2kit_needs_command + # Figure out if the current invocation already has a command. + set -l cmd (commandline -opc) + set -e cmd[1] + argparse -s (__fish_a2kit_global_optspecs) -- $cmd 2>/dev/null + or return + if set -q argv[1] + # Also print the command, so this can be used to figure out what it is. + echo $argv[1] + return 1 + end + return 0 +end + +function __fish_a2kit_using_subcommand + set -l cmd (__fish_a2kit_needs_command) + test -z "$cmd" + and return 1 + contains -- $cmd[1] $argv +end + +complete -c a2kit -n "__fish_a2kit_needs_command" -s h -l help -d 'Print help (see more with \'--help\')' +complete -c a2kit -n "__fish_a2kit_needs_command" -s V -l version -d 'Print version' +complete -c a2kit -n "__fish_a2kit_needs_command" -f -a "mkdsk" -d 'write a blank disk image to the given path' +complete -c a2kit -n "__fish_a2kit_needs_command" -f -a "mkdir" -d 'create a new directory inside a disk image' +complete -c a2kit -n "__fish_a2kit_needs_command" -f -a "delete" -d 'delete a file or directory inside a disk image' +complete -c a2kit -n "__fish_a2kit_needs_command" -f -a "del" -d 'delete a file or directory inside a disk image' +complete -c a2kit -n "__fish_a2kit_needs_command" -f -a "era" -d 'delete a file or directory inside a disk image' +complete -c a2kit -n "__fish_a2kit_needs_command" -f -a "protect" -d 'password protect a disk or file' +complete -c a2kit -n "__fish_a2kit_needs_command" -f -a "unprotect" -d 'remove password protection from a disk or file' +complete -c a2kit -n "__fish_a2kit_needs_command" -f -a "lock" -d 'write protect a file or directory inside a disk image' +complete -c a2kit -n "__fish_a2kit_needs_command" -f -a "unlock" -d 'remove write protection from a file or directory inside a disk image' +complete -c a2kit -n "__fish_a2kit_needs_command" -f -a "rename" -d 'rename a file or directory inside a disk image' +complete -c a2kit -n "__fish_a2kit_needs_command" -f -a "retype" -d 'change file type inside a disk image' +complete -c a2kit -n "__fish_a2kit_needs_command" -f -a "verify" -d 'read from stdin and error check' +complete -c a2kit -n "__fish_a2kit_needs_command" -f -a "minify" -d 'reduce program size' +complete -c a2kit -n "__fish_a2kit_needs_command" -f -a "renumber" -d 'renumber BASIC program lines' +complete -c a2kit -n "__fish_a2kit_needs_command" -f -a "get" -d 'read from stdin, local, or disk image, write to stdout' +complete -c a2kit -n "__fish_a2kit_needs_command" -f -a "put" -d 'read from stdin, write to local or disk image' +complete -c a2kit -n "__fish_a2kit_needs_command" -f -a "catalog" -d 'write disk image catalog to stdout' +complete -c a2kit -n "__fish_a2kit_needs_command" -f -a "cat" -d 'write disk image catalog to stdout' +complete -c a2kit -n "__fish_a2kit_needs_command" -f -a "dir" -d 'write disk image catalog to stdout' +complete -c a2kit -n "__fish_a2kit_needs_command" -f -a "ls" -d 'write disk image catalog to stdout' +complete -c a2kit -n "__fish_a2kit_needs_command" -f -a "tree" -d 'write directory tree as a JSON string to stdout' +complete -c a2kit -n "__fish_a2kit_needs_command" -f -a "stat" -d 'write FS statistics as a JSON string to stdout' +complete -c a2kit -n "__fish_a2kit_needs_command" -f -a "geometry" -d 'write disk geometry as a JSON string to stdout' +complete -c a2kit -n "__fish_a2kit_needs_command" -f -a "tokenize" -d 'read from stdin, tokenize, write to stdout' +complete -c a2kit -n "__fish_a2kit_needs_command" -f -a "tok" -d 'read from stdin, tokenize, write to stdout' +complete -c a2kit -n "__fish_a2kit_needs_command" -f -a "detokenize" -d 'read from stdin, detokenize, write to stdout' +complete -c a2kit -n "__fish_a2kit_needs_command" -f -a "dtok" -d 'read from stdin, detokenize, write to stdout' +complete -c a2kit -n "__fish_a2kit_needs_command" -f -a "asm" -d 'read from stdin, assemble, write to stdout' +complete -c a2kit -n "__fish_a2kit_needs_command" -f -a "dasm" -d 'read from stdin, disassemble, write to stdout' +complete -c a2kit -n "__fish_a2kit_needs_command" -f -a "help" -d 'Print this message or the help of the given subcommand(s)' +complete -c a2kit -n "__fish_a2kit_using_subcommand mkdsk" -s v -l volume -d 'volume name or number' -r +complete -c a2kit -n "__fish_a2kit_using_subcommand mkdsk" -s t -l type -d 'type of disk image to create' -r -f -a "{d13\t'',do\t'',po\t'',woz1\t'',woz2\t'',imd\t'',img\t'',2mg\t'',nib\t'',td0\t''}" +complete -c a2kit -n "__fish_a2kit_using_subcommand mkdsk" -s o -l os -d 'operating system format' -r -f -a "{cpm2\t'',cpm3\t'',dos32\t'',dos33\t'',prodos\t'',pascal\t'',fat\t''}" +complete -c a2kit -n "__fish_a2kit_using_subcommand mkdsk" -s k -l kind -d 'kind of disk' -r -f -a "{8in\t'',8in-trs80\t'',8in-nabu\t'',5.25in\t'',5.25in-ibm-ssdd8\t'',5.25in-ibm-ssdd9\t'',5.25in-ibm-dsdd8\t'',5.25in-ibm-dsdd9\t'',5.25in-ibm-ssqd\t'',5.25in-ibm-dsqd\t'',5.25in-ibm-dshd\t'',5.25in-kayii\t'',5.25in-kay4\t'',5.25in-osb-sd\t'',5.25in-osb-dd\t'',3.5in\t'',3.5in-ss\t'',3.5in-ds\t'',3.5in-ibm-720\t'',3.5in-ibm-1440\t'',3.5in-ibm-2880\t'',3in-amstrad\t'',hdmax\t''}" +complete -c a2kit -n "__fish_a2kit_using_subcommand mkdsk" -s d -l dimg -d 'disk image path to create' -r -F +complete -c a2kit -n "__fish_a2kit_using_subcommand mkdsk" -s w -l wrap -d 'type of disk image to wrap' -r -f -a "{do\t'',po\t'',nib\t''}" +complete -c a2kit -n "__fish_a2kit_using_subcommand mkdsk" -s b -l bootable -d 'make disk bootable' +complete -c a2kit -n "__fish_a2kit_using_subcommand mkdsk" -s h -l help -d 'Print help' +complete -c a2kit -n "__fish_a2kit_using_subcommand mkdir" -s f -l file -d 'path inside disk image of new directory' -r +complete -c a2kit -n "__fish_a2kit_using_subcommand mkdir" -s d -l dimg -d 'path to disk image itself' -r -F +complete -c a2kit -n "__fish_a2kit_using_subcommand mkdir" -s h -l help -d 'Print help' +complete -c a2kit -n "__fish_a2kit_using_subcommand delete" -s f -l file -d 'path inside disk image to delete' -r +complete -c a2kit -n "__fish_a2kit_using_subcommand delete" -s d -l dimg -d 'path to disk image itself' -r -F +complete -c a2kit -n "__fish_a2kit_using_subcommand delete" -s h -l help -d 'Print help' +complete -c a2kit -n "__fish_a2kit_using_subcommand del" -s f -l file -d 'path inside disk image to delete' -r +complete -c a2kit -n "__fish_a2kit_using_subcommand del" -s d -l dimg -d 'path to disk image itself' -r -F +complete -c a2kit -n "__fish_a2kit_using_subcommand del" -s h -l help -d 'Print help' +complete -c a2kit -n "__fish_a2kit_using_subcommand era" -s f -l file -d 'path inside disk image to delete' -r +complete -c a2kit -n "__fish_a2kit_using_subcommand era" -s d -l dimg -d 'path to disk image itself' -r -F +complete -c a2kit -n "__fish_a2kit_using_subcommand era" -s h -l help -d 'Print help' +complete -c a2kit -n "__fish_a2kit_using_subcommand protect" -s f -l file -d 'path inside disk image to protect' -r +complete -c a2kit -n "__fish_a2kit_using_subcommand protect" -s d -l dimg -d 'path to disk image itself' -r -F +complete -c a2kit -n "__fish_a2kit_using_subcommand protect" -s p -l password -d 'password to assign' -r +complete -c a2kit -n "__fish_a2kit_using_subcommand protect" -l read -d 'protect read' +complete -c a2kit -n "__fish_a2kit_using_subcommand protect" -l write -d 'protect read' +complete -c a2kit -n "__fish_a2kit_using_subcommand protect" -l delete -d 'protect read' +complete -c a2kit -n "__fish_a2kit_using_subcommand protect" -s h -l help -d 'Print help' +complete -c a2kit -n "__fish_a2kit_using_subcommand unprotect" -s f -l file -d 'path inside disk image to unprotect' -r +complete -c a2kit -n "__fish_a2kit_using_subcommand unprotect" -s d -l dimg -d 'path to disk image itself' -r -F +complete -c a2kit -n "__fish_a2kit_using_subcommand unprotect" -s h -l help -d 'Print help' +complete -c a2kit -n "__fish_a2kit_using_subcommand lock" -s f -l file -d 'path inside disk image to lock' -r +complete -c a2kit -n "__fish_a2kit_using_subcommand lock" -s d -l dimg -d 'path to disk image itself' -r -F +complete -c a2kit -n "__fish_a2kit_using_subcommand lock" -s h -l help -d 'Print help' +complete -c a2kit -n "__fish_a2kit_using_subcommand unlock" -s f -l file -d 'path inside disk image to unlock' -r +complete -c a2kit -n "__fish_a2kit_using_subcommand unlock" -s d -l dimg -d 'path to disk image itself' -r -F +complete -c a2kit -n "__fish_a2kit_using_subcommand unlock" -s h -l help -d 'Print help' +complete -c a2kit -n "__fish_a2kit_using_subcommand rename" -s f -l file -d 'path inside disk image to rename' -r +complete -c a2kit -n "__fish_a2kit_using_subcommand rename" -s n -l name -d 'new name' -r +complete -c a2kit -n "__fish_a2kit_using_subcommand rename" -s d -l dimg -d 'path to disk image itself' -r -F +complete -c a2kit -n "__fish_a2kit_using_subcommand rename" -s h -l help -d 'Print help' +complete -c a2kit -n "__fish_a2kit_using_subcommand retype" -s f -l file -d 'path inside disk image to retype' -r +complete -c a2kit -n "__fish_a2kit_using_subcommand retype" -s t -l type -d 'file system type, code or mnemonic' -r +complete -c a2kit -n "__fish_a2kit_using_subcommand retype" -s a -l aux -d 'file system auxiliary metadata' -r +complete -c a2kit -n "__fish_a2kit_using_subcommand retype" -s d -l dimg -d 'path to disk image itself' -r -F +complete -c a2kit -n "__fish_a2kit_using_subcommand retype" -s h -l help -d 'Print help' +complete -c a2kit -n "__fish_a2kit_using_subcommand verify" -s t -l type -d 'type of the file' -r -f -a "{atxt\t'',itxt\t'',mtxt\t''}" +complete -c a2kit -n "__fish_a2kit_using_subcommand verify" -s c -l config -d 'modify diagnostic configuration' -r +complete -c a2kit -n "__fish_a2kit_using_subcommand verify" -s w -l workspace -d 'workspace directory' -r +complete -c a2kit -n "__fish_a2kit_using_subcommand verify" -s s -l sexpr -d 'write S-expressions to stderr' +complete -c a2kit -n "__fish_a2kit_using_subcommand verify" -s h -l help -d 'Print help' +complete -c a2kit -n "__fish_a2kit_using_subcommand minify" -s t -l type -d 'type of the file' -r -f -a "{atxt\t''}" +complete -c a2kit -n "__fish_a2kit_using_subcommand minify" -l level -d 'set minification level' -r -f -a "{0\t'',1\t'',2\t'',3\t''}" +complete -c a2kit -n "__fish_a2kit_using_subcommand minify" -l flags -d 'set minification flags' -r +complete -c a2kit -n "__fish_a2kit_using_subcommand minify" -s h -l help -d 'Print help' +complete -c a2kit -n "__fish_a2kit_using_subcommand renumber" -s t -l type -d 'type of the file' -r -f -a "{atxt\t'',itxt\t''}" +complete -c a2kit -n "__fish_a2kit_using_subcommand renumber" -s b -l beg -d 'lowest number to renumber' -r +complete -c a2kit -n "__fish_a2kit_using_subcommand renumber" -s e -l end -d 'highest number to renumber plus 1' -r +complete -c a2kit -n "__fish_a2kit_using_subcommand renumber" -s f -l first -d 'first number' -r +complete -c a2kit -n "__fish_a2kit_using_subcommand renumber" -s s -l step -d 'step between numbers' -r +complete -c a2kit -n "__fish_a2kit_using_subcommand renumber" -s r -l reorder -d 'allow reordering of lines' +complete -c a2kit -n "__fish_a2kit_using_subcommand renumber" -s h -l help -d 'Print help' +complete -c a2kit -n "__fish_a2kit_using_subcommand get" -s f -l file -d 'path, key, or address, maybe inside disk image' -r -F +complete -c a2kit -n "__fish_a2kit_using_subcommand get" -s t -l type -d 'type of the item' -r -f -a "{any\t'',auto\t'',bin\t'',txt\t'',raw\t'',rec\t'',atok\t'',itok\t'',mtok\t'',block\t'',sec\t'',track\t'',raw_track\t'',meta\t''}" +complete -c a2kit -n "__fish_a2kit_using_subcommand get" -s d -l dimg -d 'path to disk image' -r -F +complete -c a2kit -n "__fish_a2kit_using_subcommand get" -s l -l len -d 'length of record in DOS 3.3 random access text file' -r +complete -c a2kit -n "__fish_a2kit_using_subcommand get" -l trunc -d 'truncate raw at EOF if possible' +complete -c a2kit -n "__fish_a2kit_using_subcommand get" -s h -l help -d 'Print help' +complete -c a2kit -n "__fish_a2kit_using_subcommand put" -s f -l file -d 'path, key, or address, maybe inside disk image' -r -F +complete -c a2kit -n "__fish_a2kit_using_subcommand put" -s t -l type -d 'type of the item' -r -f -a "{any\t'',auto\t'',bin\t'',txt\t'',raw\t'',rec\t'',atok\t'',itok\t'',mtok\t'',block\t'',sec\t'',track\t'',raw_track\t'',meta\t''}" +complete -c a2kit -n "__fish_a2kit_using_subcommand put" -s d -l dimg -d 'path to disk image' -r -F +complete -c a2kit -n "__fish_a2kit_using_subcommand put" -s a -l addr -d 'address of binary file' -r +complete -c a2kit -n "__fish_a2kit_using_subcommand put" -s h -l help -d 'Print help' +complete -c a2kit -n "__fish_a2kit_using_subcommand catalog" -s f -l file -d 'path of directory inside disk image' -r +complete -c a2kit -n "__fish_a2kit_using_subcommand catalog" -s d -l dimg -d 'path to disk image' -r -F +complete -c a2kit -n "__fish_a2kit_using_subcommand catalog" -l generic -d 'use generic output format' +complete -c a2kit -n "__fish_a2kit_using_subcommand catalog" -s h -l help -d 'Print help' +complete -c a2kit -n "__fish_a2kit_using_subcommand cat" -s f -l file -d 'path of directory inside disk image' -r +complete -c a2kit -n "__fish_a2kit_using_subcommand cat" -s d -l dimg -d 'path to disk image' -r -F +complete -c a2kit -n "__fish_a2kit_using_subcommand cat" -l generic -d 'use generic output format' +complete -c a2kit -n "__fish_a2kit_using_subcommand cat" -s h -l help -d 'Print help' +complete -c a2kit -n "__fish_a2kit_using_subcommand dir" -s f -l file -d 'path of directory inside disk image' -r +complete -c a2kit -n "__fish_a2kit_using_subcommand dir" -s d -l dimg -d 'path to disk image' -r -F +complete -c a2kit -n "__fish_a2kit_using_subcommand dir" -l generic -d 'use generic output format' +complete -c a2kit -n "__fish_a2kit_using_subcommand dir" -s h -l help -d 'Print help' +complete -c a2kit -n "__fish_a2kit_using_subcommand ls" -s f -l file -d 'path of directory inside disk image' -r +complete -c a2kit -n "__fish_a2kit_using_subcommand ls" -s d -l dimg -d 'path to disk image' -r -F +complete -c a2kit -n "__fish_a2kit_using_subcommand ls" -l generic -d 'use generic output format' +complete -c a2kit -n "__fish_a2kit_using_subcommand ls" -s h -l help -d 'Print help' +complete -c a2kit -n "__fish_a2kit_using_subcommand tree" -s d -l dimg -d 'path to disk image' -r -F +complete -c a2kit -n "__fish_a2kit_using_subcommand tree" -l meta -d 'include metadata' +complete -c a2kit -n "__fish_a2kit_using_subcommand tree" -s h -l help -d 'Print help' +complete -c a2kit -n "__fish_a2kit_using_subcommand stat" -s d -l dimg -d 'path to disk image' -r -F +complete -c a2kit -n "__fish_a2kit_using_subcommand stat" -s h -l help -d 'Print help' +complete -c a2kit -n "__fish_a2kit_using_subcommand geometry" -s d -l dimg -d 'path to disk image' -r -F +complete -c a2kit -n "__fish_a2kit_using_subcommand geometry" -s h -l help -d 'Print help' +complete -c a2kit -n "__fish_a2kit_using_subcommand tokenize" -s a -l addr -d 'address of tokenized code (Applesoft only)' -r +complete -c a2kit -n "__fish_a2kit_using_subcommand tokenize" -s t -l type -d 'type of the file' -r -f -a "{atxt\t'',itxt\t'',mtxt\t''}" +complete -c a2kit -n "__fish_a2kit_using_subcommand tokenize" -s h -l help -d 'Print help' +complete -c a2kit -n "__fish_a2kit_using_subcommand tok" -s a -l addr -d 'address of tokenized code (Applesoft only)' -r +complete -c a2kit -n "__fish_a2kit_using_subcommand tok" -s t -l type -d 'type of the file' -r -f -a "{atxt\t'',itxt\t'',mtxt\t''}" +complete -c a2kit -n "__fish_a2kit_using_subcommand tok" -s h -l help -d 'Print help' +complete -c a2kit -n "__fish_a2kit_using_subcommand detokenize" -s t -l type -d 'type of the file' -r -f -a "{atok\t'',itok\t'',mtok\t''}" +complete -c a2kit -n "__fish_a2kit_using_subcommand detokenize" -s h -l help -d 'Print help' +complete -c a2kit -n "__fish_a2kit_using_subcommand dtok" -s t -l type -d 'type of the file' -r -f -a "{atok\t'',itok\t'',mtok\t''}" +complete -c a2kit -n "__fish_a2kit_using_subcommand dtok" -s h -l help -d 'Print help' +complete -c a2kit -n "__fish_a2kit_using_subcommand asm" -s a -l assembler -d 'assembler variant' -r -f -a "{m8\t'',m16\t'',m16+\t'',m32\t''}" +complete -c a2kit -n "__fish_a2kit_using_subcommand asm" -s w -l workspace -d 'workspace directory' -r +complete -c a2kit -n "__fish_a2kit_using_subcommand asm" -s h -l help -d 'Print help' +complete -c a2kit -n "__fish_a2kit_using_subcommand dasm" -s p -l proc -d 'processor target' -r -f -a "{6502\t'',65c02\t'',65802\t'',65816\t''}" +complete -c a2kit -n "__fish_a2kit_using_subcommand dasm" -l mx -d 'MX status bits' -r -f -a "{00\t'',01\t'',10\t'',11\t''}" +complete -c a2kit -n "__fish_a2kit_using_subcommand dasm" -s o -l org -d 'starting address' -r +complete -c a2kit -n "__fish_a2kit_using_subcommand dasm" -s h -l help -d 'Print help' +complete -c a2kit -n "__fish_a2kit_using_subcommand help; and not __fish_seen_subcommand_from mkdsk mkdir delete protect unprotect lock unlock rename retype verify minify renumber get put catalog tree stat geometry tokenize detokenize asm dasm help" -f -a "mkdsk" -d 'write a blank disk image to the given path' +complete -c a2kit -n "__fish_a2kit_using_subcommand help; and not __fish_seen_subcommand_from mkdsk mkdir delete protect unprotect lock unlock rename retype verify minify renumber get put catalog tree stat geometry tokenize detokenize asm dasm help" -f -a "mkdir" -d 'create a new directory inside a disk image' +complete -c a2kit -n "__fish_a2kit_using_subcommand help; and not __fish_seen_subcommand_from mkdsk mkdir delete protect unprotect lock unlock rename retype verify minify renumber get put catalog tree stat geometry tokenize detokenize asm dasm help" -f -a "delete" -d 'delete a file or directory inside a disk image' +complete -c a2kit -n "__fish_a2kit_using_subcommand help; and not __fish_seen_subcommand_from mkdsk mkdir delete protect unprotect lock unlock rename retype verify minify renumber get put catalog tree stat geometry tokenize detokenize asm dasm help" -f -a "protect" -d 'password protect a disk or file' +complete -c a2kit -n "__fish_a2kit_using_subcommand help; and not __fish_seen_subcommand_from mkdsk mkdir delete protect unprotect lock unlock rename retype verify minify renumber get put catalog tree stat geometry tokenize detokenize asm dasm help" -f -a "unprotect" -d 'remove password protection from a disk or file' +complete -c a2kit -n "__fish_a2kit_using_subcommand help; and not __fish_seen_subcommand_from mkdsk mkdir delete protect unprotect lock unlock rename retype verify minify renumber get put catalog tree stat geometry tokenize detokenize asm dasm help" -f -a "lock" -d 'write protect a file or directory inside a disk image' +complete -c a2kit -n "__fish_a2kit_using_subcommand help; and not __fish_seen_subcommand_from mkdsk mkdir delete protect unprotect lock unlock rename retype verify minify renumber get put catalog tree stat geometry tokenize detokenize asm dasm help" -f -a "unlock" -d 'remove write protection from a file or directory inside a disk image' +complete -c a2kit -n "__fish_a2kit_using_subcommand help; and not __fish_seen_subcommand_from mkdsk mkdir delete protect unprotect lock unlock rename retype verify minify renumber get put catalog tree stat geometry tokenize detokenize asm dasm help" -f -a "rename" -d 'rename a file or directory inside a disk image' +complete -c a2kit -n "__fish_a2kit_using_subcommand help; and not __fish_seen_subcommand_from mkdsk mkdir delete protect unprotect lock unlock rename retype verify minify renumber get put catalog tree stat geometry tokenize detokenize asm dasm help" -f -a "retype" -d 'change file type inside a disk image' +complete -c a2kit -n "__fish_a2kit_using_subcommand help; and not __fish_seen_subcommand_from mkdsk mkdir delete protect unprotect lock unlock rename retype verify minify renumber get put catalog tree stat geometry tokenize detokenize asm dasm help" -f -a "verify" -d 'read from stdin and error check' +complete -c a2kit -n "__fish_a2kit_using_subcommand help; and not __fish_seen_subcommand_from mkdsk mkdir delete protect unprotect lock unlock rename retype verify minify renumber get put catalog tree stat geometry tokenize detokenize asm dasm help" -f -a "minify" -d 'reduce program size' +complete -c a2kit -n "__fish_a2kit_using_subcommand help; and not __fish_seen_subcommand_from mkdsk mkdir delete protect unprotect lock unlock rename retype verify minify renumber get put catalog tree stat geometry tokenize detokenize asm dasm help" -f -a "renumber" -d 'renumber BASIC program lines' +complete -c a2kit -n "__fish_a2kit_using_subcommand help; and not __fish_seen_subcommand_from mkdsk mkdir delete protect unprotect lock unlock rename retype verify minify renumber get put catalog tree stat geometry tokenize detokenize asm dasm help" -f -a "get" -d 'read from stdin, local, or disk image, write to stdout' +complete -c a2kit -n "__fish_a2kit_using_subcommand help; and not __fish_seen_subcommand_from mkdsk mkdir delete protect unprotect lock unlock rename retype verify minify renumber get put catalog tree stat geometry tokenize detokenize asm dasm help" -f -a "put" -d 'read from stdin, write to local or disk image' +complete -c a2kit -n "__fish_a2kit_using_subcommand help; and not __fish_seen_subcommand_from mkdsk mkdir delete protect unprotect lock unlock rename retype verify minify renumber get put catalog tree stat geometry tokenize detokenize asm dasm help" -f -a "catalog" -d 'write disk image catalog to stdout' +complete -c a2kit -n "__fish_a2kit_using_subcommand help; and not __fish_seen_subcommand_from mkdsk mkdir delete protect unprotect lock unlock rename retype verify minify renumber get put catalog tree stat geometry tokenize detokenize asm dasm help" -f -a "tree" -d 'write directory tree as a JSON string to stdout' +complete -c a2kit -n "__fish_a2kit_using_subcommand help; and not __fish_seen_subcommand_from mkdsk mkdir delete protect unprotect lock unlock rename retype verify minify renumber get put catalog tree stat geometry tokenize detokenize asm dasm help" -f -a "stat" -d 'write FS statistics as a JSON string to stdout' +complete -c a2kit -n "__fish_a2kit_using_subcommand help; and not __fish_seen_subcommand_from mkdsk mkdir delete protect unprotect lock unlock rename retype verify minify renumber get put catalog tree stat geometry tokenize detokenize asm dasm help" -f -a "geometry" -d 'write disk geometry as a JSON string to stdout' +complete -c a2kit -n "__fish_a2kit_using_subcommand help; and not __fish_seen_subcommand_from mkdsk mkdir delete protect unprotect lock unlock rename retype verify minify renumber get put catalog tree stat geometry tokenize detokenize asm dasm help" -f -a "tokenize" -d 'read from stdin, tokenize, write to stdout' +complete -c a2kit -n "__fish_a2kit_using_subcommand help; and not __fish_seen_subcommand_from mkdsk mkdir delete protect unprotect lock unlock rename retype verify minify renumber get put catalog tree stat geometry tokenize detokenize asm dasm help" -f -a "detokenize" -d 'read from stdin, detokenize, write to stdout' +complete -c a2kit -n "__fish_a2kit_using_subcommand help; and not __fish_seen_subcommand_from mkdsk mkdir delete protect unprotect lock unlock rename retype verify minify renumber get put catalog tree stat geometry tokenize detokenize asm dasm help" -f -a "asm" -d 'read from stdin, assemble, write to stdout' +complete -c a2kit -n "__fish_a2kit_using_subcommand help; and not __fish_seen_subcommand_from mkdsk mkdir delete protect unprotect lock unlock rename retype verify minify renumber get put catalog tree stat geometry tokenize detokenize asm dasm help" -f -a "dasm" -d 'read from stdin, disassemble, write to stdout' +complete -c a2kit -n "__fish_a2kit_using_subcommand help; and not __fish_seen_subcommand_from mkdsk mkdir delete protect unprotect lock unlock rename retype verify minify renumber get put catalog tree stat geometry tokenize detokenize asm dasm help" -f -a "help" -d 'Print this message or the help of the given subcommand(s)' diff --git a/src/cli.rs b/src/cli.rs index 7cd6949..7d74d2d 100644 --- a/src/cli.rs +++ b/src/cli.rs @@ -1,4 +1,4 @@ -use clap::{arg, crate_version, ArgAction, ArgGroup, Command, ValueHint}; +use clap::{arg, crate_version, Arg, ArgAction, ArgGroup, Command, ValueHint}; const RNG_HELP: &str = "some types support ranges using `..` and `,,` separators, e.g., `1..4,,7..10` would mean 1,2,3,7,8,9"; @@ -344,11 +344,11 @@ Detokenize from image: `a2kit get -f prog -t atok -d myimg.dsk | a2kit detokeniz main_cmd = main_cmd.subcommand( Command::new("tokenize") .arg( - arg!(-a --addr
"address of tokenized code (Applesoft only)") + Arg::new("addr").short('a').long("addr").help("address of tokenized code (Applesoft only)").value_name("ADDRESS") .required(false), ) .arg( - arg!(-t --type "type of the file") + Arg::new("type").short('t').long("type").help("type of the file").value_name("TYPE") .required(true) .value_parser(["atxt", "itxt", "mtxt"]), ) @@ -358,13 +358,46 @@ Detokenize from image: `a2kit get -f prog -t atok -d myimg.dsk | a2kit detokeniz main_cmd = main_cmd.subcommand( Command::new("detokenize") .arg( - arg!(-t --type "type of the file") + Arg::new("type").short('t').long("type").help("type of the file").value_name("TYPE") .required(true) .value_parser(["atok", "itok", "mtok"]), ) .visible_alias("dtok") .about("read from stdin, detokenize, write to stdout"), ); - + main_cmd = main_cmd.subcommand( + Command::new("asm") + .arg( + Arg::new("assembler").short('a').long("assembler").help("assembler variant").value_name("NAME") + .required(false) + .value_parser(["m8","m16","m16+","m32"]) + .default_value("m8") + ) + .arg( + Arg::new("workspace").short('w').long("workspace").help("workspace directory").value_name("PATH") + .required(false) + ) + .about("read from stdin, assemble, write to stdout") + .after_help("At present this is limited, it will error out if program counter or symbol value cannot be determined.") + ); + main_cmd = main_cmd.subcommand( + Command::new("dasm") + .arg( + Arg::new("proc").short('p').long("proc").help("processor target").value_name("NAME") + .required(true) + .value_parser(["6502","65c02","65802","65816"]) + ) + .arg( + Arg::new("mx").long("mx").help("MX status bits").value_name("BINARY") + .required(false) + .value_parser(["00","01","10","11"]) + .default_value("11") + ) + .arg( + Arg::new("org").short('o').long("org").help("starting address").value_name("ADDRESS") + .required(true) + ) + .about("read from stdin, disassemble, write to stdout") + ); return main_cmd; } diff --git a/src/lang/merlin/assembly.rs b/src/lang/merlin/assembly.rs index 4b3b585..3bfd079 100644 --- a/src/lang/merlin/assembly.rs +++ b/src/lang/merlin/assembly.rs @@ -17,6 +17,7 @@ use crate::lang::merlin::{Operation,ProcessorType}; use crate::lang::{node_radix, node_text, Navigation, Navigate}; use crate::{STDRESULT,DYNERR}; +const IGNORED_PSOPS: [&str;16] = ["ast", "cas", "cyc", "dsk", "exp", "kbd", "lst", "lstdo", "obj", "pag", "pau", "sav", "skp", "tr", "ttl", "typ"]; /// closely parallels Merlin 8/16 error messages #[derive(Error,Debug)] @@ -314,11 +315,73 @@ impl Assembler { None => Err(Box::new(Error::ExpressionEvaluation)) } }, + "pchar" => { + let txt = node.utf8_text(source.as_bytes())?; + Ok(txt.as_bytes()[1] as i64) + }, + "nchar" => { + let txt = node.utf8_text(source.as_bytes())?; + Ok(txt.as_bytes()[1] as i64 + 0x80) + }, + "current_addr" => { + match self.pc { + Some(pc) => Ok(pc as i64), + None => Err(Box::new(Error::UnresolvedProgramCounter)) + } + }, "label_ref" => { let txt = node_text(node, source); - match (txt.starts_with("_"),node_radix(node, source, "_", "%")) { - (true,Some(v)) => Ok(v), - _ => Err(Box::new(Error::ExpressionEvaluation)) + if let Some(sym) = self.symbols.globals.get(&txt) { + if let Some(val) = sym.value { + return Ok(val); + } + } + if let Some(sym) = self.symbols.vars.get(&txt) { + if let Some(val) = sym.value { + return Ok(val); + } + } + Err(Box::new(Error::UndefinedLabel)) + }, + "unary_aexpr" => { + if node.child_count() != 2 { + Err(Box::new(Error::Syntax)) + } else { + let raw = self.eval_expr(&node.named_child(0).unwrap(), source)?; + if node.named_child(1).unwrap().kind() == "eop_minus" { + Ok(-raw) + } else { + Ok(raw) + } + } + }, + "binary_aexpr" => { + if node.child_count() != 3 { + Err(Box::new(Error::Syntax)) + } else { + let val1 = self.eval_expr(&node.named_child(0).unwrap(), source)?; + let val2 = self.eval_expr(&node.named_child(2).unwrap(), source)?; + match node.named_child(1).unwrap().kind() { + "eop_plus" => Ok(val1 + val2), + "eop_minus" => Ok(val1 - val2), + "eop_times" => Ok(val1 * val2), + "eop_div" => Ok(val1 / val2), + "eop_or" => Ok(val1 | val2), + "eop_and" => Ok(val1 & val2), + "eop_xor" => Ok(val1 ^ val2), + "cop_less" => Ok(match val1 < val2 { true => 1, false => 0}), + "cop_gtr" => Ok(match val1 > val2 { true => 1, false => 0}), + "cop_eq" => Ok(match val1 == val2 { true => 1, false => 0}), + "cop_neq" => Ok(match val1 != val2 { true => 1, false => 0}), + _ => Err(Box::new(Error::ExpressionEvaluation)) + } + } + }, + "braced_aexpr" => { + if let Some(child) = node.named_child(0) { + self.eval_expr(&child, source) + } else { + Err(Box::new(Error::Syntax)) } }, _ => Err(Box::new(Error::ExpressionEvaluation)) @@ -472,6 +535,9 @@ impl Navigate for Assembler { } if curs.node().kind().starts_with("psop_") { + if IGNORED_PSOPS.contains(&&curs.node().kind()[5..]) { + return Ok(Navigation::Exit); + } match curs.node().next_named_sibling() { Some(arg) => { match arg.kind() { diff --git a/src/lang/merlin/disassembly.rs b/src/lang/merlin/disassembly.rs index 3f0c392..afa09ae 100644 --- a/src/lang/merlin/disassembly.rs +++ b/src/lang/merlin/disassembly.rs @@ -51,16 +51,44 @@ impl Operand { } } +struct DasmLine { + address: usize, + instruction: String, + prefix: String, + suffix: String, + operand: Option, + references: Vec +} + +impl DasmLine { + fn new() -> Self { + Self { + address: 0, + instruction: String::new(), + prefix: String::new(), + suffix: String::new(), + operand: None, + references: Vec::new() + } + } + fn basic(addr: usize, ins: String, op: Operand) -> Self { + Self { + address: addr, + instruction: ins, + prefix: String::new(), + suffix: String::new(), + operand: Some(op), + references: Vec::new() + } + } +} + pub struct Disassembler { config: Settings, m8bit: bool, x8bit: bool, dasm_map: HashMap, - instructions: Vec, - prefixes: Vec, - suffixes: Vec, - operands: Vec>, - addresses: Vec, + dasm_lines: Vec, std_patt: regex::Regex, mov_patt: regex::Regex } @@ -117,11 +145,7 @@ impl Disassembler { m8bit: true, x8bit: true, dasm_map: book.create_dasm_map(), - instructions: Vec::new(), - prefixes: Vec::new(), - suffixes: Vec::new(), - operands: Vec::new(), - addresses: Vec::new(), + dasm_lines: Vec::new(), std_patt: regex::Regex::new(r"[0-9]").expect(super::RCH), mov_patt: regex::Regex::new(r"[0-9][0-9]").expect(super::RCH) } @@ -141,45 +165,39 @@ impl Disassembler { } return s.to_uppercase(); } - fn push_data_psop(&mut self, ins: String, dat: String) { - self.instructions.push(ins); - self.operands.push(Some(Operand::txt(dat))); + fn push_data_psop(&mut self, addr: usize, ins: String, dat: String) { + self.dasm_lines.push(DasmLine::basic(addr, ins, Operand::txt(dat))); } fn push_data_pattern(&mut self, addr: usize, img: &[u8], length: usize, reps: usize) { if reps > 1 { - self.addresses.push(addr); - self.push_data_psop(self.modify("LUP"), reps.to_string()); + self.push_data_psop(addr, self.modify("LUP"), reps.to_string()); } let v: Vec = img[addr..addr+length].to_vec(); - self.push_data_psop(self.modify("HEX"),v.encode_hex_upper()); + self.push_data_psop(addr, self.modify("HEX"),v.encode_hex_upper()); if reps > 1 { - self.addresses.push(addr); - self.push_data_psop("--^".to_string(), "".to_string()); + self.push_data_psop(addr, "--^".to_string(), "".to_string()); } } /// * `neg` indicates the string that was found is negative ASCII /// * `s` is the string that was found /// * `lookahead` is the byte value that follows the string /// * returns 0, or 1 if a terminating byte was included - fn push_string(&mut self, neg: bool, s: String, lookahead: Option) -> usize { + fn push_string(&mut self, addr: usize, neg: bool, s: String, lookahead: Option) -> usize { let mut delim = match neg { true => "\"" , false => "'"}; if s.starts_with(delim) { delim = match neg { true=> "&", false => "/"}; } let off = match neg { true => 0, false => 128 }; if lookahead.is_some() && lookahead.unwrap() == 0 { - self.instructions.push(self.modify("ASC")); - self.operands.push(Some(Operand::txt([delim,&s,delim,",00"].concat()))); + self.dasm_lines.push(DasmLine::basic(addr,self.modify("ASC"),Operand::txt([delim,&s,delim,",00"].concat()))); return 1; } if lookahead.is_some() && probably_string(lookahead.unwrap(), off) { let term = String::from_utf8(vec![lookahead.unwrap() - off]).expect(super::RCH); - self.instructions.push(self.modify("DCI")); - self.operands.push(Some(Operand::txt([delim,&s,&term,delim].concat()))); + self.dasm_lines.push(DasmLine::basic(addr,self.modify("DCI"),Operand::txt([delim,&s,&term,delim].concat()))); return 1; } - self.instructions.push(self.modify("ASC")); - self.operands.push(Some(Operand::txt([delim, &s, delim].concat()))); + self.dasm_lines.push(DasmLine::basic(addr, self.modify("ASC"), Operand::txt([delim, &s, delim].concat()))); return 0; } fn try_data_run(&mut self, img: &[u8], mut ptr: usize, end: usize) -> usize { @@ -237,7 +255,7 @@ impl Disassembler { pat4.0 -= pat4.0 % 4; } if uniform.0 > 0 && uniform.0 >= pat2.0 && uniform.0 >= pat4.0 && uniform.0 >= pos_str.0 && uniform.0 >= neg_str.0 { - self.push_data_psop("DS".to_string(), [uniform.0.to_string(), ",$".to_string(), vec![img[ptr0]].encode_hex_upper()].concat()); + self.push_data_psop(ptr0, "DS".to_string(), [uniform.0.to_string(), ",$".to_string(), vec![img[ptr0]].encode_hex_upper()].concat()); return uniform.0; } if pat2.0 > 0 && pat2.0 >= pat4.0 && pat2.0 >= pos_str.0 && pat2.0 >= neg_str.0 { @@ -255,7 +273,7 @@ impl Disassembler { }; let v = img[ptr0..ptr0+pos_str.0].to_vec(); let s = String::from_utf8(v).expect(super::RCH); - return s.len() + self.push_string(false, s, lookahead); + return s.len() + self.push_string(ptr0, false, s, lookahead); } if neg_str.0 > 0 { let lookahead: Option = match ptr0 + neg_str.0 < end { @@ -265,7 +283,7 @@ impl Disassembler { let mut v = img[ptr0..ptr0+neg_str.0].to_vec(); v = v.iter().map(|x| x - 128).collect(); let s = String::from_utf8(v).expect(super::RCH); - return s.len() + self.push_string(true, s, lookahead); + return s.len() + self.push_string(ptr0, true, s, lookahead); } return 0 } @@ -300,6 +318,52 @@ impl Disassembler { } } None + } + fn push_instruction(&mut self, img: &[u8], mut addr: usize, op: MachineOperation, operand_bytes: usize) -> Result { + let mut new_line = DasmLine::new(); + new_line.address = addr; + new_line.instruction = self.modify(&op.mnemonic); + addr += 1; + if self.mov_patt.is_match(&op.operand_snippet) { + new_line.operand = Some(Operand::mov(img[addr+1],img[addr])); + addr += 2; + } else if operand_bytes > 0 { + let mut val = u32_from_operand(&img[addr..addr+operand_bytes]) as usize; + if op.relative { + let ival = match operand_bytes { + 1 => match val < 128 { + true => (addr + operand_bytes + val) as i64, + false => addr as i64 + operand_bytes as i64 + val as i64 - 256 + }, + _ => match val < 0x8000 { + true => (addr + operand_bytes + val) as i64, + false => addr as i64 + operand_bytes as i64 + val as i64 - 0x10000 + } + }; + val = usize::try_from(ival)?; + } + if !op.operand_snippet.starts_with("#") { + new_line.references.push(val); + } + if op.relative { + new_line.operand = Some(Operand::rel_addr(val as u32,operand_bytes,&op.operand_snippet)); + } else { + // suffix forcing appears to be the most universal + new_line.suffix = match operand_bytes { + 2 if val < 0x100 && op.abs_suffixable => ":".to_string(), + 3 if val < 0x10000 && op.absl_suffixable => "L".to_string(), + _ => String::new() + }; + new_line.prefix = match operand_bytes { + 3 if op.absl_prefixable => ">".to_string(), + _ => String::new() + }; + new_line.operand = Some(Operand::abs_addr(val as u32,operand_bytes,&self.modify(&op.operand_snippet))); + } + addr += operand_bytes; + } + self.dasm_lines.push(new_line); + Ok(addr) } pub fn disassemble(&mut self, img: &[u8], range: DasmRange, proc: ProcessorType, labeling: &str) -> Result { let addr_range = match range { @@ -310,77 +374,34 @@ impl Disassembler { }; let mut addr = addr_range[0]; let mut code = String::new(); - self.addresses = Vec::new(); - self.instructions = Vec::new(); - self.prefixes = Vec::new(); - self.suffixes = Vec::new(); - self.operands = Vec::new(); - let mut references = HashSet::new(); + + self.dasm_lines = Vec::new(); let mut labels = HashSet::new(); while addr < addr_range[1] { - let mut prefix = String::new(); - let mut suffix = String::new(); - self.addresses.push(addr); if let Some((op,operand_bytes)) = self.is_instruction(img[addr],addr,addr_range[1],&proc) { - self.instructions.push(self.modify(&op.mnemonic)); - addr += 1; - if self.mov_patt.is_match(&op.operand_snippet) { - self.operands.push(Some(Operand::mov(img[addr+1],img[addr]))); - addr += 2; - } else if operand_bytes > 0 { - let mut val = u32_from_operand(&img[addr..addr+operand_bytes]) as usize; - if op.relative { - let ival = match operand_bytes { - 1 => match val < 128 { - true => (addr + operand_bytes + val) as i64, - false => addr as i64 + operand_bytes as i64 + val as i64 - 256 - }, - _ => match val < 0x8000 { - true => (addr + operand_bytes + val) as i64, - false => addr as i64 + operand_bytes as i64 + val as i64 - 0x10000 - } - }; - val = usize::try_from(ival)?; - } - if !op.operand_snippet.starts_with("#") { - references.insert(val); - } - if op.relative { - self.operands.push(Some(Operand::rel_addr(val as u32,operand_bytes,&op.operand_snippet))); - } else { - // suffix forcing appears to be the most universal - suffix = match operand_bytes { - 2 if val < 0x100 && op.abs_suffixable => ":".to_string(), - 3 if val < 0x10000 && op.absl_suffixable => "L".to_string(), - _ => String::new() - }; - prefix = match operand_bytes { - 3 if op.absl_prefixable => ">".to_string(), - _ => String::new() - }; - self.operands.push(Some(Operand::abs_addr(val as u32,operand_bytes,&self.modify(&op.operand_snippet)))); - } - addr += operand_bytes; - } else { - self.operands.push(None); - } + addr = self.push_instruction(img, addr, op, operand_bytes)?; } else { let data_bytes = self.try_data_run(img, addr, addr_range[1]); addr += data_bytes; if data_bytes == 0 { - self.push_data_psop(self.modify("DFB"), hex_from_val("$",img[addr] as u32,1)); + self.push_data_psop(addr, self.modify("DFB"), hex_from_val("$",img[addr] as u32,1)); addr += 1; } } - self.prefixes.push(prefix); - self.suffixes.push(suffix); } - // first pass determine labels - for i in 0..self.addresses.len() { + // gather references + let mut references = HashSet::new(); + for line in &self.dasm_lines { + for r in &line.references { + references.insert(*r); + } + } + // determine labels + for i in 0..self.dasm_lines.len() { if labeling.contains("all") { - labels.insert(self.addresses[i]); - } else if labeling.contains("some") && references.contains(&self.addresses[i]) { - labels.insert(self.addresses[i]); + labels.insert(self.dasm_lines[i].address); + } else if labeling.contains("some") && references.contains(&self.dasm_lines[i].address) { + labels.insert(self.dasm_lines[i].address); } } let widths = [self.config.columns.c1 as usize,self.config.columns.c2 as usize,self.config.columns.c3 as usize]; @@ -388,18 +409,18 @@ impl Disassembler { ProcessorType::_65c816 => 3, _ => 2 }; - for i in 0..self.addresses.len() { + for i in 0..self.dasm_lines.len() { let mut line = String::new(); - if labels.contains(&self.addresses[i]) { + if labels.contains(&self.dasm_lines[i].address) { line += "_"; - line += &hex_from_val("",self.addresses[i] as u32,pc_bytes); + line += &hex_from_val("",self.dasm_lines[i].address as u32,pc_bytes); } line.push(super::COLUMN_SEPARATOR); - line += &self.instructions[i]; - line += &self.suffixes[i]; - if let Some(operand) = &self.operands[i] { + line += &self.dasm_lines[i].instruction; + line += &self.dasm_lines[i].suffix; + if let Some(operand) = &self.dasm_lines[i].operand { line.push(super::COLUMN_SEPARATOR); - line += &self.prefixes[i]; + line += &self.dasm_lines[i].prefix; if operand.num.len() == 1 && labels.contains(&(operand.num[0] as usize)) { line += "_"; line += &hex_from_val("",operand.num[0] as u32,pc_bytes); @@ -416,24 +437,21 @@ impl Disassembler { pub fn disassemble_as_data(&mut self, img: &[u8]) -> String { let mut addr = 0; let mut code = String::new(); - self.addresses = Vec::new(); - self.instructions = Vec::new(); - self.operands = Vec::new(); + self.dasm_lines = Vec::new(); while addr < img.len() { - self.addresses.push(addr); let data_bytes = self.try_data_run(img, addr, img.len()); addr += data_bytes; if data_bytes == 0 { - self.push_data_psop(self.modify("DFB"), hex_from_val("$",img[addr] as u32,1)); + self.push_data_psop(addr, self.modify("DFB"), hex_from_val("$",img[addr] as u32,1)); addr += 1; } } let widths = [self.config.columns.c1 as usize,self.config.columns.c2 as usize,self.config.columns.c3 as usize]; - for i in 0..self.addresses.len() { + for i in 0..self.dasm_lines.len() { let mut line = String::new(); line.push(super::COLUMN_SEPARATOR); - line += &self.instructions[i]; - if let Some(operand) = &self.operands[i] { + line += &self.dasm_lines[i].instruction; + if let Some(operand) = &self.dasm_lines[i].operand { line.push(super::COLUMN_SEPARATOR); line += &operand.txt; } diff --git a/src/lang/mod.rs b/src/lang/mod.rs index d6201fe..337d992 100644 --- a/src/lang/mod.rs +++ b/src/lang/mod.rs @@ -224,10 +224,13 @@ pub fn node_integer(node: &tree_sitter::Node,source: &str) -> Option } /// Parse a node that may use a prefix to indicate radix, e.g., `$0F` or `%00001111`. -/// This will ignore all spaces and underscores. +/// This will ignore all spaces and underscores, except for an underscore prefix. pub fn node_radix(node: &tree_sitter::Node, source: &str, hex: &str, bin: &str) -> Option { if let Ok(s) = node.utf8_text(source.as_bytes()) { - let trimmed = s.to_string().replace(" ","").replace("_",""); + let mut trimmed = s.to_string().replace(" ","").replace("_",""); + if s.starts_with("_") && (hex=="_" || bin=="_") { + trimmed = ["_",&trimmed].concat(); + } if trimmed.starts_with(hex) { match T::from_str_radix(&trimmed[1..],16) { Ok(ans) => Some(ans), diff --git a/src/main.rs b/src/main.rs index 675ad09..fdb798b 100644 --- a/src/main.rs +++ b/src/main.rs @@ -9,7 +9,6 @@ use std::io::{Read,Write}; use std::str::FromStr; #[cfg(windows)] use colored; -use log::error; use a2kit::commands; use a2kit::commands::{ItemType,CommandError}; use a2kit::lang; @@ -18,7 +17,6 @@ use a2kit::lang::integer; use a2kit::lang::merlin; use a2kit::lang::server::Analysis; use colored::Colorize; -use log::warn; mod cli; @@ -150,7 +148,7 @@ fn main() -> Result<(),Box> if let Some(cmd) = matches.subcommand_matches("minify") { if atty::is(atty::Stream::Stdin) { - error!("line entry is not supported for `minify`, please pipe something in"); + log::error!("line entry is not supported for `minify`, please pipe something in"); return Err(Box::new(CommandError::InvalidCommand)); } let typ = ItemType::from_str(cmd.get_one::("type").expect(RCH)); @@ -158,12 +156,12 @@ fn main() -> Result<(),Box> match std::io::stdin().read_to_string(&mut program) { Ok(_) => {}, Err(e) => { - error!("the file to minify could not be interpreted as a string"); + log::error!("the file to minify could not be interpreted as a string"); return Err(Box::new(e)); } } if program.len()==0 { - error!("minify did not receive any data from previous node"); + log::error!("minify did not receive any data from previous node"); return Err(Box::new(CommandError::InvalidCommand)); } return match typ @@ -189,7 +187,7 @@ fn main() -> Result<(),Box> if let Some(cmd) = matches.subcommand_matches("renumber") { if atty::is(atty::Stream::Stdin) { - error!("line entry is not supported for `renumber`, please pipe something in"); + log::error!("line entry is not supported for `renumber`, please pipe something in"); return Err(Box::new(CommandError::InvalidCommand)); } let typ = ItemType::from_str(cmd.get_one::("type").expect(RCH)); @@ -202,12 +200,12 @@ fn main() -> Result<(),Box> match std::io::stdin().read_to_string(&mut program) { Ok(_) => {}, Err(e) => { - error!("the file to renumber could not be interpreted as a string"); + log::error!("the file to renumber could not be interpreted as a string"); return Err(Box::new(e)); } } if program.len()==0 { - error!("renumber did not receive any data from previous node"); + log::error!("renumber did not receive any data from previous node"); return Err(Box::new(CommandError::InvalidCommand)); } return match typ @@ -225,7 +223,7 @@ fn main() -> Result<(),Box> let mut renumberer = integer::renumber::Renumberer::new(); renumberer.set_flags(match reorder {true => 1, false => 0}); let new_prog = renumberer.renumber(&program,beg,end,first,step)?; - warn!("line number expressions must be manually adjusted"); + log::warn!("line number expressions must be manually adjusted"); println!("{}",&new_prog); Ok(()) } @@ -237,7 +235,7 @@ fn main() -> Result<(),Box> if let Some(cmd) = matches.subcommand_matches("tokenize") { if atty::is(atty::Stream::Stdin) { - error!("line entry is not supported for `tokenize`, please pipe something in"); + log::error!("line entry is not supported for `tokenize`, please pipe something in"); return Err(Box::new(CommandError::InvalidCommand)); } let typ = ItemType::from_str(cmd.get_one::("type").expect(RCH)); @@ -246,12 +244,12 @@ fn main() -> Result<(),Box> match std::io::stdin().read_to_string(&mut program) { Ok(_) => {}, Err(e) => { - error!("the file to tokenize could not be interpreted as a string"); + log::error!("the file to tokenize could not be interpreted as a string"); return Err(Box::new(e)); } } if program.len()==0 { - error!("tokenize did not receive any data from previous node"); + log::error!("tokenize did not receive any data from previous node"); return Err(Box::new(CommandError::InvalidCommand)); } return match typ @@ -259,7 +257,7 @@ fn main() -> Result<(),Box> Ok(ItemType::ApplesoftText) => { lang::verify_str(tree_sitter_applesoft::language(),&program)?; if addr_opt==None { - error!("address needed to tokenize Applesoft"); + log::error!("address needed to tokenize Applesoft"); return Err(Box::new(CommandError::InvalidCommand)); } if let Ok(addr) = u16::from_str_radix(addr_opt.expect(RCH),10) { @@ -277,7 +275,7 @@ fn main() -> Result<(),Box> Ok(ItemType::IntegerText) => { lang::verify_str(tree_sitter_integerbasic::language(),&program)?; if let Some(_addr) = addr_opt { - error!("unnecessary address argument"); + log::error!("unnecessary address argument"); return Err(Box::new(CommandError::InvalidCommand)); } let mut tokenizer = integer::tokenizer::Tokenizer::new(); @@ -292,7 +290,7 @@ fn main() -> Result<(),Box> Ok(ItemType::MerlinText) => { lang::verify_str(tree_sitter_merlin6502::language(),&program)?; if let Some(_addr) = addr_opt { - error!("unnecessary address argument"); + log::error!("unnecessary address argument"); return Err(Box::new(CommandError::InvalidCommand)); } let mut tokenizer = merlin::tokenizer::Tokenizer::new(); @@ -312,14 +310,14 @@ fn main() -> Result<(),Box> if let Some(cmd) = matches.subcommand_matches("detokenize") { if atty::is(atty::Stream::Stdin) { - error!("line entry is not supported for `detokenize`, please pipe something in"); + log::error!("line entry is not supported for `detokenize`, please pipe something in"); return Err(Box::new(CommandError::InvalidCommand)); } let typ = ItemType::from_str(cmd.get_one::("type").expect(RCH)); let mut tok: Vec = Vec::new(); std::io::stdin().read_to_end(&mut tok).expect("could not read input stream"); if tok.len()==0 { - error!("detokenize did not receive any data from previous node"); + log::error!("detokenize did not receive any data from previous node"); return Err(Box::new(CommandError::InvalidCommand)); } return match typ @@ -352,6 +350,97 @@ fn main() -> Result<(),Box> }; } + // Assemble source code + + if let Some(cmd) = matches.subcommand_matches("asm") { + let mut config = merlin::settings::Settings::new(); + config.version = match cmd.get_one::("assembler").expect(RCH).as_str() { + "m8" => merlin::MerlinVersion::Merlin8, + "m16" => merlin::MerlinVersion::Merlin16, + "m16+" => merlin::MerlinVersion::Merlin16Plus, + "m32" => merlin::MerlinVersion::Merlin32, + _ => panic!("{}",RCH) + }; + let mut analyzer = lang::merlin::diagnostics::Analyzer::new(); + analyzer.set_config(config.clone()); + // if cmd.value_source("config").unwrap()==ValueSource::CommandLine { + // analyzer.update_config(cmd.get_one::("config").unwrap())?; + // } + let doc = lang::Document::from_string(analyzer.read_stdin(),0); + if let Some(ws_path) = cmd.get_one::("workspace") { + match lsp_types::Url::from_directory_path(ws_path) { + Ok(uri) => analyzer.init_workspace(vec![uri],vec![doc.clone()])?, + Err(_) => return Err(Box::new(lang::Error::PathNotFound)) + } + } + analyzer.analyze(&doc)?; + let symbols = analyzer.get_symbols(); + for diag in analyzer.get_diags(&doc) { + lang::eprint_diagnostic(&diag,&doc.text); + } + let [err,_warn,_info] = analyzer.err_warn_info_counts(); + if err==0 { + let mut asm = merlin::assembly::Assembler::new(); + asm.set_config(config); + asm.use_shared_symbols(std::sync::Arc::new(symbols)); + let object = asm.spot_assemble(doc.text.clone(), 0, doc.text.len() as isize)?; + if atty::is(atty::Stream::Stdout) { + a2kit::display_block(0,&object); + } else { + std::io::stdout().write_all(&object).expect("could not write output stream"); + } + return Ok(()); + } else { + eprintln!("\u{2717} {} {}",err.to_string().red(),"errors".red()); + return Err(Box::new(lang::Error::Syntax)); + } + } + + // Disassemble binary to Merlin source + + if let Some(cmd) = matches.subcommand_matches("dasm") { + if atty::is(atty::Stream::Stdin) { + log::error!("line entry is not supported for `dasm`, please pipe something in"); + return Err(Box::new(CommandError::InvalidCommand)); + } + let proc = match cmd.get_one::("proc").expect(RCH).as_str() { + "6502" => merlin::ProcessorType::_6502, + "65c02" => merlin::ProcessorType::_65c02, + "65802" => merlin::ProcessorType::_65802, + "65816" => merlin::ProcessorType::_65c816, + _ => panic!("{}",RCH) + }; + let (m8bit,x8bit) = match cmd.get_one::("mx").expect(RCH).as_str() { + "00" => (false,false), + "01" => (false,true), + "10" => (true,false), + "11" => (true,true), + _ => panic!("{}",RCH) + }; + let org = match u16::from_str(cmd.get_one::("org").expect(RCH)) { + Ok(x) => x, + Err(_) => { + log::error!("origin did not parse as decimal unsigned 16 bit integer"); + return Err(Box::new(CommandError::OutOfRange)) + } + }; + let mut tok: Vec = Vec::new(); + tok.append(&mut vec![0;org as usize]); + std::io::stdin().read_to_end(&mut tok).expect("could not read input stream"); + if tok.len()==org as usize { + log::error!("dasm did not receive any data from previous node"); + return Err(Box::new(CommandError::InvalidCommand)); + } + let mut dasm = merlin::disassembly::Disassembler::new(); + dasm.set_mx(m8bit,x8bit); + let rng = merlin::disassembly::DasmRange::Range([org as usize,tok.len()]); + let program = dasm.disassemble(&tok, rng, proc, "some")?; + for line in program.lines() { + println!("{}",line); + } + return Ok(()); + } + // Create directory inside disk image if let Some(cmd) = matches.subcommand_matches("mkdir") { let path_to_img = cmd.get_one::("dimg").expect(RCH); @@ -473,7 +562,7 @@ fn main() -> Result<(),Box> return commands::get::get(cmd); } - error!("No subcommand was found, try `a2kit --help`"); + log::error!("No subcommand was found, try `a2kit --help`"); return Err(Box::new(CommandError::InvalidCommand)); }