diff options
| author | Adam Stankiewicz <sheerun@sher.pl> | 2020-09-04 17:31:22 +0200 | 
|---|---|---|
| committer | Adam Stankiewicz <sheerun@sher.pl> | 2020-09-04 17:31:22 +0200 | 
| commit | b2640b5b760e6fc68b8cc49d3c8bab6cdef4f889 (patch) | |
| tree | 548acc4df88fc6c18c956e76df53d5228495c8f9 /plugin | |
| parent | c30ba66d2211d0c5764855d099e171fb2cd1108d (diff) | |
| download | vim-polyglot-b2640b5b760e6fc68b8cc49d3c8bab6cdef4f889.tar.gz vim-polyglot-b2640b5b760e6fc68b8cc49d3c8bab6cdef4f889.zip | |
Fix detection of indentation, #537
Diffstat (limited to 'plugin')
| -rw-r--r-- | plugin/polyglot.vim | 149 | ||||
| -rw-r--r-- | plugin/sleuth.vim | 166 | 
2 files changed, 149 insertions, 166 deletions
| diff --git a/plugin/polyglot.vim b/plugin/polyglot.vim new file mode 100644 index 00000000..db2976e6 --- /dev/null +++ b/plugin/polyglot.vim @@ -0,0 +1,149 @@ +" 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 + +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 diff --git a/plugin/sleuth.vim b/plugin/sleuth.vim deleted file mode 100644 index a0bba8c4..00000000 --- a/plugin/sleuth.vim +++ /dev/null @@ -1,166 +0,0 @@ -" Heuristically set buffer options -" -" Modified version of vim-sleuth: -"   - softtab and tabstop reduced from 8 to 2 -"   - number of considered lines reduced from 1024 to 64 -"   - maximum 6 other files are checked instead of 20 -"   - check maximum of files 2 per directory level instead of 8 -"   - maximum of 3 directory levels are checked -"   - globs are concatenated for performance -"   - tabstop setting is not configured, it's up to user -if exists('g:polyglot_disabled') && index(g:polyglot_disabled, 'autoindent') != -1 -  finish  -endif - -if exists("g:loaded_sleuth") || exists("g:polyglot_disabled") || v:version < 700 || &cp -  finish -endif - -let g:loaded_sleuth = 1 - -function! s:guess(lines) abort -  let options = {} -  let heuristics = {'spaces': 0, 'hard': 0, 'soft': 0} -  let ccomment = 0 -  let podcomment = 0 -  let triplequote = 0 -  let backtick = 0 -  let xmlcomment = 0 -  let softtab = repeat(' ', 2) - -  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 - -    if line =~# '^\t' -      let heuristics.hard += 1 -    elseif line =~# '^' . softtab -      let heuristics.soft += 1 -    endif -    if line =~# '^  ' -      let heuristics.spaces += 1 -    endif -    let indent = len(matchstr(substitute(line, '\t', softtab, 'g'), '^ *')) -    if indent > 1 && (indent < 4 || indent % 2 == 0) && -          \ get(options, 'shiftwidth', 99) > indent -      let options.shiftwidth = indent -    endif -  endfor - -  if heuristics.hard && !heuristics.spaces -    return {'expandtab': 0, 'shiftwidth': &tabstop} -  elseif heuristics.soft != heuristics.hard -    let options.expandtab = heuristics.soft > heuristics.hard -  endif - -  return options -endfunction - -function! s:apply_if_ready(options) abort -  if !has_key(a:options, 'expandtab') || !has_key(a:options, 'shiftwidth') -    return 0 -  else -    for [option, value] in items(a:options) -      call setbufvar('', '&'.option, value) -    endfor -    return 1 -  endif -endfunction - -function! s:detect() abort -  if &buftype ==# 'help' -    return -  endif - -  let options = s:guess(getline(1, 64)) -  if s:apply_if_ready(options) -    return -  endif -  let c = 6 -  let pattern = c > 0 ? sleuth#GlobForFiletype(&filetype) : '' -  let dir = expand('%:p:h') -  let level = 3 -  while isdirectory(dir) && dir !=# fnamemodify(dir, ':h') && c > 0 && level > 0 -    let level -= 1 -    for neighbor in glob(dir.'/'.pattern,0,1)[0:1] -      if neighbor !=# expand('%:p') && filereadable(neighbor) -        call extend(options, s:guess(readfile(neighbor, '', 32)), 'keep') -        let c -= 1 -      endif -      if s:apply_if_ready(options) -        let b:sleuth_culprit = neighbor -        return -      endif -      if c <= 0 -        break -      endif -    endfor -    if c <= 0 -      break -    endif -    let dir = fnamemodify(dir, ':h') -  endwhile -  if has_key(options, 'shiftwidth') -    return s:apply_if_ready(extend({'expandtab': 1}, options)) -  endif -endfunction - -setglobal smarttab - -if !exists('g:did_indent_on') -  filetype indent on -endif - -augroup polyglot -  autocmd! -  autocmd FileType * call s:detect() -augroup END | 
