From 4b5958c4e92986a248ba97cd4083b43431859ace Mon Sep 17 00:00:00 2001 From: Josh Bodah Date: Tue, 10 Mar 2020 20:45:02 -0400 Subject: [PATCH] add elixirFunctionCall Implementation from https://github.com/elixir-editors/vim-elixir/pull/506 cc: Thanks @w-sanches --- spec/syntax/alias_spec.rb | 4 +- spec/syntax/function_spec.rb | 112 +++++++++++++++++++++++++++- spec/syntax/module_function_spec.rb | 4 +- syntax/elixir.vim | 4 + 4 files changed, 119 insertions(+), 5 deletions(-) diff --git a/spec/syntax/alias_spec.rb b/spec/syntax/alias_spec.rb index 872ce360..3d29e927 100644 --- a/spec/syntax/alias_spec.rb +++ b/spec/syntax/alias_spec.rb @@ -7,7 +7,7 @@ str = "Enum.empty?(...)" expect(str).to include_elixir_syntax('elixirAlias', 'Enum') expect(str).to include_elixir_syntax('elixirOperator', '\.') - expect(str).to include_elixir_syntax('elixirId', 'empty?') + expect(str).to include_elixir_syntax('elixirFunctionCall', 'empty?') end it 'colorize the module alias even if it starts with `!`' do @@ -43,6 +43,6 @@ expect(str).to include_elixir_syntax('elixirAlias', '\.\(Baz\)\@=') expect(str).to include_elixir_syntax('elixirAlias', 'Baz') expect(str).to include_elixir_syntax('elixirOperator', '\.\(fun\)\@=') - expect(str).to include_elixir_syntax('elixirId', 'fun') + expect(str).to include_elixir_syntax('elixirFunctionCall', 'fun') end end diff --git a/spec/syntax/function_spec.rb b/spec/syntax/function_spec.rb index a42584af..f537e85b 100644 --- a/spec/syntax/function_spec.rb +++ b/spec/syntax/function_spec.rb @@ -5,7 +5,7 @@ describe 'function syntax' do it 'doesnt treat underscored functions like unsued variables' do - expect(<<~EOF).to include_elixir_syntax('elixirId', '__ensure_defimpl__') + expect(<<~EOF).to include_elixir_syntax('elixirFunctionCall', '__ensure_defimpl__') defp derive(protocol, for, struct, opts, env) do # ... code ... __ensure_defimpl__(protocol, for, env) @@ -17,4 +17,114 @@ __ensure_defimpl__(protocol, for, env) EOF end + + it 'matches top-level macros as elixirKeyword' do + expect(<<~EOF).to include_elixir_syntax('elixirKeyword', 'quote') + quote do + # ... code ... + end + EOF + + expect(<<~EOF).to include_elixir_syntax('elixirKeyword', 'quote') + quote(do: '') + EOF + end + + it 'detects higher order function calls' do + expect(<<~'EOF').to include_elixir_syntax('elixirFunctionCall', 'func') + func.() + EOF + end + + it 'detects function calls with parenthesis' do + expect(<<~'EOF').to include_elixir_syntax('elixirFunctionCall', 'func') + func() + EOF + end + + it 'detects function calls with bangs' do + expect(<<~'EOF').to include_elixir_syntax('elixirFunctionCall', 'func!') + func!() + EOF + end + + it 'detects function calls with question marks' do + expect(<<~'EOF').to include_elixir_syntax('elixirFunctionCall', 'func?') + func?() + EOF + end + + it 'detects function calls appended by module with parenthesis' do + expect(<<~'EOF').to include_elixir_syntax('elixirFunctionCall', 'func') + Mod.func() + EOF + end + + it 'detects function calls appended by atom with parenthesis' do + expect(<<~'EOF').to include_elixir_syntax('elixirFunctionCall', 'func') + :mod.func() + EOF + end + + it 'detects function calls appended by module without parenthesis' do + expect(<<~'EOF').to include_elixir_syntax('elixirFunctionCall', 'func') + Mod.func + EOF + end + + it 'detects function calls appended by atom without parenthesis' do + expect(<<~'EOF').to include_elixir_syntax('elixirFunctionCall', 'func') + :mod.func + EOF + end + + it 'detects function calls without parenthesis that contain paramenters' do + expect(<<~'EOF').to include_elixir_syntax('elixirFunctionCall', 'func') + func 1 + EOF + expect(<<~'EOF').to include_elixir_syntax('elixirFunctionCall', 'func') + func [1] + EOF + expect(<<~'EOF').to include_elixir_syntax('elixirFunctionCall', 'func') + func :atom + EOF + expect(<<~'EOF').to include_elixir_syntax('elixirFunctionCall', 'func') + func "string" + EOF + expect(<<~'EOF').to include_elixir_syntax('elixirFunctionCall', 'func') + func 'a' + EOF + end + + it 'does not highlight function calls without parenthesis that does not contain paramenters' do + expect(<<~'EOF').not_to include_elixir_syntax('elixirFunctionCall', 'func') + func + EOF + end + + it 'does not detect calls to function with invalid names' do + expect(<<~'EOF').not_to include_elixir_syntax('elixirFunctionCall', '2fast2func') + 2fast2func() + EOF + end + + it 'ignores spacing between module and function names' do + expect(<<~'EOF').to include_elixir_syntax('elixirFunctionCall', 'func') + Module . func + EOF + end + + it 'detects piped functions with parenthesis' do + expect(<<~'EOF').to include_elixir_syntax('elixirFunctionCall', 'func') + one_func() + |> func() + EOF + end + + it 'detects piped functions without parenthesis' do + expect(<<~'EOF').to include_elixir_syntax('elixirFunctionCall', 'func') + one_func() + |> func + EOF + end end diff --git a/spec/syntax/module_function_spec.rb b/spec/syntax/module_function_spec.rb index cf038a3a..9c7e9bcf 100644 --- a/spec/syntax/module_function_spec.rb +++ b/spec/syntax/module_function_spec.rb @@ -4,13 +4,13 @@ describe 'Module function syntax' do it 'for used as module function' do - expect(<<~EOF).to include_elixir_syntax('elixirId', 'for') + expect(<<~EOF).to include_elixir_syntax('elixirFunctionCall', 'for') OverridesDefault.for EOF end it 'case used as module function' do - expect(<<~EOF).to include_elixir_syntax('elixirId', 'case') + expect(<<~EOF).to include_elixir_syntax('elixirFunctionCall', 'case') OverridesDefault.case EOF end diff --git a/syntax/elixir.vim b/syntax/elixir.vim index a21698df..63d00ea6 100644 --- a/syntax/elixir.vim +++ b/syntax/elixir.vim @@ -18,6 +18,10 @@ syn keyword elixirTodo FIXME NOTE TODO OPTIMIZE XXX HACK contained syn match elixirId '\<[_a-zA-Z]\w*[!?]\?\>' contains=elixirUnusedVariable +syn match elixirFunctionCall '\<[a-z_]\w*[!?]\?\(\s*\.\?\s*(\|\s\+[a-zA-Z0-9@:\'\"\[]\)\@=' +syn match elixirFunctionCall '\(:\w\+\s*\.\s*\|[A-Z]\w*\s*\.\s*\)\@<=[a-z_]\w*[!?]\?' +syn match elixirFunctionCall '\(>\s+\)\<[a-z_]\w*[!?]\?' + syn match elixirKeyword '\(\.\)\@:\@!' syn keyword elixirInclude import require alias use