Mercurial > dotfiles
comparison .vim/indent/python.vim @ 0:c30d68fbd368
Initial import from svn.
| author | Augie Fackler <durin42@gmail.com> |
|---|---|
| date | Wed, 26 Nov 2008 10:56:09 -0600 |
| parents | |
| children |
comparison
equal
deleted
inserted
replaced
| -1:000000000000 | 0:c30d68fbd368 |
|---|---|
| 1 " Python indent file | |
| 2 " Language: Python | |
| 3 " Maintainer: Eric Mc Sween <em@tomcom.de> | |
| 4 " Original Author: David Bustos <bustos@caltech.edu> | |
| 5 " Last Change: 2004 Jun 07 | |
| 6 | |
| 7 " Only load this indent file when no other was loaded. | |
| 8 if exists("b:did_indent") | |
| 9 finish | |
| 10 endif | |
| 11 let b:did_indent = 1 | |
| 12 | |
| 13 setlocal expandtab | |
| 14 setlocal nolisp | |
| 15 setlocal autoindent | |
| 16 setlocal indentexpr=GetPythonIndent(v:lnum) | |
| 17 setlocal indentkeys=!^F,o,O,<:>,0),0],0},=elif,=except,0# | |
| 18 | |
| 19 | |
| 20 let s:maxoff = 50 | |
| 21 | |
| 22 " Find backwards the closest open parenthesis/bracket/brace. | |
| 23 function! s:SearchParensPair() | |
| 24 let line = line('.') | |
| 25 let col = col('.') | |
| 26 | |
| 27 " Skip strings and comments and don't look too far | |
| 28 let skip = "line('.') < " . (line - s:maxoff) . " ? dummy :" . | |
| 29 \ 'synIDattr(synID(line("."), col("."), 0), "name") =~? ' . | |
| 30 \ '"string\\|comment"' | |
| 31 | |
| 32 " Search for parentheses | |
| 33 call cursor(line, col) | |
| 34 let parlnum = searchpair('(', '', ')', 'bW', skip) | |
| 35 let parcol = col('.') | |
| 36 | |
| 37 " Search for brackets | |
| 38 call cursor(line, col) | |
| 39 let par2lnum = searchpair('\[', '', '\]', 'bW', skip) | |
| 40 let par2col = col('.') | |
| 41 | |
| 42 " Search for braces | |
| 43 call cursor(line, col) | |
| 44 let par3lnum = searchpair('{', '', '}', 'bW', skip) | |
| 45 let par3col = col('.') | |
| 46 | |
| 47 " Get the closest match | |
| 48 if par2lnum > parlnum || (par2lnum == parlnum && par2col > parcol) | |
| 49 let parlnum = par2lnum | |
| 50 let parcol = par2col | |
| 51 endif | |
| 52 if par3lnum > parlnum || (par3lnum == parlnum && par3col > parcol) | |
| 53 let parlnum = par3lnum | |
| 54 let parcol = par3col | |
| 55 endif | |
| 56 | |
| 57 " Put the cursor on the match | |
| 58 if parlnum > 0 | |
| 59 call cursor(parlnum, parcol) | |
| 60 endif | |
| 61 return parlnum | |
| 62 endfunction | |
| 63 | |
| 64 " Find the start of a multi-line statement | |
| 65 function! s:StatementStart(lnum) | |
| 66 let lnum = a:lnum | |
| 67 while 1 | |
| 68 if getline(lnum - 1) =~ '\\$' | |
| 69 let lnum = lnum - 1 | |
| 70 else | |
| 71 call cursor(lnum, 1) | |
| 72 let maybe_lnum = s:SearchParensPair() | |
| 73 if maybe_lnum < 1 | |
| 74 return lnum | |
| 75 else | |
| 76 let lnum = maybe_lnum | |
| 77 endif | |
| 78 endif | |
| 79 endwhile | |
| 80 endfunction | |
| 81 | |
| 82 " Find the block starter that matches the current line | |
| 83 function! s:BlockStarter(lnum, block_start_re) | |
| 84 let lnum = a:lnum | |
| 85 let maxindent = 10000 " whatever | |
| 86 while lnum > 1 | |
| 87 let lnum = prevnonblank(lnum - 1) | |
| 88 if indent(lnum) < maxindent | |
| 89 if getline(lnum) =~ a:block_start_re | |
| 90 return lnum | |
| 91 else | |
| 92 let maxindent = indent(lnum) | |
| 93 " It's not worth going further if we reached the top level | |
| 94 if maxindent == 0 | |
| 95 return -1 | |
| 96 endif | |
| 97 endif | |
| 98 endif | |
| 99 endwhile | |
| 100 return -1 | |
| 101 endfunction | |
| 102 | |
| 103 function! GetPythonIndent(lnum) | |
| 104 | |
| 105 " First line has indent 0 | |
| 106 if a:lnum == 1 | |
| 107 return 0 | |
| 108 endif | |
| 109 | |
| 110 " If we can find an open parenthesis/bracket/brace, line up with it. | |
| 111 call cursor(a:lnum, 1) | |
| 112 let parlnum = s:SearchParensPair() | |
| 113 if parlnum > 0 | |
| 114 let parcol = col('.') | |
| 115 let closing_paren = match(getline(a:lnum), '^\s*[])}]') != -1 | |
| 116 if match(getline(parlnum), '[([{]\s*$', parcol - 1) != -1 | |
| 117 if closing_paren | |
| 118 return indent(parlnum) | |
| 119 else | |
| 120 return indent(parlnum) + &shiftwidth | |
| 121 endif | |
| 122 else | |
| 123 if closing_paren | |
| 124 return parcol - 1 | |
| 125 else | |
| 126 return parcol | |
| 127 endif | |
| 128 endif | |
| 129 endif | |
| 130 | |
| 131 " Examine this line | |
| 132 let thisline = getline(a:lnum) | |
| 133 let thisindent = indent(a:lnum) | |
| 134 | |
| 135 " If the line starts with 'elif' or 'else', line up with 'if' or 'elif' | |
| 136 if thisline =~ '^\s*\(elif\|else\)\>' | |
| 137 let bslnum = s:BlockStarter(a:lnum, '^\s*\(if\|elif\)\>') | |
| 138 if bslnum > 0 | |
| 139 return indent(bslnum) | |
| 140 else | |
| 141 return -1 | |
| 142 endif | |
| 143 endif | |
| 144 | |
| 145 " If the line starts with 'except' or 'finally', line up with 'try' | |
| 146 " or 'except' | |
| 147 if thisline =~ '^\s*\(except\|finally\)\>' | |
| 148 let bslnum = s:BlockStarter(a:lnum, '^\s*\(try\|except\)\>') | |
| 149 if bslnum > 0 | |
| 150 return indent(bslnum) | |
| 151 else | |
| 152 return -1 | |
| 153 endif | |
| 154 endif | |
| 155 | |
| 156 " Examine previous line | |
| 157 let plnum = a:lnum - 1 | |
| 158 let pline = getline(plnum) | |
| 159 let sslnum = s:StatementStart(plnum) | |
| 160 | |
| 161 " If the previous line is blank, keep the same indentation | |
| 162 if pline =~ '^\s*$' | |
| 163 return -1 | |
| 164 endif | |
| 165 | |
| 166 " If this line is explicitly joined, try to find an indentation that looks | |
| 167 " good. | |
| 168 if pline =~ '\\$' | |
| 169 let compound_statement = '^\s*\(if\|while\|for\s.*\sin\|except\)\s*' | |
| 170 let maybe_indent = matchend(getline(sslnum), compound_statement) | |
| 171 if maybe_indent != -1 | |
| 172 return maybe_indent | |
| 173 else | |
| 174 return indent(sslnum) + &sw * 2 | |
| 175 endif | |
| 176 endif | |
| 177 | |
| 178 " If the previous line ended with a colon, indent relative to | |
| 179 " statement start. | |
| 180 if pline =~ ':\s*$' | |
| 181 return indent(sslnum) + &sw | |
| 182 endif | |
| 183 | |
| 184 " If the previous line was a stop-execution statement or a pass | |
| 185 if getline(sslnum) =~ '^\s*\(break\|continue\|raise\|return\|pass\)\>' | |
| 186 " See if the user has already dedented | |
| 187 if indent(a:lnum) > indent(sslnum) - &sw | |
| 188 " If not, recommend one dedent | |
| 189 return indent(sslnum) - &sw | |
| 190 endif | |
| 191 " Otherwise, trust the user | |
| 192 return -1 | |
| 193 endif | |
| 194 | |
| 195 " In all other cases, line up with the start of the previous statement. | |
| 196 return indent(sslnum) | |
| 197 endfunction |
