@@ -91,23 +91,24 @@ let s:initialized = 0
9191" }}}1
9292
9393" shellslash handling {{{1
94- function ! s: DisableShellSlash () " {{{2
94+ function ! s: DisableShellSlash (bufnr ) " {{{2
9595 " disable shellslash for proper escaping of Windows paths
9696
9797 " In Windows, 'shellslash' also changes the behavior of 'shellescape'.
9898 " It makes 'shellescape' behave like in UNIX environment. So ':setl
9999 " noshellslash' before evaluating 'shellescape' and restore the
100100 " settings afterwards when 'shell' does not contain 'sh' somewhere.
101- if has (' win32' ) && empty (matchstr (&shell , ' sh' ))
102- let s: old_shellslash = &l: shellslash
103- setlocal noshellslash
101+ let l: shell = getbufvar (a: bufnr , ' &shell' )
102+ if has (' win32' ) && empty (matchstr (l: shell , ' sh' ))
103+ let s: old_shellslash = getbufvar (a: bufnr , ' &shellslash' )
104+ setbufvar (a: bufnr , ' &shellslash' , 0 )
104105 endif
105106endfunction " }}}2
106107
107- function ! s: ResetShellSlash () " {{{2
108+ function ! s: ResetShellSlash (bufnr ) " {{{2
108109 " reset shellslash to the user-set value, if any
109110 if exists (' s:old_shellslash' )
110- let & l: shellslash = s: old_shellslash
111+ setbufvar ( a: bufnr , ' & shellslash' , s: old_shellslash)
111112 unlet ! s: old_shellslash
112113 endif
113114endfunction " }}}2
@@ -204,9 +205,20 @@ function! s:GetFilenames(path, filename) " {{{1
204205 return l: path_list
205206endfunction " }}}1
206207
207- function ! s: UseConfigFiles () abort " Apply config to the current buffer {{{1
208- call setbufvar (' %' , ' editorconfig_tried' , 1 )
209- let l: buffer_name = expand (' %:p' )
208+ function ! s: UseConfigFiles (from_autocmd) abort " Apply config to the current buffer {{{1
209+ " from_autocmd is truthy if called from an autocmd, falsy otherwise.
210+
211+ " Get the properties of the buffer we are working on
212+ if a: from_autocmd
213+ let l: bufnr = str2nr (expand (' <abuf>' ))
214+ let l: buffer_name = expand (' <afile>:p' )
215+ let l: buffer_path = expand (' <afile>:p:h' )
216+ else
217+ let l: bufnr = bufnr (' %' )
218+ let l: buffer_name = expand (' %:p' )
219+ let l: buffer_path = expand (' %:p:h' )
220+ endif
221+ call setbufvar (l: bufnr , ' editorconfig_tried' , 1 )
210222
211223 " Only process normal buffers (do not treat help files as '.txt' files)
212224 " When starting Vim with a directory, the buftype might not yet be set:
@@ -226,7 +238,7 @@ function! s:UseConfigFiles() abort " Apply config to the current buffer {{{1
226238 endif
227239 endif
228240
229- if getbufvar (' % ' , ' EditorConfig_disable' , 0 )
241+ if getbufvar (l: bufnr , ' EditorConfig_disable' , 0 )
230242 if g: EditorConfig_verbose
231243 echo ' EditorConfig disabled --- skipping buffer "' . l: buffer_name . ' "'
232244 endif
@@ -245,7 +257,7 @@ function! s:UseConfigFiles() abort " Apply config to the current buffer {{{1
245257 endfor
246258
247259 " Check if any .editorconfig does exist
248- let l: conf_files = s: GetFilenames (expand ( ' %:p:h ' ) , ' .editorconfig' )
260+ let l: conf_files = s: GetFilenames (l: buffer_path , ' .editorconfig' )
249261 let l: conf_found = 0
250262 for conf_file in conf_files
251263 if filereadable (conf_file)
@@ -269,12 +281,12 @@ function! s:UseConfigFiles() abort " Apply config to the current buffer {{{1
269281 endif
270282
271283 if s: editorconfig_core_mode == ? ' vim_core'
272- if s: UseConfigFiles_VimCore (l: buffer_name ) == 0
273- call setbufvar (' % ' , ' editorconfig_applied' , 1 )
284+ if s: UseConfigFiles_VimCore (l: bufnr , l: buffer_name ) == 0
285+ call setbufvar (l: bufnr , ' editorconfig_applied' , 1 )
274286 endif
275287 elseif s: editorconfig_core_mode == ? ' external_command'
276- call s: UseConfigFiles_ExternalCommand (l: buffer_name )
277- call setbufvar (' % ' , ' editorconfig_applied' , 1 )
288+ call s: UseConfigFiles_ExternalCommand (l: bufnr , l: buffer_name )
289+ call setbufvar (l: bufnr , ' editorconfig_applied' , 1 )
278290 else
279291 echohl Error |
280292 \ echo " Unknown EditorConfig Core: " .
@@ -290,8 +302,8 @@ function! s:EditorConfigEnable(should_enable)
290302 augroup editorconfig
291303 autocmd !
292304 if a: should_enable
293- autocmd BufNewFile ,BufReadPost ,BufFilePost * call s: UseConfigFiles ()
294- autocmd VimEnter ,BufNew * call s: UseConfigFiles ()
305+ autocmd BufNewFile ,BufReadPost ,BufFilePost * call s: UseConfigFiles (1 )
306+ autocmd VimEnter ,BufNew * call s: UseConfigFiles (1 )
295307 endif
296308 augroup END
297309endfunction
@@ -302,7 +314,7 @@ endfunction
302314command ! EditorConfigEnable call s: EditorConfigEnable (1 )
303315command ! EditorConfigDisable call s: EditorConfigEnable (0 )
304316
305- command ! EditorConfigReload call s: UseConfigFiles () " Reload EditorConfig files
317+ command ! EditorConfigReload call s: UseConfigFiles (0 ) " Reload EditorConfig files
306318" }}}2
307319
308320" On startup, enable the autocommands
@@ -312,29 +324,29 @@ call s:EditorConfigEnable(1)
312324
313325" UseConfigFiles function for different modes {{{1
314326
315- function ! s: UseConfigFiles_VimCore (target)
327+ function ! s: UseConfigFiles_VimCore (bufnr , target)
316328" Use the vimscript EditorConfig core
317329 try
318330 let l: config = editorconfig_core#handler#get_configurations (
319331 \ { ' target' : a: target } )
320- call s: ApplyConfig (l: config )
332+ call s: ApplyConfig (a: bufnr , l: config )
321333 return 0 " success
322334 catch
323335 return 1 " failure
324336 endtry
325337endfunction
326338
327- function ! s: UseConfigFiles_ExternalCommand (target)
339+ function ! s: UseConfigFiles_ExternalCommand (bufnr , target)
328340" Use external EditorConfig core (e.g., the C core)
329341
330- call s: DisableShellSlash ()
342+ call s: DisableShellSlash (a: bufnr )
331343 let l: exec_path = shellescape (s: editorconfig_exec_path )
332- call s: ResetShellSlash ()
344+ call s: ResetShellSlash (a: bufnr )
333345
334- call s: SpawnExternalParser (l: exec_path , a: target )
346+ call s: SpawnExternalParser (a: bufnr , l: exec_path , a: target )
335347endfunction
336348
337- function ! s: SpawnExternalParser (cmd, target) " {{{2
349+ function ! s: SpawnExternalParser (bufnr , cmd, target) " {{{2
338350" Spawn external EditorConfig. Used by s:UseConfigFiles_ExternalCommand()
339351
340352 let l: cmd = a: cmd
@@ -345,9 +357,9 @@ function! s:SpawnExternalParser(cmd, target) " {{{2
345357
346358 let l: config = {}
347359
348- call s: DisableShellSlash ()
360+ call s: DisableShellSlash (a: bufnr )
349361 let l: cmd = l: cmd . ' ' . shellescape (a: target )
350- call s: ResetShellSlash ()
362+ call s: ResetShellSlash (a: bufnr )
351363
352364 let l: parsing_result = split (system (l: cmd ), ' \v[\r\n]+' )
353365
@@ -386,96 +398,102 @@ function! s:SpawnExternalParser(cmd, target) " {{{2
386398 let l: config [l: eq_left ] = l: eq_right
387399 endfor
388400
389- call s: ApplyConfig (l: config )
401+ call s: ApplyConfig (a: bufnr , l: config )
390402endfunction " }}}2
391403
392404" }}}1
393405
394- function ! s: ApplyConfig (config) abort " Set the buffer options {{{1
406+ function ! s: ApplyConfig (bufnr , config) abort " Set the buffer options {{{1
395407 if g: EditorConfig_verbose
396408 echo ' Options: ' . string (a: config )
397409 endif
398410
399411 if s: IsRuleActive (' indent_style' , a: config )
400412 if a: config [" indent_style" ] == " tab"
401- setl noexpandtab
413+ call setbufvar ( a: bufnr , ' &expandtab ' , 0 )
402414 elseif a: config [" indent_style" ] == " space"
403- setl expandtab
415+ call setbufvar ( a: bufnr , ' & expandtab' , 1 )
404416 endif
405417 endif
406418
407419 if s: IsRuleActive (' tab_width' , a: config )
408- let &l: tabstop = str2nr (a: config [" tab_width" ])
420+ let l: tabstop = str2nr (a: config [" tab_width" ])
421+ call setbufvar (a: bufnr , ' &tabstop' , l: tabstop )
422+ else
423+ " Grab the current ts so we can use it below
424+ let l: tabstop = getbufvar (a: bufnr , ' &tabstop' )
409425 endif
410426
411427 if s: IsRuleActive (' indent_size' , a: config )
412428 " if indent_size is 'tab', set shiftwidth to tabstop;
413429 " if indent_size is a positive integer, set shiftwidth to the integer
414430 " value
415431 if a: config [" indent_size" ] == " tab"
416- let & l: shiftwidth = & l: tabstop
432+ call setbufvar ( a: bufnr , ' &shiftwidth ' , l: tabstop)
417433 if type (g: EditorConfig_softtabstop_tab ) != type ([])
418- let &l: softtabstop = g: EditorConfig_softtabstop_tab > 0 ?
419- \ &l: shiftwidth : g: EditorConfig_softtabstop_tab
434+ call setbufvar (a: bufnr , ' &softtabstop' ,
435+ \ g: EditorConfig_softtabstop_tab > 0 ?
436+ \ l: tabstop : g: EditorConfig_softtabstop_tab )
420437 endif
421438 else
422439 let l: indent_size = str2nr (a: config [" indent_size" ])
423440 if l: indent_size > 0
424- let & l: shiftwidth = l: indent_size
441+ call setbufvar ( a: bufnr , ' & shiftwidth' , l: indent_size)
425442 if type (g: EditorConfig_softtabstop_space ) != type ([])
426- let &l: softtabstop = g: EditorConfig_softtabstop_space > 0 ?
427- \ &l: shiftwidth : g: EditorConfig_softtabstop_space
443+ call setbufvar (a: bufnr , ' &softtabstop' ,
444+ \ g: EditorConfig_softtabstop_space > 0 ?
445+ \ l: indent_size : g: EditorConfig_softtabstop_space )
428446 endif
429447 endif
430448 endif
431449
432450 endif
433451
434452 if s: IsRuleActive (' end_of_line' , a: config ) &&
435- \ & l: modifiable
453+ \ getbufvar ( a: bufnr , ' & modifiable' )
436454 if a: config [" end_of_line" ] == " lf"
437- setl fileformat = unix
455+ call setbufvar ( a: bufnr , ' & fileformat' , ' unix' )
438456 elseif a: config [" end_of_line" ] == " crlf"
439- setl fileformat = dos
457+ call setbufvar ( a: bufnr , ' & fileformat' , ' dos' )
440458 elseif a: config [" end_of_line" ] == " cr"
441- setl fileformat = mac
459+ call setbufvar ( a: bufnr , ' & fileformat' , ' mac' )
442460 endif
443461 endif
444462
445463 if s: IsRuleActive (' charset' , a: config ) &&
446- \ & l: modifiable
464+ \ getbufvar ( a: bufnr , ' & modifiable' )
447465 if a: config [" charset" ] == " utf-8"
448- setl fileencoding = utf- 8
449- setl nobomb
466+ call setbufvar ( a: bufnr , ' & fileencoding' , ' utf-8' )
467+ call setbufvar ( a: bufnr , ' &bomb ' , 0 )
450468 elseif a: config [" charset" ] == " utf-8-bom"
451- setl fileencoding = utf- 8
452- setl bomb
469+ call setbufvar ( a: bufnr , ' & fileencoding' , ' utf-8' )
470+ call setbufvar ( a: bufnr , ' & bomb' , 1 )
453471 elseif a: config [" charset" ] == " latin1"
454- setl fileencoding = latin1
455- setl nobomb
472+ call setbufvar ( a: bufnr , ' & fileencoding' , ' latin1' )
473+ call setbufvar ( a: bufnr , ' &bomb ' , 0 )
456474 elseif a: config [" charset" ] == " utf-16be"
457- setl fileencoding = utf- 16 be
458- setl bomb
475+ call setbufvar ( a: bufnr , ' & fileencoding' , ' utf-16be' )
476+ call setbufvar ( a: bufnr , ' & bomb' , 1 )
459477 elseif a: config [" charset" ] == " utf-16le"
460- setl fileencoding = utf- 16 le
461- setl bomb
478+ call setbufvar ( a: bufnr , ' & fileencoding' , ' utf-16le' )
479+ call setbufvar ( a: bufnr , ' & bomb' , 1 )
462480 endif
463481 endif
464482
465483 augroup editorconfig_trim_trailing_whitespace
466484 autocmd ! BufWritePre <buffer>
467485 if s: IsRuleActive (' trim_trailing_whitespace' , a: config ) &&
468486 \ get (a: config , ' trim_trailing_whitespace' , ' false' ) == # ' true'
469- autocmd BufWritePre <buffer> call s: TrimTrailingWhitespace ()
487+ execute ' autocmd BufWritePre <buffer= ' . a: bufnr . ' > call s:TrimTrailingWhitespace()'
470488 endif
471489 augroup END
472490
473491 if s: IsRuleActive (' insert_final_newline' , a: config )
474492 if exists (' +fixendofline' )
475493 if a: config [" insert_final_newline" ] == " false"
476- setl nofixendofline
494+ call setbufvar ( a: bufnr , ' &fixendofline ' , 0 )
477495 else
478- setl fixendofline
496+ call setbufvar ( a: bufnr , ' & fixendofline' , 1 )
479497 endif
480498 elseif exists (' :SetNoEOL' ) == 2
481499 if a: config [" insert_final_newline" ] == " false"
@@ -490,23 +508,39 @@ function! s:ApplyConfig(config) abort " Set the buffer options {{{1
490508 let l: max_line_length = str2nr (a: config [' max_line_length' ])
491509
492510 if l: max_line_length >= 0
493- let & l: textwidth = l: max_line_length
511+ call setbufvar ( a: bufnr , ' & textwidth' , l: max_line_length)
494512 if g: EditorConfig_preserve_formatoptions == 0
495- setlocal formatoptions += tc
513+ " setlocal formatoptions+=tc
514+ let l: fo = getbufvar (a: bufnr , ' &formatoptions' )
515+ if l: fo !~# ' t'
516+ let l: fo .= ' t'
517+ endif
518+ if l: fo !~# ' c'
519+ let l: fo .= ' c'
520+ endif
521+ call setbufvar (a: bufnr , ' &formatoptions' , l: fo )
496522 endif
497523 endif
498524
499525 if exists (' +colorcolumn' )
500526 if l: max_line_length > 0
501527 if g: EditorConfig_max_line_indicator == ' line'
502- setlocal colorcolumn += + 1
528+ " setlocal colorcolumn+=+1
529+ let l: cocol = getbufvar (a: bufnr , ' &colorcolumn' )
530+ if ! empty (l: cocol )
531+ let l: cocol .= ' ,'
532+ endif
533+ let l: cocol .= ' +1'
534+ call setbufvar (a: bufnr , ' &colorcolumn' , l: cocol )
503535 elseif g: EditorConfig_max_line_indicator == ' fill' &&
504- \ l: max_line_length < & l: columns
536+ \ l: max_line_length < getbufvar ( a: bufnr , ' & columns' )
505537 " Fill only if the columns of screen is large enough
506- let &l: colorcolumn = join (
507- \ range (l: max_line_length+ 1 ,&l: columns ),' ,' )
538+ call setbufvar (a: bufnr , ' &colorcolumn' ,
539+ \ join (range (l: max_line_length+ 1 ,
540+ \ getbufvar (a: bufnr , ' &columns' )),
541+ \ ' ,' ))
508542 elseif g: EditorConfig_max_line_indicator == ' exceeding'
509- let & l: colorcolumn = ' '
543+ call setbufvar ( a: bufnr , ' & colorcolumn' , ' ' )
510544 for l: match in getmatches ()
511545 if get (l: match , ' group' , ' ' ) == ' ColorColumn'
512546 call matchdelete (get (l: match , ' id' ))
@@ -534,7 +568,8 @@ endfunction
534568" }}}1
535569
536570function ! s: TrimTrailingWhitespace () " {{{1
537- if &l: modifiable
571+ " Called from within a buffer-specific autocmd, so we can use '%'
572+ if getbufvar (' %' , ' &modifiable' )
538573 " don't lose user position when trimming trailing whitespace
539574 let s: view = winsaveview ()
540575 try
0 commit comments