Compare commits

...

26 Commits

Author SHA1 Message Date
F.B. a90f5f474b
Merge 5359bbf0e7 into 8d93e4c1ee 2026-02-16 13:59:25 -08:00
Shohei YOSHIDA 8d93e4c1ee
Merge pull request #1223 from zsh-users/update-golang
Update golang completion to version 1.26.0
2026-02-15 23:29:28 +09:00
Shohei YOSHIDA 3429cd2c1f
Merge pull request #1222 from zsh-users/update-flutter
Update flutter and dart completions
2026-02-15 23:29:09 +09:00
Shohei YOSHIDA 4dbdbd4f8b
Update 'go tool pprof' options 2026-02-13 15:06:34 +09:00
Shohei YOSHIDA 5a5edf6914
update fix subcommand for go 1.26 2026-02-12 16:57:28 +09:00
Shohei YOSHIDA 39b0b06c15
Update flutter completions to version 3.41 2026-02-12 15:58:10 +09:00
Shohei YOSHIDA d4af3659cc
update dart completion to version 3.11 2026-02-12 15:49:35 +09:00
Shohei YOSHIDA 46c88449e6
Support new subcommand 'widget-preview' completion 2026-02-12 10:10:04 +09:00
Shohei YOSHIDA 989d044545
Merge pull request #1221 from zsh-users/add-bento4
Add Bento4 tool completions
2026-02-04 15:29:27 +09:00
Shohei YOSHIDA 318dc0bec5
Add Bento4 tool completions 2026-02-03 13:38:16 +09:00
Shohei YOSHIDA a83d61b6c6
Merge pull request #1220 from zsh-users/update-node
Update node.js completion to version v25.5
2026-01-27 19:06:17 +09:00
Shohei YOSHIDA ad47c4a28f
Update node.js completion to version v25.5 2026-01-27 17:00:56 +09:00
fishBone000 5359bbf0e7
Forgot to change ToC 2024-09-18 06:07:34 +00:00
fishBone000 a3e89f7c56
Reread to make the doc more fluent 2024-09-18 06:06:48 +00:00
fishBone000 cf57a3266c
Try to fix ToC 2024-09-18 04:52:48 +00:00
fishBone000 41896a6013
Finish most TODOs 2024-09-18 04:43:01 +00:00
fishBone000 0d8667bb6a
Fix Table of Contents
I forgot to change it
2024-09-18 04:17:10 +00:00
fishBone000 79c6d1715f
Finish Other resources 2024-09-18 04:15:31 +00:00
fishBone000 f5e58a5ca7
Finish Tips 2024-09-18 04:12:15 +00:00
fishBone000 6c8cd1b111
Finish Gotchas (things to look out for) 2024-09-18 04:01:09 +00:00
fishBone000 eb711299c5
Finish Testing & debugging 2024-09-18 03:53:13 +00:00
fishBone000 d71c3c84cc
Finish Writing your own completion code 2024-09-18 03:43:52 +00:00
fishBone000 c3f1f7748d
Finish Getting started 2024-09-17 07:40:59 +00:00
fishBone000 45fd6f398a
Fix document file extension 2024-09-17 07:15:24 +00:00
fishBone000 26b538f012
Finish Intro 2024-09-17 07:13:14 +00:00
fishBone000 fd43209f3a
Beginning of zh_cn translation 2024-09-17 06:37:21 +00:00
6 changed files with 1094 additions and 173 deletions

318
src/_bento4 Normal file
View File

@ -0,0 +1,318 @@
#compdef aac2mp4 mp42aac mp42avc mp42hevc mp42hls mp42ts mp4compact mp4dash mp4dashclone mp4dcfpackager mp4decrypt mp4dump mp4edit mp4encrypt mp4extract mp4fragment mp4hls mp4iframeindex mp4info mp4mux mp4rtphintinfo mp4split mp4tag
# ------------------------------------------------------------------------------
# Copyright (c) 2026 Github zsh-users - https://github.com/zsh-users
#
# Permission is hereby granted, free of charge, to any person obtaining
# a copy of this software and associated documentation files (the
# "Software"), to deal in the Software without restriction, including
# without limitation the rights to use, copy, modify, merge, publish,
# distribute, sublicense, and/or sell copies of the Software, and to
# permit persons to whom the Software is furnished to do so, subject to
# the following conditions:
#
# The above copyright notice and this permission notice shall be included
# in all copies or substantial portions of the Software.
#
# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
# OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
# THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR
# OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
# ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
# OTHER DEALINGS IN THE SOFTWARE.
# ------------------------------------------------------------------------------
# Description
# -----------
#
# Completion script for bento4 tools 1.6.0-641 (https://github.com/axiomatic-systems/Bento4)
#
# ------------------------------------------------------------------------------
# Authors
# -------
#
# * Shohei Yoshida (https://github.com/syohex) <syohex@gmail.com>
#
# ------------------------------------------------------------------------------
local -a encrypt_methods=(
OMA-PDCF-CBC OMA-PDCF-CTR MARLIN-IPMP-ACBC MARLIN-IPMP-ACGK ISMA-IAEC PIFF-CBC
PIFF-CTR MPEG-CENC MPEG-CBC1 MPEG-CENS MPEG-CBCS
)
local -a options=()
case $service in
(mp42aac|mp42avc|mp42hevc)
options+=('--key[128-bit decryption key (in hex: 32 chars)]:key')
;;
(mp42hls)
options+=(
'--verbose[enable verbose mode]'
'--show-info[show information]'
'--hls-version[HLS version(default: 3)]:version'
'--pmt-pid[PID to use for the PMT(default: 0x100)]:pid'
'--audio-pid[PID to use for audio packets(default: 0x101)]:pid'
'--video-pid[PID to use for video packets(default: 0x102)]:pid'
'--audio-track-id[Read audio from the given track ID(0 means no audio)]:track_id'
'--video-track-id[Read video from the given track ID(0 means no video)]:track_id'
'--audio-format[Format to use for audio-only segments(default: ts)]:format:(ts packed)'
'--segment-duration[Target segment duration in seconds(default: 6)]:seconds'
'--segment-duration-threshold[Segment duration threshold in milliseconds(default: 15)]:seconds'
'--pcr-offset[offset in units of 90kHz(default: 1000)]:offset'
'--index-filename[File name to use for the playlist/index(default: stream.m3u8)]:name:_files'
'--allow-cache[set #EXT-X-ALLOW_CACHE to YES or NO]: :(YES NO)'
'--segment-filename-template[File name pattern to use for the segment(default: segment-%d.<ext> or stream.<ext>)]:pattern'
'--segment-url-template[URL pattern to use for segments(default: segment-%d.<ext> or stream.<ext>)]:pattern'
'--iframe-index-filename[File name to use for the I-Frame playlist(default: iframes.m3u8)]:file:_files'
'--output-single-file[Output all the media in a single file instead of separate segment files]'
'--encryption-mode[Encryption mode(default: AES-128)]:mode:(AES-128 SAMPLE-AES)'
'--encryption-key[Encryption key in hexadecimal(default: no encryption)]:key'
'--encryption-iv-mode[Encryption IV mode(default: separate)]:mode:(sequence random fps)'
'--encryption-key-uri[Encryption key URI, relative or absolute URI(default: key.bin)]:uri'
'--encryption-key-format[Encryption key format(default: identity)]:format'
'--encryption-key-format-versions[Encryption key format versions]:versions'
'--encryption-key-line[Preformatted encryption key line]:ext_x_key_line'
)
;;
(mp42ts)
options+=(
'--pmt-pid[PID to use for the PMT(default: 0x100)]:pid'
'--audio-pid[PID to use for audio packets(default: 0x101)]:pid'
'--video-pid[PID to use for video packets(default: 0x102)]:pid'
'--segment[Segment duration in seconds]:seconds'
'--segment-duration-threshold[Segment duration threshold in milliseconds(default: 50)]:seconds'
'--pcr-offset[offset in units of 90kHz(default: 1000)]:offset'
'--verbose[enable verbose mode]'
'--playlist[Playlist file name]:file:_files'
'--playlist-hls-version[HLS version(default: 3)]:version'
)
;;
(mp4compact)
options+=('--verbose[Enable verbose mode]')
;;
(mp4dash)
options+=(
'(- *)'{-h,--help}'[Show this help message and exit]'
'(-v --verbose)'{-v,--verbose}'[Be verbose]'
'(-d --debug)'{-d,--debug}'[Print out debugging information]'
'(-o --output-dir)'{-o,--output-dir=}'[Output directory]:dir:_files -/'
'(-f --force)'{-f,--force}'[Allow output to an existing directory]'
'--mpd-name=[MPD file name]:file:_files'
'--profiles=[Comma-separated list of one or more profile(s)]:profiles'
'--no-media[Do not output media files (MPD/Manifests only)]'
'--rename-media[Use a file name pattern instead of the base name of input files]'
'--media-prefix=[Use this prefix for prefixed media file names(default: media)]:prefix'
'--init-segment=[Initialization segment name]:file:_files'
'--no-split[Do not split the file into individual segment files]'
'--use-segment-list[Use segment lists instead of segment templates]'
'--use-segment-template-number-padding[Use padded numbers in segment URL/filename templates]'
'--use-segment-timeline[Use segment timelines]'
'--min-buffer-time=[Minimum buffer time in seconds]:seconds'
'--max-playout-rate=[Max Playout Rate setting strategy for trick-play support]:strategy:(lowest:X)'
'--language-map=[Remap language code <lang_from> to <lang_to>]:from_to_list'
'--always-output-lang[Always output an @lang attribute for audio tracks]'
'--subtitles[Enable Subtitles]'
*'--attributes=[Specify the attributes of a set of tracks]:attribute'
'--smooth[Produce an output compatible with Smooth Streaming]'
'--smooth-client-manifest-name=[Smooth Streaming Client Manifest file name]:file:_files'
'--smooth-server-manifest-name=[Smooth Streaming Server Manifest file name]:file:_files'
'--smooth-h264-fourcc=[Smooth Streaming FourCC value for H.264 video(default H264)]:fourcc'
'--hls[Output HLS playlists in addition to MPEG DASH]'
'--hls-key-url=[HLS key URL (default: key.bin)]:url'
'--hls-master-playlist-name=[HLS master playlist name (default: master.m3u8)]:file:_files'
'--hls-media-playlist-name=[HLS media playlist name (default: media.m3u8)]:file:_files'
'--hls-iframes-playlist-name=[HLS I-Frames playlist name (default: iframes.m3u8)]'
'--hippo[Produce an output compatible with the Hippo Media Server]'
'--hippo-server-manifest-name=[Hippo Media Server Manifest file name]:file:_files'
'--use-compat-namespace[Use the original DASH MPD namespace]'
'--use-legacy-audio-channel-config-uri[Use the legacy DASH namespace URI]'
'--encryption-key=[Encryption key specifications]:key_spec'
'--encryption-cenc-scheme=[MPEG Common Encryption scheme(default: cenc)]:scheme:(cenc cbc1 cens cbcs)'
'--encryption-args=[Pass additional command line arguments to mp4encrypt]:args'
'--eme-signaling=[Add EME-compliant signaling in the MPD and PSSH boxes]:type:(pssh-v0 pssh-v1)'
'--merge-keys[Merge all keys in a single set used for all ContentProtection elements]'
'--marlin[Add Marlin signaling to the MPD]'
'--marlin-add-pssh[Add an (optional) Marlin "pssh" box in the init segment(s)]'
'--playready[Add PlayReady signaling to the MPD]'
'--playready-version=[PlayReady version to use]:version:(4.0 4.1 4.2 4.3)'
'--playready-header=[Add a PlayReady PRO element in the MPD and a PlayReady PSSH box in the init segments]:header'
'--playready-no-pssh[Do not store the PlayReady header in a "pssh" box in the init segment(s)]'
'--widevine[Add Widevine signaling to the MPD]'
'--widevine-header=[Add a Widevine entry in the MPD, and a Widevine PSSH box in the init segments]:header'
'--primetime[Add Primetime signaling to the MPD]'
'--primetime-metadata=[Add Primetime metadata in a PSSH box in the init segments]:metadata'
'--fairplay-key-uri=[Specify the key URI to use for FairPlay Streaming key delivery]:uri'
'--clearkey[Add Clear Key signaling to the MPD]'
'--clearkey-license-uri=[Specify the license/key URI to use for Clear Key]'
'--exec-dir=[Directory where the Bento4 executables are located]:dir:_files -/'
)
;;
(mp4dashclone)
options+=(
'(- *)'{-h,--help}'[Show this help message and exit]'
'--quiet[Be quiet]'
'--encrypt=[Encrypt the media with KID and KEY specified in HEX(32 characters each)]:key'
'--exec-dir=[Directory where the Bento4 executables are located]:dir:_files -/'
)
;;
(mp4dcfpackager)
options+=(
'--method[method name]:method:(NULL CBC CTR)'
'--content-type[Content MIME type]:mime_type'
'--content-id[Content ID]:id'
'--rights-issuer[rights issuer URL]:url'
'--key[Specify the key to use for encryption]:key'
*'--textual-header[Specify a textual header]:header'
)
;;
(mp4decrypt)
options+=(
'--show-progress[Show progress details]'
'--key[Specify the key to use for decryption]:key'
'--fragments-info[File to decrypt the fragments read from]:file:_files'
)
;;
(mp4dump)
options+=(
'--verbosity[Set the verbosity level]:level:(0 1 2 3)'
'--track[Write the track data into a file]:file:_files'
'--format[Format to use for the output(default: text)]:format:(text json)'
)
;;
(mp4edit)
options+=(
'--insert[insert atom data]:atom_path_and_source_and_position'
'--remove[remove atom data]:atom_path'
'--replace[replace atom data]:atom_path_and_source'
)
;;
(mp4encrypt)
options+=(
'--method=[Encryption method]:method:($encrypt_methods)'
'--show-progress[Show progress details]'
'--fragments-info[Encrypt the fragments read from <input> with track info read from the given file]:file:_files'
'--multi[Encrypt multiple individual fragment files]'
'--key[Specify the key to use for a track (or group key)]:key_spec'
'--strict[Fail if there is a warning]'
*'--property[Specify a named string property for a track]:property'
'--global-option[Set the global option]:option'
'--pssh[Add a "pssh" atom for this system ID with the payload]:pssh'
'--pssh-v1[Same as --pssh but generates a version=1 "pssh" atom]:pssh'
'--kms-uri[Specify the KMS URI for the ISMA-IAEC method]:uri'
)
;;
(mp4extract)
options+=(
'--payload-only[Omit the atom header]'
)
;;
(mp4fragment)
options+=(
'--verbosity[Set the verbosity level]:level:(0 1 2 3)'
'--debug[Enable debugging information output]'
'--quiet[Do not print out notice messages]'
'--fragment-duration[Fragment duration in milliseconds(default: automatic)]:msecs'
'--timescale[Time scale]:time_scale'
'--track[Specify track ID or type only include media from one track]:id_or_type:(audio video subtitles)'
'--index[(Re)create the segment index]'
'--trim[Trim excess media in longer tracks]'
'--no-tfdt[Do not add "tfdt boxes in the fragments"]'
'--tfdt-start[Set start value of the first tfdt timestamp]:start'
'--sequence-number-start[Set start value of the first segment sequence number(default: 1)]:number'
'--force-i-frame-sync[Treat all I-frames as sync samples]:type:(auto all)'
'--copy-udta[Copy the moov/udta atom from input to output]'
'--no-zero-elst[Do not set the last edit list entry to 0 duration]'
'--trun-version-zero[Set the "trun" box version to zero(default version: 1)]'
)
;;
(mp4hls)
options+=(
'(- *)'{-h,--help}'[Show this help message and exit]'
'(-v --verbose)'{-v,--verbose}'[Be verbose]'
'(-d --debug)'{-d,--debug}'[Print out debugging information]'
'(-o --output-dir)'{-o,--output-dir=}'[Output directory]:dir:_files -/'
'(-f --force)'{-f,--force}'[Allow output to an existing directory]'
'--hls-version=[HLS version]:version'
'--master-playlist-name=[Master Playlist name]:file:_files'
'--media-playlist-name=[Media Playlist name]:file:_files'
'--iframe-playlist-name=[I-frame Playlist name]:name'
'--output-single-file[Store segment data in a single output file per input file]'
'--audio-format=[Format for audio segments]:format:(packed ts)'
'--segment-duration=[Segment duration(default: 6)]:duration'
'--encryption-mode=[Encryption mode(default: AES-128)]:mode:(AES-128 SAMPLE-AES)'
'--encryption-key=[Encryption key in hexadecimal]:key'
'--encryption-iv-mode=[Encryption IV mode]:mode:(sequence random fps)'
'--encryption-key-uri=[Encryption key URI(default: key.bin)]:uri'
'--encryption-key-format=[Encryption key format (default: identity)]:mode:(identity)'
'--encryption-key-format-versions=[Encryption key format versions]:versions'
'--signal-session-key[Signal an #EXT-X-SESSION-KEY tag in the master playlist]'
'--fairplay=[Enable FairPlay Key Delivery and set parameters]:parameters'
'--widevine=[Enable Widevine Key Delivery and set parameters]:parameters'
'--output-encryption-key[Output the encryption key to a file]'
'--exec-dir=[Directory where the Bento4 executables are located]:dir:_files -/'
'--base-url=[The base URL for the Media Playlists and TS files listed in the playlists]:uri'
)
;;
(mp4iframeindex)
options+=(
'--track[ID of the video track]:id'
)
;;
(mp4info)
options+=(
'--verbose[Show extended information when available]'
'--format[Display the information in this format(default: text)]:format:(text json)'
'--show-layout[Show sample layout]'
'--show-samples[Show sample details]'
'--show-sample-data[Show sample data]'
'--fast[Skip some details that are slow to compute]'
)
;;
(mp4mux)
options+=(
*'--track=[Track type, input, parameters]:track'
'--verbose[Show more details]'
)
;;
(mp4rtphintinfo)
options+=(
'--trackid[Hint track ID]:id'
)
;;
(mp4split)
options+=(
'--verbose[Print verbose information when running]'
'--init-segment[Name of init segment(default: init.mp4)]:file:_files'
'--init-only[Only output the init segment(no media segments)]'
'--media-segment[Segment file name pattern(default: segment-%llu.%04llu.m4s)]:pattern'
'--start-number[Start numbering segments at n(default=1)]:number'
'--pattern-parameters[One or more selector letter(default: IN)]:params'
'--track-id[Only output segments with this track ID]:id'
'--audio[Only output audio segments]'
'--video[Only output video segments]'
)
;;
(mp4tag)
options+=(
'--help[Print this usage information]'
'--show-tags[Show tags found in the input file]'
'--list-symbols[List all the builtin symbols]'
'--list-keys[List all the builtin symbolic key names]'
'--set[Set a tag]:tag'
'--add[Set/Add a tag]:tag'
'--remove[Remove a tag]:key'
'--extract[extract the value of a tag and save it to a file]:key_file'
)
;;
esac
_arguments \
$options[@] \
"*::file:_files"
# Local Variables:
# mode: Shell-Script
# sh-indentation: 2
# indent-tabs-mode: nil
# sh-basic-offset: 2
# End:
# vim: ft=zsh sw=2 ts=2 et

