mirror of
https://github.com/sheerun/vim-polyglot.git
synced 2025-11-10 12:33:51 -05:00
Fix auto-detecting indent, closes #540
This commit is contained in:
@@ -1761,6 +1761,162 @@ au BufNewFile,BufRead,StdinReadPost *
|
|||||||
\ if !did_filetype() && expand("<amatch>") !~ g:ft_ignore_pat
|
\ if !did_filetype() && expand("<amatch>") !~ g:ft_ignore_pat
|
||||||
\ | call polyglot#Heuristics() | endif
|
\ | call polyglot#Heuristics() | endif
|
||||||
|
|
||||||
|
|
||||||
|
if v:version < 700 || &cp
|
||||||
|
finish
|
||||||
|
endif
|
||||||
|
|
||||||
|
|
||||||
|
" Code below re-implements sleuth for vim-polyglot
|
||||||
|
let g:loaded_sleuth = 1
|
||||||
|
|
||||||
|
" Makes shiftwidth to be synchronized with tabstop by default
|
||||||
|
if &shiftwidth == &tabstop
|
||||||
|
let &shiftwidth = 0
|
||||||
|
endif
|
||||||
|
|
||||||
|
function! s:guess(lines) abort
|
||||||
|
let options = {}
|
||||||
|
let ccomment = 0
|
||||||
|
let podcomment = 0
|
||||||
|
let triplequote = 0
|
||||||
|
let backtick = 0
|
||||||
|
let xmlcomment = 0
|
||||||
|
let heredoc = ''
|
||||||
|
let minindent = 10
|
||||||
|
let spaces_minus_tabs = 0
|
||||||
|
|
||||||
|
for line in a:lines
|
||||||
|
if !len(line) || line =~# '^\W*$'
|
||||||
|
continue
|
||||||
|
endif
|
||||||
|
|
||||||
|
if line =~# '^\s*/\*'
|
||||||
|
let ccomment = 1
|
||||||
|
endif
|
||||||
|
if ccomment
|
||||||
|
if line =~# '\*/'
|
||||||
|
let ccomment = 0
|
||||||
|
endif
|
||||||
|
continue
|
||||||
|
endif
|
||||||
|
|
||||||
|
if line =~# '^=\w'
|
||||||
|
let podcomment = 1
|
||||||
|
endif
|
||||||
|
if podcomment
|
||||||
|
if line =~# '^=\%(end\|cut\)\>'
|
||||||
|
let podcomment = 0
|
||||||
|
endif
|
||||||
|
continue
|
||||||
|
endif
|
||||||
|
|
||||||
|
if triplequote
|
||||||
|
if line =~# '^[^"]*"""[^"]*$'
|
||||||
|
let triplequote = 0
|
||||||
|
endif
|
||||||
|
continue
|
||||||
|
elseif line =~# '^[^"]*"""[^"]*$'
|
||||||
|
let triplequote = 1
|
||||||
|
endif
|
||||||
|
|
||||||
|
if backtick
|
||||||
|
if line =~# '^[^`]*`[^`]*$'
|
||||||
|
let backtick = 0
|
||||||
|
endif
|
||||||
|
continue
|
||||||
|
elseif &filetype ==# 'go' && line =~# '^[^`]*`[^`]*$'
|
||||||
|
let backtick = 1
|
||||||
|
endif
|
||||||
|
|
||||||
|
if line =~# '^\s*<\!--'
|
||||||
|
let xmlcomment = 1
|
||||||
|
endif
|
||||||
|
if xmlcomment
|
||||||
|
if line =~# '-->'
|
||||||
|
let xmlcomment = 0
|
||||||
|
endif
|
||||||
|
continue
|
||||||
|
endif
|
||||||
|
|
||||||
|
" This is correct order because both "<<EOF" and "EOF" matches end
|
||||||
|
if heredoc != ''
|
||||||
|
if line =~# heredoc
|
||||||
|
let heredoc = ''
|
||||||
|
endif
|
||||||
|
continue
|
||||||
|
endif
|
||||||
|
let herematch = matchlist(line, '\C<<\W*\([A-Z]\+\)\s*$')
|
||||||
|
if len(herematch) > 0
|
||||||
|
let heredoc = herematch[1] . '$'
|
||||||
|
endif
|
||||||
|
|
||||||
|
let spaces_minus_tabs += line[0] == "\t" ? 1 : -1
|
||||||
|
|
||||||
|
if line[0] == "\t"
|
||||||
|
setlocal noexpandtab
|
||||||
|
return 1
|
||||||
|
elseif line[0] == " "
|
||||||
|
let indent = len(matchstr(line, '^ *'))
|
||||||
|
if (indent % 2 == 0 || indent % 3 == 0) && indent < minindent
|
||||||
|
let minindent = indent
|
||||||
|
endif
|
||||||
|
endif
|
||||||
|
endfor
|
||||||
|
|
||||||
|
if minindent < 10
|
||||||
|
setlocal expandtab
|
||||||
|
let &shiftwidth=minindent
|
||||||
|
return 1
|
||||||
|
endif
|
||||||
|
|
||||||
|
return 0
|
||||||
|
endfunction
|
||||||
|
|
||||||
|
function! s:detect_indent() abort
|
||||||
|
if &buftype ==# 'help'
|
||||||
|
return
|
||||||
|
endif
|
||||||
|
|
||||||
|
if s:guess(getline(1, 32))
|
||||||
|
return
|
||||||
|
endif
|
||||||
|
let pattern = sleuth#GlobForFiletype(&filetype)
|
||||||
|
if len(pattern) == 0
|
||||||
|
return
|
||||||
|
endif
|
||||||
|
let pattern = '{' . pattern . ',.git,.svn,.hg}'
|
||||||
|
let dir = expand('%:p:h')
|
||||||
|
let level = 3
|
||||||
|
while isdirectory(dir) && dir !=# fnamemodify(dir, ':h') && level > 0
|
||||||
|
" Ignore files from homedir and root
|
||||||
|
if dir == expand('~') || dir == '/'
|
||||||
|
return
|
||||||
|
endif
|
||||||
|
for neighbor in glob(dir . '/' . pattern, 0, 1)[0:level]
|
||||||
|
" Do not consider directories above .git, .svn or .hg
|
||||||
|
if fnamemodify(neighbor, ":h:t")[0] == "."
|
||||||
|
return
|
||||||
|
endif
|
||||||
|
if neighbor !=# expand('%:p') && filereadable(neighbor)
|
||||||
|
if s:guess(readfile(neighbor, '', 32))
|
||||||
|
return
|
||||||
|
endif
|
||||||
|
endif
|
||||||
|
endfor
|
||||||
|
|
||||||
|
let dir = fnamemodify(dir, ':h')
|
||||||
|
let level -= 1
|
||||||
|
endwhile
|
||||||
|
endfunction
|
||||||
|
|
||||||
|
setglobal smarttab
|
||||||
|
|
||||||
|
augroup polyglot
|
||||||
|
autocmd!
|
||||||
|
autocmd FileType * call s:detect_indent()
|
||||||
|
augroup END
|
||||||
|
|
||||||
" restore Vi compatibility settings
|
" restore Vi compatibility settings
|
||||||
let &cpo = s:cpo_save
|
let &cpo = s:cpo_save
|
||||||
unlet s:cpo_save
|
unlet s:cpo_save
|
||||||
|
|||||||
@@ -1,167 +0,0 @@
|
|||||||
" Heuristically set expandtab and shiftwidth options
|
|
||||||
"
|
|
||||||
" Modified version of vim-sleuth:
|
|
||||||
" - tabstop is not set, it's up to user to set it
|
|
||||||
" - check maximum of 32 lines, instead of 1024
|
|
||||||
" - check maximum 6 files, instead of 20
|
|
||||||
" - check maximum of 2 filer per directory level, instead of 8
|
|
||||||
" - check maximum of 3 directory levels
|
|
||||||
" - check only to the nearest .git, .hg, or .svn directory
|
|
||||||
" - globs are concatenated for performance
|
|
||||||
if exists('g:polyglot_disabled') && index(g:polyglot_disabled, 'autoindent') != -1
|
|
||||||
finish
|
|
||||||
endif
|
|
||||||
|
|
||||||
if exists("g:loaded_polyglot") || v:version < 700 || &cp
|
|
||||||
finish
|
|
||||||
endif
|
|
||||||
|
|
||||||
let g:loaded_sleuth = 1
|
|
||||||
let g:loaded_polyglot = 1
|
|
||||||
|
|
||||||
" Makes shiftwidth to be synchronized with tabstop by default
|
|
||||||
if &shiftwidth == &tabstop
|
|
||||||
let &shiftwidth = 0
|
|
||||||
endif
|
|
||||||
|
|
||||||
function! s:guess(lines) abort
|
|
||||||
let options = {}
|
|
||||||
let ccomment = 0
|
|
||||||
let podcomment = 0
|
|
||||||
let triplequote = 0
|
|
||||||
let backtick = 0
|
|
||||||
let xmlcomment = 0
|
|
||||||
let heredoc = ''
|
|
||||||
let minindent = 10
|
|
||||||
let spaces_minus_tabs = 0
|
|
||||||
|
|
||||||
for line in a:lines
|
|
||||||
if !len(line) || line =~# '^\W*$'
|
|
||||||
continue
|
|
||||||
endif
|
|
||||||
|
|
||||||
if line =~# '^\s*/\*'
|
|
||||||
let ccomment = 1
|
|
||||||
endif
|
|
||||||
if ccomment
|
|
||||||
if line =~# '\*/'
|
|
||||||
let ccomment = 0
|
|
||||||
endif
|
|
||||||
continue
|
|
||||||
endif
|
|
||||||
|
|
||||||
if line =~# '^=\w'
|
|
||||||
let podcomment = 1
|
|
||||||
endif
|
|
||||||
if podcomment
|
|
||||||
if line =~# '^=\%(end\|cut\)\>'
|
|
||||||
let podcomment = 0
|
|
||||||
endif
|
|
||||||
continue
|
|
||||||
endif
|
|
||||||
|
|
||||||
if triplequote
|
|
||||||
if line =~# '^[^"]*"""[^"]*$'
|
|
||||||
let triplequote = 0
|
|
||||||
endif
|
|
||||||
continue
|
|
||||||
elseif line =~# '^[^"]*"""[^"]*$'
|
|
||||||
let triplequote = 1
|
|
||||||
endif
|
|
||||||
|
|
||||||
if backtick
|
|
||||||
if line =~# '^[^`]*`[^`]*$'
|
|
||||||
let backtick = 0
|
|
||||||
endif
|
|
||||||
continue
|
|
||||||
elseif &filetype ==# 'go' && line =~# '^[^`]*`[^`]*$'
|
|
||||||
let backtick = 1
|
|
||||||
endif
|
|
||||||
|
|
||||||
if line =~# '^\s*<\!--'
|
|
||||||
let xmlcomment = 1
|
|
||||||
endif
|
|
||||||
if xmlcomment
|
|
||||||
if line =~# '-->'
|
|
||||||
let xmlcomment = 0
|
|
||||||
endif
|
|
||||||
continue
|
|
||||||
endif
|
|
||||||
|
|
||||||
" This is correct order because both "<<EOF" and "EOF" matches end
|
|
||||||
if heredoc != ''
|
|
||||||
if line =~# heredoc
|
|
||||||
let heredoc = ''
|
|
||||||
endif
|
|
||||||
continue
|
|
||||||
endif
|
|
||||||
let herematch = matchlist(line, '\C<<\W*\([A-Z]\+\)\s*$')
|
|
||||||
if len(herematch) > 0
|
|
||||||
let heredoc = herematch[1] . '$'
|
|
||||||
endif
|
|
||||||
|
|
||||||
let spaces_minus_tabs += line[0] == "\t" ? 1 : -1
|
|
||||||
|
|
||||||
if line[0] == "\t"
|
|
||||||
setlocal noexpandtab
|
|
||||||
return 1
|
|
||||||
elseif line[0] == " "
|
|
||||||
let indent = len(matchstr(line, '^ *'))
|
|
||||||
if indent % 2 == 0 && indent < minindent
|
|
||||||
let minindent = indent
|
|
||||||
endif
|
|
||||||
endif
|
|
||||||
endfor
|
|
||||||
|
|
||||||
if minindent < 10
|
|
||||||
setlocal expandtab
|
|
||||||
let &shiftwidth=minindent
|
|
||||||
return 1
|
|
||||||
endif
|
|
||||||
|
|
||||||
return 0
|
|
||||||
endfunction
|
|
||||||
|
|
||||||
function! s:detect_indent() abort
|
|
||||||
if &buftype ==# 'help'
|
|
||||||
return
|
|
||||||
endif
|
|
||||||
|
|
||||||
if s:guess(getline(1, 32))
|
|
||||||
return
|
|
||||||
endif
|
|
||||||
let pattern = sleuth#GlobForFiletype(&filetype)
|
|
||||||
if len(pattern) == 0
|
|
||||||
return
|
|
||||||
endif
|
|
||||||
let pattern = '{' . pattern . ',.git,.svn,.hg}'
|
|
||||||
let dir = expand('%:p:h')
|
|
||||||
let level = 3
|
|
||||||
while isdirectory(dir) && dir !=# fnamemodify(dir, ':h') && level > 0
|
|
||||||
" Ignore files from homedir and root
|
|
||||||
if dir == expand('~') || dir == '/'
|
|
||||||
return
|
|
||||||
endif
|
|
||||||
for neighbor in glob(dir . '/' . pattern, 0, 1)[0:level]
|
|
||||||
" Do not consider directories above .git, .svn or .hg
|
|
||||||
if fnamemodify(neighbor, ":h:t")[0] == "."
|
|
||||||
return
|
|
||||||
endif
|
|
||||||
if neighbor !=# expand('%:p') && filereadable(neighbor)
|
|
||||||
if s:guess(readfile(neighbor, '', 32))
|
|
||||||
return
|
|
||||||
endif
|
|
||||||
endif
|
|
||||||
endfor
|
|
||||||
|
|
||||||
let dir = fnamemodify(dir, ':h')
|
|
||||||
let level -= 1
|
|
||||||
endwhile
|
|
||||||
endfunction
|
|
||||||
|
|
||||||
setglobal smarttab
|
|
||||||
|
|
||||||
augroup polyglot
|
|
||||||
autocmd!
|
|
||||||
autocmd FileType * call s:detect_indent()
|
|
||||||
augroup END
|
|
||||||
Reference in New Issue
Block a user