summaryrefslogtreecommitdiffstats
path: root/plugin/polyglot.vim
diff options
context:
space:
mode:
Diffstat (limited to 'plugin/polyglot.vim')
-rw-r--r--plugin/polyglot.vim149
1 files changed, 149 insertions, 0 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