View File

@ -24,7 +24,7 @@
# Description
# -----------
#
# Completion script for dart 3.9.0 (https://dart.dev/)
# Completion script for dart 3.11.0 (https://dart.dev/)
#
# ------------------------------------------------------------------------------
# Authors
@ -362,6 +362,7 @@ _dart_pub() {
(add|get|remove|upgrade)
opts+=(
'--precompile[Build executables in immediate dependencies]'
'--no-example[Do not run "example/" if it exists]'
)
;|
(get)
@ -373,6 +374,7 @@ _dart_pub() {
opts+=(
'(-f --force)'{-f,--force}'[Publish without confirmation if there are no errors]'
'--skip-validation[Publish without validation and resolution]'
'--ignore-warnings[Do not treat warnings as fatal]'
)
;|
(upgrade)

View File

@ -25,7 +25,7 @@
# Description
# -----------
#
# Completion script for the Flutter.io sdk's cli tool 3.35.1 (https://flutter.dev)
# Completion script for the Flutter.io sdk's cli tool 3.41.1 (https://flutter.dev)
#
# ------------------------------------------------------------------------------
# Authors
@ -106,16 +106,15 @@ _flutter() {
(assemble)
_arguments \
'(- *)'{-h,--help}'[Print this usage information]' \
\*{-d,--define=}'[Allows passing configuration to a target]:configuration' \
'--performance-measurement-file[Output individual target performance to a JSON file]' \
{-i,--input=}'[Allows passing additional input]: :' \
'--depfile=[A file path where a depfile will be written]: :_path_files' \
'--build-inputs=[A file path where a newline-separated file containing all inputs used will be written after a build]: :_path_files' \
'--build-outputs=[A file path where a newline-separated file containing all outputs used will be written after a build]: :_path_files' \
'(-o --output)'{-o,--output=}'[A directory where output files will be written]: :_path_files -/' \
'*--dart-define=[Additional key-value pairs that will be available as constants]:' \
\*{-D,--dart-define=}'[Additional key-value pairs that will be available as constants]:define' \
'--dart-define-from-file=[The path of a json format file where flutter define a global constant pool]: :_files -g "*.(json|env)"' \
'--resource-pool-size=[The maximum number of concurrent tasks the build system will run]:number:' \
'--performance-measurement-file[Output individual target performance to a JSON file]' \
{-i,--input=}'[Allows passing additional input]::input' \
'--depfile=[A file path where a depfile will be written]:file:_files' \
'--build-inputs=[A file path where a newline-separated file containing all inputs used will be written after a build]:files:_files' \
'--build-outputs=[A file path where a newline-separated file containing all outputs used will be written after a build]:files:_files' \
'(-o --output)'{-o,--output=}'[A directory where output files will be written]:dir:_files -/' \
'--resource-pool-size=[The maximum number of concurrent tasks the build system will run]:number' \
&& ret=0
;;
(attach)
@ -126,15 +125,15 @@ _flutter() {
'(-t --target)'{-t,--target=}'[The main entry-point file of the application, as run on the device.(defaults to "lib/main.dart")]::_files -g "*.dart"' \
'--device-vmservice-port=[Look for vmservice connections only from the specified port]:port:' \
'--host-vmservice-port=[When a device-side vmservice port is forwarded to a host-side port]:port:' \
'*--dart-define=[Additional key-value pairs that will be available as constants]:' \
\*{-D,--dart-define=}'[Additional key-value pairs that will be available as constants]:define' \
'--dart-define-from-file=[The path of a json format file where flutter define a global constant pool]: :_files -g "*.(json|env)"' \
'--device-user=[Identifier number for a user or work profile on Android only]:id:' \
'--debug-url=[The URL at which the observatory is listening]:url:' \
'--app-id=[The package name (Android) or bundle identifier (iOS) for the app]:app_id:' \
'--pid-file=[Specify a file to write the process id to]: :_files' \
'--device-user=[Identifier number for a user or work profile on Android only]:id' \
'--debug-url=[The URL at which the observatory is listening]:url' \
'--app-id=[The package name (Android) or bundle identifier (iOS) for the app]:app_id' \
'--pid-file=[Specify a file to write the process id to]:file:_files' \
'(--no-track-widget-creation --track-widget-creation)--track-widget-creation[Track widget creation location(defaults on)]' \
'(--no-track-widget-creation --track-widget-creation)--no-track-widget-creation[Not track widget creation locations]' \
'--dds-port=[When this value is provided, the Dart Development Service (DDS) will be bound to the provided port]:port:' \
'--dds-port=[When this value is provided, the Dart Development Service (DDS) will be bound to the provided port]:port' \
'(--no-dds --dds)--dds[Enable the Dart Developer Service]' \
'(--no-dds --dds)--no-dds[Disable the Dart Developer Service]' \
'--device-timeout=[Time in seconds to wait for devices to attach]:seconds:' \
@ -144,8 +143,8 @@ _flutter() {
(bash-completion)
_arguments \
'(- *)'{-h,--help}'[Print this usage information]' \
'(--no-overwrite --overwrite)--overwrite[Overwritten completion setup if it already exists]' \
'(--overwrite --no-overwrite)--no-overwrite[Not overwritten completion setup if it already exists]' \
'(--no-overwrite --overwrite)--overwrite[Overwrite completion setup if it already exists]' \
'(--overwrite --no-overwrite)--no-overwrite[Not overwrite completion setup if it already exists]' \
&& ret=0
;;
(build)
@ -153,13 +152,14 @@ _flutter() {
;;
(config)
_arguments \
'(-h --help)'{-h,--help}'[Print this usage information]' \
'(- *)'{-h,--help}'[Print this usage information]' \
'--list[List all settings and their current values]' \
'--clear-ios-signing-cert[Clear the saved development certificate choice used to sign apps for iOS device deployment]' \
'--android-sdk=[The Android SDK directory]: :_path_files -/' \
'--android-studio-dir=[The Android Studio install directory]: :_path_files -/' \
'--jdk-dir=[The Java Development Kit installation directory]: :_path_files -/' \
'--build-dir=[The relative path to override a projects build directory]: :_path_files -/' \
'--select-ios-signing-settings[Complete prompt to select and save code signing settings to sign apps for iOS]' \
'--android-sdk=[The Android SDK directory]:dir:_files -/' \
'--android-studio-dir=[The Android Studio install directory]:dir:_files -/' \
'--jdk-dir=[The Java Development Kit installation directory]:dir:_files -/' \
'--build-dir=[The relative path to override a projects build directory]:dir:_files -/' \
'(--no-enable-web --enable-web)--enable-web[Enable Flutter for web]' \
'(--no-enable-web --enable-web)--no-enable-web[Disable Flutter for web]' \
'(--no-enable-linux-desktop --enable-linux-desktop)--enable-linux-desktop[Enable support for desktop on Linux]' \
@ -182,43 +182,43 @@ _flutter() {
'(--no-cli-animations --cli-animations)--no-cli-animations[Disable animations in the command line interface]' \
'(--no-enable-native-assets --enable-native-assets)--enable-native-assets[Enable native assets compilation and bundling]' \
'(--no-enable-native-assets --enable-native-assets)--no-enable-native-assets[Disable native assets compilation and bundling]' \
'(--no-enable-flutter-preview --enable-flutter-preview)--enable-flutter-preview[Enable Flutter preview prebuilt device]' \
'(--no-enable-flutter-preview --enable-flutter-preview)--no-enable-flutter-preview[Disable Flutter preview prebuilt device]' \
'(--no-enable-dart-data-assets --enable-dart-data-assets)--enable-dart-data-assets[Enable Dart data assets building and bundling]' \
'(--no-enable-dart-data-assets --enable-dart-data-assets)--no-enable-dart-data-assets[Disable Dart data assets building and bundling]' \
'(--no-enable-swift-package-manager --enable-swift-package-manager)--enable-swift-package-manager[Enable support for Swift Package Manager]' \
'(--no-enable-swift-package-manager --enable-swift-package-manager)--no-enable-swift-package-manager[Disable support for Swift Package Manager]' \
'(--no-omit-legacy-version-file --omit-legacy-version-file)--omit-legacy-version-file[Enable stops writing the legacy version file]' \
'(--no-omit-legacy-version-file --omit-legacy-version-file)--no-omit-legacy-version-file[Disable stops writing the legacy version file]' \
'(--no-enable-windowing --enable-windowing)--enable-windowing[Enable for windowing]' \
'(--no-enable-windowing --enable-windowing)--no-enable-windowing[Disable for windowing]' \
'(--no-enable-lldb-debugging --enable-lldb-debugging)--enable-lldb-debugging[Enable support for debugging with LLDB]' \
'(--no-enable-lldb-debugging --enable-lldb-debugging)--no-enable-lldb-debugging[Disable support for debugging with LLDB]' \
'(--no-enable-uiscene-migration --enable-uiscene-migration)--enable-uiscene-migration[Enable support for migration to UIScene lifecycle]' \
'(--no-enable-uiscene-migration --enable-uiscene-migration)--no-enable-uiscene-migration[Disable support for migration to UIScene lifecycle]' \
'--clear-features[Remove all configured features and restore them to the default values]' \
&& ret=0
;;
(create)
_arguments \
'(- *)'{-h,--help}'[Print this usage information]' \
'(--pub --no-pub)--pub[Whether to run "flutter packages get" after the project has been created. (defaults to on)]' \
'(--pub --no-pub)--no-pub[Whether to run "flutter packages get" after the project has been created. (defaults to on)]' \
'(--offline --no-offline)--offline[Offline mode when "flutter packages get" is run]' \
'(--offline --no-offline)--no-offline[Offline mode when "flutter packages get" is run]' \
'(--pub --no-pub)--pub[Run "flutter packages get" after the project has been created. (defaults to on)]' \
'(--pub --no-pub)--no-pub[Do not run "flutter packages get" after the project has been created]' \
'(--offline --no-offline)--offline[Run "flutter packages get" in offline mode]' \
'(--offline --no-offline)--no-offline[Do not run "flutter packages get" in offline mode]' \
'(--overwrite --no-overwrite)--overwrite[When performing operations, overwrite existing files]' \
'(--overwrite --no-overwrite)--no-overwrite[When performing operations, not overwrite existing files]' \
"--description=[The description to use for your new Flutter project. (defaults to 'A new Flutter project.')]::" \
"--description=[The description to use for your new Flutter project(defaults to 'A new Flutter project.')]::" \
"--org=[The organization responsible for new Flutter project, in reverse domain name notation.(defaults to 'com.example')]::" \
'--project-name=[The project name for this new Flutter project]:name:' \
'(-i --ios-language)'{-i,--ios-language=}'[iOS project language]: :_flutter_ios_languages' \
'(-a --android-language)'{-a,--android-language=}'[Android project language]: :_flutter_android_languages' \
'--platforms=[The platforms supported by this project]:platforms:_flutter_platforms' \
'(-t --template=)'{-t,--template=}'[Specify the type of project to create]: :_flutter_project_templates' \
'(-s --sample=)'{-s,--sample=}'[Specifies the Flutter code sample to use as the "main.dart" for an application]:id:' \
'(-e --empty)'{-e,--empty}'[Specifies creating using an application template with a main.dart that is minimal]' \
'--list-samples=[Specifies a JSON output file for a listing of Flutter code samples that can be created with "--sample"]: :_path_files' \
&& ret=0
;;
(custom-devices)
_flutter_custom_devices && ret=0
;;
(daemon)
_arguments \
'(- *)'{-h,--help}'[Print this usage information]' \
'--listen-on-tcp-port=[If specified, the daemon will be listening for commands on the specified port instead of stdio]:port:' \
&& ret=0
;;
(debug-adapter)
_arguments \
'(- *)'{-h,--help}'[Print this usage information]' \
@ -232,7 +232,6 @@ _flutter() {
(devices)
_arguments \
'(- *)'{-h,--help}'[Print this usage information]' \
'--machine[Output device information in machine readable structured JSON format]' \
"--device-timeout=[Time in seconds to wait for devices to attach]:seconds:" \
'--device-connection=[Discover devices based on connection type]:type:_flutter_device_connection_types' \
&& ret=0
@ -251,26 +250,23 @@ _flutter() {
'--release[Build a release version of your app]' \
'*--dart-define=[Additional key-value pairs that will be available as constants]:' \
'--dart-define-from-file=[The path of a json or .env file containing key-value pairs]: :_files -g "*.(json|env)"' \
'*--web-define=[Additional key-value pairs that will be available as template variables in web/index.html]' \
'--flavor[Build a custom app flavor as defined by platform-specific build setup]:flavor' \
'--web-renderer=[The renderer implementation to use when building for the web]: :_flutter_web_renderers' \
'--no-web-resources-cdn[Do not use Web static resources hosted on a CDN]' \
'--use-application-binary=[Specify a pre-built application binary to use when running]:app:_files -g "*.apk"' \
'--trace-startup[Start tracing during startup]' \
'(--cache-startup-profile --no-cache-startup-profile)--cache-startup-profile[Caches the CPU profile collected before the first frame for startup analysis]' \
'(--cache-startup-profile --no-cache-startup-profile)--no-cache-startup-profile[Not caches the CPU profile collected before the first frame for startup analysis]' \
'--verbose-system-logs[Include verbose logging from the Flutter engine]' \
'--cache-sksl[Cache the shader in the SkSL format instead of in binary or GLSL formats]' \
'--dump-skp-on-shader-compilation[Cache the shader in the SkSL format instead of in binary or GLSL formats]' \
'--purge-persistent-cache[Removes all existing persistent caches]' \
'--route[Which route to load when running the app]' \
'(--no-start-paused --start-paused)--start-paused[Start in a paused mode and wait for a debugger to connect]' \
'(--no-start-paused --start-paused)--no-start-paused[Not tart in a paused mode and wait for a debugger to connect]' \
'(--no-start-paused --start-paused)--no-start-paused[Not start in a paused mode and wait for a debugger to connect]' \
'--endless-trace-buffer[Enable tracing to an infinite buffer, instead of a ring buffer]' \
'--trace-systrace[Enable tracing to the system tracer]' \
'--trace-to-file=[Write the timeline trace to a file at the specified path]:file:_files' \
'--trace-skia[Enable tracing of Skia code]' \
'--no-enable-dart-profiling[Disable the Dart VM sampling CPU profiler]' \
'--skia-deterministic-rendering[provide completely deterministic Skia rendering]' \
*{-a,--dart-entrypoint-args=}'[Pass a list of arguments to the Dart entrypoint at application startup]: :' \
'--wasm[Compile to WebAssembly rather than JavaScript]' \
'--web-tls-cert-path=[The certificate that host will use to serve using TLS connection]:cert:_files' \
@ -279,8 +275,8 @@ _flutter() {
'(-t --target=)'{-t,--target=}'[The main entry-point file of the application, as run on the device.(defaults to "lib/main.dart")]: :_files -g "*.dart"' \
'--device-vmservice-port=[Look for vmservice connections only from the specified port]:port:' \
'--host-vmservice-port=[When a device-side vmservice port is forwarded to a host-side port]:port:' \
'(--no-pub --pub)--pub[Whether to run "flutter packages get" before executing this command. (defaults to on)]' \
'(--no-pub --pub)--no-pub[Whether to run "flutter packages get" before executing this command. (defaults to on)]' \
'(--no-pub --pub)--pub[Run "flutter packages get" before executing this command. (default: on)]' \
'(--no-pub --pub)--no-pub[Do not run "flutter packages get" before executing this command]' \
'(--no-track-widget-creation --track-widget-creation)--track-widget-creation[Track widget creation locations(defaults on)]' \
'(--no-track-widget-creation --track-widget-creation)--no-track-widget-creation[Not track widget creation locations]' \
'--device-user=[Identifier number for a user or work profile on Android only]:id:' \
@ -296,8 +292,8 @@ _flutter() {
'(--no-keep-app-running --keep-app-running)--keep-app-running[Will keep the Flutter application running when done testing]' \
'--use-existing-app=[Connect to an already running instance via the given observatory URL]' \
'--driver=[The test file to run on the host]: :_files' \
'--build[If necessary, build the app before running. (defaults to on)]' \
'--no-build[If necessary, not build the app before running]' \
'(--no-build --build)--build[If necessary, build the app before running. (defaults to on)]' \
'(--no-build --build)--no-build[If necessary, not build the app before running]' \
'--screenshot=[Directory location to write screenshots on test failure]::_path_files -/' \
'--driver-port=[The port where Webdriver server is launched at(default to "4444")]:port:' \
'(--no-headless --headless)--headless[Launch driver browser in headless mode(defaults to on)]' \
@ -307,9 +303,8 @@ _flutter() {
'(--no-android-emulator --android-emulator)--android-emulator[Perform Flutter Driver testing using an Android Emulator]' \
'(--no-android-emulator --android-emulator)--no-android-emulator[Not perform Flutter Driver testing using an Android Emulator]' \
'--chrome-binary=[Location of the Chrome binary]::_files' \
'--write-sksl-on-exit[Attempts to write an SkSL file when the drive process is finished to the provided file, overwriting it if necessary]' \
'*--test-arguments=[Additional arguments to pass to the Dart VM running The test script]: :' \
'--profile-memory=[Launch devtools and profile application memory, writing the output data as JSON]::_files -g "*.json"' \
'*--test-arguments=[Additional arguments to pass to the Dart VM running The test script]:arg' \
'--profile-memory=[Launch devtools and profile application memory, writing the output data as JSON]:file:_files -g "*.json"' \
'--timeout=[Timeout the test after the given number of seconds]:seconds' \
&& ret=0
;;
@ -337,8 +332,6 @@ _flutter() {
'(--no-use-deferred-loading --use-deferred-loading)--use-deferred-loading[Generate the Dart localization file as deferred]' \
'(--no-use-deferred-loading --use-deferred-loading)--no-use-deferred-loading[Not generate the Dart localization file as deferred]' \
'--gen-inputs-and-outputs-list=[the tool generates a JSON file containing the tools inputs and outputs]::_path_files -/' \
'(--no-synthetic-package --synthetic-package)--synthetic-package[Generate files as a synthetic package]' \
'(--no-synthetic-package --synthetic-package)--no-synthetic-package[Not generate files as a synthetic package]' \
'--project-dir=[the directory of the root Flutter project]::_path_files -/' \
'(--no-required-resource-attributes --required-resource-attributes)--required-resource-attributes[Requires all resource ids to contain a corresponding resource attribute]' \
'(--no-required-resource-attributes --required-resource-attributes)--no-required-resource-attributes[Requires all resource ids to contain a corresponding resource attribute]' \
@ -404,9 +397,10 @@ _flutter() {
'--debug[Build a debug version of your app (default mode)]' \
'--profile[Build a version of your app specialized for performance profiling]' \
'--release[Build a release version of your app]' \
'*--dart-define=[Additional key-value pairs that will be available as constants]: ' \
\*{-D,--dart-define=}'[Additional key-value pairs that will be available as constants]:define' \
'--dart-define-from-file=[The path of a json format file where flutter define a global constant pool]: :_files -g "*.(json|env)"' \
'*--web-define=[Additional key-value pairs that will be available as template variables in web/index.html]' \
'--flavor[Build a custom app flavor as defined by platform-specific build setup]:flavor' \
'--web-renderer=[The renderer implementation to use when building for the web]: :_flutter_web_renderers' \
'--no-web-resources-cdn[Do not use Web static resources hosted on a CDN]' \
'--use-application-binary=[Specify a pre-built-application binary to use when running]: :_files' \
'--trace-startup[Start tracing during startup]' \
@ -414,42 +408,42 @@ _flutter() {
'(--cache-startup-profile --no-cache-startup-profile)--no-cache-startup-profile[Not caches the CPU profile collected before the first frame for startup analysis]' \
'--verbose-system-logs[Include verbose logging from the Flutter engine]' \
'--cache-sksl[Cache the shader in the SkSL format instead of in binary or GLSL formats]' \
'--dump-skp-on-shader-compilation[Cache the shader in the SkSL format instead of in binary or GLSL formats]' \
'--purge-persistent-cache[Removes all existing persistent caches]' \
'--route[Which route to load when running the app]' \
'(--no-start-paused --start-paused)--start-paused[Start in a paused mode and wait for a debugger to connect]' \
'(--no-start-paused --start-paused)--no-start-paused[Not start in a paused mode and wait for a debugger to connect]' \
'--endless-trace-buffer[Enable tracing to an infinite buffer, instead of a ring buffer]' \
'--trace-systrace[Enable tracing to the system tracer]' \
'--trace-to-file=[Write the timeline trace to a file at the specified path]:file:_files' \
'--trace-skia[Enable tracing of Skia code]' \
'--no-enable-dart-profiling[Disable the Dart VM sampling CPU profiler]' \
'--enable-software-rendering[Enable rendering using the Skia software backend]' \
'--skia-deterministic-rendering[When combined with --enable-software-rendering, provides 100% deterministic Skia rendering]' \
*{-a,--dart-entrypoint-args=}'[Pass a list of arguments to the Dart entrypoint at application startup]: :' \
\*{-a,--dart-entrypoint-args=}'[Pass a list of arguments to the Dart entrypoint at application startup]: :' \
'--wasm[Compile to WebAssembly rather than JavaScript]' \
'--web-tls-cert-path=[The certificate that host will use to serve using TLS connection]:cert:_files' \
'--web-tls-cert-key-path=[The certificate key that host will use to authenticate cert]:key:_files' \
'--web-launch-url=[The URL to provide to the browser]: :' \
'(-t= --target=)'{-t=,--target=}'[The main entry-point file of the application, as run on the device.(defaults to "lib/main.dart")]: :_files -g "*.dart"' \
'(-t --target=)'{-t,--target=}'[The main entry-point file of the application, as run on the device(default: "lib/main.dart")]: :_files -g "*.dart"' \
'--device-vmservice-port=[Look for vmservice connections only from the specified port]:port:' \
'--host-vmservice-port=[When a device-side vmservice port is forwarded to a host-side port]:port:' \
'--pub[Whether to run "flutter packages get" before executing this command. (defaults to on)]' \
'--no-pub[Whether to run "flutter packages get" before executing this command. (defaults to on)]' \
'--track-widget-creation[Track widget creation locations. (defaults to on)]' \
'--no-track-widget-creation[Not rack widget creation locations. (defaults to on)]' \
'--device-user=[Identifier number for a user or work profile on Android only]:id:' \
'--device-timeout=[Time in seconds to wait for devices to attach]:seconds:' \
'--device-connection=[Discover devices based on connection type]: :_flutter_device_connection_types' \
'(--no-pub --pub)--pub[Run "flutter packages get" before executing this command(default: on)]' \
'(--no-pub --pub)--no-pub[Do not run "flutter packages get" before executing this command]' \
'(--no-track-widget-creation --track-widget-creation)--track-widget-creation[Track widget creation locations. (defaults to on)]' \
'(--no-track-widget-creation --track-widget-creation)--no-track-widget-creation[Not track widget creation locations]' \
'--device-user=[Identifier number for a user or work profile on Android only]:id' \
'--device-timeout=[Time in seconds to wait for devices to attach]:seconds' \
'--device-connection=[Discover devices based on connection type]:type:_flutter_device_connection_types' \
'--dds-port=[When this value is provided, the Dart Development Service (DDS) will be bound to the provided port]:port:' \
'(--no-dds --dds)--dds[Enable the Dart Developer Service]' \
'(--no-dds --dds)--no-dds[Disable the Dart Developer Service]' \
'--dds-port=[When this value is provided, the Dart Development Service (DDS) will be bound to the provided port]:port:' \
'(--no-android-skip-build-dependency-validation --android-skip-build-dependency-validation)--android-skip-build-dependency-validation[Skip version checking during Android builds]' \
'(--no-android-skip-build-dependency-validation --android-skip-build-dependency-validation)--no-android-skip-build-dependency-validation[Skip version checking during Android builds]' \
*{-P,--android-project-arg=}'[Additional arguments specified as key=value that are passed directly to the gradle project via the -P flag]: :' \
'--multidex[indicates that the app should be built with multidex support(defaults to on)]' \
'--no-multidex[indicates that the app should not be built with multidex support(defaults to on)]' \
'--android-project-cache-dir[Specify the project-specific cache directory]:dir:_file -/' \
'--ignore-deprecation[Indicates that the app should ignore deprecation warnings and continue to build using deprecated APIs]' \
'--no-await-first-frame-when-tracing[Just dump the trace as soon as the application is running]' \
'--use-test-fonts[Enable (and default to) the "Ahem" font]' \
'--no-use-test-fonts[Not enable (and default to) the "Ahem" font]' \
'(--no-use-test-fonts --use-test-fonts)--use-test-fonts[Enable (and default to) the "Ahem" font]' \
'(--no-use-test-fonts --use-test-fonts)--no-use-test-fonts[Not enable (and default to) the "Ahem" font]' \
'--no-build[Do not build the app before running]' \
'--no-hot[Run without support for hot reloading]' \
'--pid-file=[Specify a file to write the process id to]: :_files' \
@ -481,9 +475,8 @@ _flutter() {
'(--pub --no-pub)--no-pub[Not to run "flutter packages get" before executing this command]' \
'(--track-widget-creation --no-track-widget-creation)--track-widget-creation[Track widget creation locations]' \
'(--track-widget-creation --no-track-widget-creation)--no-track-widget-creation[Not track widget creation locations]' \
'*--dart-define=[Additional key-value pairs that will be available as constants]:' \
\*{-D,--dart-define=}'[Additional key-value pairs that will be available as constants]:define' \
'--dart-define-from-file=[The path of a json format file where flutter define a global constant pool]: :_files -g "*.(json|env)"' \
'--web-renderer=[The renderer implementation to use when building for the web]: :_flutter_web_renderers' \
'--device-user=[Identifier number for a user or work profile on Android only]:id:' \
'--flavor[Build a custom app flavor as defined by platform-specific build setup]:flavor' \
'--name=[A regular expression matching substrings of the names of tests to run]' \
@ -491,12 +484,15 @@ _flutter() {
*{-t,--tags=}'[Run only tests associated with the specified tags]:tag:' \
*{-x,--exclude-tags=}'[Run only tests that do not have the specified tags]:tag:' \
'--start-paused[Start in a paused mode and wait for a debugger to connect]' \
'(--no-fail-fast --fail-fast)--fail-fast[Stop running tests after the first failure]' \
'(--no-fail-fast --fail-fast)--no-fail-fast[Do not stop running tests after the first failure]' \
'(--no-run-skipped --run-skipped)--run-skipped[Run skipped tests instead of skipping them]' \
'(--no-run-skipped --run-skipped)--no-run-skipped[Not run skipped tests instead of skipping them]' \
'--coverage[Whether to collect coverage information]' \
'--merge-coverage[Whether to merge coverage data with "coverage/lcov.base.info" (Requires lcov)]' \
'--branch-coverage[Whether to collect branch coverage information]' \
'--coverage-path=[Where to store coverage information (if coverage is enabled). (defaults to "coverage/lcov.info")]::_files' \
'--coverage-package=[A regular expression matching packages names to include in the coverage report]:pattern' \
'--update-goldens[Whether "matchesGoldenFile()" calls within your test methods should update the golden files]' \
'(-j --concurrency)'{-j,--concurrency=}'[The number of concurrent test processes to run]:nums:' \
'(--test-assets --no-test-assets)--test-assets[Build the assets bundle for testing]' \
@ -504,14 +500,14 @@ _flutter() {
'--test-randomize-ordering-seed[The seed to randomize the execution order of test cases within test files]' \
'--total-shards[Tests can be sharded with the "--total-shards" and "--shard-index" arguments]' \
'--shard-index[Tests can be sharded with the "--total-shards" and "--shard-index" arguments]' \
{-r,--reporter=}'[Set how to print test results]: :(compact expanded github json silent)' \
{-r,--reporter=}'[Set how to print test results]: :(compact expanded failures-only github json silent)' \
'--file-reporter[Enable an additional reporter writing test results to a file]' \
'--timeout=[The default test timeout, specified either in seconds (e.g. "60s"). Defaults to "30s"]:seconds:' \
'--ignore-timeouts[Ignore all timeouts]' \
'--wasm[Compile to WebAssembly rather than JavaScript]' \
'--dds-port=[the Dart Development Service (DDS) will be bound to the provided port]:port:' \
'(--no-dds --dds)--dds[Enable the Dart Developer Service]' \
'(--no-dds --dds)--no-dds[Disable the Dart Developer Service]' \
'--dds-port=[the Dart Development Service (DDS) will be bound to the provided port]:port:' \
&& ret=0
;;
(upgrade)
@ -521,6 +517,9 @@ _flutter() {
'--verify-only[Checks for any new Flutter updates, without actually fetching them]' \
&& ret=0
;;
(widget-preview)
_flutter_widget_preview && ret=0
;;
(*)
_arguments \
'(- *)'{-h,--help}'[Print this usage information]' \
@ -564,6 +563,7 @@ _flutter_root_commands() {
'symbolize:Symbolize a stack trace from an AOT-compiled Flutter app.'
'test:Run Flutter unit tests for the current project.'
'upgrade:Upgrade your copy of Flutter.'
'widget-preview:Manage the widget preview environment'
)
_describe -t commands 'command' commands "$@"
}
@ -574,7 +574,7 @@ _flutter_build() {
_arguments -C \
'(- *)'{-h,--help}'[Print this usage information]' \
'1: :_flutter_build_entities' \
'1: :_flutter_build_subcommands' \
'*:: :->args' \
&& ret=0
@ -637,8 +637,6 @@ _flutter_build() {
'--asset-dir[The output directory for the kernel_blob.bin file]: :_files -/'
)
;;
(fuchsia)
;;
(ios)
opts+=(
'--code-size-directory=[The location to write code size analysis files]: :_files -/'
@ -647,6 +645,13 @@ _flutter_build() {
'--simulator[Build for the iOS simulator instead of the device]'
)
;;
(ios-framework|macos-framework)
opts+=(
'--cocoapods[Produce a Flutter.podspec instead of an engine Flutter.xcframework]'
'--plugins[Produce frameworks for the plugins]'
'--static[Build plugins as static frameworks]'
)
;;
(linux)
opts+=(
'(--no-analyze-size)--analyze-size[Produce additional profile information for artifact output size]'
@ -698,19 +703,20 @@ _flutter_build() {
return ret
}
(( $+functions[_flutter_build_entities] )) ||
_flutter_build_entities() {
(( $+functions[_flutter_build_subcommands] )) ||
_flutter_build_subcommands() {
local -a entities=(
"aar:Build a repository containing an AAR and a POM file."
"apk:Build an Android APK file from your app."
"appbundle:Build an Android App Bundle file from your app."
"bundle:Build the Flutter assets directory from your app."
"fuchsia:Build the Fuchsia target."
"ios:Build an iOS application bundle (Mac OS X host only)."
"linux:Build a Linux desktop application."
"macos:Build a macOS desktop application."
"aar:Build a repository containing an AAR and a POM file"
"apk:Build an Android APK file from your app"
"appbundle:Build an Android App Bundle file from your app"
"bundle:Build the Flutter assets directory from your app"
"ios:Build an iOS application bundle"
"ios-framework:Produces .xcframeworks for a Flutter project for existing, plain iOS Xcode projects"
"linux:Build a Linux desktop application"
"macos:Build a macOS desktop application"
"macos-framework:Produces .xcframeworks for a Flutter project for existing, plain macOS Xcode projects"
"web:Build a web application bundle"
"windows:Build a Windows desktop application."
"windows:Build a Windows desktop application"
)
_describe -t entities 'entity' entities "$@"
}
@ -758,43 +764,6 @@ _flutter_custom_devices_subcommands() {
_describe -t subcmds 'subcommands' subcmds "$@"
}
(( $+functions[_flutter_project_templates] )) ||
_flutter_project_templates() {
local -a templates=(
"app:(default) Generate a Flutter application"
"module:Generate a shareable Flutter project containing modular Dart code"
"package:Generate a shareable Flutter project containing modular Dart code"
"plugin:Generate a shareable Flutter project containing an API in Dart code with a platform-specific implementation for Android, for iOS code, or for both"
"plugin_ffi:Generate a shareable Flutter project containing an API in Dart code with a platform-specific implementation through dart:ffi for Android, iOS, Linux, macOS, Windows, or any combination of these"
"skeleton:Generate a List View / Detail View Flutter application that follows community best practices"
)
_describe -t templates 'template' templates "$@"
}
(( $+functions[_flutter_platforms] )) ||
_flutter_platforms() {
local -a platforms=("ios" "android" "windows" "linux" "macos" "web")
_values -s , "platforms" $platforms
}
(( $+functions[_flutter_ios_languages] )) ||
_flutter_ios_languages() {
local -a languages=(
"objc:Objective-C"
"swift:(default) Swift"
)
_describe -t languages 'language' languages "$@"
}
(( $+functions[_flutter_android_languages] )) ||
_flutter_android_languages() {
local -a languages=(
"java:Java"
"kotlin:(default) Kotlin"
)
_describe -t languages 'language' languages "$@"
}
(( $+functions[_flutter_pub] )) ||
_flutter_pub() {
local ret=1
@ -874,6 +843,7 @@ _flutter_pub() {
'(-f --force)'{-f,--force}'[Publish without confirmation if there are no errors]' \
'--skip-validation[Publish without validation and resolution]' \
'(-C --directory)'{-C,--directory=}'[Run this in the given directory]:dir:_files -/' \
'--ignore-warnings[Do not treat warnings as fatal]' \
&& ret=0
;;
(run)
@ -896,6 +866,7 @@ _flutter_pub() {
'--precompile[Build executables in immediate dependencies]' \
'--unlock-transitive[Also upgrades the transitive dependencies of the listed dependencies]' \
'--major-versions[Upgrades packages to their latest resolvable versions]' \
'--no-example[Do not run in "example/" if it exists]' \
'(-C --directory)'{-C,--directory=}'[Run this in the given directory]:dir:_files -/' \
&& ret=0
;;
@ -1091,6 +1062,97 @@ _flutter_pub_token_subcommand() {
_describe -t subcommands 'subcommand' subcommands "$@"
}
(( $+functions[_flutter_widget_preview] )) ||
_flutter_widget_preview() {
local ret=1
_arguments -C \
'(- *)'{-h,--help}'[Print this usage information]' \
\*{-v,--verbose}'[Noisy logging, including all shell commands executed]' \
'(-d --device-id)'{-d,--device-id}'[Target device id or name]:id_or_name' \
'(- *)--version[Report the version of this tool]' \
'(--enable-analytics --disable-analytics)--enable-analytics[Enable telemetry reporting each time a flutter or dart command runs]' \
'(--enable-analytics --disable-analytics)--disable-analytics[Disable telemetry reporting each time a flutter or dart command runs]' \
'--suppress-analytics[Suppress analytics reporting for the current CLI invocation]' \
'1: :_flutter_widget_preview_subcommand' \
'*:: :->arg' \
&& ret=0
case $state in
(arg)
case $words[1] in
(clean)
_arguments \
'(- *)'{-h,--help}'[Print this usage information]' \
&& ret=0
;;
(start)
_arguments \
'(- *)'{-h,--help}'[Print this usage information]' \
'(--pub --no-pub)--pub[Run "flutter packages get" after the project has been created]' \
'(--pub --no-pub)--no-pub[Do not run "flutter packages get" after the project has been created]' \
'(--offline --no-offline)--offline[Run "flutter packages get" in offline mode]' \
'(--offline --no-offline)--no-offline[Do not run "flutter packages get" in offline mode]' \
'(--web-server --no-web-server)--web-server[Serve the widget preview environment using the web-server device instead of browser]' \
'(--web-server --no-web-server)--no-web-server[Do not serve the widget preview environment using the web-server device]' \
&& ret=0
;;
esac
;;
esac
return ret
}
(( $+functions[_flutter_widget_preview_subcommand] )) ||
_flutter_widget_preview_subcommand() {
local -a subcommands=(
"clean:Cleans up widget preview state"
"start:Starts the widget preview environment"
)
_describe -t subcommands 'subcommand' subcommands "$@"
}
# Utilities
(( $+functions[_flutter_project_templates] )) ||
_flutter_project_templates() {
local -a templates=(
"app:(default) Generate a Flutter application"
"module:Generate a shareable Flutter project containing modular Dart code"
"package:Generate a shareable Dart/Flutter project containing modular Dart code"
"package_ffi:Generate a shareable Dart/Flutter project containing an API in Dart with FFI"
"plugin:Generate a shareable Flutter project containing an API in Dart code with a platform-specific implementation for Android, for iOS code, or for both"
"plugin_ffi:Generate a shareable Flutter project containing an API in Dart code with a platform-specific implementation through dart:ffi for Android, iOS, Linux, macOS, Windows, or any combination of these"
"skeleton:Generate a List View / Detail View Flutter application that follows community best practices"
)
_describe -t templates 'template' templates "$@"
}
(( $+functions[_flutter_platforms] )) ||
_flutter_platforms() {
local -a platforms=("ios" "android" "windows" "linux" "macos" "web" "darwin")
_values -s , "platforms" $platforms
}
(( $+functions[_flutter_ios_languages] )) ||
_flutter_ios_languages() {
local -a languages=(
"objc:Objective-C"
"swift:(default) Swift"
)
_describe -t languages 'language' languages "$@"
}
(( $+functions[_flutter_android_languages] )) ||
_flutter_android_languages() {
local -a languages=(
"java:Java"
"kotlin:(default) Kotlin"
)
_describe -t languages 'language' languages "$@"
}
(( $+functions[_flutter_web_renderers] )) ||
_flutter_web_renderers() {
local -a renderers=(

View File

@ -30,7 +30,7 @@
# Description
# -----------
#
# Completion script for go 1.25.0 (https://go.dev/).
# Completion script for go 1.26.0 (https://go.dev/).
#
# ------------------------------------------------------------------------------
# Authors
@ -312,20 +312,45 @@ __go_packages() {
fi
}
__go_fix_names() {
local -a fix_names=(
'buildtag[remove +build comments from modules using Go 1.18 or later]'
'cftype[fixes initializers and casts of C.*Ref and JNI types]'
'context[Change imports of golang.org/x/net/context to context]'
'egl[fixes initializers of EGLDisplay]'
'eglconf[fixes initializers of EGLConfig]'
'gotypes[change imports of oglang.org/x/tools/go{exact,types} to go/{constant,types}]'
"jni[fixes initializers of JNI's jobject and subtypes]"
'netipv6zone[adapt element key to IPAddr, UPDAddr, TCPAddr composite literals]'
'printerconfig[add element keys to Config composite literals]'
__go_fix_analyzers() {
local -a fix_analyzers=(
"any[replace interface{} with any]"
"buildtag[check //go:build and // +build directives]"
"fmtappendf[replace \[\]byte(fmt.Sprintf) with fmt.Appendf]"
"forvar[remove redundant re-declaration of loop variables]"
"hostport[check format of addresses passed to net.Dial]"
"inline[apply fixes based on 'go:fix inline' comment directives]"
"mapsloop[replace explicit loops over maps with calls to maps package]"
"minmax[replace if/else statements with calls to min or max]"
"newexpr[simplify code by using go1.26's new(expr)]"
"omitzero[suggest replacing omitempty with omitzero for struct fields]"
"plusbuild[remove obsolete //+build comments]"
"rangeint[replace 3-clause for loops with for-range over integers]"
"reflecttypefor[replace reflect.TypeOf(x) with TypeFor\[T\]()]"
"slicescontains[replace loops with slices.Contains or slices.ContainsFunc]"
"slicessort[replace sort.Slice with slices.Sort for basic types]"
"stditerators[use iterators instead of Len/At-style APIs]"
"stringsbuilder[replace += with strings.Builder]"
"stringscut[replace strings.Index etc. with strings.Cut]"
"stringscutprefix[replace HasPrefix/TrimPrefix with CutPrefix]"
"stringsseq[replace ranging over Split/Fields with SplitSeq/FieldsSeq]"
"testingcontext[replace context.WithCancel with t.Context in tests]"
"waitgroup[replace wg.Add(1)/go/wg.Done() with wg.Go]"
)
_values -s ',' 'fix name' $fix_names
_values 'analyzer' $fix_analyzers
}
__go_pprof_symbolize_types() {
local -a symbolize_types=(
"none[Do not attempt symbolization]"
"local[Examine only local binaries]"
"fastlocal[Only get function names from local binaries]"
"remote[Do not examine local binaries]"
"force[Force re-symbolization]"
)
_values 'symbolize_type' $symbolize_types
}
if [[ "$service" = -value-* ]]; then
@ -399,6 +424,38 @@ case $state in
'why:explain why packages or modules are needed'
'help:get more information about a command'
)
local -a fix_flags=(
'-fixtool=[specify fix analyzer]:analyzer:__go_fix_analyzers'
'-diff[display diffs instead of rewriting files]'
'-fixtool=[select analysis tool]:analyzer:'
'(- *)-V[print version and exit]'
'-any[enable any analysis]'
'-buildtag[enable buildtag analysis]'
'-c[display offending line with this many lines of content(default: -1)]:num'
'-fix[apply all suggested fixes]'
'-flags[print analyzer flags in JSON]'
'-fmtappendf[enable fmtappendf analysis]'
'-forvar[enable forvar analysis]'
'-hostport[enable hostport analysis]'
'-inline[enable inline analysis]'
'-json[emit JSON output]'
'-mapsloop[enable mapsloop analysis]'
'-minmax[enable minmax analysis]'
'-newexpr[enable newexpr analysis]'
'-omitzero[enable omitzero analysis]'
'-plusbuild[enable plusbuild analysis]'
'-rangeint[enable rangeint analysis]'
'-reflecttypefor[enable reflecttypefor analysis]'
'-slicescontains[enable slicescontains analysis]'
'-slicessort[enable slicessort analysis]'
'-stditerators[enable stditerators analysis]'
'-stringsbuilder[enable stringsbuilder analysis]'
'-stringscut[enable stringscut analysis]'
'-stringscutprefix[enable stringscutprefix analysis]'
'-stringsseq[enable stringsseq analysis]'
'-testingcontext[enable testingcontext analysis]'
'-waitgroup[enable waitgroup analysis]'
)
case $words[1] in
(build)
@ -532,10 +589,7 @@ case $state in
(fix)
_arguments \
'-C[change to directory before running the command]: :_files -/' \
'-diff[display diffs instead of rewriting files]' \
'-force[force these fixes to run even if the code looks updated]:fix_names:__go_fix_names' \
'-go[go language version for files]:version' \
'-r[restrict the rewrites to this comma-separated list]:fix_names:__go_fix_names' \
$fix_flags[@] \
'*:importpaths:__go_packages'
;;
@ -572,7 +626,6 @@ case $state in
(install)
_arguments \
${build_flags[@]} \
'-json[emit install output in JSON suitable for automated processing]' \
'*:importpaths:__go_packages'
;;
@ -602,7 +655,7 @@ case $state in
;;
(mod)
_arguments \
_arguments -C \
"1: :{_describe 'command' mod_commands}" \
'*:: :->args'
@ -639,8 +692,8 @@ case $state in
'-e[attempt to proceed despite errors encountered while loading packages]' \
'-x[print the commands download executes]' \
'-diff[not to modify go.mod or go.sum but instead print necessary changes as a unified diff]' \
'-go[update the go directive in the go.mod file to the given version]:goversion' \
'-compat[preserves additional checksums needed for the indicated Go version]:version'
'-go=[update the go directive in the go.mod file to the given version]:goversion' \
'-compat=[preserves additional checksums needed for the indicated Go version]:version'
;;
(vendor)
_arguments \
@ -712,6 +765,7 @@ case $state in
else
_arguments \
"-c[compile but don't run test]" \
'-artifacts[save test artifacts in the directory specified by -outputdir]' \
'-bench[run benchmarks matching the regular expression]:regexp' \
'-benchmem[print memory allocation statistics for benchmarks]' \
'-benchtime[run benchmarks for t rime]:t' \
@ -908,12 +962,12 @@ case $state in
;;
(fix)
if [[ $words[2] == "help" ]]; then
__go_fix_analyzers
else
_arguments \
'(* -)-help[show help message]' \
'-diff[display diffs instead of rewriting files]' \
'-force[force fixes to run even if the code looks updated]:string:__go_fix_names' \
'-r[restrict the rewrites]:string:__go_fix_names' \
'*:files:_files'
"*:args:{ _alternative ':subcommand:(help)' _files }"
fi
;;
(link)
@ -995,15 +1049,17 @@ case $state in
':files:_files'
;;
pprof)
(pprof)
_arguments \
'-callgrind[outputs a graph in callgrind format]' \
'-comments[output all profile comments]' \
'-disasm=[output annotated assembly]:p' \
'-dot[outputs a graph in DOT format]' \
'-eog[visualize graph through eog]' \
'-evince[visualize graph through evince]' \
'-gif[outputs a graph image in GIF format]' \
'-gv[visualize graph through gv]' \
'-kcachegrind[visualize report in KCachegrind]' \
'-list=[output annotated source for functions matching regexp]:p' \
'-pdf[outputs a graph in PDF format]' \
'-peek=[output callers/callees of functions matching regexp]:p' \
@ -1015,23 +1071,61 @@ case $state in
'-tags[outputs all tags in the profile]' \
'-text[outputs top entries in text form]' \
'-top[outputs top entries in text form]' \
'-topproto[outputs top entries in compresses protobuf format]' \
'-traces[outputs all profile samples in text form]' \
'-tree[outputs a text rendering of call graph]' \
'-web[visualize graph through web browser]' \
'-weblist=[output annotated source in HTML]:p' \
'-call_tree[generate a context-sensitive call tree]' \
'-compact_labels[show minimal headers]' \
'-divide_by=[scale all samples by dividing them by f]:f' \
'-drop_negative[ignore negative differences]' \
'-edgefraction=[hide edges below <f>*total]:f' \
'-focus=[restricts to paths going through a node matching regexp]:r' \
'-hide=[skips nodes matching regexp]:regexp' \
'-ignore=[skips paths going through any nodes matching regexp]:r' \
'-intel_syntax[show assembly in Intel syntax]' \
'-mean[average sample value over first value]' \
'-nodecount=[max number of nodes to show]:n' \
'-nodefraction=[hide nodes below <f>*total]:f' \
'-noinlines[ignore inlines]' \
'-normalize[scales profile based on the base profile]' \
'-output=[generate output on file f (stdout by default)]:f' \
'-prune_from[drops any functions below the matched frame]' \
'-relative_percentages[show percentages relative to focused subgraph]' \
'-sample_index[index of sample value to display]' \
'-show=[only show nodes matching regexp]:regexp' \
'-show-from=[drops functions above the highest matched frame]:regexp' \
'-show-columns[show column numbers at the source code line level]' \
'-source_path=[search path for source files]:path:_files -/' \
'-tagfocus=[restrict to samples tagged with key:value matching regexp]:r' \
'-taghide=[skip tags matching this regexp]:regexp' \
'-tagignore=[discard samples tagged with key:value matching regexp]:regexp' \
'-tagleaf[add pseudo stack frames for labels key/value pairs at the callstack leaf]' \
'-tagroot[add pseudo stack frames for labels key/value pairs at the callstack root]' \
'-trim[honor nodefraction/edgefraction/nodecount defaults]' \
'-trim_path[path to trim from source paths before search]:path:_files -/' \
'-unit=[convert all samples to unit u for display]:u' \
'-functions[report at function level (default)]' \
'-filefunctions[aggregate at the file function level]' \
'-files[report at source file level]' \
'-lines[report at source line level]' \
'-addresses[report at address level]' \
'-base[show delta from this profile]:profile' \
'-drop_negative[ignore negative differences]' \
'-cum[sort by cumulative data]' \
'-flat[sort entries based on own weight]' \
'-seconds=[length of time for dynamic profiles]:n' \
'-nodecount=[max number of nodes to show]:n' \
'-nodefraction=[hide nodes below <f>*total]:f' \
'-edgefraction=[hide edges below <f>*total]:f' \
'-sample_index[index of sample value to display]' \
'-mean[average sample value over first value]' \
'-timeout=[timeout in seconds for profile collection]:seconds' \
'-buildid=[override build id for main binary in profile]:id' \
'-add_comment=[free-form annotation to add to the profile]:comment' \
'-diff_base=[source of base profile for comparison]:source:_files' \
'-base[show delta from this profile]:profile' \
'-symbolize=[controls source of symbol information]:source:__go_pprof_symbolize_types' \
'-tls_cert=[TLS client certificate file for fetchign profile and symbols]:file:_files' \
'-tls_key=[TLS private key file for fetching profile and symbols]:file:_files' \
'-tls_ca=[TLS CA certs file for fetching profile and symbols]:file:_files' \
'-http=[provide web interface at host:port]:host_port' \
'-no_browser[skip opening a browser for the interactive web UI]' \
'-tools=[search path for object tools]:path:_files -/' \
'-inuse_space[display in-use memory size]' \
'-inuse_objects[display in-use object counts]' \
'-alloc_space[display allocated memory size]' \
@ -1039,16 +1133,6 @@ case $state in
'-total_delay[display total delay at each region]' \
'-contentions[display number of delays at each region]' \
'-mean_delay[display mean delay at each region]' \
'-runtime[show runtime call frames in memory profiles]' \
'-focus=[restricts to paths going through a node matching regexp]:r' \
'-ignore=[skips paths going through any nodes matching regexp]:r' \
'-tagfocus=[restrict to samples tagged with key:value matching regexp]:r' \
'-tagignore=[discard samples tagged with key:value matching regexp]' \
'-call_tree[generate a context-sensitive call tree]' \
'-unit=[convert all samples to unit u for display]:u' \
'-divide_by=[scale all samples by dividing them by f]:f' \
'-buildid=[override build id for main binary in profile]:id' \
'-tools=[search path for object-level tools]:path' \
'-help[help message]' \
'*:files:_files'
;;

View File

@ -28,7 +28,7 @@
# Description
# -----------
#
# Completion script for Node.js v25.4.0 (https://nodejs.org)
# Completion script for Node.js v25.5.0 (https://nodejs.org)
#
# ------------------------------------------------------------------------------
# Authors
@ -84,6 +84,7 @@ _node() {
'--allow-net[allow use of network when any permissions are set]' \
'--allow-wasi[allow wasi when any permissions are set]' \
'--allow-worker[allow worker threads when any permissions are set]' \
'--build-sea=[Build a Node.js single executable application]:sea_config:_files -g "*.json"' \
'--build-snapshot[generate a snapshot blob when the process exits]' \
'--build-snapshot-config=[generate a snapshot blob when the process exits using a JSON configuration in the specified path]:path:_files' \
{-c,--check}'[syntax check script without executing]' \

View File

@ -0,0 +1,454 @@
* 目录
- [[#介绍][介绍]]
- [[#开始][开始]]
- [[#让zsh知道用哪个函数补全命令][让zsh知道用哪个函数补全命令]]
- [[#补全gnu格式命令][补全gnu格式命令]]
- [[#从其它命令复制补全][从其它命令复制补全]]
- [[#编写你自己的补全代码][编写你自己的补全代码]]
- [[#工具函数][工具函数]]
- [[#用_describe编写简单的补全函数][用_describe编写简单的补全函数]]
- [[#用_alternative编写补全函数][用_alternative编写补全函数]]
- [[#用_arguments编写补全函数][用_arguments编写补全函数]]
- [[#用_regex_arguments和_regex_words编写补全函数][用_regex_arguments和_regex_words编写补全函数]]
- [[#用_values_sep_parts和_multi_parts实现复杂补全][用_values、_sep_parts和_multi_parts实现复杂补全]]
- [[#用compadd直接添加补全词][用compadd直接添加补全词]]
- [[#测试与debug][测试与debug]]
- [[#踩坑了吧-需要小心的东西][踩坑了吧 (需要小心的东西)]]
- [[#小贴士][小贴士]]
- [[#其它资源][其它资源]]
> 译注:本文可能有不通顺的地方,或者采用的词汇不是很正确。
> 如果你有更好的主意欢迎提交PR。
* 介绍
Zsh官方的补全函数文档令人费解而且也没提供多少示例。
写这份文档的当下我已经在网上找到了其它几份教程,但是那些教程只涉及了补全系统的一小部分。
这份文档目的在于补全网上其它地方没涵盖的部分,同时附带示例,这样读者就可以学会如何写更高级的补全函数。
我不会展开每一细节,但给你提供的内容和示例足以从零开始。
如果你需要了解更多细节,你可以自行查询[[https://zsh.sourceforge.net/Doc/Release/Completion-System.html#Completion-System][官方文档]]。
还请公开你所创作的任何脚本比如fork这个仓库然后[[id:64bcd501-b0f0-48c7-b8e2-07af708b95ec][pr]])。
此外如果你有任何更多补充内容或对此教程的改进,欢迎做贡献。
* 开始
** 让zsh知道用哪个函数补全命令
补全命令用的补全函数储存于名字以下划线“_”起始的文件这些文件应存于$fpath变量所列出的某目录中。
你可以将下面的代码写入你的~/.zshrc以在$fpath中新增目录
#+BEGIN_SRC sh
fpath=(~/newdir $fpath)
#+END_SRC
一个补全函数文件的第一行长这个样:
#+BEGIN_SRC sh
#compdef foobar
#+END_SRC
这行代码表示这个文件含有补全foobar命令的代码。
多数情况下第一行都采用这个格式,但你也可以用同一个文件补全多个不同的函数。
查阅[[https://zsh.sourceforge.net/Doc/Release/Completion-System.html#Autoloaded-files][官方文档]]以了解更多细节。
你也可以直接使用compdef命令(比如在你的~/.zshrc文件里)来告诉zsh用哪个函数补全命令
#+BEGIN_SRC sh
> compdef _function foobar
#+END_SRC
或者对多个命令使用同一种补全:
#+BEGIN_SRC sh
> compdef _function foobar goocar hoodar
#+END_SRC
如果你想提供参数的话:
#+BEGIN_SRC sh
> compdef '_function arg1 arg2' foobar
#+END_SRC
查阅[[https://zsh.sourceforge.net/Doc/Release/Completion-System.html#Functions-4][官方文档]]以了解更多细节。
** 补全gnu格式命令
很多[[https://www.gnu.org/][gnu]]命令以标准化的方式列出选项描述(使用--help选项时
对于这些命令你可以使用_gnu_generic函数自动创建补全比如这样
#+BEGIN_SRC sh
> compdef _gnu_generic foobar
#+END_SRC
或者对多个不同命令使用_gnu_generic
#+BEGIN_SRC sh
> compdef _gnu_generic foobar goocar hoodar
#+END_SRC
你可以把这行代码放进~/.zshrc文件里。
** 从其它命令复制补全
如果你想要让一个命令比如cmd1和另一个已有补全的命令比如cmd2)拥有相同的补全,你可以:
#+BEGIN_SRC sh
> compdef cmd1=cmd2
#+END_SRC
比如当你给一个命令创建了一个助记alias的时候会很有帮助。
* 编写你自己的补全代码
你可以通过阅读已有的补全函数来开始入门。
在我的Linux系统上这些补全函数在/usr/share/zsh/functions/Completion/Unix、
/usr/share/zsh/functions/Completion/Linux和一些其它子目录下。
你会注意到这些文件频繁使用_arguments函数。
该函数是一个工具函数,可用于编写简单的补全函数。
_arguments函数是一个compadd内置函数的包装函数。
compadd内置函数是一个核心函数用于向命令行加入补全词并控制其行为。
不过多数情况下你不需要使用compadd因为有很多更易于使用的工具函数如_arguments和_describe。
对于非常基础的补全_describe函数已经够用了。
** 工具函数
下面是一个工具函数列表,你或许会用到它们。
工具函数的完整列表及使用方法在[[https://zsh.sourceforge.net/Doc/Release/Completion-System.html#Completion-Functions][]]可供查阅。
这些函数的使用示例在下一节给出。
> 译注从这里开始会出现一些术语如定义specification、描述description、动作action、词汇word等。
> 初次阅读可能会觉得比较困难,尤其是下面的工具函数表格,稍后教程开始一一讲解并给出示例的时候就好懂多了。
> 定义指的是对补全规则的定义,如`_describe 定义`。
> 描述当然指的是对命令行选项和参数的用户友好描述,补全时会显示在屏幕上,如:'-o 输出文件'
> 词汇指的是如同'word'、'-o'、'--help'、'start'等连续的一小段字符串
> 动作指的是匹配成功后执行的操作,比如执行某函数生成补全,或直接补全等等。
> 选项option和参数指给命令提供的选项和参数如`cp -r src dst`中,`-r`为选项,`src`和`dst`为参数。有些选项带参,如`tar -f file ...`中`-f`选项带`file`参数。
> 候选candidate指可能的补全结果如补全`tar -f`时目录下所有文件会被作为候选,补全`systemctl`时`start`、`stop`、`list-units`等指令会被作为候选。
> 还请不要感到灰心,读下去就是了。
*** 用于大部分补全的主要工具函数
| _alternative | 从其它工具函数或shell代码生成补全候选。 |
| _arguments | 指定如何补全一命令的各选项和参数命令选项风格为unix风格。 |
| _describe | 创建由带描述的词汇但不包含动作组成的简单补全。比_arguments更简单。 |
| _gnu_generic | 为带有“--help”选项的命令补全选项。 |
| _regex_arguments | 创建一先用regex表达式匹配命令行参数再执行动作/补全的函数。 |
*** 对单个词汇进行复杂补全的工具函数
| _values | 补全任意词汇(值)及其参数,或逗号分隔的词汇与参数列表。 |
| _combination | 补全值的组合,比如域名和用户名的二元组。 |
| _multi_parts | 对词汇的由符号分隔的多个部分分别补全,比如补全路径:/u/i/sy -> /usr/include/sys |
| _sep_parts | 类似_multi_parts但在补全的不同部分中允许不同的分隔符。 |
| _sequence | 包装另一补全函数,并补全由该函数生成的匹配列表。 |
*** 用于补全特定对象种类的函数
| _path_files | 补全文件目录。用多个选项控制行为。 |
| _files | 使用所有选项调用_path_files除了-g和-/。这些选项取决于file-patterns风格设置。 |
| _net_interfaces | 补全网络接口名称。 |
| _users | 补全用户名 |
| _groups | 补全组名 |
| _options | 补全shell选项名。 |
| _parameters | 补全shell参数/变量名(可用模式匹配限制要补全的参数/变量名)。 |
*** 处理已缓存的补全的函数
如果你有大量的补全,你可以将补全保存于一个缓存文件以快速加载。
| _cache_invalid | 指明补全缓存是否需要重新构建rebuild缓存由标识符指定 |
| _retrieve_cache | 从缓存文件获取补全信息 |
| _store_cache | 储存缓存于缓存文件,缓存由标识符指定 |
*** 其它函数
| _message | 当无补全可生成时显示帮助信息。 |
| _regex_words | 为_regex_arguments命令生成参数。比手写参数更简单。 |
| _guard | 检查被补全的词汇用于_arguments和类似函数的定义的ACTION中。 |
*** 动作Actions
许多工具函数如_arguments、_regex_arguments、_alternative和_values在选项/参数末尾有一个action。
这个action指定如何补全对应的参数。
这些action可以是如下形式之一
| ( ) | 需要提供参数但未生成任何匹配 |
| (ITEM1 ITEM2) | 匹配列表 |
| ((ITEM1\:'DESC1' ITEM2\:'DESC2')) | 匹配列表,带有描述。引号必须和整个定义所使用的引号不同。 |
| ->STRING | 将$state设为STRING然后继续可在调用工具函数后用case语句检查$state的值 |
| FUNCTION | 生成匹配或完成其它操作的函数的函数名比如_files或_message |
| {EVAL-STRING} | 把字符串当作shell代码执行evaluate。可用于带参调用工具函数如_values或_describe |
| =ACTION | 在补全命令行中插入占位词汇不改变补全点。 |
并非所有的action种类都可用于使用action的工具函数。比如->STRING类不可用于_regex_arguments或_alternative函数。
** 用_describe编写简单的补全函数
_describe函数可以用于简单的补全此类补全的选项/参数的位置与顺序无关紧要。
你只需用一个数组参数储存这些选项和其描述然后将数组参数的名作为参数传入_describe。
下面的示例创建补全候选c和d注意代码文件名应为_cmd并且文件存于$fpath所列出的目录之下
#+BEGIN_SRC sh
#compdef cmd
local -a subcmds
subcmds=('c:c命令描述' 'd:d命令描述')
_describe 'command' subcmds
#+END_SRC
你可以像下面一样使用由双横杠分隔的列表,但注意实操时会混合匹配结果,所以不应该用于不同种类的补全候选:
#+BEGIN_SRC sh
local -a subcmds topics
subcmds=('c:c命令描述' 'd:d命令的描述')
topics=('e:e帮助主题的描述' 'f:f帮助主题的描述')
_describe 'command' subcmds -- topics
#+END_SRC
如果两个候选有相同的描述_describe把它们集于一行并确保描述严格按列对齐。
_describe函数可用在_alternative、_arguments或_regex_arguments的ACTION中。
在这种情况下你需要用括号将_describe和参数包起来比如'TAG:DESCRIPTION:{_describe 'values' options}'
** 用_alternative编写补全函数
如同_describe该函数进行简单补全其选项/参数的顺序和位置并不重要。
然而与_describe的固定匹配不同_alternative可进一步调用函数生成补全候选。
此外_alternative允许混合不同种类的补全候选。
关于参数该函数接受一列定义specification每项定义的形式为“TAG:DESCRIPTION:ACTION”即“标签:描述:动作”其中TAG是一个标识补全匹配种类的特殊标签。
DESCRIPTION以标题heading的形式描述补全候选组而ACTION是先前列出的动作种类之一除了->STRING和=ACTION之外
例如:
#+BEGIN_SRC sh
_alternative 'arguments:自定义参数:(a b c)' 'files:文件名:_files'
#+END_SRC
第一个定义增加了补全候选a、b和c而第二个定义调用_files函数以补全文件目录。
我们可以用反斜杠 \ 将不同定义分成几行并给每个自定义参数加入描述文字:
#+BEGIN_SRC sh
_alternative \
'args:自定义参数:((a\:"描述a" b\:"描述b" c\:"描述c"))' \
'files:文件名:_files'
#+END_SRC
如果我们想向_files传递参数我们可以直接写在_files后面
#+BEGIN_SRC sh
_alternative \
'args:自定义参数:((a\:"描述a" b\:"描述b" c\:"描述c"))' \
'files:文件名:_files -/'
#+END_SRC
如要用变量展开创建补全列表,必须用双引号将定义括起来,
如:
#+BEGIN_SRC sh
_alternative \
"dirs:用户目录:($userdirs)" \
"pids:进程ID:($(ps -A o pid=))"
#+END_SRC
在此例子中第一个定义加入$userdirs变量中的词汇第二个定义执行'ps -A o pid='并获取pid表pid表用作补全候选。
实操中我们使用已有的_pids函数而不是像上面那样手写。
我们可以在ACTION中使用_values等其它工具函数以完成更复杂的补全
#+BEGIN_SRC sh
_alternative \
"directories:用户目录:($userdirs)" \
'options:逗号分隔选项: _values -s , letter a b c'
#+END_SRC
该示例补全$userdirs里的项目以及用逗号分隔的、含有a、b和/或c的列表。
注意_values前面的空格。空格不可省略因为_values不能接受标准compadd描述选项。
和_describe一样_alternative可用作ACTION并作为_arguments或_regex_arguments的一部分。
** 用_arguments编写补全函数
只需要调用_arguments函数一次就可以创造出非常智能的补全函数。该函数本身就是用于处理这种带有带参选项的命令的。
如同_alternative函数_arguments接受一列定义字符串参数。
这些定义字符串指定选项和任何对应的选项参数(如:-f 文件名),或命令参数。
简单的选项定义用'-OPT[DESCRIPTION]'(即'-选项[描述]'),比如:
#+BEGIN_SRC sh
_arguments '-s[排序后输出]' '--l[更多输出]' '-l[更多输出]'
#+END_SRC
选项参数可在选项描述后指定,形式用'-OPT[DESCRIPTION]:MESSAGE:ACTION'(即'-选项[描述]:消息:动作',
其中MESSAGE是待显示的信息而ACTION可以是前面的动作Actions章节提到的任何形式。
比如:
#+BEGIN_SRC sh
_arguments '-f[输入文件]:文件名:_files'
#+END_SRC
命令参数定义用'N:MESSAGE:ACTION'(即'N:消息:动作'其中N指定这是第N个命令参数而MESSAGE和ACTION都和前面的一样。
如果N被省略则其仅表示这是在所有已定义的参数之后的下一个参数。如果开头在N后面用的是双冒号则参数非必需。
比如:
#+BEGIN_SRC sh
_arguments '-s[排序后输出]' '1:第一个参数:_net_interfaces' '::可选参数:_files' ':下一个参数:(a b c)'
#+END_SRC
这里第一个参数是网络接口下一个可选参数是一个文件名最后一个参数可以是a、b或c而-s选项可以在任何位置被补全。
_arguments函数允许所有ACTION形式在前面的动作(Actions)章节列出)。
这表示你可以用动作来选择case语句分支
#+BEGIN_SRC sh
_arguments '-m[音乐文件]:文件名:->files' '-f[flags]:flag:->flags'
case "$state" in
files)
local -a music_files
music_files=( Music/**/*.{mp3,wav,flac,ogg} )
_multi_parts / music_files
;;
flags)
_values -s , 'flags' a b c d e
;;
esac
#+END_SRC
在此例子中指向音乐文件的路径被_multi_parts一步步地沿目录下降补全
而flags被_values函数按照逗号分隔列表补全。
我已经介绍了_arguments定义的基础部分你还可以定义互斥选项、重复选项和参数、以+开头的选项等。有关更多细节,查阅[[https://zsh.sourceforge.net/Doc/Release/Completion-System.html#Completion-System][官方文档]]。
同时你也可以看看本文末尾列出的教程,以及[[https://github.com/vapniks/zsh-completions/tree/master/src][src目录]]下的补全函数。
** 用_regex_arguments和_regex_words编写补全函数
如果你的命令行定义比较复杂有多个可能的参数序列那你可能需要_regex_arguments函数。
该函数也适用于有一系列跟着多个参数的关键词的情况。
_regex_arguments创建名字由第一个参数给出的补全函数。
因此你需要先调用_regex_arguments来创建补全函数然后再调用该函数比如
#+BEGIN_SRC sh
_regex_arguments _cmd OTHER_ARGS..
_cmd "$@"
#+END_SRC
OTHER_ARGS即“其它参数”是一序列用于在命令行上匹配和补全词汇的定义。
这些序列可被'|'分隔来表示备选词汇序列。
你可以用任意嵌套深度的括号来指定备选序列,但括号必须带反斜杠前缀,如\( \),或用引号括起来,如'(' ')'。
比如:
#+BEGIN_SRC sh
_regex_arguments _cmd 序列1 '|' 序列2 \( 序列2a '|' 序列2b \)
_cmd "$@"
#+END_SRC
该示例定义一个匹配序列1或序列2后跟着序列2a或序列2b的命令行。这种方式和正则表达式语法类似。
一个序列中的每个定义必须在开头包含一个/ PATTERN/ (即/ 模式/)部分,后跟着可选的':TAG:DESCRIPTION:ACTION'(即':标签:描述:动作')部分。
每个PATTERN是一个匹配一命令行词汇的正则表达式。这些模式按顺序匹配直到某个模式不匹配不匹配的模式将执行对应的ACTION动作以进行补全。
注意,一定要有一个匹配命令自身的模式。
下面有对PATTERN模式更详细的解释。
':TAG:DESCRIPTION:ACTION'的使用方法和_alternative相同只是开头多了个冒号“:”并且前面列出的所有ACTION格式都可用。
例如:
#+BEGIN_SRC sh
_regex_arguments _cmd /$'[^\0]##\0'/ \( /$'word1(a|b|c)\0'/ ':word:first word:(word1a word1b word1c)' '|'\
/$'word11(a|b|c)\0'/ ':word:first word:(word11a word11b word11c)' \( /$'word2(a|b|c)\0'/ ':word:second word:(word2a word2b word2c)'\
'|' /$'word22(a|b|c)\0'/ ':word:second word:(word22a word22b word22c)' \) \)
_cmd "$@"
#+END_SRC
TODO 英文原文和例子有出入
在这个例子中第一个词可以是word1即“词1”下同或者word11后紧跟a、b或c并且如果第一个词含有11则第二个词可以是word2后紧跟a、b或c或一个文件名。
如果感觉太复杂你也可以用更简单的_regex_words函数达到相同效果。
*** 模式
你可能注意到了上个例子中的/ PATTERN/和普通的正则表达式不太一样。
通常使用的是形如$'foo\0'的字符串参数。这是为了让\0表示成null字符而zsh内部用来分隔词汇的也是null字符。
如果不在末尾包含\0的话可能会无法匹配下一个词。如果你要把一个变量的值作为模式的一部分你可以用双括号包起来
这样变量就会展开然后再在后面加个包含null字符的字符串参数比如"$somevar"$'\0'somevar即“某变量”
表示模式用的正则表达式语法和正常的正则表达式不太一样,但我也找不到有关的文档。
不过我还是试图搞清楚了这些特殊字符的意义:
| * | 通配符 - 任何数量的字符 |
| ? | 通配符 - 单个字符 |
| # | 零个或更多的上一个字符(和一般正则表达式里的*一样) |
| ## | 一个或更多的上一个字符(和一般正则表达式里的+一样) |
*** _regex_words
_regex_words函数比_regex_arguments更简单易用。
调用_regex_words后的结果可以存在变量里。
要用_regex_words创建一个定义specification你需要提供一个标签后跟一段描述后跟一个定义不同词汇的列表。
这些定义采用'WORD:DESCRIPTION:SPEC'(即'词汇:描述:定义'的格式WORD即待补全的词DESCRIPTION是对应的描述
SPEC可以是由_regex_words创建的另一个变量以指定当前词后的下一个词汇也可以留空以表示没有更多的词。
比如:
#+BEGIN_SRC sh
_regex_words firstword '第一个词' 'word1a:词a:' 'word1b:词b:' 'word1c:词c'
#+END_SRC
该函数的返回结果将被存入$replyreply即“回复”、“回应”数组里所以我们需要在$reply变化前将结果存进另一个数组里
#+BEGIN_SRC sh
local -a firstword
_regex_words word 'The first word' 'word1a:a word:' 'word1b:b word:' 'word1c:c word'
firstword="$reply[@]"
#+END_SRC
firstword即“第一个词”。
然后我们可以把结果用在_regex_arguments里
#+BEGIN_SRC sh
_regex_arguments _cmd /$'[^\0]##\0'/ "$firstword[@]"
_cmd "$@"
#+END_SRC
注意到我给命令自身也加了模式。
这里还有个更复杂的词汇我们调用_regex_words以匹配不同词汇
#+BEGIN_SRC sh
local -a firstword firstword2 secondword secondword2
_regex_words word1 '第二个词' 'woo:鄧族' 'hoo:不关我事'
secondword=("$reply[@]")
_regex_words word2 '另一个第二个词' 'yee:汝' 'haa:很搞笑!'
secondword2=("$reply[@]")
_regex_words commands '第一个词' 'foo:做foo' 'man:yeah man' 'chu:at chu' # 译注作者在自嗨at chu除了比较像at you外没什么特殊意义
firstword=("$reply[@]")
_regex_words word4 '另一个第一个词' 'boo:吓死某人:$secondword' 'ga:嘤嘤嘤:$secondword'\
'loo:上厕所:$secondword2'
firstword2=("$reply[@]")
_regex_arguments _hello /$'[^\0]##\0'/ "${firstword[@]}" "${firstword2[@]}"
_hello "$@"
#+END_SRC
在这个例子中第一个词可以是"foo"、"man"、"chu"、"boo"、"ga"或"loo"。
如果第一个词是"boo"或"ga",那下一个词可以是"woo"或"hoo"
而如果第一个词是"loo"则第二个词可以是"yee"或"haa",其它情况下没有第二个词。
_ip函数是_regex_words的一个好用例。
** 用_values、_sep_parts和_multi_parts实现复杂补全
_values、_sep_parts和_multi_parts可以单独使用也可以作为_alternative、_arguments或_regex_arguments定义里的ACTION。可以看看下面的例子。
查阅[[https://zsh.sourceforge.net/Doc/Release/Completion-System.html#Completion-System][官方文档]]以了解更多信息。
空格分隔的mp3文件列表
#+BEGIN_SRC sh
_values 'mp3文件' ~/*.mp3
#+END_SRC
逗号分隔的会话id列表
#+BEGIN_SRC sh
_values -s , '会话id' "${(uonzf)$(ps -A o sid=)}"
#+END_SRC
补全foo@news:woo、foo@news:laa或bar@news:woo等
#+BEGIN_SRC sh
_sep_parts '(foo bar)' @ '(news ftp)' : '(woo laa)'
#+END_SRC
补全MAC地址一次补全一个字节
#+BEGIN_SRC sh
_multi_parts : '(00:11:22:33:44:55 00:23:34:45:56:67 00:23:45:56:67:78)'
#+END_SRC
** 用compadd直接添加补全词
你可以使用内置的compadd函数增加补全词以获得更细致的控制。
这个函数有各种选项控制如何显示补全以及补全时如何替换命令行上的文字。
阅读[[https://zsh.sourceforge.net/Doc/Release/Completion-System.html#Completion-System][官方文档]]以获得更多细节。
这里我只给出几个简单的示例。
向补全列表里加入若干词汇:
#+BEGIN_SRC sh
compadd foo bar blah
#+END_SRC
同上但显示注释:
#+BEGIN_SRC sh
compadd -X '一些注释' foo bar blah
#+END_SRC
同上但在补全前自动插入"what_"前缀
#+BEGIN_SRC sh
compadd -P what_ foo bar blah
#+END_SRC
同上但补全后自动插入"_todo"后缀:
#+BEGIN_SRC sh
compadd -S _todo foo bar blah
#+END_SRC
同上但在后缀后打空格时自动移除"_todo"后缀:
#+BEGIN_SRC sh
compadd -P _todo -q foo bar blah
#+END_SRC
向补全数组$wordsarraywordsarray即“词数组”加入词汇
#+BEGIN_SRC sh
compadd -a wordsarray
#+END_SRC
* 测试与debug
重新加载补全函数:
#+BEGIN_SRC sh
> unfunction _func
> autoload -U _func
#+END_SRC
这些函数会提供有用的信息。
如果默认按键没有用你可以尝试Alt+x然后再输入命令名。
| 函数 | 默认按键 | 作用 |
|-----------------+--------------------+----------------------------------------------------------------|
| _complete_help | Ctrl+x h | 在当前光标位置补全时显示有关上下文名称、标签和补全函数的信息 |
| _complete_help | Alt+2 Ctrl+x h | 同上但显示更多信息 |
| _complete_debug | Ctrl+x ? | 执行正常补全但跟踪补全系统执行的shell命令并存入一个临时文件 |
* 踩坑了吧 (需要小心的东西)
记得在补全函数的文件开头加那行#compdef
_arguments或_regex_arguments的定义中要使用正确的引号
如果定义中有变量要展开,用双引号,其它情况用单引号,
并且记得在ITEM项目描述处用不同的引号。译注见[[#动作Actions][动作Actions]]章节)
_arguments、_alternative、_regex_arguments等的定义处要在正确的地方使用正确数量的冒号“:”。
使用_regex_arguments时要记得在开头写匹配命令的模式不需要加入匹配动作action
记得在_regex_arguments的任何PATTERN模式参数后加上null字符$'\0'
* 小贴士
有时一个子命令后只会跟一个选项这时zsh会在tab在子命令后按下时自动补全。如果你想要在补全前先列出选项和描述
你可以向ACTION动作加入另一个空选项比如\:),如':TAG:DESCRIPTION:((opt1\:"opt1描述" \:))'
注意这只对在定义参数中使用ACTION的工具函数_arguments、_regex_arguments等有效。
* 其它资源
[[https://wikimatze.de/writing-zsh-completion-for-padrino/][]]是个展示_arguments函数的基本使用方法的教程短小精悍
而[[https://web.archive.org/web/20190411104837/http://www.linux-mag.com/id/1106/][]]是_arguments函数的稍稍更进阶的教程。
[[https://zsh.sourceforge.net/Doc/Release/Completion-System.html#Completion-System][]]是zshcompsys手册页man page