summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorw0rp <devw0rp@gmail.com>2019-02-07 18:10:34 +0000
committerw0rp <devw0rp@gmail.com>2019-02-07 18:10:34 +0000
commit19cc724807de4cdf9f8147c70932b49a79a7f7ee (patch)
tree66e2c7642441f628d80f117c971e402009afd328
parent2885c57e3e8c7e6a02017640a8ae39348b01def3 (diff)
downloadale-19cc724807de4cdf9f8147c70932b49a79a7f7ee.zip
Add a function for parsing command args
-rw-r--r--autoload/ale/args.vim43
-rw-r--r--test/test_parse_command_args.vader52
2 files changed, 95 insertions, 0 deletions
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 <devw0rp@gmail.com>
+" 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'], <q-args>)
+
+ 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