From 604f2b9a68a69fafacbb59a69df2b3a5719a4505 Mon Sep 17 00:00:00 2001 From: Arseny Maslennikov Date: Mon, 17 Jul 2017 03:00:21 +0300 Subject: [PATCH] Add zsh completion function for Meson Deprecated Meson syntax is not supported. There are features not yet implemented, like completing build targets and build options; more on this in the comments. --- data/_meson | 189 ++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 189 insertions(+) create mode 100644 data/_meson diff --git a/data/_meson b/data/_meson new file mode 100644 index 000000000..dad1252aa --- /dev/null +++ b/data/_meson @@ -0,0 +1,189 @@ +#compdef meson mesonconf=meson-configure mesontest=meson-test mesonintrospect=meson-introspect + +# vim:ts=2 sw=2 + +local curcontext="$curcontext" state line +local -i ret + +local __meson_backends="(ninja xcode ${(j. .)${:-vs{,2010,2015,2017}}})" +local __meson_build_types="(plain debug debugoptimized minsize release)" +local __meson_wrap_modes="(WrapMode.{default,nofallback,nodownload})" + +local -a meson_commands=( +'setup:set up a build directory' +'configure:configure a project' +'test:run tests' +'introspect:query project properties' +'wrap:manage source dependencies' +) + +(( $+functions[__meson_is_build_dir] )) || __meson_is_build_dir() { + local mpd="${1:-$PWD}/meson-private" + [[ -f "$mpd/build.dat" && -f "$mpd/coredata.dat" ]] + return $? +} + +# TODO: implement build option completion +(( $+functions[__meson_build_options] )) || __meson_build_options() {} +# TODO: implement target name completion +(( $+functions[__meson_targets] )) || __meson_targets() {} +# `meson introspect` currently can provide that information in JSON. +# We can: +# 1) pipe its output to python3 -m json.tool | grep "$alovelyregex" | cut <...> +# 2) teach mintro.py to use a different output format +# (or perhaps just to select the fields printed) + +(( $+functions[__meson_test_names] )) || __meson_test_names() { + local rtests + if rtests="$(_call_program meson meson test ${opt_args[-C]:+-C "$opt_args[-C]"} --list)"; + then + local -a tests=(${(@f)rtests}) + _describe -t "tests" "Meson tests" tests + else + _message -r "current working directory is not a build directory" + _message -r 'use -C $build_dir or cd $build_dir' + fi +} + +(( $+functions[_meson_commands] )) || _meson_commands() { + _describe -t commands "Meson subcommands" meson_commands +} + +(( $+functions[_meson-setup] )) || _meson-setup() { + local firstd secondd + if [[ -f "meson.build" ]]; then + # if there's no second argument on the command line + # cwd will implicitly be substituted: + # - as the source directory if it has a file with the name "meson.build"; + # - as the build directory otherwise + # more info in mesonbuild/mesonmain.py + firstd="build" + secondd="source" + else + firstd="source" + secondd="build" + fi + + _arguments \ + '*-D-[set the value of a build option]:build option:__meson_build_options' \ + '--prefix=[installation prefix]: :_directories' \ + '--libdir=[library directory]: :_directories' \ + '--libexecdir=[library executable directory]: :_directories' \ + '--bindir=[executable directory]: :_directories' \ + '--sbindir=[system executable directory]: :_directories' \ + '--includedir=[header file directory]: :_directories' \ + '--datadir=[data file directory]: :_directories' \ + '--mandir=[manual page directory]: :_directories' \ + '--infodir=[info page directory]: :_directories' \ + '--localedir=[locale data directory]: :_directories' \ + '--sysconfdir=[system configuration directory]: :_directories' \ + '--localstatedir=[local state data directory]: :_directories' \ + '--sharedstatedir=[arch-independent data directory]: :_directories' \ + '--backend=[backend to use]:Meson backend:'"$__meson_backends" \ + '--buildtype=[build type to use]:Meson build type:'"$__meson_build_types" \ + '--strip[strip targets on install]' \ + '--unity=[unity builds on/off]:whether to do unity builds:(on off subprojects)' \ + '--werror[treat warnings as errors]' \ + '--layout=[build directory layout]:build directory layout:(flat mirror)' \ + '--default-library=[default library type]:default library type:(shared static)' \ + '--warnlevel=[compiler warning level]:compiler warning level:warning level:(1 2 3)' \ + '--stdsplit=[split stdout and stderr in test logs]' \ + '--errorlogs=[prints the logs from failing tests]' \ + '--cross-file=[cross-compilation environment description]:cross file:_files' \ + '--wrap-mode=[special wrap mode]:wrap mode:'"$__meson_wrap_modes" \ + ":$firstd directory:_directories" \ + "::$secondd directory:_directories" \ + # +} + +(( $+functions[_meson-configure] )) || _meson-configure() { + local curcontext="$curcontext" + # TODO: implement 'mesonconf @file' + local -a specs=( + '--clearcache[clear cached state]' + '*-D-[set the value of a build option]:build option:__meson_build_options' + '::build directory:_directories' + ) + + _arguments \ + '(: -)'{'--help','-h'}'[show a help message and quit]' \ + "${(@)specs}" +} + +(( $+functions[_meson-test] )) || _meson-test() { + local curcontext="$curcontext" + + # TODO: complete test suites + local -a specs=( + '(--quiet -q)'{'--quiet','-q'}'[produce less output to the terminal]' + '(--verbose -v)'{'--verbose','-v'}'[do not redirect stdout and stderr]' + '(--timeout-multiplier -t)'{'--timeout-multiplier','-t'}'[a multiplier for test timeouts]:Python floating-point number: ' + '-C[directory to cd into]: :_directories' + '--repeat[number of times to run the tests]:number of times to repeat: ' + '--no-rebuild[do not rebuild before running tests]' + '--gdb[run tests under gdb]' + '--list[list available tests]' + '(--wrapper --wrap)'{'--wrapper=','--wrap='}'[wrapper to run tests with]:wrapper program:_path_commands' + '(--no-suite)--suite[only run tests from this suite]:test suite: ' + '(--suite)--no-suite[do not run tests from this suite]:test suite: ' + '--no-stdsplit[do not split stderr and stdout in logs]' + '--print-errorlogs[print logs for failing tests]' + '--benchmark[run benchmarks instead of tests]' + '--logbase[base name for log file]:filename: ' + '--num-processes[how many threads to use]:number of processes: ' + '--setup[which test setup to use]:test setup: ' + '--test-args[arguments to pass to the tests]: : ' + '*:Meson tests:__meson_test_names' + ) + + _arguments \ + '(: -)'{'--help','-h'}'[show a help message and quit]' \ + "${(@)specs}" +} + +(( $+functions[_meson-introspect] )) || _meson-introspect() { + local curcontext="$curcontext" + local -a specs=( + '--targets[list top level targets]' + '--installed[list all installed files and directories]' + '--target-files[list source files for a given target]:target:__meson_targets' + '--buildsystem-files[list files that belong to the build system]' + '--buildoptions[list all build options]' + '--tests[list all unit tests]' + '--benchmarks[list all benchmarks]' + '--dependencies[list external dependencies]' + '--projectinfo[show project information]' + '::build directory:_directories' + ) +_arguments \ + '(: -)'{'--help','-h'}'[show a help message and quit]' \ + "${(@)specs}" +} + +(( $+functions[_meson-wrap] )) || _meson-wrap() { + # TODO +} + +if [[ $service != meson ]]; then + _call_function ret _$service + return ret +fi + +_arguments -C -R \ + '(: -)'{'--help','-h'}'[show a help message and quit]' \ + '(: -)'{'--version','-v'}'[show version information and quit]' \ + '(-): :_meson_commands' \ + '*:: :->post-command' \ +# +ret=$? + +[[ $ret = 300 ]] && case "$state" in + post-command) + service="meson-$words[1]" + curcontext=${curcontext%:*:*}:$service: + _call_function ret _$service + ;; +esac + +return ret +