mirror of
https://github.com/SpaceVim/SpaceVim.git
synced 2025-02-03 12:40:05 +08:00
289 lines
7.4 KiB
VimL
289 lines
7.4 KiB
VimL
|
function! sj#elixir#SplitDoBlock()
|
||
|
let [function_name, function_start, function_end, function_type] =
|
||
|
\ sj#argparser#elixir#LocateFunction()
|
||
|
if function_start < 0
|
||
|
return 0
|
||
|
endif
|
||
|
|
||
|
let is_if = function_name == 'if' || function_name == 'unless'
|
||
|
|
||
|
let parser = sj#argparser#elixir#Construct(function_start, function_end, getline('.'))
|
||
|
call parser.Process()
|
||
|
|
||
|
let do_body = ''
|
||
|
let else_body = ''
|
||
|
let args = []
|
||
|
|
||
|
for arg in parser.args
|
||
|
if arg =~ '^do:' && do_body == ''
|
||
|
let do_body = substitute(arg, '^do:\s*', '', '')
|
||
|
elseif arg =~ '^else:' && is_if && else_body == ''
|
||
|
let else_body = substitute(arg, '^else:\s*', '', '')
|
||
|
else
|
||
|
call add(args, arg)
|
||
|
endif
|
||
|
endfor
|
||
|
|
||
|
if do_body == ''
|
||
|
return 0
|
||
|
endif
|
||
|
|
||
|
let line = getline('.')
|
||
|
|
||
|
if is_if && function_type == 'with_round_braces'
|
||
|
" skip the round brackets before the if-clause
|
||
|
let new_line = strpart(line, 0, function_start - 2) . ' ' . join(args, ', ')
|
||
|
else
|
||
|
let new_line = strpart(line, 0, function_start - 1) . join(args, ', ')
|
||
|
endif
|
||
|
|
||
|
if function_end > 0
|
||
|
if is_if && function_type == 'with_round_braces'
|
||
|
" skip the round brackets after the if-clause
|
||
|
let new_line .= strpart(line, function_end + 1)
|
||
|
else
|
||
|
let new_line .= strpart(line, function_end)
|
||
|
end
|
||
|
else
|
||
|
" we didn't detect an end, so it goes on to the end of the line
|
||
|
endif
|
||
|
|
||
|
if else_body != ''
|
||
|
let do_block = " do\n" . do_body . "\nelse\n" . else_body . "\nend"
|
||
|
else
|
||
|
let do_block = " do\n" . do_body . "\nend"
|
||
|
endif
|
||
|
|
||
|
call sj#ReplaceLines(line('.'), line('.'), new_line . do_block)
|
||
|
return 1
|
||
|
endfunction
|
||
|
|
||
|
function! sj#elixir#JoinDoBlock()
|
||
|
let do_pattern = '\s*do\s*\%(#.*\)\=$'
|
||
|
let def_lineno = line('.')
|
||
|
let def_line = getline(def_lineno)
|
||
|
|
||
|
if def_line !~ do_pattern
|
||
|
return 0
|
||
|
endif
|
||
|
|
||
|
let [function_name, function_start, function_end, function_type] =
|
||
|
\ sj#argparser#elixir#LocateFunction()
|
||
|
if function_start < 0
|
||
|
return 0
|
||
|
endif
|
||
|
|
||
|
let is_if = function_name == 'if' || function_name == 'unless'
|
||
|
let body_lineno = line('.') + 1
|
||
|
let body_line = getline(body_lineno)
|
||
|
|
||
|
if is_if && getline(line('.') + 2) =~ '^\s*else\>'
|
||
|
let else_lineno = line('.') + 2
|
||
|
let else_line = getline(else_lineno)
|
||
|
|
||
|
let else_body_lineno = line('.') + 3
|
||
|
let else_body_line = getline(else_body_lineno)
|
||
|
|
||
|
let end_lineno = line('.') + 4
|
||
|
let end_line = getline(end_lineno)
|
||
|
else
|
||
|
let else_line = ''
|
||
|
|
||
|
let end_lineno = line('.') + 2
|
||
|
let end_line = getline(end_lineno)
|
||
|
endif
|
||
|
|
||
|
if end_line !~ '^\s*end$'
|
||
|
return 0
|
||
|
endif
|
||
|
|
||
|
exe 'keeppatterns s/'.do_pattern.'//'
|
||
|
if function_end < 0
|
||
|
let function_end = col('$') - 1
|
||
|
endif
|
||
|
|
||
|
let args = sj#GetCols(function_start, function_end)
|
||
|
let joined_args = ', do: '.sj#Trim(body_line)
|
||
|
if else_line != ''
|
||
|
let joined_args .= ', else: '.sj#Trim(else_body_line)
|
||
|
endif
|
||
|
|
||
|
call sj#ReplaceCols(function_start, function_end, args . joined_args)
|
||
|
exe body_lineno.','.end_lineno.'delete _'
|
||
|
return 1
|
||
|
endfunction
|
||
|
|
||
|
function! sj#elixir#JoinCommaDelimitedItems()
|
||
|
if getline('.') !~ ',\s*$'
|
||
|
return 0
|
||
|
endif
|
||
|
|
||
|
let start_lineno = line('.')
|
||
|
let end_lineno = start_lineno
|
||
|
let lineno = nextnonblank(start_lineno + 1)
|
||
|
let line = getline(lineno)
|
||
|
|
||
|
while lineno <= line('$') && line =~ ',\s*$'
|
||
|
let end_lineno = lineno
|
||
|
let lineno = nextnonblank(lineno + 1)
|
||
|
let line = getline(lineno)
|
||
|
endwhile
|
||
|
|
||
|
let end_lineno = lineno
|
||
|
|
||
|
call cursor(start_lineno, 0)
|
||
|
exe "normal! V".(end_lineno - start_lineno)."jJ"
|
||
|
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)
|
||
|
|
||
|
if len(items) == 0 || to - from < 2
|
||
|
return 1
|
||
|
endif
|
||
|
|
||
|
" 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")
|
||
|
if len(items) == 0
|
||
|
return 0
|
||
|
endif
|
||
|
|
||
|
" 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
|
||
|
|
||
|
let s:pipe_pattern = '^\s*|>\s\+'
|
||
|
let s:atom_pattern = ':\k\+'
|
||
|
let s:module_pattern = '\k\%(\k\|\.\)*'
|
||
|
let s:function_pattern = '\k\+[?!]\='
|
||
|
let s:atom_or_module_pattern = '\%(' . s:atom_pattern . '\.\|' . s:module_pattern . '\.\)\='
|
||
|
|
||
|
function! sj#elixir#SplitPipe()
|
||
|
let line = getline('.')
|
||
|
|
||
|
call sj#PushCursor()
|
||
|
normal! 0f(
|
||
|
let [function_name, function_start, function_end, function_type] =
|
||
|
\ sj#argparser#elixir#LocateFunction()
|
||
|
call sj#PopCursor()
|
||
|
|
||
|
" We only support function calls that start at the beginning of the line
|
||
|
" (accounting for whitespace)
|
||
|
let prefix = strpart(line, 0, function_start - 1)
|
||
|
let prefix_pattern = '^\s*' . s:atom_or_module_pattern . function_name . '\((\|\s\+\)$'
|
||
|
|
||
|
if function_start < 0 || prefix !~ prefix_pattern
|
||
|
return 0
|
||
|
endif
|
||
|
|
||
|
let comment_pattern = '\s*\(#.*\)\=$'
|
||
|
|
||
|
if function_end < 0
|
||
|
let comment_start = match(line, comment_pattern)
|
||
|
|
||
|
if comment_start < 0
|
||
|
let rest = 'none'
|
||
|
else
|
||
|
let rest = strpart(line, comment_start)
|
||
|
let function_end = comment_start
|
||
|
endif
|
||
|
else
|
||
|
let rest = strpart(line, function_end + 1)
|
||
|
|
||
|
if rest !~ '^' . comment_pattern
|
||
|
return 0
|
||
|
endif
|
||
|
end
|
||
|
|
||
|
let parser = sj#argparser#elixir#Construct(function_start, function_end, line)
|
||
|
call parser.Process()
|
||
|
|
||
|
let args = parser.args
|
||
|
|
||
|
let function_call = sj#Trim(strpart(line, 0, function_start - 2))
|
||
|
let result = args[0] . "\n|> " . function_call . '(' . join(args[1:], ', ') . ')' . rest
|
||
|
|
||
|
call sj#ReplaceLines(line('.'), line('.'), result)
|
||
|
|
||
|
return 1
|
||
|
endfunction
|
||
|
|
||
|
function! sj#elixir#JoinPipe()
|
||
|
call sj#PushCursor()
|
||
|
|
||
|
let line = getline('.')
|
||
|
if line !~ s:pipe_pattern
|
||
|
normal! j
|
||
|
let line = getline('.')
|
||
|
endif
|
||
|
|
||
|
let line_num = line('.')
|
||
|
let prev_line = sj#Trim(getline(line_num - 1))
|
||
|
|
||
|
if line !~ s:pipe_pattern || prev_line =~ s:pipe_pattern
|
||
|
call sj#PopCursor()
|
||
|
return 0
|
||
|
endif
|
||
|
|
||
|
let empty_args_pattern = s:pipe_pattern . '\(' . s:atom_or_module_pattern . s:function_pattern . '\)()'
|
||
|
|
||
|
if line =~ empty_args_pattern
|
||
|
let function_name = substitute(line, empty_args_pattern, '\1', '')
|
||
|
let result = function_name . '(' . prev_line . ')'
|
||
|
call sj#PopCursor()
|
||
|
else
|
||
|
normal! f(l
|
||
|
let [function_name, function_start, function_end, function_type] =
|
||
|
\ sj#argparser#elixir#LocateFunction()
|
||
|
call sj#PopCursor()
|
||
|
|
||
|
if function_start < 0
|
||
|
return 0
|
||
|
endif
|
||
|
|
||
|
let parser = sj#argparser#elixir#Construct(function_start, function_end, line)
|
||
|
call parser.Process()
|
||
|
|
||
|
let args = parser.args
|
||
|
let function_call = substitute(strpart(line, 0, function_start - 2), '|>\s\+', '', '')
|
||
|
let result = function_call . '(' . prev_line . ', ' . join(args, ', ') . ')'
|
||
|
endif
|
||
|
|
||
|
call sj#ReplaceLines(line_num - 1, line_num, result)
|
||
|
return 1
|
||
|
endfunction
|