diff --git a/plugin/detectindent.vim b/plugin/detectindent.vim index d903948..9f43e45 100644 --- a/plugin/detectindent.vim +++ b/plugin/detectindent.vim @@ -56,6 +56,30 @@ fun! s:GetValue(option) endif endfun +fun! s:SetIndent(expandtab, desired_tabstop) + let &l:expandtab = a:expandtab + + " Only modify tabs if we have a valid value. + if a:desired_tabstop > 0 + " See `:help 'tabstop'`. We generally adhere to #1 or #4, but when + " guessing what to do for mixed tabs and spaces we use #2. + + let &l:tabstop = a:desired_tabstop + " NOTE: shiftwidth=0 keeps it in sync with tabstop, but that breaks + " many indentation plugins that read 'sw' instead of calling the new + " shiftwidth(). See + " https://github.com/tpope/vim-sleuth/issues/25 + let &l:shiftwidth = a:desired_tabstop + + if v:version >= 704 + " Negative value automatically keeps in sync with shiftwidth in Vim 7.4+. + setl softtabstop=-1 + else + let &l:softtabstop = a:desired_tabstop + endif + endif +endfun + fun! DetectIndent() let l:has_leading_tabs = 0 let l:has_leading_spaces = 0 @@ -138,24 +162,23 @@ fun! DetectIndent() if l:has_leading_tabs && ! l:has_leading_spaces " tabs only, no spaces let l:verbose_msg = "Detected tabs only and no spaces" - setl noexpandtab - if s:GetValue("detectindent_preferred_indent") - let &l:shiftwidth = g:detectindent_preferred_indent - let &l:tabstop = g:detectindent_preferred_indent + let indent = s:GetValue("detectindent_preferred_indent") + if indent == 0 + " Default behavior is to retain current tabstop. Still need to set + " it to ensure softtabstop, shiftwidth, tabstop are in sync. + let indent = &l:tabstop endif + call s:SetIndent(0, indent) elseif l:has_leading_spaces && ! l:has_leading_tabs " spaces only, no tabs let l:verbose_msg = "Detected spaces only and no tabs" - setl expandtab - let &l:shiftwidth = l:shortest_leading_spaces_run - let &l:softtabstop = l:shortest_leading_spaces_run + call s:SetIndent(1, l:shortest_leading_spaces_run) elseif l:has_leading_spaces && l:has_leading_tabs && ! s:GetValue("detectindent_preferred_when_mixed") " spaces and tabs let l:verbose_msg = "Detected spaces and tabs" - setl noexpandtab - let &l:shiftwidth = l:shortest_leading_spaces_run + call s:SetIndent(1, l:shortest_leading_spaces_run) " mmmm, time to guess how big tabs are if l:longest_leading_spaces_run <= 2 @@ -169,20 +192,7 @@ fun! DetectIndent() else " no spaces, no tabs let l:verbose_msg = s:GetValue("detectindent_preferred_when_mixed") ? "preferred_when_mixed is active" : "Detected no spaces and no tabs" - if s:GetValue("detectindent_preferred_indent") && - \ (s:GetValue("detectindent_preferred_expandtab")) - setl expandtab - let &l:shiftwidth = g:detectindent_preferred_indent - let &l:softtabstop = g:detectindent_preferred_indent - elseif s:GetValue("detectindent_preferred_indent") - setl noexpandtab - let &l:shiftwidth = g:detectindent_preferred_indent - let &l:tabstop = g:detectindent_preferred_indent - elseif s:GetValue("detectindent_preferred_expandtab") - setl expandtab - else - setl noexpandtab - endif + call s:SetIndent(s:GetValue("detectindent_preferred_expandtab"), s:GetValue("detectindent_preferred_indent")) endif