@@ -38,6 +38,8 @@ let s:saved_cpo = &cpo
3838set cpo &vim
3939
4040" variables {{{1
41+
42+ " Make sure the globals all exist
4143if ! exists (' g:EditorConfig_exec_path' )
4244 let g: EditorConfig_exec_path = ' '
4345endif
@@ -62,12 +64,20 @@ if !exists('g:EditorConfig_disable_rules')
6264 let g: EditorConfig_disable_rules = []
6365endif
6466
67+ " Copy some of the globals into script variables --- changes to these
68+ " globals won't affect the plugin until the plugin is reloaded.
6569if exists (' g:EditorConfig_core_mode' ) && ! empty (g: EditorConfig_core_mode )
6670 let s: editorconfig_core_mode = g: EditorConfig_core_mode
6771else
6872 let s: editorconfig_core_mode = ' '
6973endif
7074
75+ if exists (' g:EditorConfig_exec_path' ) && ! empty (g: EditorConfig_exec_path )
76+ let s: editorconfig_exec_path = g: EditorConfig_exec_path
77+ else
78+ let s: editorconfig_exec_path = ' '
79+ endif
80+
7181let s: initialized = 0
7282
7383" }}}1
@@ -107,50 +117,62 @@ function! s:InitializeVimCore()
107117 endtry
108118 return 0
109119endfunction
120+
121+ function ! s: InitializeExternalCommand ()
122+ " Initialize external_command mode
123+
124+ if empty (s: editorconfig_exec_path )
125+ echo ' Please specify a g:EditorConfig_exec_path'
126+ return 1
127+ endif
128+
129+ if g: EditorConfig_verbose
130+ echo ' Checking for external command ' . s: editorconfig_exec_path . ' ...'
131+ endif
132+
133+ if ! executable (s: editorconfig_exec_path )
134+ echo ' File ' . s: editorconfig_exec_path . ' is not executable.'
135+ return 1
136+ endif
137+
138+ return 0
139+ endfunction
110140" }}}1
111141
112142function ! s: Initialize () " Initialize the plugin. {{{1
113143 " Returns truthy on error, falsy on success.
114144
115- " Do some initialization if the user has specified a core mode {{{2
116- if exists (' s:editorconfig_core_mode' ) && ! empty (s: editorconfig_core_mode )
145+ if empty (s: editorconfig_core_mode )
146+ let s: editorconfig_core_mode = ' vim_core' " Default core choice
147+ endif
117148
118- if s: editorconfig_core_mode == ? ' vim_core'
119- if s: InitializeVimCore ()
120- echo ' EditorConfig: Failed to initialize vim_core mode'
121- return 1
122- endif
123- else
124- echo " EditorConfig: I don't know how to use mode " . s: editorconfig_core_mode
125- return 1
149+ if s: editorconfig_core_mode == ? ' external_command'
150+ if s: InitializeExternalCommand ()
151+ echohl WarningMsg
152+ echo ' EditorConfig: Failed to initialize external_command mode. ' .
153+ \ ' Falling back to vim_core mode.'
154+ echohl None
155+ let s: editorconfig_core_mode = ' vim_core'
126156 endif
157+ endif
127158
128- endif " }}}2
129-
130- " Determine the editorconfig_core_mode we should use {{{2
131- while 1
132- " If user has specified a mode, just break
133- if exists ( ' s:editorconfig_core_mode ' ) && ! empty ( s: editorconfig_core_mode )
134- break
159+ if s: editorconfig_core_mode == ? ' vim_core '
160+ if s: InitializeVimCore ()
161+ echohl ErrorMsg
162+ echo ' EditorConfig: Failed to initialize vim_core mode. ' .
163+ \ ' The plugin will not function. '
164+ echohl None
165+ return 1
135166 endif
136167
137- " Try the Vimscript core
138- try
139- let l: vim_core_ver = editorconfig_core#version ()
140- let s: editorconfig_core_mode = ' vim_core'
141- break
142- catch
143- " if the Vim core wasn't loaded, we will report it below
144- endtry
145-
146- break
147- endwhile " }}}2
168+ elseif s: editorconfig_core_mode == ? ' external_command'
169+ " Nothing to do here, but this elseif is required to avoid
170+ " external_command falling into the else clause.
148171
149- " No EditorConfig Core is available
150- if empty (s: editorconfig_core_mode )
151- echo " EditorConfig: " .
152- \ " No EditorConfig Core is available. " .
153- \ " The plugin won't work."
172+ else " neither external_command nor vim_core
173+ echohl ErrorMsg
174+ echo " EditorConfig: I don't know how to use mode " . s: editorconfig_core_mode
175+ echohl None
154176 return 1
155177 endif
156178
@@ -214,6 +236,8 @@ function! s:UseConfigFiles() abort " Apply config to the current buffer {{{1
214236
215237 if s: editorconfig_core_mode == ? ' vim_core'
216238 call s: UseConfigFiles_VimCore ()
239+ elseif s: editorconfig_core_mode == ? ' external_command'
240+ call s: UseConfigFiles_ExternalCommand ()
217241 else
218242 echohl Error |
219243 \ echo " Unknown EditorConfig Core: " .
@@ -268,6 +292,71 @@ function! s:UseConfigFiles_VimCore()
268292 endtry
269293endfunction
270294
295+ function ! s: UseConfigFiles_ExternalCommand ()
296+ " Use external EditorConfig core (e.g., the C core)
297+
298+ call s: DisableShellSlash ()
299+ let l: exec_path = shellescape (s: editorconfig_exec_path )
300+ call s: ResetShellSlash ()
301+
302+ call s: SpawnExternalParser (l: exec_path )
303+ endfunction
304+
305+ function ! s: SpawnExternalParser (cmd) " {{{2
306+ " Spawn external EditorConfig. Used by s:UseConfigFiles_ExternalCommand()
307+
308+ let l: cmd = a: cmd
309+
310+ if empty (l: cmd )
311+ throw ' No cmd provided'
312+ endif
313+
314+ let l: config = {}
315+
316+ call s: DisableShellSlash ()
317+ let l: cmd = l: cmd . ' ' . shellescape (expand (' %:p' ))
318+ call s: ResetShellSlash ()
319+
320+ let l: parsing_result = split (system (l: cmd ), ' \v[\r\n]+' )
321+
322+ " if editorconfig core's exit code is not zero, give out an error
323+ " message
324+ if v: shell_error != 0
325+ echohl ErrorMsg
326+ echo ' Failed to execute "' . l: cmd . ' ". Exit code: ' .
327+ \ v: shell_error
328+ echo ' '
329+ echo ' Message:'
330+ echo l: parsing_result
331+ echohl None
332+ return
333+ endif
334+
335+ if g: EditorConfig_verbose
336+ echo ' Output from EditorConfig core executable:'
337+ echo l: parsing_result
338+ endif
339+
340+ for one_line in l: parsing_result
341+ let l: eq_pos = stridx (one_line, ' =' )
342+
343+ if l: eq_pos == -1 " = is not found. Skip this line
344+ continue
345+ endif
346+
347+ let l: eq_left = strpart (one_line, 0 , l: eq_pos )
348+ if l: eq_pos + 1 < strlen (one_line)
349+ let l: eq_right = strpart (one_line, l: eq_pos + 1 )
350+ else
351+ let l: eq_right = ' '
352+ endif
353+
354+ let l: config [l: eq_left ] = l: eq_right
355+ endfor
356+
357+ call s: ApplyConfig (l: config )
358+ endfunction " }}}2
359+
271360" }}}1
272361
273362function ! s: ApplyConfig (config) abort " Set the buffer options {{{1
0 commit comments