Skip to content

Commit 0ab5420

Browse files
committed
IsAvailable: Fix "type mismatch" and print nicer errors
Prints user-friendly errors if a formatter fails an IsAvailable call (also allowing other formatters to still be checked), and fixes a particular "type mismatch" error encountered on vim versions older than 7.4.1546. Fixes #155.
1 parent b089925 commit 0ab5420

File tree

2 files changed

+49
-20
lines changed

2 files changed

+49
-20
lines changed

autoload/codefmt.vim

Lines changed: 43 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -107,20 +107,40 @@ endfunction
107107
" @function(#SetWhetherToPerformIsAvailableChecksForTesting), skips the
108108
" IsAvailable check and always returns true.
109109
function! s:IsAvailable(formatter) abort
110-
if codefmt#ShouldPerformIsAvailableChecks()
111-
return a:formatter.IsAvailable()
110+
if !codefmt#ShouldPerformIsAvailableChecks()
111+
return 1
112112
endif
113-
return 1
113+
return a:formatter.IsAvailable()
114+
endfunction
115+
116+
117+
" Checks whether {formatter} is available, safely handling errors by logging
118+
" an error and returning 0.
119+
function! s:IsAvailableSafe(formatter) abort
120+
try
121+
return s:IsAvailable(a:formatter)
122+
catch /.*/
123+
call maktaba#error#Shout(
124+
\ 'Failed to evaluate whether formatter %s is available: %s',
125+
\ a:formatter.name,
126+
\ v:exception)
127+
return 0
128+
endtry
114129
endfunction
115130

116131

117132
""
118133
" Detects whether a formatter has been defined for the current buffer/filetype.
119134
function! codefmt#IsFormatterAvailable() abort
120-
let l:formatters = copy(s:registry.GetExtensions())
121-
let l:is_available = 'v:val.AppliesToBuffer() && s:IsAvailable(v:val)'
122-
return !empty(filter(l:formatters, l:is_available)) ||
123-
\ !empty(get(b:, 'codefmt_formatter'))
135+
if !empty(get(b:, 'codefmt_formatter'))
136+
return 1
137+
endfor
138+
for l:formatter in s:registry.GetExtensions()
139+
if l:formatter.AppliesToBuffer() && s:IsAvailableSafe(l:formatter)
140+
return 1
141+
endif
142+
endfor
143+
return 0
124144
endfunction
125145

126146

@@ -153,23 +173,32 @@ function! s:GetFormatter(...) abort
153173
return
154174
endif
155175
let l:formatter = l:selected_formatters[0]
156-
if !s:IsAvailable(l:formatter)
176+
try
177+
let l:formatter_is_available = s:IsAvailable(l:formatter)
178+
catch /.*/
179+
call maktaba#error#Shout(
180+
\ 'Error checking if formatter %s is available: %s',
181+
\ l:formatter.name,
182+
\ v:exception)
183+
return
184+
endtry
185+
if !l:formatter_is_available
157186
call maktaba#error#Shout(s:GetSetupInstructions(l:formatter))
158187
return
159188
endif
160189
else
161190
" No explicit name, use default.
191+
let l:applicable_formatters = filter(
192+
\ copy(l:formatters), 'v:val.AppliesToBuffer()')
162193
let l:default_formatters = filter(
163-
\ copy(l:formatters), 'v:val.AppliesToBuffer() && s:IsAvailable(v:val)')
194+
\ copy(l:applicable_formatters), 's:IsAvailableSafe(v:val)')
164195
if !empty(l:default_formatters)
165196
let l:formatter = l:default_formatters[0]
166197
else
167198
" Check if we have formatters that are not available for some reason.
168199
" Report a better error message in that case.
169-
let l:unavailable_formatters = filter(
170-
\ copy(l:formatters), 'v:val.AppliesToBuffer()')
171-
if !empty(l:unavailable_formatters)
172-
let l:error = join(map(copy(l:unavailable_formatters),
200+
if !empty(l:applicable_formatters)
201+
let l:error = join(map(copy(l:applicable_formatters),
173202
\ 's:GetSetupInstructions(v:val)'), "\n")
174203
else
175204
let l:error = 'Not available. codefmt doesn''t have a default ' .
@@ -248,7 +277,7 @@ function! codefmt#GetSupportedFormatters(ArgLead, CmdLine, CursorPos) abort
248277
let l:groups = [[], [], []]
249278
for l:formatter in s:registry.GetExtensions()
250279
let l:key = l:formatter.AppliesToBuffer() ? (
251-
\ l:formatter.IsAvailable() ? 0 : 1) : 2
280+
\ s:IsAvailable(l:formatter) ? 0 : 1) : 2
252281
call add(l:groups[l:key], l:formatter.name)
253282
endfor
254283
return join(l:groups[0] + l:groups[1] + l:groups[2], "\n")

autoload/codefmt/formatterhelpers.vim

Lines changed: 6 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -98,12 +98,12 @@ function! codefmt#formatterhelpers#ResolveFlagToArray(flag_name) abort
9898
\ a:flag_name, l:value)
9999
endif
100100
" Convert spaceless string to single-element list.
101-
let l:value = [l:value]
102-
elseif !maktaba#value#IsList(l:value)
103-
throw maktaba#error#WrongType(
104-
\ '%s flag should be a list after calling. Found %s',
105-
\ a:flag_name, maktaba#value#TypeName(l:value))
101+
return [l:value]
102+
elseif maktaba#value#IsList(l:value)
103+
return l:value
106104
endif
107105

108-
return l:value
106+
throw maktaba#error#WrongType(
107+
\ '%s flag should be a list after calling. Found %s',
108+
\ a:flag_name, maktaba#value#TypeName(l:value))
109109
endfunction

0 commit comments

Comments
 (0)