]> git.madduck.net Git - etc/vim.git/commitdiff

madduck's git repository

Every one of the projects in this repository is available at the canonical URL git://git.madduck.net/madduck/pub/<projectpath> — see each project's metadata for the exact URL.

All patches and comments are welcome. Please squash your changes to logical commits before using git-format-patch and git-send-email to patches@git.madduck.net. If you'd read over the Git project's submission guidelines and adhered to them, I'd be especially grateful.

SSH access, as well as push access can be individually arranged.

If you use my repositories frequently, consider adding the following snippet to ~/.gitconfig and using the third clone URL listed for each project:

[url "git://git.madduck.net/madduck/"]
  insteadOf = madduck:

Initial import
authorHynek Schlawack <schlawack@variomedia.de>
Tue, 26 Jun 2012 12:07:20 +0000 (14:07 +0200)
committerHynek Schlawack <schlawack@variomedia.de>
Tue, 26 Jun 2012 12:07:20 +0000 (14:07 +0200)
README.rst [new file with mode: 0644]
python.vim [new file with mode: 0644]

diff --git a/README.rst b/README.rst
new file mode 100644 (file)
index 0000000..ebcf4d4
--- /dev/null
@@ -0,0 +1,37 @@
+vim-python-pep8-indent
+======================
+
+This small script that goes directly into `~/.vim/indent/` modifies vim_’s
+indentation behavior to comply with PEP8_: ::
+
+   foobar(foo,
+          bar)
+
+and ::
+
+   foobar(
+      foo,
+      bar
+   )
+
+It was *not* originally written by me. I have found the script in vim’s `script
+repo`_, however the indentation was off by one character in the first case.
+
+I fixed it with the help of `Steve Losh`_ and am putting it out here so you
+don’t have to patch the original. The original patch is still available here_.
+
+While my Vimscript_ skills are still feeble, I intend to maintain it for now.
+So feel free to report bugs, I’ll try to address them as good as possible if
+they fit into the scope of this project.
+
+Unfortunately, I wasn’t able to reach any of the original authors/maintainers:
+**David Bustos** and **Eric Mc Sween**. I’d like to thank them here for their
+work and release it hereby to the *Public Domain*. If anyone – who has a say in
+this – objects, please let me know.
+
+.. _vim: http://www.vim.org/
+.. _PEP8: http://www.python.org/dev/peps/pep-0008/
+.. _`script repo`: http://www.vim.org/scripts/script.php?script_id=974
+.. _`Steve Losh`: http://stevelosh.com/
+.. _here: https://gist.github.com/2965846
+.. _`Vimscript`: http://learnvimscriptthehardway.stevelosh.com/
diff --git a/python.vim b/python.vim
new file mode 100644 (file)
index 0000000..82f0d7c
--- /dev/null
@@ -0,0 +1,194 @@
+" PEP8 compatible Python indent file
+" Language:         Python
+" Maintainer:       Hynek Schlawack <hs@ox.cx>
+" Prev Maintainer:  Eric Mc Sween <em@tomcom.de> (address invalid)
+" Original Author:  David Bustos <bustos@caltech.edu> (address invalid)
+" Last Change:      2012-06-21
+" License:          Public Domain
+
+" Only load this indent file when no other was loaded.
+if exists("b:did_indent")
+    finish
+endif
+let b:did_indent = 1
+
+setlocal expandtab
+setlocal nolisp
+setlocal autoindent
+setlocal indentexpr=GetPythonIndent(v:lnum)
+setlocal indentkeys=!^F,o,O,<:>,0),0],0},=elif,=except
+
+let s:maxoff = 50
+
+" Find backwards the closest open parenthesis/bracket/brace.
+function! s:SearchParensPair()
+    let line = line('.')
+    let col = col('.')
+
+    " Skip strings and comments and don't look too far
+    let skip = "line('.') < " . (line - s:maxoff) . " ? dummy :" .
+                \ 'synIDattr(synID(line("."), col("."), 0), "name") =~? ' .
+                \ '"string\\|comment"'
+
+    " Search for parentheses
+    call cursor(line, col)
+    let parlnum = searchpair('(', '', ')', 'bW', skip)
+    let parcol = col('.')
+
+    " Search for brackets
+    call cursor(line, col)
+    let par2lnum = searchpair('\[', '', '\]', 'bW', skip)
+    let par2col = col('.')
+
+    " Search for braces
+    call cursor(line, col)
+    let par3lnum = searchpair('{', '', '}', 'bW', skip)
+    let par3col = col('.')
+
+    " Get the closest match
+    if par2lnum > parlnum || (par2lnum == parlnum && par2col > parcol)
+        let parlnum = par2lnum
+        let parcol = par2col
+    endif
+    if par3lnum > parlnum || (par3lnum == parlnum && par3col > parcol)
+        let parlnum = par3lnum
+        let parcol = par3col
+    endif
+
+    " Put the cursor on the match
+    if parlnum > 0
+        call cursor(parlnum, parcol)
+    endif
+    return parlnum
+endfunction
+
+" Find the start of a multi-line statement
+function! s:StatementStart(lnum)
+    let lnum = a:lnum
+    while 1
+        if getline(lnum - 1) =~ '\\$'
+            let lnum = lnum - 1
+        else
+            call cursor(lnum, 1)
+            let maybe_lnum = s:SearchParensPair()
+            if maybe_lnum < 1
+                return lnum
+            else
+                let lnum = maybe_lnum
+            endif
+        endif
+    endwhile
+endfunction
+
+" Find the block starter that matches the current line
+function! s:BlockStarter(lnum, block_start_re)
+    let lnum = a:lnum
+    let maxindent = 10000       " whatever
+    while lnum > 1
+        let lnum = prevnonblank(lnum - 1)
+        if indent(lnum) < maxindent
+            if getline(lnum) =~ a:block_start_re
+                return lnum
+            else
+                let maxindent = indent(lnum)
+                " It's not worth going further if we reached the top level
+                if maxindent == 0
+                    return -1
+                endif
+            endif
+        endif
+    endwhile
+    return -1
+endfunction
+
+function! GetPythonIndent(lnum)
+
+    " First line has indent 0
+    if a:lnum == 1
+        return 0
+    endif
+
+    " If we can find an open parenthesis/bracket/brace, line up with it.
+    call cursor(a:lnum, 1)
+    let parlnum = s:SearchParensPair()
+    if parlnum > 0
+        let parcol = col('.')
+        let closing_paren = match(getline(a:lnum), '^\s*[])}]') != -1
+        if match(getline(parlnum), '[([{]\s*$', parcol - 1) != -1
+            if closing_paren
+                return indent(parlnum)
+            else
+                return indent(parlnum) + &shiftwidth
+            endif
+        else
+            return parcol
+        endif
+    endif
+
+    " Examine this line
+    let thisline = getline(a:lnum)
+    let thisindent = indent(a:lnum)
+
+    " If the line starts with 'elif' or 'else', line up with 'if' or 'elif'
+    if thisline =~ '^\s*\(elif\|else\)\>'
+        let bslnum = s:BlockStarter(a:lnum, '^\s*\(if\|elif\)\>')
+        if bslnum > 0
+            return indent(bslnum)
+        else
+            return -1
+        endif
+    endif
+
+    " If the line starts with 'except' or 'finally', line up with 'try'
+    " or 'except'
+    if thisline =~ '^\s*\(except\|finally\)\>'
+        let bslnum = s:BlockStarter(a:lnum, '^\s*\(try\|except\)\>')
+        if bslnum > 0
+            return indent(bslnum)
+        else
+            return -1
+        endif
+    endif
+
+    " Examine previous line
+    let plnum = a:lnum - 1
+    let pline = getline(plnum)
+    let sslnum = s:StatementStart(plnum)
+
+    " If the previous line is blank, keep the same indentation
+    if pline =~ '^\s*$'
+        return -1
+    endif
+
+    " If this line is explicitly joined, try to find an indentation that looks
+    " good.
+    if pline =~ '\\$'
+        let compound_statement = '^\s*\(if\|while\|for\s.*\sin\|except\)\s*'
+        let maybe_indent = matchend(getline(sslnum), compound_statement)
+        if maybe_indent != -1
+            return maybe_indent
+        else
+            return indent(sslnum) + &sw * 2
+        endif
+    endif
+
+    " If the previous line ended with a colon, indent relative to
+    " statement start.
+    if pline =~ ':\s*$'
+        return indent(sslnum) + &sw
+    endif
+
+    " If the previous line was a stop-execution statement or a pass
+    if getline(sslnum) =~ '^\s*\(break\|continue\|raise\|return\|pass\)\>'
+        " See if the user has already dedented
+        if indent(a:lnum) > indent(sslnum) - &sw
+            " If not, recommend one dedent
+            return indent(sslnum) - &sw
+        endif
+        " Otherwise, trust the user
+        return -1
+    endif
+
+    " In all other cases, line up with the start of the previous statement.
+    return indent(sslnum)
+endfunction