From de0cfdd3234ad08cd7019bf286a0aba98f73889f Mon Sep 17 00:00:00 2001 From: Larpon Date: Fri, 20 Nov 2020 19:50:01 +0100 Subject: [PATCH] v complete: add better support for tool flag completion (#6894) --- cmd/tools/vcomplete.v | 126 +++++++++++++++++++++++++++++++++--------- 1 file changed, 99 insertions(+), 27 deletions(-) diff --git a/cmd/tools/vcomplete.v b/cmd/tools/vcomplete.v index 2cfcce7349..509dfc054e 100644 --- a/cmd/tools/vcomplete.v +++ b/cmd/tools/vcomplete.v @@ -27,12 +27,12 @@ module main import os const ( - auto_complete_shells = ['bash', 'fish', 'zsh', 'powershell'] + auto_complete_shells = ['bash', 'fish', 'zsh', 'powershell'] // list of supported shells ) // Snooped from cmd/v/v.v, vlib/v/pref/pref.v const ( - auto_complete_commands = [ + auto_complete_commands = [ /* simple_cmd */ 'fmt', 'up', @@ -75,7 +75,7 @@ const ( 'build', 'build-module', ] - auto_complete_flags = [ + auto_complete_flags = [ '-apk', '-show-timings', '-check-syntax', @@ -132,7 +132,46 @@ const ( '-version', '--version', ] - auto_complete_compilers = [ + auto_complete_flags_doc = [ + '-all', + '-f', + '-h', + '-help', + '-m', + '-o', + '-readme', + '-v', + '-filename', + '-pos', + '-no-timestamp', + '-inline-assets', + '-open', + '-p', + '-s', + '-l', + ] + auto_complete_flags_fmt = [ + '-c', + '-diff', + '-l', + '-w', + '-debug', + '-verify', + ] + auto_complete_flags_bin2v = [ + '-h', + '--help', + '-m', + '--module', + '-p', + '--prefix', + '-w', + '--write', + ] + auto_complete_flags_self = [ + '-prod', + ] + auto_complete_compilers = [ 'cc', 'gcc', 'tcc', @@ -206,7 +245,7 @@ complete -o nospace -F _v_completions v fn auto_complete_request(args []string) []string { // Using space will ensure a uniform input in cases where the shell - // returns the completion input as a string + // returns the completion input as a string (['v','run'] vs. ['v run']). split_by := ' ' request := args.join(split_by) mut list := []string{} @@ -218,34 +257,67 @@ fn auto_complete_request(args []string) []string { } } else { part := parts.last().trim(' ') + mut parent_command := '' + for i := parts.len - 1; i >= 0; i-- { + if parts[i].starts_with('-') { + continue + } + parent_command = parts[i] + break + } + get_flags := fn (base []string, flag string) []string { + if flag.len == 1 { return base + } else { return base.filter(it.starts_with(flag)) + } + } if part.starts_with('-') { // 'v -' -> flags. - for flag in auto_complete_flags { - if flag == part { - if flag == '-cc' { // 'v -cc ' -> list of available compilers. - for compiler in auto_complete_compilers { - path := os.find_abs_path_of_executable(compiler) or { - '' - } - if path != '' { - list << compiler + match parent_command { + 'bin2v' { // 'v bin2v -' + list = get_flags(auto_complete_flags_bin2v, part) + } + 'build' { // 'v build -' -> flags. + list = get_flags(auto_complete_flags, part) + } + 'doc' { // 'v doc -' -> flags. + list = get_flags(auto_complete_flags_doc, part) + } + 'fmt' { // 'v fmt -' -> flags. + list = get_flags(auto_complete_flags_fmt, part) + } + 'self' { // 'v self -' -> flags. + list = get_flags(auto_complete_flags_self, part) + } + else { + for flag in auto_complete_flags { + if flag == part { + if flag == '-cc' { // 'v -cc ' -> list of available compilers. + for compiler in auto_complete_compilers { + path := os.find_abs_path_of_executable(compiler) or { + '' + } + if path != '' { + list << compiler + } + } } + } else if flag.starts_with(part) { // 'v -' -> flags matching "". + list << flag } } - } else if flag.starts_with(part) { // 'v -' -> flags matching "". - list << flag } } } else { - if part == 'help' { // 'v help ' -> top level commands except "help". - list = auto_complete_commands.filter(it != part).filter(it != 'complete') - } else if part == 'build' { // 'v build ' -> all flags. - list = auto_complete_flags - } else { - // 'v ' -> commands matching "". - // Don't include if part matches a full command - instead go to path completion below. - for command in auto_complete_commands { - if part != command && command.starts_with(part) { - list << command + match part { + 'help' { // 'v help ' -> top level commands except "help". + list = auto_complete_commands.filter(it != part && it != 'complete') + } + else { + // 'v ' -> commands matching "". + // Don't include if part matches a full command - instead go to path completion below. + for command in auto_complete_commands { + if part != command && command.starts_with(part) { + list << command + } } } } @@ -297,6 +369,6 @@ fn auto_complete_request(args []string) []string { fn main() { args := os.args[1..] - //println('"$args"') + // println('"$args"') auto_complete(args) }