2008-11-09 15:17:20 -06:00
|
|
|
" Name: detectindent (global plugin)
|
|
|
|
" Version: 1.0
|
|
|
|
" Author: Ciaran McCreesh <ciaranm at gentoo.org>
|
|
|
|
" Updates: http://dev.gentoo.org/~ciaranm/vim/
|
|
|
|
" Purpose: Detect file indent settings
|
|
|
|
"
|
|
|
|
" License: You may redistribute this plugin under the same terms as Vim
|
|
|
|
" itself.
|
|
|
|
"
|
|
|
|
" Usage: :DetectIndent
|
|
|
|
"
|
|
|
|
" " to prefer expandtab to noexpandtab when detection is
|
|
|
|
" " impossible:
|
|
|
|
" :let g:detectindent_preferred_expandtab = 1
|
|
|
|
"
|
|
|
|
" " to set a preferred indent level when detection is
|
|
|
|
" " impossible:
|
|
|
|
" :let g:detectindent_preferred_indent = 4
|
|
|
|
"
|
|
|
|
" Requirements: Untested on Vim versions below 6.2
|
|
|
|
|
|
|
|
fun! <SID>IsCommentStart(line)
|
|
|
|
" &comments isn't reliable
|
2009-02-15 23:10:57 -06:00
|
|
|
if &ft == "c" || &ft == "cpp" || &ft == "java" || &ft == "scala"
|
2008-11-09 15:17:20 -06:00
|
|
|
return -1 != match(a:line, '/\*')
|
2010-01-19 18:30:11 -06:00
|
|
|
elseif &ft == "ocaml" " ocaml comments
|
|
|
|
return -1 != match(a:line, '(\*')
|
2008-12-29 16:33:50 -06:00
|
|
|
elseif &ft == "perl" " catch POD in Perl
|
|
|
|
return -1 != match(a:line, '^=\w')
|
2008-11-09 15:17:20 -06:00
|
|
|
else
|
|
|
|
return 0
|
|
|
|
endif
|
|
|
|
endfun
|
|
|
|
|
|
|
|
fun! <SID>IsCommentEnd(line)
|
2009-02-15 23:10:57 -06:00
|
|
|
if &ft == "c" || &ft == "cpp" || &ft == "java" || &ft == "scala"
|
2008-11-09 15:17:20 -06:00
|
|
|
return -1 != match(a:line, '\*/')
|
2010-01-19 18:30:11 -06:00
|
|
|
elseif &ft == "ocaml" " ocaml comments
|
|
|
|
return -1 != match(a:line, '\*(')
|
2008-12-29 16:33:50 -06:00
|
|
|
elseif &ft == "perl" " catch POD
|
|
|
|
return -1 != match(a:line, '^=cut')
|
2008-11-09 15:17:20 -06:00
|
|
|
else
|
|
|
|
return 0
|
|
|
|
endif
|
|
|
|
endfun
|
|
|
|
|
|
|
|
fun! <SID>DetectIndent()
|
|
|
|
let l:has_leading_tabs = 0
|
|
|
|
let l:has_leading_spaces = 0
|
|
|
|
let l:shortest_leading_spaces_run = 0
|
|
|
|
let l:longest_leading_spaces_run = 0
|
|
|
|
|
|
|
|
let l:idx_end = line("$")
|
|
|
|
let l:idx = 1
|
|
|
|
while l:idx <= l:idx_end
|
|
|
|
let l:line = getline(l:idx)
|
|
|
|
|
|
|
|
" try to skip over comment blocks, they can give really screwy indent
|
|
|
|
" settings in c/c++ files especially
|
|
|
|
if <SID>IsCommentStart(l:line)
|
|
|
|
while l:idx <= l:idx_end && ! <SID>IsCommentEnd(l:line)
|
|
|
|
let l:line = getline(l:idx)
|
|
|
|
let l:idx = l:idx + 1
|
|
|
|
endwhile
|
|
|
|
let l:idx = l:idx + 1
|
|
|
|
continue
|
|
|
|
endif
|
|
|
|
|
|
|
|
let l:leading_char = strpart(l:line, 0, 1)
|
|
|
|
|
|
|
|
if l:leading_char == "\t"
|
|
|
|
let l:has_leading_tabs = 1
|
|
|
|
|
|
|
|
elseif l:leading_char == " "
|
|
|
|
" only interested if we don't have a run of spaces followed by a
|
|
|
|
" tab.
|
|
|
|
if -1 == match(l:line, '^ \+\t')
|
|
|
|
let l:has_leading_spaces = 1
|
|
|
|
let l:spaces = strlen(matchstr(l:line, '^ \+'))
|
|
|
|
if l:shortest_leading_spaces_run == 0 ||
|
|
|
|
\ l:spaces < l:shortest_leading_spaces_run
|
|
|
|
let l:shortest_leading_spaces_run = l:spaces
|
|
|
|
endif
|
|
|
|
if l:spaces > l:longest_leading_spaces_run
|
|
|
|
let l:longest_leading_spaces_run = l:spaces
|
|
|
|
endif
|
|
|
|
endif
|
|
|
|
|
|
|
|
endif
|
|
|
|
|
|
|
|
let l:idx = l:idx + 1
|
|
|
|
endwhile
|
|
|
|
|
|
|
|
if l:has_leading_tabs && ! l:has_leading_spaces
|
|
|
|
" tabs only, no spaces
|
|
|
|
set noexpandtab
|
|
|
|
if exists("g:detectindent_preferred_tabsize")
|
|
|
|
let &shiftwidth = g:detectindent_preferred_indent
|
|
|
|
let &tabstop = g:detectindent_preferred_indent
|
|
|
|
endif
|
|
|
|
|
|
|
|
elseif l:has_leading_spaces && ! l:has_leading_tabs
|
|
|
|
" spaces only, no tabs
|
|
|
|
set expandtab
|
|
|
|
let &shiftwidth = l:shortest_leading_spaces_run
|
|
|
|
let &softtabstop = l:shortest_leading_spaces_run
|
|
|
|
|
|
|
|
elseif l:has_leading_spaces && l:has_leading_tabs
|
|
|
|
" spaces and tabs
|
|
|
|
set noexpandtab
|
|
|
|
let &shiftwidth = l:shortest_leading_spaces_run
|
|
|
|
|
|
|
|
" mmmm, time to guess how big tabs are
|
|
|
|
if l:longest_leading_spaces_run < 2
|
|
|
|
let &tabstop = 2
|
|
|
|
elseif l:longest_leading_spaces_run < 4
|
|
|
|
let &tabstop = 4
|
|
|
|
else
|
|
|
|
let &tabstop = 8
|
|
|
|
endif
|
|
|
|
|
|
|
|
else
|
|
|
|
" no spaces, no tabs
|
|
|
|
if exists("g:detectindent_preferred_tabsize")
|
|
|
|
let &shiftwidth = g:detectindent_preferred_indent
|
|
|
|
let &tabstop = g:detectindent_preferred_indent
|
|
|
|
endif
|
|
|
|
if exists("g:detectindent_preferred_expandtab")
|
|
|
|
set expandtab
|
|
|
|
if exists("g:detectindent_preferred_tabsize")
|
|
|
|
let &softtabstop = l:shortest_leading_spaces_run
|
|
|
|
endif
|
|
|
|
endif
|
|
|
|
|
|
|
|
endif
|
|
|
|
endfun
|
|
|
|
|
|
|
|
command! -nargs=0 DetectIndent call <SID>DetectIndent()
|
|
|
|
|