" 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 minindent = 10
let spaces_minus_tabs = 0
for line in a:lines
if !len(line) || line =~# '^\s*$'
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
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
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
if !exists('g:did_indent_on')
filetype indent on
endif
augroup polyglot
autocmd!
autocmd FileType * call s:detect_indent()
augroup END