Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
45 changes: 45 additions & 0 deletions autoload/codefmt/formatterhelpers.vim
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,9 @@
" limitations under the License.


let s:plugin = maktaba#plugin#Get('codefmt')


""
" @public
" Format lines in the current buffer via a formatter invoked by {cmd}, which
Expand All @@ -31,6 +34,7 @@ function! codefmt#formatterhelpers#Format(cmd) abort
call maktaba#buffer#Overwrite(1, line('$'), l:formatted)
endfunction


""
" @public
" Attempt to format a range of lines from {startline} to {endline} in the
Expand Down Expand Up @@ -62,3 +66,44 @@ function! codefmt#formatterhelpers#AttemptFakeRangeFormatting(

call maktaba#buffer#Overwrite(1, line('$'), l:full_formatted)
endfunction


""
" @public
" Resolve a flag (function, string or array) to a normalized array, with special
" handling to convert a spaceless string to a single-element array. This is the
" common case for executables, and more importantly, is backward-compatible for
" existing user settings.
"
" @throws WrongType if the flag doesn't resolve to a string or array
function! codefmt#formatterhelpers#ResolveFlagToArray(flag_name) abort
let l:FlagFn = s:plugin.Flag(a:flag_name)
if maktaba#value#IsFuncref(l:FlagFn)
let l:value = maktaba#function#Call(l:FlagFn)
else
let l:value = l:FlagFn
endif

" After (conditionally) calling the function, the resulting value should be
" either a list that we can use directly, or a string that we can treat as
" a single-element list, mainly for backward compatibility.
if maktaba#value#IsString(l:value)
if l:value =~ '\s'
" Uh oh, there are spaces in the string. Rather than guessing user intent
" with shell quoting and word splitting, handle this (hopefully unusual)
" case by telling them to update their configuration.
throw maktaba#error#WrongType(
\ '%s flag is a string with spaces, please make it a list. ' .
\ 'Resolved value was: %s',
\ a:flag_name, l:value)
endif
" Convert spaceless string to single-element list.
let l:value = [l:value]
elseif !maktaba#value#IsList(l:value)
throw maktaba#error#WrongType(
\ '%s flag should be a list after calling. Found %s',
\ a:flag_name, maktaba#value#TypeName(l:value))
endif

return l:value
endfunction
23 changes: 9 additions & 14 deletions autoload/codefmt/prettier.vim
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,7 @@
let s:plugin = maktaba#plugin#Get('codefmt')

" See https://prettier.io for a list of supported file types.
let s:supported_filetypes = ['javascript', 'markdown', 'html', 'css', 'yaml',
let s:supported_filetypes = ['javascript', 'markdown', 'html', 'css', 'yaml',
\ 'jsx', 'less', 'scss', 'mdx', 'vue']


Expand All @@ -30,7 +30,9 @@ function! codefmt#prettier#GetFormatter() abort
\ 'and configure the prettier_executable flag'}

function l:formatter.IsAvailable() abort
return executable(s:plugin.Flag('prettier_executable'))
let l:cmd = codefmt#formatterhelpers#ResolveFlagToArray(
\ 'prettier_executable')
return !empty(l:cmd) && executable(l:cmd[0])
endfunction

function l:formatter.AppliesToBuffer() abort
Expand All @@ -42,17 +44,8 @@ function! codefmt#prettier#GetFormatter() abort
" @flag(prettier_executable), only targeting the range between {startline} and
" {endline}.
function l:formatter.FormatRange(startline, endline) abort
let l:Prettier_options = s:plugin.Flag('prettier_options')
if type(l:Prettier_options) is# type([])
let l:prettier_options = l:Prettier_options
elseif maktaba#value#IsCallable(l:Prettier_options)
let l:prettier_options = maktaba#function#Call(l:Prettier_options)
else
throw maktaba#error#WrongType(
\ 'prettier_options flag must be list or callable. Found %s',
\ string(l:Prettier_options))
endif
let l:cmd = [s:plugin.Flag('prettier_executable'), '--stdin', '--no-color']
let l:cmd = codefmt#formatterhelpers#ResolveFlagToArray(
\ 'prettier_executable') + ['--stdin', '--no-color']

" prettier is able to automatically choose the best parser if the filepath
" is provided. Otherwise, fall back to the previous default: babylon.
Expand All @@ -74,7 +67,9 @@ function! codefmt#prettier#GetFormatter() abort
let l:lines_end = join(l:lines[0 : a:endline - 1], "\n")
call extend(l:cmd, ['--range-end', string(strchars(l:lines_end))])

call extend(l:cmd, l:prettier_options)
call extend(l:cmd, codefmt#formatterhelpers#ResolveFlagToArray(
\ 'prettier_options'))

try
let l:result = maktaba#syscall#Create(l:cmd).WithStdin(l:input).Call()
let l:formatted = split(l:result.stdout, "\n")
Expand Down
26 changes: 9 additions & 17 deletions autoload/codefmt/zprint.vim
Original file line number Diff line number Diff line change
Expand Up @@ -38,7 +38,9 @@ function! codefmt#zprint#GetFormatter() abort
\ 'and configure the zprint_executable flag'}

function l:formatter.IsAvailable() abort
return executable(s:plugin.Flag('zprint_executable'))
let l:cmd = codefmt#formatterhelpers#ResolveFlagToArray(
\ 'zprint_executable')
return !empty(l:cmd) && executable(l:cmd[0])
endfunction

function l:formatter.AppliesToBuffer() abort
Expand All @@ -50,25 +52,15 @@ function! codefmt#zprint#GetFormatter() abort
" @flag(zprint_executable), only targeting the range between {startline} and
" {endline}.
function l:formatter.FormatRange(startline, endline) abort
" Must be upper-cased to call as a function
let l:ZprintOptions = s:plugin.Flag('zprint_options')
if type(l:ZprintOptions) is# type([])
" Assign upper-case to lower-case
let l:zprint_options = l:ZprintOptions
elseif maktaba#value#IsCallable(l:ZprintOptions)
" Call upper-case to assign lower-case
let l:zprint_options = maktaba#function#Call(l:ZprintOptions)
else
throw maktaba#error#WrongType(
\ 'zprint_options flag must be list or callable. Found %s',
\ string(l:ZprintOptions))
endif
let l:cmd_args = [s:plugin.Flag('zprint_executable')]
call extend(l:cmd_args, l:zprint_options)
let l:exe = codefmt#formatterhelpers#ResolveFlagToArray(
\ 'zprint_executable')
let l:opts = codefmt#formatterhelpers#ResolveFlagToArray(
\ 'zprint_options')

" Prepare the syscall, changing to the containing directory in case the user
" has configured {:search-config? true} in ~/.zprintrc
let l:cmd = maktaba#syscall#Create(l:cmd_args).WithCwd(expand('%:p:h'))
let l:cmd = maktaba#syscall#Create(l:exe + l:opts).WithCwd(expand('%:p:h'))

" zprint does not support range formatting yet:
" https://github.com/kkinnear/zprint/issues/122
" This fake range formatting works well for top-level forms, although it's
Expand Down