Vim Tips Wiki
No edit summary
 
(Change <tt> to <code>, perhaps also minor tweak.)
 
(19 intermediate revisions by 7 users not shown)
Line 1: Line 1:
  +
{{TipImported
{{review}}
 
{{Tip
 
 
|id=1231
 
|id=1231
  +
|previous=1230
|title=set indent parameters for python files.
 
  +
|next=1232
|created=May 13, 2006 11:32
 
  +
|created=2006
 
|complexity=intermediate
 
|complexity=intermediate
 
|author=Davide Alberani
 
|author=Davide Alberani
|version=5.7
+
|version=6.0
 
|rating=42/15
 
|rating=42/15
  +
|category1=Indenting
|text=
 
  +
|category2=Python
" Tip: set indent parameters for python files.
 
  +
}}
  +
You may need to maintain source files that use different indentation styles. For example, some files may use four spaces for each indent, while others use three spaces, or use tabs, or use a mixture of tabs and spaces.
   
  +
This tip presents alternative procedures to automatically detect and set the indent options so Vim adapts to the style of the program you are working on. The procedures are oriented towards working on Python programs but may be useful for other languages.
" Version: 0.1
 
   
  +
==IndentConsistencyCop==
" Date: 13 May 2006
 
  +
The {{script|id=1690|text=IndentConsistencyCop}} plugin warns if inconsistent indentation is used in a buffer and also offers to correct the buffer's indent settings (<code>shiftwidth</code>, <code>softtabstop</code>, etc) if they do not match the indent type used in the buffer. This plugin is not limited to Python files. Checks can be triggered manually or (with the {{script|id=1691|text=IndentConsistencyCopAutoCmds}} add-on plugin) automatically for certain filetypes.
   
  +
==Indent Finder==
"
 
  +
The {{script|id=513|text=Indent Finder}} plugin sets the correct indentation for each file that you edit. It uses a Python script that determines what indent style was used, then adjusts your settings so that new modifications use the same style.
   
  +
==Vindect==
" Description: most python scripts use four spaces for indenting, but
 
  +
[http://freshmeat.net/projects/vindect/ Vindect] is a Python script to detect the indent options required for editing a Python program. In Vim, output from the <code>:version</code> command should include "+python".
   
  +
The following options are set based upon usage in the current file, and your preferences: <code>shiftwidth</code>, <code>tabstop</code>, <code>softtabstop</code>, <code>smarttab</code>, <code>expandtab</code>.
" sometimes you will end up editing a script where tabs
 
   
  +
Rename the downloaded file to <code>vindect.py</code>. The file includes setup instructions using the deprecated <code>mysyntaxfile</code> variable. Following is a better procedure that should be used instead.
" are used; in these situations it can be useful to
 
   
  +
The following commands need to be executed once per Vim session (done below):
" automatically detect whether spaces or tabs were used,
 
  +
<pre>
  +
" First need to set the Python path so vindect.py is found.
  +
:py import vindect
  +
:py vindect.setDefaults(...) " optional to set different defaults
  +
</pre>
   
  +
This command detects and sets the indent options when a new file is opened (done below):
" and set some parameters (or call some functions) consequently.
 
  +
<pre>
  +
:py vindect.detect(preferred='space')
  +
</pre>
   
  +
The following setup performs all the required steps whenever a Python file is opened.
"
 
  +
*Place <code>vindent.py</code> in your <code>.vim</code> (Unix based systems) or <code>vimfiles</code> (Windows) directory.
  +
*Create an <code>after/ftplugin/python.vim</code> file with the following contents. On Windows systems, change <code>.vim</code> to <code>vimfiles</code>.
  +
<pre>
  +
if !exists('s:configured_vindect')
  +
if has('python')
  +
py import sys,os; sys.path.append(os.path.expanduser('~/.vim/'))
  +
try
  +
py import vindect
  +
let s:configured_vindect = 1
  +
catch
  +
let s:configured_vindect = 0
  +
endtry
  +
" to set different defaults: py vindect.setDefaults(...)
  +
else
  +
let s:configured_vindect = 0
  +
endif
  +
endif
  +
if s:configured_vindect
  +
py vindect.detect(preferred='space')
  +
endif
  +
</pre>
   
  +
==DetectIndent==
" Usage: you can put this script in you vimrc and call the PyIndentAutoCfg
 
  +
The {{script|id=1171|text=DetectIndent}} plugin is another alternative.
   
  +
==Vim script==
" function with an autocmd associated to python files, or call
 
  +
The following script can only choose between two sets of fixed options. One set is used if tabs are detected; otherwise another set is used (for space indents).
   
  +
You could put the following in your [[vimrc]] and use a mapping to call <code>PyIndentAutoCfg()</code> when wanted, or define an auto command to call that function when a Python file is opened.
" it manually, or put it in the python.vim syntax script, or... :-)
 
  +
<pre>
  +
" Set options if using spaces for indents (default).
  +
function PySpacesCfg()
  +
set expandtab
  +
set tabstop=8
  +
set softtabstop=4
  +
set shiftwidth=4
  +
endfunction
   
  +
" Set options if using tabs for indents.
  +
function PyTabsCfg()
  +
set noexpandtab
  +
set tabstop=4
  +
set softtabstop=4
  +
set shiftwidth=4
  +
endfunction
   
  +
" Return 1 if using tabs for indents, or 0 otherwise.
  +
function PyIsTabIndent()
  +
let lnum = 1
  +
let got_cols = 0 " 1 if previous lines ended with columns
  +
while lnum <= 100
  +
let line = getline(lnum)
  +
let lnum = lnum + 1
  +
if got_cols == 1
  +
if line =~ "^\t\t" " two tabs to prevent false positives
  +
return 1
  +
endif
  +
endif
  +
if line =~ ":\s*$"
  +
let got_cols = 1
  +
else
  +
let got_cols = 0
  +
endif
  +
endwhile
  +
return 0
  +
endfunction
   
  +
" Check current buffer and configure for tab or space indents.
" Function to set parameters for python scripts that use
 
  +
function PyIndentAutoCfg()
  +
if PyIsTabIndent()
  +
call PyTabsCfg()
  +
else
  +
call PySpacesCfg()
  +
endif
  +
endfunction
  +
</pre>
   
  +
==Comments==
" spaces for indention. This is also the default. YMMV.
 
  +
Re configuration of vindent: It may be possible to avoid a hard coded path to <code>vindect.py</code> by using <code>:exec</code> with <code>expand('<sfile>')</code> and <code>filenamemodify()</code>.
   
  +
----
function PySpacesCfg()
 
  +
Re the Vim script: The following version of PyIsTabIndent() handles more languages:
 
  +
<pre>
set expandtab " use spaces in place of tabs.
 
  +
function! PyIsTabIndent()
 
  +
let lnum = 1
set tabstop=8 " number of spaces for a tab.
 
  +
while lnum <= 100
 
  +
let line = getline(lnum)
set softtabstop=4 " number of spaces for a tab in editing operations.
 
  +
let lnum = lnum + 1
 
  +
if line =~ '^\t\t\(if\|while\|do\|for\|public\|private\|char\|int\|float\|double\|call\)\>'
set shiftwidth=4 " number of spaces for indent (&gt;&gt;, &lt;&lt;, ...)
 
  +
return 1
 
  +
endif
endfunction
 
  +
endwhile
 
  +
return 0
 
 
" Function to set parameters for python scripts that use
 
 
" tabs for indention. YMMV.
 
 
function PyTabsCfg()
 
 
set noexpandtab
 
 
set tabstop=4
 
 
set softtabstop=4
 
 
set shiftwidth=4
 
 
endfunction
 
 
 
 
" This function returns 1 if the file looks like a python script
 
 
" that uses tabs for indenting, or 0 otherwise.
 
 
function PyIsTabIndent()
 
 
let lnum = 1
 
 
let max_lines = 100 " max number of lines to check.
 
 
let got_tabs = 0
 
 
let got_cols = 0 " 1 if the previous lines ended with columns.
 
 
while lnum &lt;= max_lines
 
 
let line = getline(lnum)
 
 
let lnum = lnum + 1
 
 
if got_cols == 1
 
 
if line =~ "^\t\t" " at least two tabs, to prevent false-positives.
 
 
let got_tabs = 1
 
 
break
 
 
endif
 
 
endif
 
 
if line =~ ":\s*$"
 
 
let got_cols = 1
 
 
else
 
 
let got_cols = 0
 
 
endif
 
 
endwhile
 
 
 
 
return got_tabs
 
 
endfunction
 
 
 
 
" Check the file, and run the relative function.
 
 
function PyIndentAutoCfg()
 
 
if PyIsTabIndent() == 1
 
 
call PyTabsCfg()
 
 
else
 
 
call PySpacesCfg()
 
 
endif
 
 
endfunction
 
 
 
 
" Call the PyIndentAutoCfg function. Uncomment this line if you've copied
 
 
" this script in the python.vim syntax file or something like that.
 
 
" call PyIndentAutoCfg()
 
 
 
}}
 
 
== Comments ==
 
Very useful tip! I adapted it to work for more programming languages in general
 
by changing PyIsTabIndent() as below.
 
 
function! PyIsTabIndent()
 
let lnum = 1
 
let max_lines = 100 " max number of lines to check.
 
let got_tabs = 0
 
while lnum &lt;= max_lines
 
let line = getline(lnum)
 
let lnum = lnum + 1
 
if line =~ '^\t\t\(if\|while\|do\|for\|public\|private\|char\|int\|float\|double\|call\)\&gt;'
 
let got_tabs = 1
 
break
 
endif
 
endwhile
 
 
return got_tabs
 
 
endfunction
 
endfunction
  +
</pre>
   
'''Anonymous'''
 
, May 16, 2006 12:44
 
 
----
 
----
<!-- parsed by vimtips.py in 0.578721 seconds-->
 

Latest revision as of 06:15, 13 July 2012

Tip 1231 Printable Monobook Previous Next

created 2006 · complexity intermediate · author Davide Alberani · version 6.0


You may need to maintain source files that use different indentation styles. For example, some files may use four spaces for each indent, while others use three spaces, or use tabs, or use a mixture of tabs and spaces.

This tip presents alternative procedures to automatically detect and set the indent options so Vim adapts to the style of the program you are working on. The procedures are oriented towards working on Python programs but may be useful for other languages.

IndentConsistencyCop[]

The IndentConsistencyCop plugin warns if inconsistent indentation is used in a buffer and also offers to correct the buffer's indent settings (shiftwidth, softtabstop, etc) if they do not match the indent type used in the buffer. This plugin is not limited to Python files. Checks can be triggered manually or (with the IndentConsistencyCopAutoCmds add-on plugin) automatically for certain filetypes.

Indent Finder[]

The Indent Finder plugin sets the correct indentation for each file that you edit. It uses a Python script that determines what indent style was used, then adjusts your settings so that new modifications use the same style.

Vindect[]

Vindect is a Python script to detect the indent options required for editing a Python program. In Vim, output from the :version command should include "+python".

The following options are set based upon usage in the current file, and your preferences: shiftwidth, tabstop, softtabstop, smarttab, expandtab.

Rename the downloaded file to vindect.py. The file includes setup instructions using the deprecated mysyntaxfile variable. Following is a better procedure that should be used instead.

The following commands need to be executed once per Vim session (done below):

" First need to set the Python path so vindect.py is found.
:py import vindect
:py vindect.setDefaults(...)  " optional to set different defaults

This command detects and sets the indent options when a new file is opened (done below):

:py vindect.detect(preferred='space')

The following setup performs all the required steps whenever a Python file is opened.

  • Place vindent.py in your .vim (Unix based systems) or vimfiles (Windows) directory.
  • Create an after/ftplugin/python.vim file with the following contents. On Windows systems, change .vim to vimfiles.
if !exists('s:configured_vindect')
  if has('python')
    py import sys,os; sys.path.append(os.path.expanduser('~/.vim/'))
    try
      py import vindect
      let s:configured_vindect = 1
    catch
      let s:configured_vindect = 0
    endtry
    " to set different defaults: py vindect.setDefaults(...)
  else
    let s:configured_vindect = 0
  endif
endif
if s:configured_vindect
  py vindect.detect(preferred='space')
endif

DetectIndent[]

The DetectIndent plugin is another alternative.

Vim script[]

The following script can only choose between two sets of fixed options. One set is used if tabs are detected; otherwise another set is used (for space indents).

You could put the following in your vimrc and use a mapping to call PyIndentAutoCfg() when wanted, or define an auto command to call that function when a Python file is opened.

" Set options if using spaces for indents (default).
function PySpacesCfg()
  set expandtab
  set tabstop=8
  set softtabstop=4
  set shiftwidth=4
endfunction

" Set options if using tabs for indents.
function PyTabsCfg()
  set noexpandtab
  set tabstop=4
  set softtabstop=4
  set shiftwidth=4
endfunction

" Return 1 if using tabs for indents, or 0 otherwise.
function PyIsTabIndent()
  let lnum = 1
  let got_cols = 0  " 1 if previous lines ended with columns
  while lnum <= 100
    let line = getline(lnum)
    let lnum = lnum + 1
    if got_cols == 1
      if line =~ "^\t\t"  " two tabs to prevent false positives
        return 1
      endif
    endif
    if line =~ ":\s*$"
      let got_cols = 1
    else
      let got_cols = 0
    endif
  endwhile
  return 0
endfunction

" Check current buffer and configure for tab or space indents.
function PyIndentAutoCfg()
  if PyIsTabIndent()
    call PyTabsCfg()
  else
    call PySpacesCfg()
  endif
endfunction

Comments[]

Re configuration of vindent: It may be possible to avoid a hard coded path to vindect.py by using :exec with expand('<sfile>') and filenamemodify().


Re the Vim script: The following version of PyIsTabIndent() handles more languages:

function! PyIsTabIndent()
  let lnum = 1
  while lnum <= 100
    let line = getline(lnum)
    let lnum = lnum + 1
    if line =~ '^\t\t\(if\|while\|do\|for\|public\|private\|char\|int\|float\|double\|call\)\>'
      return 1
    endif
  endwhile
  return 0
endfunction