From 19cc724807de4cdf9f8147c70932b49a79a7f7ee Mon Sep 17 00:00:00 2001 From: w0rp Date: Thu, 7 Feb 2019 18:10:34 +0000 Subject: [PATCH] Add a function for parsing command args --- autoload/ale/args.vim | 43 ++++++++++++++++++++++++ test/test_parse_command_args.vader | 52 ++++++++++++++++++++++++++++++ 2 files changed, 95 insertions(+) create mode 100644 autoload/ale/args.vim create mode 100644 test/test_parse_command_args.vader diff --git a/autoload/ale/args.vim b/autoload/ale/args.vim new file mode 100644 index 00000000..70afb2e5 --- /dev/null +++ b/autoload/ale/args.vim @@ -0,0 +1,43 @@ +" Author: w0rp +" Description: This module implements a function for parsing arguments for +" commands. + +" Given a list of valid arguments like ['foo', 'bar'] and a string to parse, +" parse the arguments from the string and return [parsed_args, remainder]. +" +" Arguments must be prefixed in the string with a single minus (-), and a +" double minus (--) denotes the end of arguments. +function! ale#args#Parse(arg_list, string) abort + let l:parsed = {} + let l:end_of_args = 0 + let l:word_list = split(a:string, ' ') + let l:index = 0 + + while l:index < len(l:word_list) + let l:word = l:word_list[l:index] + + if l:word[:0] is# '-' + let l:index += 1 + + if l:word is# '--' + break + endif + + let l:arg = l:word[1:] + + if index(a:arg_list, l:arg) >= 0 + let l:parsed[l:arg] = '' + else + throw 'Invalid argument: ' . l:word + endif + elseif l:word is# '' + let l:index += 1 + else + break + endif + endwhile + + let l:new_string = join(l:word_list[l:index :], ' ') + + return [l:parsed, l:new_string] +endfunction diff --git a/test/test_parse_command_args.vader b/test/test_parse_command_args.vader new file mode 100644 index 00000000..0103b967 --- /dev/null +++ b/test/test_parse_command_args.vader @@ -0,0 +1,52 @@ +After: + unlet! b:parse_result + + if exists(':ParseTest') + delcommand ParseTest + endif + +Execute(ale#args#Parse should handle empty input): + AssertEqual + \ [{}, ''], + \ ale#args#Parse([], '') + AssertEqual + \ [{}, ''], + \ ale#args#Parse(['foo', 'bar'], '') + +Execute(ale#args#Parse should parse commands correctly): + AssertEqual + \ [{'foo': '', 'bar': ''}, 'leave these alone'], + \ ale#args#Parse(['foo', 'bar'], '-foo -bar leave these alone') + AssertEqual + \ [{'foo': ''}, 'leave these alone'], + \ ale#args#Parse(['foo', 'bar'], '-foo leave these alone') + +Execute(ale#args#Parse should raise errors for unknown arguments): + AssertThrows call ale#args#Parse(['foo', 'bar'], '-nope leave these alone') + AssertEqual 'Invalid argument: -nope', g:vader_exception + +Execute(ale#args#Parse should stop parsing arguments after --): + AssertEqual + \ [{'foo': ''}, ' --nope leave these alone'], + \ ale#args#Parse(['foo', 'bar'], '-foo -- --nope leave these alone') + AssertEqual + \ [{}, '--'], + \ ale#args#Parse(['foo', 'bar'], '-- --') + AssertEqual + \ [{}, ''], + \ ale#args#Parse(['foo', 'bar'], '--') + +Execute(ale#args#Parse should work for an example command): + command! -nargs=* ParseTest let b:parse_result = ale#args#Parse(['foo', 'bar'], ) + + ParseTest + AssertEqual [{}, ''], b:parse_result + + ParseTest -foo + AssertEqual [{'foo': ''}, ''], b:parse_result + + ParseTest -foo -bar + AssertEqual [{'foo': '', 'bar': ''}, ''], b:parse_result + + ParseTest -foo -bar leave these alone + AssertEqual [{'foo': '', 'bar': ''}, 'leave these alone'], b:parse_result