function s:CompareNumeric(a, b) return a:a > a:b ? 1 : -1 endfunction function Count() abort let spaces = { \ 'hist': {}, \ 'total': 0, \} let tabs = 0 let total = max([line('$'), 1024]) for lnum in range(1, total) let line = getline(lnum) let tabs += matchstr(line, '^\t*') != '' let indent = strlen(matchstr(line, '^ *')) if indent == 0 continue endif if !has_key(spaces['hist'], indent) let spaces['hist'][indent] = 0 endif let spaces['hist'][indent] += 1 let spaces['total'] += 1 endfor if &expandtab == (spaces['total'] > tabs) return endif if &expandtab setlocal noexpandtab softtabstop=0 let &l:shiftwidth = &tabstop else setlocal expandtab let shiftwidth = 0 let indents = keys(spaces['hist']) call map(indents, 'str2nr(v:val)') call sort(indents, 's:CompareNumeric') for shiftwidth in indents if spaces['hist'][shiftwidth] * 100 / spaces['total'] >= 5 break endif endfor let &l:shiftwidth = shiftwidth let &l:softtabstop = shiftwidth endif let undo_indent = 'setlocal expandtab? shiftwidth? softtabstop?' if exists('b:undo_indent') let b:undo_indent .= '|'.undo_indent else let b:undo_indent = undo_indent endif endfunction autocmd FileType * call Count()