mirror of
https://github.com/SpaceVim/SpaceVim.git
synced 2025-02-02 22:20:06 +08:00
406 lines
10 KiB
VimL
406 lines
10 KiB
VimL
function! sj#go#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#go#JoinImports()
|
|
if getline('.') =~ '^import\s*($' &&
|
|
\ getline(line('.') + 1) =~ '^\s*\%(\k\+\s\+\)\=".*"$' &&
|
|
\ getline(line('.') + 2) =~ '^)$'
|
|
call sj#Keeppatterns('s/^import (\_s\+\(\%(\k\+\s\+\)\=\(".*"\)\)\_s\+)$/import \1/')
|
|
return 1
|
|
else
|
|
return 0
|
|
endif
|
|
endfunction
|
|
|
|
function! sj#go#SplitVars() abort
|
|
let pattern = '^\s*\(var\|type\|const\)\s\+[[:keyword:], ]\+=\='
|
|
if sj#SearchUnderCursor(pattern) <= 0
|
|
return 0
|
|
endif
|
|
|
|
call search(pattern, 'Wce', line('.'))
|
|
let line = getline('.')
|
|
|
|
if line[col('.') - 1] == '='
|
|
" before and after =
|
|
let lhs = sj#Trim(strpart(line, 0, col('.') - 1))
|
|
let rhs = sj#Ltrim(strpart(line, col('.')))
|
|
|
|
let values_parser = sj#argparser#go_vars#Construct(rhs)
|
|
call values_parser.Process()
|
|
|
|
let values = values_parser.args
|
|
let comment = values_parser.comment
|
|
else
|
|
let [comment, comment_start, _] = matchstrpos(line, '\s*\%(\/\/.*\)\=$')
|
|
if comment == ""
|
|
let lhs = sj#Trim(line)
|
|
else
|
|
let lhs = sj#Trim(strpart(line, 0, comment_start))
|
|
endif
|
|
|
|
let values = []
|
|
endif
|
|
|
|
if len(values) > 0 && values[-1] =~ '[{([]\s*$'
|
|
" the value is incomplete, so let's not attempt to split it
|
|
return 0
|
|
endif
|
|
|
|
let [prefix, _, prefix_end] = matchstrpos(lhs, '^\s*\(var\|type\|const\)\s\+')
|
|
let lhs = strpart(lhs, prefix_end)
|
|
|
|
let variables = []
|
|
let last_type = ''
|
|
for variable in reverse(split(lhs, ',\s*'))
|
|
let variable = sj#Trim(variable)
|
|
let type = matchstr(variable, '^\k\+\s\+\zs\S.*$')
|
|
|
|
if empty(type) && !empty(last_type)
|
|
" No type, take the last one that we saw going backwards
|
|
call add(variables, variable . ' ' . last_type)
|
|
else
|
|
let last_type = type
|
|
call add(variables, variable)
|
|
endif
|
|
endfor
|
|
call reverse(variables)
|
|
|
|
let declarations = []
|
|
for i in range(0, len(variables) - 1)
|
|
if i < len(values)
|
|
call add(declarations, variables[i] . ' = ' . values[i])
|
|
else
|
|
call add(declarations, variables[i])
|
|
endif
|
|
endfor
|
|
|
|
let replacement = prefix . "(\n"
|
|
let replacement .= join(declarations, "\n")
|
|
let replacement .= "\n)"
|
|
if comment != ''
|
|
let replacement .= ' ' . sj#Ltrim(comment)
|
|
endif
|
|
|
|
call sj#ReplaceMotion('_vg_', replacement)
|
|
return 0
|
|
endfunction
|
|
|
|
function! sj#go#JoinVars() abort
|
|
let pattern = '^\s*\(var\|type\|const\)\s\+('
|
|
if sj#SearchUnderCursor(pattern) <= 0
|
|
return 0
|
|
endif
|
|
|
|
call search(pattern, 'Wce', line('.'))
|
|
|
|
let declarations = sj#TrimList(split(sj#GetMotion('vi('), "\n"))
|
|
if len(declarations) == 1
|
|
" Only one line, so just join it as-is
|
|
call sj#ReplaceMotion('va(', declarations[0])
|
|
return 1
|
|
endif
|
|
|
|
let variables = []
|
|
let values = []
|
|
let types = []
|
|
|
|
for line in declarations
|
|
let [lhs, _, match_end] = matchstrpos(line, '.\{-}\s*=\s*')
|
|
|
|
if match_end > -1
|
|
let variable_description = matchstr(lhs, '.\{-}\ze\s*=\s*')
|
|
let line = substitute(line, ',$', '', '')
|
|
call add(values, strpart(line, match_end))
|
|
else
|
|
let line = substitute(line, ',$', '', '')
|
|
let variable_description = line
|
|
endif
|
|
|
|
let [variable, _, match_end] = matchstrpos(variable_description, '^\k\+\s*')
|
|
let type = strpart(variable_description, match_end)
|
|
call add(variables, { 'variable': sj#Rtrim(variable), 'type': type })
|
|
call add(types, type)
|
|
endfor
|
|
|
|
if len(variables) == 0
|
|
return 0
|
|
endif
|
|
|
|
if len(uniq(types)) > 1
|
|
" We have assignment to values, but we also have different types, so it
|
|
" can't be on one line
|
|
return 0
|
|
endif
|
|
|
|
" Handle var one, two string -> one should also get "string"
|
|
let declarations = []
|
|
let index = 0
|
|
for entry in variables
|
|
if empty(entry.type) || (len(variables) > index + 1 && entry.type ==# variables[index + 1].type)
|
|
" This variable's type is the same as the next one's, so skip it
|
|
call add(declarations, entry.variable)
|
|
elseif empty(entry.type)
|
|
call add(declarations, entry.variable)
|
|
else
|
|
call add(declarations, entry.variable . ' ' . entry.type)
|
|
endif
|
|
|
|
let index += 1
|
|
endfor
|
|
|
|
let combined_declaration = join(declarations, ', ')
|
|
if len(values) > 0
|
|
let combined_declaration .= ' = ' . join(values, ', ')
|
|
endif
|
|
|
|
call sj#ReplaceMotion('va(', combined_declaration)
|
|
return 1
|
|
endfunction
|
|
|
|
function! sj#go#SplitStruct()
|
|
let [start, end] = sj#LocateBracesAroundCursor('{', '}', ['goString', 'goComment'])
|
|
if start < 0 && end < 0
|
|
return 0
|
|
endif
|
|
|
|
let args = sj#ParseJsonObjectBody(start + 1, end - 1)
|
|
if len(args) == 0
|
|
return 0
|
|
endif
|
|
|
|
for arg in args
|
|
if arg !~ '^\k\+\s*:'
|
|
" this is not really a struct instantiation
|
|
return 0
|
|
end
|
|
endfor
|
|
|
|
call sj#ReplaceCols(start + 1, end - 1, "\n".join(args, ",\n").",\n")
|
|
return 1
|
|
endfunction
|
|
|
|
function! sj#go#JoinStructDeclaration()
|
|
let start_lineno = line('.')
|
|
let pattern = '^\s*type\s\+.*\s*\zsstruct\s*{$'
|
|
|
|
if search(pattern, 'Wc', line('.')) <= 0 &&
|
|
\ search(pattern, 'Wcb', line('.')) <= 0
|
|
return 0
|
|
endif
|
|
|
|
call sj#PushCursor()
|
|
normal! f{%
|
|
let end_lineno = line('.')
|
|
|
|
if start_lineno == end_lineno
|
|
" we haven't moved, brackets not found
|
|
call sj#PopCursor()
|
|
return 0
|
|
endif
|
|
|
|
let arguments = []
|
|
for line in getbufline('%', start_lineno + 1, end_lineno - 1)
|
|
let argument = substitute(line, ',$', '', '')
|
|
let argument = sj#Trim(argument)
|
|
|
|
if argument != ''
|
|
call add(arguments, argument)
|
|
endif
|
|
endfor
|
|
|
|
if len(arguments) == 0
|
|
let replacement = 'struct{}'
|
|
else
|
|
let replacement = 'struct{ ' . join(arguments, ', ') . ' }'
|
|
endif
|
|
|
|
call sj#PopCursor()
|
|
call sj#ReplaceMotion('vf{%', replacement)
|
|
return 1
|
|
endfunction
|
|
|
|
function! sj#go#JoinStruct()
|
|
let start_lineno = line('.')
|
|
let pattern = '\k\+\s*{$'
|
|
|
|
if search(pattern, 'Wc', line('.')) <= 0 &&
|
|
\ search(pattern, 'Wcb', line('.')) <= 0
|
|
return 0
|
|
endif
|
|
|
|
call search(pattern, 'Wce', line('.'))
|
|
|
|
normal! %
|
|
let end_lineno = line('.')
|
|
|
|
if start_lineno == end_lineno
|
|
" we haven't moved, brackets not found
|
|
return 0
|
|
endif
|
|
|
|
let arguments = []
|
|
for line in getbufline('%', start_lineno + 1, end_lineno - 1)
|
|
let argument = substitute(line, ',$', '', '')
|
|
let argument = sj#Trim(argument)
|
|
|
|
if argument !~ '^\k\+\s*:'
|
|
" this is not really a struct instantiation
|
|
return 0
|
|
end
|
|
|
|
if sj#settings#Read('normalize_whitespace')
|
|
let argument = substitute(argument, '^\k\+\zs:\s\+', ': ', 'g')
|
|
endif
|
|
|
|
call add(arguments, argument)
|
|
endfor
|
|
|
|
let replacement = '{' . join(arguments, ', ') . '}'
|
|
call sj#ReplaceMotion('va{', replacement)
|
|
return 1
|
|
endfunction
|
|
|
|
function! sj#go#SplitSingleLineCurlyBracketBlock()
|
|
let [start, end] = sj#LocateBracesAroundCursor('{', '}', ['goString', 'goComment'])
|
|
if start < 0 && end < 0
|
|
return 0
|
|
endif
|
|
|
|
let body = sj#GetMotion('vi{')
|
|
|
|
if getline('.')[0:start - 1] =~# '\<struct\s*{$'
|
|
" struct { is enforced by gofmt
|
|
let padding = ' '
|
|
else
|
|
let padding = ''
|
|
endif
|
|
|
|
call sj#ReplaceMotion('va{', padding."{\n".sj#Trim(body)."\n}")
|
|
return 1
|
|
endfunction
|
|
|
|
function! sj#go#JoinSingleLineFunctionBody()
|
|
let start_lineno = line('.')
|
|
|
|
if search('{$', 'Wc', line('.')) <= 0
|
|
return 0
|
|
endif
|
|
|
|
normal! %
|
|
let end_lineno = line('.')
|
|
|
|
if start_lineno == end_lineno
|
|
" we haven't moved, brackets not found
|
|
return 0
|
|
endif
|
|
|
|
if end_lineno - start_lineno > 2
|
|
" more than one line between them, can't join
|
|
return 0
|
|
endif
|
|
|
|
normal! va{J
|
|
return 1
|
|
endfunction
|
|
|
|
function! sj#go#SplitFunc()
|
|
let pattern = '^func\%(\s*(.\{-})\s*\)\=\s\+\k\+\zs('
|
|
if search(pattern, 'Wcn', line('.')) <= 0 &&
|
|
\ search(pattern, 'Wbcn', line('.')) <= 0
|
|
return 0
|
|
endif
|
|
|
|
let split_type = ''
|
|
|
|
let [start, end] = sj#LocateBracesAroundCursor('(', ')', ['goString', 'goComment'])
|
|
if start > 0
|
|
let split_type = 'definition_list'
|
|
else
|
|
let [start, end] = sj#LocateBracesAroundCursor('{', '}', ['goString', 'goComment'])
|
|
|
|
if start > 0
|
|
let split_type = 'function_body'
|
|
endif
|
|
endif
|
|
|
|
if split_type == 'function_body'
|
|
let contents = sj#Trim(sj#GetCols(start + 1, end - 1))
|
|
call sj#ReplaceCols(start + 1, end - 1, "\n".contents."\n")
|
|
return 1
|
|
elseif split_type == 'definition_list'
|
|
let parsed = sj#ParseJsonObjectBody(start + 1, end - 1)
|
|
|
|
" Keep `a, b int` variable groups on the same line
|
|
let arg_groups = []
|
|
let typed_arg_group = ''
|
|
for elem in parsed
|
|
if match(elem, '\s\+') != -1
|
|
let typed_arg_group .= elem
|
|
call add(arg_groups, typed_arg_group)
|
|
let typed_arg_group = ''
|
|
else
|
|
" not typed here, group it with later vars
|
|
let typed_arg_group .= elem . ', '
|
|
endif
|
|
endfor
|
|
|
|
call sj#ReplaceCols(start + 1, end - 1, "\n".join(arg_groups, ",\n").",\n")
|
|
return 1
|
|
else
|
|
return 0
|
|
endif
|
|
endfunction
|
|
|
|
function! sj#go#SplitFuncCall()
|
|
let [start, end] = sj#LocateBracesAroundCursor('(', ')', ['goString', 'goComment'])
|
|
if start < 0 && end < 0
|
|
return 0
|
|
endif
|
|
|
|
let args = sj#ParseJsonObjectBody(start + 1, end - 1)
|
|
call sj#ReplaceCols(start + 1, end - 1, "\n".join(args, ",\n").",\n")
|
|
return 1
|
|
endfunction
|
|
|
|
function! sj#go#JoinFuncCallOrDefinition()
|
|
let start_lineno = line('.')
|
|
|
|
if search('($', 'Wc', line('.')) <= 0
|
|
return 0
|
|
endif
|
|
|
|
if strpart(getline('.'), 0, col('.')) =~ '\(var\|type\|const\|import\)\s\+($'
|
|
" This isn't a function call, it's a multiline var/const/type declaration
|
|
return 0
|
|
endif
|
|
|
|
normal! %
|
|
let end_lineno = line('.')
|
|
|
|
if start_lineno == end_lineno
|
|
" we haven't moved, brackets not found
|
|
return 0
|
|
endif
|
|
|
|
let arguments = []
|
|
for line in getbufline('%', start_lineno + 1, end_lineno - 1)
|
|
let argument = substitute(line, ',$', '', '')
|
|
let argument = sj#Trim(argument)
|
|
call add(arguments, argument)
|
|
endfor
|
|
|
|
let replacement = '(' . join(arguments, ', ') . ')'
|
|
call sj#ReplaceMotion('va(', replacement)
|
|
return 1
|
|
endfunction
|