From e123ca298602ab5d9b43b702f821f815e15c0e6c Mon Sep 17 00:00:00 2001 From: Fernando Mendes Date: Thu, 14 May 2020 21:17:43 +0100 Subject: [PATCH 1/3] Add support for Elixir arrays --- autoload/sj/elixir.vim | 46 +++++++++++++++++++++++++++++++++++ ftplugin/elixir/splitjoin.vim | 2 ++ spec/plugin/elixir_spec.rb | 44 +++++++++++++++++++++++++++++++++ 3 files changed, 92 insertions(+) diff --git a/autoload/sj/elixir.vim b/autoload/sj/elixir.vim index 398c644d..7f07925b 100644 --- a/autoload/sj/elixir.vim +++ b/autoload/sj/elixir.vim @@ -39,3 +39,49 @@ function! sj#elixir#JoinDef() call sj#ReplaceLines(def_lineno, end_lineno, joined_line) return 1 endfunction + +function! sj#elixir#SplitArray() + let [from, to] = sj#LocateBracesAroundCursor('[', ']', [ + \ 'elixirInterpolationDelimiter', + \ 'elixirString', + \ 'elixirStringDelimiter', + \ 'elixirSigilDelimiter', + \ ]) + + if from < 0 + return 0 + endif + + let items = sj#ParseJsonObjectBody(from + 1, to - 1) + + " substitute [1, 2, | tail] + let items[-1] = substitute(items[-1], "\\(|[^>].*\\)", "\n\\1", "") + + let body = "[\n" . join(items, ",\n") . "\n]" + + call sj#ReplaceMotion('Va[', body) + + return 1 +endfunction + +function! sj#elixir#JoinArray() + normal! $ + + if getline('.')[col('.') - 1] != '[' + return 0 + endif + + let body = sj#Trim(sj#GetMotion('Vi[')) + " remove trailing comma + let body = substitute(body, ',\ze\_s*$', '', '') + + let items = split(body, ",\s*\n") + + " join isolated | tail on the last line + let items[-1] = substitute(items[-1], "[[:space:]]*\\(|[^>].*\\)", " \\1", "") + + let body = join(sj#TrimList(items), ', ') + call sj#ReplaceMotion('Va[', '['.body.']') + + return 1 +endfunction diff --git a/ftplugin/elixir/splitjoin.vim b/ftplugin/elixir/splitjoin.vim index 9fc58b60..15f45aac 100644 --- a/ftplugin/elixir/splitjoin.vim +++ b/ftplugin/elixir/splitjoin.vim @@ -1,7 +1,9 @@ let b:splitjoin_split_callbacks = [ \ 'sj#elixir#SplitDef', + \ 'sj#elixir#SplitArray', \ ] let b:splitjoin_join_callbacks = [ \ 'sj#elixir#JoinDef', + \ 'sj#elixir#JoinArray', \ ] diff --git a/spec/plugin/elixir_spec.rb b/spec/plugin/elixir_spec.rb index 3a76d08b..68128128 100644 --- a/spec/plugin/elixir_spec.rb +++ b/spec/plugin/elixir_spec.rb @@ -99,4 +99,48 @@ def bar(foo) do EOF end end + + specify "arrays" do + set_file_contents <<~EOF + [a, b, c] + EOF + + split + + assert_file_contents <<~EOF + [ + a, + b, + c + ] + EOF + + vim.search('[') + join + + assert_file_contents <<~EOF + [a, b, c] + EOF + + set_file_contents <<~EOF + [a: 1, b: 2, c: %{a: 1, b: 2}] + EOF + + split + + assert_file_contents <<~EOF + [ + a: 1, + b: 2, + c: %{a: 1, b: 2} + ] + EOF + + vim.search('[') + join + + assert_file_contents <<~EOF + [a: 1, b: 2, c: %{a: 1, b: 2}] + EOF + end end From ee3f26366abf95eb433429a44bd430af1e24ba80 Mon Sep 17 00:00:00 2001 From: Fernando Mendes Date: Tue, 21 Jul 2020 00:19:50 +0100 Subject: [PATCH 2/3] Code review --- autoload/sj/elixir.vim | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/autoload/sj/elixir.vim b/autoload/sj/elixir.vim index 7f07925b..f526f321 100644 --- a/autoload/sj/elixir.vim +++ b/autoload/sj/elixir.vim @@ -54,6 +54,10 @@ function! sj#elixir#SplitArray() let items = sj#ParseJsonObjectBody(from + 1, to - 1) + if len(items) == 0 + return 1 + endif + " substitute [1, 2, | tail] let items[-1] = substitute(items[-1], "\\(|[^>].*\\)", "\n\\1", "") @@ -77,6 +81,10 @@ function! sj#elixir#JoinArray() let items = split(body, ",\s*\n") + if len(items) == 0 + return 1 + endif + " join isolated | tail on the last line let items[-1] = substitute(items[-1], "[[:space:]]*\\(|[^>].*\\)", " \\1", "") From 6478f9bb4b1448774b35b21157a7729cdcc07377 Mon Sep 17 00:00:00 2001 From: Fernando Mendes Date: Tue, 21 Jul 2020 00:29:59 +0100 Subject: [PATCH 3/3] Code review --- autoload/sj/elixir.vim | 2 +- spec/plugin/elixir_spec.rb | 18 ++++++++++++++++++ 2 files changed, 19 insertions(+), 1 deletion(-) diff --git a/autoload/sj/elixir.vim b/autoload/sj/elixir.vim index f526f321..2f5befaf 100644 --- a/autoload/sj/elixir.vim +++ b/autoload/sj/elixir.vim @@ -54,7 +54,7 @@ function! sj#elixir#SplitArray() let items = sj#ParseJsonObjectBody(from + 1, to - 1) - if len(items) == 0 + if len(items) == 0 || to - from < 2 return 1 endif diff --git a/spec/plugin/elixir_spec.rb b/spec/plugin/elixir_spec.rb index 68128128..285df5d1 100644 --- a/spec/plugin/elixir_spec.rb +++ b/spec/plugin/elixir_spec.rb @@ -142,5 +142,23 @@ def bar(foo) do assert_file_contents <<~EOF [a: 1, b: 2, c: %{a: 1, b: 2}] EOF + + set_file_contents <<~EOF + [] + EOF + + vim.search('[') + split + + assert_file_contents <<~EOF + [] + EOF + + vim.search('[') + join + + assert_file_contents <<~EOF + [] + EOF end end