Created
April 27, 2020 02:16
-
-
Save The0x539/865479766e81132740deba6c8a10f361 to your computer and use it in GitHub Desktop.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
# Sample output of 'mkvmerge -i file.mkv' | |
# | |
# File 'file.mkv': container: Matroska | |
# Track ID 0: video (MPEG-4p10/AVC/h.264) | |
# Track ID 1: audio (AAC) | |
# Track ID 2: subtitles (SubStationAlpha) | |
# Attachment ID 1: type 'application/x-truetype-font', size 53532 bytes, file name 'some_font.ttf' | |
# Chapters: 7 entries | |
function __fish_mkvextract_get_mode | |
set -l cmd (commandline -opc) | |
set -l skip_next 0 | |
set -l mode | |
for arg in $cmd[2..-1] | |
test $skip_next = 1; and set skip_next 0; and continue | |
switch $arg | |
case tracks tags attachments chapters cuesheet timecodes_v2 cues | |
# Docs specify that an invocation can use multiple modes | |
# With that in mind, find the last one rather than returning now | |
set mode $arg | |
case --ui-language --command-line-charset --output-charset -r --redirect-output --ui-language --debug --engage -c --blockadd --simple-language | |
# Switches that are accompanied by a value | |
set skip_next 1 | |
case -h --help -V --version --check-for-updates | |
# Switches that disable normal program behavior | |
return 1 | |
end | |
end | |
if test $mode | |
echo $mode | |
return 0 | |
else | |
return 1 | |
end | |
end | |
function __fish_mkvextract_get_file | |
# According to mkvtoolnix docs, the source file should be argv[1] | |
# However, at the time of writing, other invocations, most notably `mkvextract tracks file.mkv ...`, are accepted | |
# In accordance with the robustness principle: | |
# - suggested completions will fullfil that expectation | |
# - parsing of the command line will not assume this to necessarily be true | |
set -l cmd (commandline -opc) | |
set -l skip_next 0 | |
for arg in $cmd[2..-1] | |
test $skip_next = 1; and set skip_next 0; and continue | |
switch $arg | |
case tracks tags attachments chapters cuesheet timecodes_v2 cues -f --parse-fully --flush-on-close --abort-on-warnings --gui-mode -v --verbose -q --quiet --cuesheet --raw --fullraw -s --simple | |
# Switches that aren't accompanied by a value, but shouldn't be | |
continue | |
case '@*' | |
# JSON options files, specified to contain an array of string literals | |
# For maximum correctness, one might open the file and treat its contents as args | |
# In the context of tab completions, however, that seems almost out of scope | |
continue | |
case --ui-language --command-line-charset --output-charset -r --redirect-output --ui-language --debug --engage -c --blockadd --simple-language | |
# Switches that are accompanied by a value | |
set skip_next 1 | |
case -h --help -V --version --check-for-updates | |
# Switches that disable normal program behavior | |
return 1 | |
case '*' | |
# If we haven't found a filename yet, anything not matching the above patterns ought to be our input file | |
echo $arg | |
return 0 | |
end | |
end | |
return 1 | |
end | |
function __fish_mkvextract_using_mode | |
set -l mode (__fish_mkvextract_get_mode) | |
and contains -- $mode $argv | |
end | |
function __fish_mkvextract_no_mode | |
__fish_mkvextract_get_file | |
and not __fish_mkvextract_get_mode | |
end | |
function __fish_mkvextract_print_attachments | |
if set -l matroska (__fish_mkvextract_get_file) | |
if set -l info (mkvmerge -i $matroska) | |
string match 'Attachment ID*' -- $info | string replace -r '.*?(\d+).*? type \'(.*?)\'.*?file name \'(.*?)\'' '$1:\t$3 ($2)' | |
end | |
end | |
end | |
function __fish_mkvextract_print_tracks | |
set -l matroska (__fish_mkvextract_get_file) | |
or return 1 # No file | |
mkvmerge -q -i $matroska >/dev/null 2>/dev/null | |
or return 2 # Not a valid Matroska file (either nonexistent or wrong contents) | |
if type -q jq | |
# mkvmerge -J gives more information than mkvmerge -i | |
# mkvinfo also gives the information we'd need | |
# however, due to its format, the text manipulation necessary for what we're doing here would be... complicated | |
# introducing jq as an optional dependency makes things much easier | |
mkvmerge -J $matroska | jq -r ' .tracks[] | |
| .properties as $p | |
| (if $p.language == "und" then "" else "/"+$p.language end) as $lang | |
| (if $p.track_name then ": "+$p.track_name else "" end) as $name | |
| "\(.id):\t\(.type)\($lang)\($name) (\(.codec))" | |
' | |
else | |
mkvmerge -i $matroska | string match 'Track ID*' | string replace -r '.*?(\d+): (.*)' '$1:\t$2' | |
end | |
end | |
# simple options | |
complete -c mkvextract -s 'V' -l 'version' -f -d 'Show version information' | |
complete -c mkvextract -s 'h' -l 'help' -f -d 'Show help' | |
complete -c mkvextract -l 'check-for-updates' -f -d 'Check online for updates' | |
# once a file has been specified, no more are needed | |
complete -c mkvextract -n '__fish_mkvextract_get_file' -f | |
# extraction modes | |
complete -c mkvextract -n '__fish_mkvextract_no_mode' -k -a 'tracks' | |
complete -c mkvextract -n '__fish_mkvextract_no_mode' -k -a 'tags' | |
complete -c mkvextract -n '__fish_mkvextract_no_mode' -k -a 'attachments' | |
complete -c mkvextract -n '__fish_mkvextract_no_mode' -k -a 'chapters' | |
complete -c mkvextract -n '__fish_mkvextract_no_mode' -k -a 'cuesheet' | |
complete -c mkvextract -n '__fish_mkvextract_no_mode' -k -a 'timecodes_v2' | |
complete -c mkvextract -n '__fish_mkvextract_no_mode' -k -a 'cues' | |
# suggest tracks/attachments when appropriate | |
complete -c mkvextract -n '__fish_mkvextract_using_mode tracks timecodes_v2 cues' -a '(__fish_mkvextract_print_tracks)' | |
complete -c mkvextract -n '__fish_mkvextract_using_mode attachments' -a '(__fish_mkvextract_print_attachments)' | |
# these extraction modes have no parameters other than optional flags and the file | |
complete -c mkvextract -n '__fish_mkvextract_using_mode tags chapters cuesheet' | |
# general switches | |
complete -c mkvextract -s 'f' -l 'parse-fully' -d 'Parse the whole file instead of relying on the index' | |
complete -c mkvextract -s 'v' -l 'verbose' -d 'Increase verbosity' | |
complete -c mkvextract -s 'q' -l 'quiet' -d 'Suppress status output' | |
complete -c mkvextract -l 'ui-language' -r -d 'Force a locale' | |
complete -c mkvextract -l 'command-line-charset' -r -d 'Charset for strings on the command line' | |
complete -c mkvextract -l 'output-charset' -r -d 'Outputs messages in specified charset' | |
complete -c mkvextract -s 'r' -l 'redirect-output' -r -d 'Redirect all messages into a file' -F | |
complete -c mkvextract -l 'debug' -r -d 'Turn on debugging for a specific feature' | |
complete -c mkvextract -l 'engage' -r -d 'Turn on an experimental feature' -a '(mkvextract --engage list | tail -n+2)' | |
complete -c mkvextract -l 'gui-mode' -d 'Enable GUI mode' | |
complete -c mkvextract -l 'flush-on-close' -d 'Flush all cached data from memory when closing opened files' | |
complete -c mkvextract -l 'abort-on-warnings' -d 'Abort with exit code 1 after the first warning is emitted' | |
# track extraction switches | |
complete -c mkvextract -n '__fish_mkvextract_using_mode tracks' -s 'c' -r -d 'Convert text subtitles to a charset' | |
complete -c mkvextract -n '__fish_mkvextract_using_mode tracks' -l 'cuesheet' -d 'Also try to extract the CUE sheet' | |
complete -c mkvextract -n '__fish_mkvextract_using_mode tracks' -l 'blockadd' -r -d 'Keep only the BlockAdditions up to the specified level' | |
complete -c mkvextract -n '__fish_mkvextract_using_mode tracks' -l 'raw' -d 'Extract the data to a raw file' | |
complete -c mkvextract -n '__fish_mkvextract_using_mode tracks' -l 'fullraw' -d 'Extract the data to a raw file including the CodecPrivate as header' | |
# chapter extraction switches | |
complete -c mkvextract -n '__fish_mkvextract_using_mode chapters' -s 's' -l 'simple' -d 'Output chapter information as OGM instead of XML' | |
complete -c mkvextract -n '__fish_mkvextract_using_mode chapters' -l 'simple-language' -r -d 'Output only a specific language\'s chapter names' |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment