From e6befe1278de0c3d97fefde2b52f401c6554ef20 Mon Sep 17 00:00:00 2001 From: Eloi Perdereau Date: Mon, 19 Feb 2024 02:23:02 +0100 Subject: [PATCH 1/4] add CUE initial support, based on js.vim --- autoload/sj/cue.vim | 140 +++++++++++++++++++++++++++++++++++++ ftplugin/cue/splitjoin.vim | 18 +++++ 2 files changed, 158 insertions(+) create mode 100644 autoload/sj/cue.vim create mode 100644 ftplugin/cue/splitjoin.vim diff --git a/autoload/sj/cue.vim b/autoload/sj/cue.vim new file mode 100644 index 00000000..dbad13c9 --- /dev/null +++ b/autoload/sj/cue.vim @@ -0,0 +1,140 @@ +function! sj#cue#SplitStructLiteral() + let [from, to] = sj#LocateBracesOnLine('{', '}') + + if from < 0 && to < 0 + return 0 + endif + + let pairs = sj#ParseJsonObjectBody(from + 1, to - 1) + let body = join(pairs, "\n") + let body = "{\n".body."\n}" + call sj#ReplaceMotion('Va{', body) + + if sj#settings#Read('align') + let body_start = line('.') + 1 + let body_end = body_start + len(pairs) - 1 + call sj#Align(body_start, body_end, 'json_object') + endif + + return 1 +endfunction + +function! sj#cue#JoinStructLiteral() + let line = getline('.') + + if line =~ '{\s*$' + call search('{', 'c', line('.')) + let body = sj#GetMotion('Vi{') + + let lines = split(body, "\n") + let lines = sj#TrimList(lines) + if sj#settings#Read('normalize_whitespace') + let lines = map(lines, 'substitute(v:val, ":\\s\\+", ": ", "")') + endif + + let body = join(lines, ', ') + let body = substitute(body, ',$', '', '') + + if sj#settings#Read('curly_brace_padding') + let body = '{ '.body.' }' + else + let body = '{'.body.'}' + endif + + call sj#ReplaceMotion('Va{', body) + + return 1 + else + return 0 + endif +endfunction + +function! sj#cue#SplitArray() + return s:SplitList(['[', ']'], 'cursor_on_line') +endfunction + +function! sj#cue#JoinArray() + return s:JoinList(['[', ']'], 'padding') +endfunction + +function! sj#cue#SplitArgs() + return s:SplitList(['(', ')'], 'cursor_inside') +endfunction + +function! sj#cue#JoinArgs() + return s:JoinList(['(', ')'], 'no_padding') +endfunction + +function! s:SplitList(delimiter, cursor_position) + let start = a:delimiter[0] + let end = a:delimiter[1] + + let lineno = line('.') + let indent = indent('.') + + if a:cursor_position == 'cursor_inside' + let [from, to] = sj#LocateBracesAroundCursor(start, end) + elseif a:cursor_position == 'cursor_on_line' + let [from, to] = sj#LocateBracesOnLine(start, end) + else + echoerr "Invalid value for a:cursor_position: ".a:cursor_position + return + endif + + if from < 0 && to < 0 + return 0 + endif + + let items = sj#ParseJsonObjectBody(from + 1, to - 1) + if empty(items) + return 0 + endif + + if sj#settings#Read('trailing_comma') + let body = start."\n".join(items, ",\n").",\n".end + else + let body = start."\n".join(items, ",\n")."\n".end + endif + + call sj#ReplaceMotion('Va'.start, body) + + " built-in js indenting doesn't indent this properly + for l in range(lineno + 1, lineno + len(items)) + call sj#SetIndent(l, indent + &sw) + endfor + " closing bracket + let end_line = lineno + len(items) + 1 + call sj#SetIndent(end_line, indent) + + return 1 +endfunction + +function! s:JoinList(delimiter, delimiter_padding) + let start = a:delimiter[0] + let end = a:delimiter[1] + + let line = getline('.') + + if line !~ start . '\s*$' + return 0 + endif + + call search(start, 'c', line('.')) + let body = sj#GetMotion('Vi'.start) + + let lines = split(body, "\n") + let lines = sj#TrimList(lines) + let body = sj#Trim(join(lines, ' ')) + let body = substitute(body, ',\s*$', '', '') + + if a:delimiter_padding == 'padding' + let body = start.' '.body.' '.end + else + let body = start.body.end + endif + + call sj#ReplaceMotion('Va'.start, body) + + return 1 +endfunction + diff --git a/ftplugin/cue/splitjoin.vim b/ftplugin/cue/splitjoin.vim new file mode 100644 index 00000000..2176f66b --- /dev/null +++ b/ftplugin/cue/splitjoin.vim @@ -0,0 +1,18 @@ +if !exists('b:splitjoin_split_callbacks') + let b:splitjoin_split_callbacks = [ + \ 'sj#cue#SplitStructLiteral', + \ 'sj#cue#SplitArray', + \ 'sj#cue#SplitArgs', + \ ] +endif + +if !exists('b:splitjoin_join_callbacks') + let b:splitjoin_join_callbacks = [ + \ 'sj#cue#JoinStructLiteral', + \ 'sj#cue#JoinArray', + \ 'sj#cue#JoinArgs', + \ ] +endif + +" in CUE, trailing comma means something else +let b:splitjoin_trailing_comma = 0 From 12d1d124b71c5198d204a8826d11e494d7423d8b Mon Sep 17 00:00:00 2001 From: Eloi Perdereau Date: Fri, 23 Feb 2024 00:12:30 +0100 Subject: [PATCH 2/4] CUE documentation + simplifications --- autoload/sj/cue.vim | 11 +-------- doc/splitjoin.txt | 47 ++++++++++++++++++++++++++++++++++++++ ftplugin/cue/splitjoin.vim | 3 --- 3 files changed, 48 insertions(+), 13 deletions(-) diff --git a/autoload/sj/cue.vim b/autoload/sj/cue.vim index dbad13c9..a2475c5b 100644 --- a/autoload/sj/cue.vim +++ b/autoload/sj/cue.vim @@ -90,19 +90,10 @@ function! s:SplitList(delimiter, cursor_position) return 0 endif - if sj#settings#Read('trailing_comma') - let body = start."\n".join(items, ",\n").",\n".end - else - let body = start."\n".join(items, ",\n")."\n".end - endif + let body = start."\n".join(items, ",\n")."\n".end call sj#ReplaceMotion('Va'.start, body) - " built-in js indenting doesn't indent this properly - for l in range(lineno + 1, lineno + len(items)) - call sj#SetIndent(l, indent + &sw) - endfor - " closing bracket let end_line = lineno + len(items) + 1 call sj#SetIndent(end_line, indent) diff --git a/doc/splitjoin.txt b/doc/splitjoin.txt index b58a33ae..88404530 100644 --- a/doc/splitjoin.txt +++ b/doc/splitjoin.txt @@ -10,6 +10,7 @@ CONTENTS *splitjoin* *splitjoin-content Clojure................................: |splitjoin-clojure| Coffeescript...........................: |splitjoin-coffee| CSS....................................: |splitjoin-css| + CUE....................................: |splitjoin-cue| Elixir.................................: |splitjoin-elixir| Elm....................................: |splitjoin-elm| Eruby..................................: |splitjoin-eruby| @@ -356,6 +357,52 @@ Multiline selectors ~ } < +============================================================================== +CUE *splitjoin-cue* + +CUE Structs are JSON objects but with a cleaner syntax. Lists and Function +arguments behave like JSON's. +See |splitjoin-json|. + +Structs ~ + +Structs are first class, so the cursor can precede the first curly brace. +> + a: foo: { x: bar: baz: bool, y: bar: baz: int, z: bar: baz: string } + + a: foo: { + x: bar: baz: bool + y: bar: baz: int + z: bar: baz: string + } +< +Lists ~ + +The same applies to lists. +> + foo: [ 'x:y:z', "\xFFFF0000", a.foo.y ] + + foo: [ + 'x:y:z', + "\xFFFF0000", + a.foo.y + ] +< +Function Arguments ~ + +Function splitting requires the cursor to be positioned inside the +parenthesis, preferably near the closing one. +> + bar: m.Baz(foo[2].bar.baz, 42, true) + + bar: m.Baz( + foo[2].bar.baz, + 42, + true + ) +< + + ============================================================================== ELIXIR *splitjoin-elixir* diff --git a/ftplugin/cue/splitjoin.vim b/ftplugin/cue/splitjoin.vim index 2176f66b..7b635596 100644 --- a/ftplugin/cue/splitjoin.vim +++ b/ftplugin/cue/splitjoin.vim @@ -13,6 +13,3 @@ if !exists('b:splitjoin_join_callbacks') \ 'sj#cue#JoinArgs', \ ] endif - -" in CUE, trailing comma means something else -let b:splitjoin_trailing_comma = 0 From 43e42ee2bd68ce828567cb86938b6632145f2df5 Mon Sep 17 00:00:00 2001 From: Eloi Perdereau Date: Fri, 23 Feb 2024 00:47:42 +0100 Subject: [PATCH 3/4] split CUE import by reusing Go --- ftplugin/cue/splitjoin.vim | 1 + 1 file changed, 1 insertion(+) diff --git a/ftplugin/cue/splitjoin.vim b/ftplugin/cue/splitjoin.vim index 7b635596..7f0739fc 100644 --- a/ftplugin/cue/splitjoin.vim +++ b/ftplugin/cue/splitjoin.vim @@ -3,6 +3,7 @@ if !exists('b:splitjoin_split_callbacks') \ 'sj#cue#SplitStructLiteral', \ 'sj#cue#SplitArray', \ 'sj#cue#SplitArgs', + \ 'sj#go#SplitImports', \ ] endif From cf178b02ea694e2274c72e7ae62af72ab3386510 Mon Sep 17 00:00:00 2001 From: Eloi Perdereau Date: Fri, 23 Feb 2024 00:51:21 +0100 Subject: [PATCH 4/4] copy go's function because it may diverge --- autoload/sj/cue.vim | 12 ++++++++++++ ftplugin/cue/splitjoin.vim | 2 +- 2 files changed, 13 insertions(+), 1 deletion(-) diff --git a/autoload/sj/cue.vim b/autoload/sj/cue.vim index a2475c5b..dd698415 100644 --- a/autoload/sj/cue.vim +++ b/autoload/sj/cue.vim @@ -1,3 +1,15 @@ +function! sj#cue#SplitImports() + let pattern = '^import\s\+\(\%(\k\+\s\+\)\=\%(".*"\)\)$' + + if getline('.') =~ pattern + call sj#Keeppatterns('s/' . pattern . '/import (\r\1\r)/') + normal! k== + return 1 + else + return 0 + endif +endfunction + function! sj#cue#SplitStructLiteral() let [from, to] = sj#LocateBracesOnLine('{', '}') diff --git a/ftplugin/cue/splitjoin.vim b/ftplugin/cue/splitjoin.vim index 7f0739fc..4084bef2 100644 --- a/ftplugin/cue/splitjoin.vim +++ b/ftplugin/cue/splitjoin.vim @@ -3,7 +3,7 @@ if !exists('b:splitjoin_split_callbacks') \ 'sj#cue#SplitStructLiteral', \ 'sj#cue#SplitArray', \ 'sj#cue#SplitArgs', - \ 'sj#go#SplitImports', + \ 'sj#cue#SplitImports', \ ] endif