[1] If use-cache style is not on, nothing is completed for % pandoc -f <TAB> or for any other options that use cache (--t, --highlight-style, etc.). [2] The options -f and -t accepts FORMAT with zero, one or more EXTENSIONs -f FORMAT -f FORMAT+EXTENSION1-EXTENSION2+EXTENSION3 but the current _pandoc can complete at most one EXTENSION. [3] To complete FORMAT{+,-}EXTENSION, _pandoc creates a list of all the possible pairs of FORMAT{+,-}EXTENSION by calling pandoc --list-extensions=FORMAT repeatedly for all the supported FORMATs (more than 60 FORMATs). This may take some time, and I guess this is the reason that the use-cache is required. With this patch, "pandoc --list-extensions=FORMAT" is called only once after the FORMAT-part has been completed, and two or more EXTENSIONs can be completed after the FORMAT. With this change I think we don't need to use the cache. So I removed all the cache-related stuff. [4] "pandoc --list-extensions=markdown" gives a list of extensions like -abbreviations +all_symbols_escapable -amuse ... Here +/- indicates it is on/off by default. But the current _pandoc offers 'abbreviations' for -f markdown-<TAB> and 'all_symbols_escapable' for -f markdown+<TAB>; this should be the other way round. --- Completion/Unix/Command/_pandoc | 257 +++++++------------------------- 1 file changed, 56 insertions(+), 201 deletions(-) diff --git a/Completion/Unix/Command/_pandoc b/Completion/Unix/Command/_pandoc index 0c0672aaa..97f1190be 100644 --- a/Completion/Unix/Command/_pandoc +++ b/Completion/Unix/Command/_pandoc @@ -1,119 +1,29 @@ #compdef pandoc -# {{{ helper: cache policy for available formats and other variables -(( $+functions[__pandoc_cache_policy] )) || -__pandoc_cache_policy(){ - local cache_file="$1" - if [[ -f "${commands[pandoc]}" && -f "${cache_file}" ]]; then - # if the manifest file is newer then the cache: - if [[ "${commands[pandoc]}" -nt "${cache_file}" ]]; then - return 0 - else - return 1 - fi +# {{{ input or output formats with optional extensions +# required option: -T (input|output) +(( $+functions[_pandoc_format] )) || +_pandoc_format() { + local -a inout expl + zparseopts -D -E - T:=inout + local format=${PREFIX%%(+|-)*} + if compset -P '*(+|-)'; then + local pm=${IPREFIX[-1]} # '+' or '-' + local -a extensions=(${${$(pandoc --list-extensions=$format):#$pm*}#(+|-)}) + _wanted extensions expl 'extension' compadd -S '+' -r '-+ ' -a extensions else - return 0 + local -a formats=( $(pandoc --list-$inout[2]-formats) ) + _wanted formats expl 'format' compadd -S '+' -r '-+ ' -a formats fi } # }}} -# {{{ choose a format among supported output format -(( $+functions[_pandoc_output_format] )) || -_pandoc_output_format(){ - local update_policy - zstyle -s ":completion:${curcontext}:" cache-policy update_policy - if [[ -z "$update_policy" ]]; then - zstyle ":completion:${curcontext}:" cache-policy __pandoc_cache_policy - fi - if _cache_invalid pandoc_output_formats_simple; then - output_formats_simple=($(pandoc --list-output-formats)) - _store_cache pandoc_output_formats_simple output_formats_simple - else - _retrieve_cache pandoc_output_formats_simple - fi - if _cache_invalid pandoc_output_formats_plus_extensible || _cache_invalid pandoc_output_formats_minus_extensible; then - for f in ${output_formats_simple[*]}; do - for e in $(pandoc --list-extensions=${f}); do - if [[ "${e}" =~ '^\+' ]]; then - output_formats_plus_extensible+=("${f}${e}") - elif [[ "${e}" =~ '^\-' ]]; then - output_formats_minus_extensible+=("${f}${e}") - fi - done - done - _store_cache pandoc_output_formats_minus_extensible output_formats_minus_extensible - _store_cache pandoc_output_formats_plus_extensible output_formats_plus_extensible - else - _retrieve_cache pandoc_output_formats_minus_extensible - _retrieve_cache pandoc_output_formats_plus_extensible - fi - _alternative \ - 'formats_plus:format:{_multi_parts "+" output_formats_plus_extensible}' \ - 'formats_minus:format:{_multi_parts -- "-" output_formats_minus_extensible}' -} -# }}} -# {{{ choose a format among supported input format -(( $+functions[_pandoc_input_format] )) || -_pandoc_input_format(){ - local update_policy - zstyle -s ":completion:${curcontext}:" cache-policy update_policy - if [[ -z "$update_policy" ]]; then - zstyle ":completion:${curcontext}:" cache-policy __pandoc_cache_policy - fi - if _cache_invalid pandoc_input_formats_simple; then - input_formats_simple=($(pandoc --list-input-formats)) - _store_cache pandoc_input_formats_simple input_formats_simple - else - _retrieve_cache pandoc_input_formats_simple - fi - if _cache_invalid pandoc_input_formats_plus_extensible || _cache_invalid pandoc_input_formats_minus_extensible; then - for f in ${input_formats_simple[*]}; do - for e in $(pandoc --list-extensions=${f}); do - if [[ "${e}" =~ '^\+' ]]; then - input_formats_plus_extensible+=("${f}${e}") - elif [[ "${e}" =~ '^\-' ]]; then - input_formats_minus_extensible+=("${f}${e}") - fi - done - done - _store_cache pandoc_input_formats_minus_extensible input_formats_minus_extensible - _store_cache pandoc_input_formats_plus_extensible input_formats_plus_extensible - else - _retrieve_cache pandoc_input_formats_minus_extensible - _retrieve_cache pandoc_input_formats_plus_extensible - fi - _alternative \ - 'formats_plus:format:{_multi_parts "+" input_formats_plus_extensible}' \ - 'formats_minus:format:{_multi_parts -- "-" input_formats_minus_extensible}' -} -# }}} -# {{{ choose a format among all supported formats +# {{{ all supported formats (( $+functions[_pandoc_all_formats] )) || _pandoc_all_formats(){ - local update_policy - zstyle -s ":completion:${curcontext}:" cache-policy update_policy - if [[ -z "$update_policy" ]]; then - zstyle ":completion:${curcontext}:" cache-policy __pandoc_cache_policy - fi - if _cache_invalid pandoc_input_formats_simple; then - input_formats_simple=($(pandoc --list-input-formats)) - _store_cache pandoc_input_formats_simple input_formats_simple - else - _retrieve_cache pandoc_input_formats_simple - fi - if _cache_invalid pandoc_output_formats_simple; then - output_formats_simple=($(pandoc --list-output-formats)) - _store_cache pandoc_output_formats_simple output_formats_simple - else - _retrieve_cache pandoc_output_formats_simple - fi - if _cache_invalid pandoc_all_formats; then - all_formats=(${output_formats_simple} ${input_formats_simple}) - all_formats=($(sort -u <<<"${all_formats[*]}")) - _store_cache pandoc_all_formats all_formats - else - _retrieve_cache pandoc_all_formats - fi - _describe "format" all_formats + local -a expl + local -aU formats + formats=( $(pandoc --list-input-formats) $(pandoc --list-output-formats) ) + _wanted formats expl 'format' compadd -a formats } # }}} # {{{ pdf engine choice @@ -141,113 +51,58 @@ _pandoc_pdf_engine_opts(){ esac } # }}} -# {{{ choose data-dir -(( $+functions[_pandoc_data_dir] )) || -_pandoc_data_dir(){ - _files -/ +# {{{ data-dir specified by --data-dir option, or the default dir +_pandoc_default_dir() { + if (( $+opt_args[--data-dir] )); then + echo ${opt_args[--data-dir]:a} + else + # XXX Some versions of pandoc may output two user data directories: + # ~/.local/share/pandoc or ~/.pandoc + # Here we use only the first one. + pandoc --version | sed -ne 's/.*[Uu]ser data directory: \([^ ]*\).*/\1/p' + fi } -# }}} -# {{{ choose template from data-dir +# {{{ template file in $PWD or data-dir/templates/, or URL (( $+functions[_pandoc_template] )) || _pandoc_template(){ - local update_policy - zstyle -s ":completion:${curcontext}:" cache-policy update_policy - if [[ -z "$update_policy" ]]; then - zstyle ":completion:${curcontext}:" cache-policy __pandoc_cache_policy - fi - if _cache_invalid pandoc_output_formats_simple; then - output_formats_simple=($(pandoc --list-output-formats)) - _store_cache pandoc_output_formats_simple output_formats_simple - else - _retrieve_cache pandoc_output_formats_simple - fi - local data_dir=${opt_args[--data-dir]} - if [[ -z $data_dir ]]; then - if _cache_invalid pandoc_default_data_dir; then - default_data_dir=$(pandoc --version | sed -ne 's/Default user data directory: \(.*\)/\1/p') - _store_cache pandoc_default_data_dir default_data_dir - else - _retrieve_cache pandoc_default_data_dir - fi - data_dir=${default_data_dir} - fi - _pandoc_template_find_args="-name '*.'${output_formats_simple[1]}" - for ((i = 2; i < ${#output_formats_simple[@]}; i++ )); do - _pandoc_template_find_args=$_pandoc_template_find_args" -or -name '*.'${output_formats_simple[$i]}" - done - templates=($(eval find -L ${data_dir}/templates ${_pandoc_template_find_args} 2>/dev/null | sed -e 's/.*\///' -e 's/\.[^.]*$//')) - if [[ -z "${templates}" ]]; then - templates=default - fi - _describe 'templates from default data-dir' templates + # find output format from '-t format' or '-o xxx.format' + local format=${${(v)opt_args[(i)(-t|--to|-w|--write)]}%%(+|-)*} + [[ -z $format ]] && format=${(v)opt_args[(i)(-o|--output)]:e} + local pat="'*'" # or '*.*' ? + [[ -n $format ]] && pat="'*.$format'" + local template_dir=$(_pandoc_default_dir)/templates + _alternative \ + "local-templates:local template:_files -g $pat" \ + "data-dir-templates:template in data-dir:_files -W $template_dir -g $pat" \ + 'urls: :_urls' } # }}} # {{{ choose highlight-style (( $+functions[_pandoc_highlight_style] )) || _pandoc_highlight_style(){ - local update_policy - zstyle -s ":completion:${curcontext}:" cache-policy update_policy - if [[ -z "$update_policy" ]]; then - zstyle ":completion:${curcontext}:" cache-policy __pandoc_cache_policy - fi - if _cache_invalid pandoc_highlighting_styles; then - highlighting_styles=($(pandoc --list-highlight-styles)) - _store_cache pandoc_highlighting_styles highlighting_styles - else - _retrieve_cache pandoc_highlighting_styles - fi _alternative \ - 'styles:style:{_values "syntax builting style" ${highlighting_styles[*]}}' \ - 'style_files_here:style:{_files -g "*.theme"}' + 'styles:style:( $(pandoc --list-highlight-styles) )' \ + 'style-files:style file:_files -g "*.theme"' } # }}} -# {{{ choose filter from specified or default data-dir +# {{{ filter file in $PWD, data-dir/filters/ or $PATH (( $+functions[_pandoc_filter] )) || _pandoc_filter(){ - local update_policy - zstyle -s ":completion:${curcontext}:" cache-policy update_policy - if [[ -z "$update_policy" ]]; then - zstyle ":completion:${curcontext}:" cache-policy __pandoc_cache_policy - fi - local data_dir=${opt_args[--data-dir]} - if [[ -z $data_dir ]]; then - if _cache_invalid pandoc_default_data_dir; then - default_data_dir=$(pandoc --version | sed -ne 's/Default user data directory: \(.*\)/\1/p') - _store_cache pandoc_default_data_dir default_data_dir - else - _retrieve_cache pandoc_default_data_dir - fi - data_dir=${default_data_dir} - fi - local filters_dir=$data_dir"/filters" + local filters_dir=$(_pandoc_default_dir)/filters _alternative \ - 'local_filter:filter:{_files -g "*.lua"}' \ - 'data_dir_filter:filter:{_files -W filters_dir -g "*.lua"}' + 'local-filters:local filter:_files' \ + 'data-dir-filters:filter in data-dir:_files -W filters_dir' \ + 'commands: : _command_names -e' } # }}} -# {{{ choose lua filter from specified or default data-dir +# {{{ lua filter in $PWD or data-dir/filters/ (( $+functions[_pandoc_lua_filter] )) || _pandoc_lua_filter(){ - local update_policy - zstyle -s ":completion:${curcontext}:" cache-policy update_policy - if [[ -z "$update_policy" ]]; then - zstyle ":completion:${curcontext}:" cache-policy __pandoc_cache_policy - fi - local data_dir=${opt_args[--data-dir]} - if [[ -z $data_dir ]]; then - if _cache_invalid pandoc_default_data_dir; then - default_data_dir=$(pandoc --version | sed -ne 's/Default user data directory: \(.*\)/\1/p') - _store_cache pandoc_default_data_dir default_data_dir - else - _retrieve_cache pandoc_default_data_dir - fi - data_dir=${default_data_dir} - fi - local filters_dir=$data_dir"/filters" + local filters_dir=$(_pandoc_default_dir)/filters _alternative \ - 'local_filter:filter:{_files -g "(#q*)(.)"}' \ - 'data_dir_filter:filter:{_files -W filters_dir -g "(#q*)(.)"}' - } + 'local-filters:local filter:_files -g "*.lua"' \ + 'data-dir-filters:filter in data-dir:_files -W filters_dir -g "*.lua"' +} # }}} # {{{ choose reference location (( $+functions[_pandoc_reference_location] )) || @@ -328,11 +183,11 @@ _pandoc_track_changes() { # }}} # The real thing -_arguments -C \ - {-f,-r,--from=,--read=}'[specify input format]:format:_pandoc_input_format' \ - {-t,-w,--to=,--write=}'[specify output format]:format:_pandoc_output_format' \ +_arguments -s \ + {-f+,-r+,--from=,--read=}'[specify input format]: :_pandoc_format -T input' \ + {-t+,-w+,--to=,--write=}'[specify output format]: :_pandoc_format -T output' \ {-o,--output=}'[write output to FILE instead of stdout]:file:_files' \ - '--data-dir=[specify the user data directory to search for pandoc data files]:dir:_pandoc_data_dir' \ + '--data-dir=[specify the user data directory to search for pandoc data files]:data directory:_files -/' \ '--base-header-level=[specify the base level for headers (defaults to 1)]:number:_pandoc_header_level' \ '--strip-empty-paragraphs[deprecated. Use the +empty_paragraphs extension instead]: :' \ '--indented-code-classes=[classes to use for indented code blocks]:class:{_message "Classes separated with ,"}' \ @@ -347,7 +202,7 @@ _arguments -C \ '--template=[use FILE as a custom template for the generated document. Implies --standalone]: :_pandoc_template' \ {\*-M,\*--metadata=}'[set the metadata field KEY to the value VALUE]:key\:value: ' \ {\*-V,\*--variable=}'[set the variable KEY to the value VALUE]:key\:value: ' \ - '(- :)'{-D,--print-default-template=}'[print the system default template for an output]:format:_pandoc_output_format' \ + '(- :)'{-D+,--print-default-template=}"[print the system default template for an output]:format:( $(pandoc --list-output-formats) )" \ '(- :)--print-default-data-file=[print a system default data file]:file: ' \ '(- :)--print-highlight-style=[prints a JSON version of a highlighting style]:style|file: ' \ '--dpi=[specify the dpi (dots per inch) value for conversion from pixels to inch/centimeters and vice versa]:number: ' \ -- 2.21.1 (Apple Git-122.3)