Skip to content

Commit

Permalink
Merge pull request #209 from perelo/main
Browse files Browse the repository at this point in the history
add CUE initial support, based on js.vim
  • Loading branch information
AndrewRadev authored Feb 23, 2024
2 parents 3e60a0b + cf178b0 commit 1aa617d
Show file tree
Hide file tree
Showing 3 changed files with 206 additions and 0 deletions.
143 changes: 143 additions & 0 deletions autoload/sj/cue.vim
Original file line number Diff line number Diff line change
@@ -0,0 +1,143 @@
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('{', '}')

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

let body = start."\n".join(items, ",\n")."\n".end

call sj#ReplaceMotion('Va'.start, body)

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

47 changes: 47 additions & 0 deletions doc/splitjoin.txt
Original file line number Diff line number Diff line change
Expand Up @@ -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|
Expand Down Expand Up @@ -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*

Expand Down
16 changes: 16 additions & 0 deletions ftplugin/cue/splitjoin.vim
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
if !exists('b:splitjoin_split_callbacks')
let b:splitjoin_split_callbacks = [
\ 'sj#cue#SplitStructLiteral',
\ 'sj#cue#SplitArray',
\ 'sj#cue#SplitArgs',
\ 'sj#cue#SplitImports',
\ ]
endif

if !exists('b:splitjoin_join_callbacks')
let b:splitjoin_join_callbacks = [
\ 'sj#cue#JoinStructLiteral',
\ 'sj#cue#JoinArray',
\ 'sj#cue#JoinArgs',
\ ]
endif

0 comments on commit 1aa617d

Please sign in to comment.