From b6cde05f9e4751e14c5634afb1b39e541749d877 Mon Sep 17 00:00:00 2001 From: Ayed Date: Mon, 21 Oct 2013 13:57:08 +0300 Subject: [PATCH 1/6] Added folding syntax --- autoload/folding.vim | 76 ++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 76 insertions(+) create mode 100644 autoload/folding.vim diff --git a/autoload/folding.vim b/autoload/folding.vim new file mode 100644 index 0000000..99e45e6 --- /dev/null +++ b/autoload/folding.vim @@ -0,0 +1,76 @@ +" Python-mode folding functions + + +let s:blank_regex = '^\s*$' +let s:def_regex = '^\s*\%(class\|def\) \w\+' +let s:decorator_regex = '^\s*@' +let s:doc_begin_regex = '^\s*\%("""\|''''''\)' +let s:doc_end_regex = '\%("""\|''''''\)\s*$' +let s:doc_line_regex = '^\s*\("""\|''''''\).\+\1\s*$' + + +fun! folding#text() " {{{ + let fs = v:foldstart + while getline(fs) =~ '\%(^\s*@\)\|\%(^\s*\%("""\|''''''\)\s*$\)' + let fs = nextnonblank(fs + 1) + endwhile + let line = getline(fs) + + let nucolwidth = &fdc + &number * &numberwidth + let windowwidth = winwidth(0) - nucolwidth - 3 + let foldedlinecount = v:foldend - v:foldstart + + " expand tabs into spaces + let onetab = strpart(' ', 0, &tabstop) + let line = substitute(line, '\t', onetab, 'g') + + let line = strpart(line, 0, windowwidth - 2 -len(foldedlinecount)) + let line = substitute(line, '\%("""\|''''''\)', '', '') + let fillcharcount = windowwidth - len(line) - len(foldedlinecount) + return line . '…' . repeat(" ",fillcharcount) . foldedlinecount . '…' . ' ' +endfunction "}}} + + +fun! folding#expr(lnum) "{{{ + + let line = getline(a:lnum) + let indent = indent(a:lnum) + let prev_line = getline(a:lnum - 1) + + if line =~ s:def_regex || line =~ s:decorator_regex + if prev_line =~ s:decorator_regex + return '=' + else + return ">".(indent / &shiftwidth + 1) + endif + endif + + if line =~ s:doc_begin_regex + \ && line !~ s:doc_line_regex + \ && prev_line =~ s:def_regex + return ">".(indent / &shiftwidth + 1) + endif + + if line =~ s:doc_end_regex + \ && line !~ s:doc_line_regex + return "<".(indent / &shiftwidth + 1) + endif + + if line =~ s:blank_regex + if prev_line =~ s:blank_regex + return -1 + else + return '=' + endif + endif + + if indent == 0 + return 0 + endif + + return '=' + +endfunction "}}} + + +" vim: fdm=marker:fdl=0 From 84bcf99a8af8e5ae47b305702b78763c44affdd5 Mon Sep 17 00:00:00 2001 From: Ayed Date: Mon, 21 Oct 2013 14:10:19 +0300 Subject: [PATCH 2/6] Added folding and python based folding to the package --- after/indent/python.vim | 7 ++ autoload/indent.vim | 184 ++++++++++++++++++++++++++++++++++++++++ 2 files changed, 191 insertions(+) create mode 100644 after/indent/python.vim create mode 100644 autoload/indent.vim diff --git a/after/indent/python.vim b/after/indent/python.vim new file mode 100644 index 0000000..d36e6fe --- /dev/null +++ b/after/indent/python.vim @@ -0,0 +1,7 @@ +setlocal nolisp +setlocal shiftround +setlocal indentexpr=indent#Indent(v:lnum) +setlocal indentkeys=!^F,o,O,<:>,0),0],0},=elif,=except +setlocal foldmethod=expr +setlocal foldexpr=folding#expr(v:lnum) +setlocal foldtext=folding#text() diff --git a/autoload/indent.vim b/autoload/indent.vim new file mode 100644 index 0000000..97a7d73 --- /dev/null +++ b/autoload/indent.vim @@ -0,0 +1,184 @@ +" PEP8 compatible Python indent file +" Language: Python +" Maintainer: Hynek Schlawack +" Prev Maintainer: Eric Mc Sween (address invalid) +" Original Author: David Bustos (address invalid) +" Last Change: 2012-06-21 +" License: Public Domainlet + + +function! indent#Indent(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 and is not a comment, indent + " relative to statement start. + if pline =~ ':\s*$' && 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 + + +" 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 - 50) . " ? 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 From eb088ba0e861792d2eba60ea4a2b21f0c8007460 Mon Sep 17 00:00:00 2001 From: Ayed Date: Mon, 21 Oct 2013 14:16:45 +0300 Subject: [PATCH 3/6] Revert "Add new option 'python_highlight_file_headers_as_comments'" This reverts commit 69f8e12a46237f556e6b2a1bd2d2172eec4b6b0d. --- CHANGES.txt | 3 --- README.rst | 2 -- syntax/python.vim | 15 ++++----------- 3 files changed, 4 insertions(+), 16 deletions(-) diff --git a/CHANGES.txt b/CHANGES.txt index ca6ab78..79d87f2 100644 --- a/CHANGES.txt +++ b/CHANGES.txt @@ -2,9 +2,6 @@ Revision 3.3.5 (2013-08-31): - Highlight 'import', 'from' and 'as' as include statements. Patch by pydave at GitHub. - - Added new option 'python_highlight_file_headers_as_comments' (disabled by - default) to highlight shebang and coding file headers as comments. - Proposed by pydave at GitHub. Revision 3.3.4 (2013-08-11): diff --git a/README.rst b/README.rst index f7d20f4..7dca0c2 100644 --- a/README.rst +++ b/README.rst @@ -117,8 +117,6 @@ Options used by the script Highlight doc-tests ``python_print_as_function`` Highlight ``print`` statement as function for Python 2 -``python_highlight_file_headers_as_comments`` - Highlight shebang and coding headers as comments ``python_highlight_all`` Enable all the options above. *NOTE: This option don't override any previously set options* diff --git a/syntax/python.vim b/syntax/python.vim index e2eaa90..ec9bc2f 100644 --- a/syntax/python.vim +++ b/syntax/python.vim @@ -73,9 +73,6 @@ " python_highlight_doctests Highlight doc-tests " python_print_as_function Highlight 'print' statement as " function for Python 2 -" python_highlight_file_headers_as_comments -" Highlight shebang and coding -" headers as comments " " python_highlight_all Enable all the options above " NOTE: This option don't override @@ -182,10 +179,8 @@ syn match pythonDot "\." display containedin=pythonDottedName " syn match pythonComment "#.*$" display contains=pythonTodo,@Spell -if !s:Enabled("g:python_highlight_file_headers_as_comments") - syn match pythonRun "\%^#!.*$" - syn match pythonCoding "\%^.*\%(\n.*\)\?#.*coding[:=]\s*[0-9A-Za-z-_.]\+.*$" -endif +syn match pythonRun "\%^#!.*$" +syn match pythonCoding "\%^.*\%(\n.*\)\?#.*coding[:=]\s*[0-9A-Za-z-_.]\+.*$" syn keyword pythonTodo TODO FIXME XXX contained " @@ -487,10 +482,8 @@ if version >= 508 || !exists("did_python_syn_inits") HiLink pythonDot Normal HiLink pythonComment Comment - if !s:Enabled("g:python_highlight_file_headers_as_comments") - HiLink pythonCoding Special - HiLink pythonRun Special - endif + HiLink pythonCoding Special + HiLink pythonRun Special HiLink pythonTodo Todo HiLink pythonError Error From f87097623b8b6162192013e7edfa6dfe49f6919c Mon Sep 17 00:00:00 2001 From: Ayed Date: Mon, 21 Oct 2013 15:24:28 +0300 Subject: [PATCH 4/6] Modify readme --- README.rst | 140 +---------------------------------------------------- 1 file changed, 1 insertion(+), 139 deletions(-) diff --git a/README.rst b/README.rst index 7dca0c2..1133347 100644 --- a/README.rst +++ b/README.rst @@ -1,140 +1,2 @@ -Python syntax highlighting script for Vim -========================================= +Bringing , **fold** and **indentation** from `python-mode `_ plugin to this plugin. -.. contents:: - -About ------ - -Enhanced version of the original Python syntax highlighting script. Based on -``python.vim`` from Vim 6.1 distribution by Neil Schemenauer (nas at python dot -ca). Check also `python.vim page on vim.org -`_. - -Please use the following channels for reporting bugs, offering suggestions or -feedback: - -- python.vim issue tracker: https://github.com/hdima/python-syntax/issues -- Email: Dmitry Vasiliev (dima at hlabs.org) -- Send a message or follow me for updates on Twitter: `@hdima - `__ - -Features --------- - -Changes from the original ``python.vim`` are: - -- Added support for Python 3 syntax highlighting -- Added ``:Python2Syntax`` and ``:Python3Syntax`` commands which allow to - switch between Python 2 and Python 3 syntaxes respectively without - reloads/restarts -- Updated strings highlighting -- Enhanced special symbols highlighting inside strings -- Enhanced highlighting of numeric constants -- Added optional highlighting for %-formatting inside strings -- Added highlighting for magic comments: source code encoding and #! - (executable) strings -- Added highlighting for new exceptions and builtins -- Added highlighting for doctests -- Added highlighting for new ``@decorator`` syntax introduced in Python 2.4a2 -- Added highlighting for the following errors: - - - invalid symbols in source file - - mixing spaces and tabs - - invalid numeric constants - - invalid %-formatting inside strings - - invalid variable names - - trailing spaces (triggered by the ``python_highlight_space_errors`` option) - -Some of these features was later backported into the original ``python.vim``. - -How to install --------------- - -The easiest installation method is to place `syntax/python.vim -`_ script -into your ``~/.vim/syntax/`` directory. - -You can also use `Pathogen `_ or `Vundle -`_ plugin managers in which case you can -install the whole `python.vim repository -`_ into the corresponding plugins -directory. - -Script options --------------- - -There are two commands to enable or disable an option: - -``:let OPTION_NAME = 1`` - Enable option -``:let OPTION_NAME = 0`` - Disable option - -For example to enable all syntax highlighting features you can place the -following command in your ``~/.vimrc`` script:: - - let python_highlight_all = 1 - -Option and commands to select Python version -~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ - -``python_version_2`` - Enable highlighting for Python 2 (Python 3 highlighting is enabled by - default). Can also be set as a local to buffer ``b:python_version_2`` - variable. - -The following local to buffer commands can be used to switch between two -highlighting modes: - -``:Python2Syntax`` - Switch to Python 2 highlighting mode -``:Python3Syntax`` - Switch to Python 3 highlighting mode - -Options used by the script -~~~~~~~~~~~~~~~~~~~~~~~~~~ - -``python_highlight_builtins`` - Highlight builtin functions and objects -``python_highlight_builtin_objs`` - Highlight builtin objects only -``python_highlight_builtin_funcs`` - Highlight builtin functions only -``python_highlight_exceptions`` - Highlight standard exceptions -``python_highlight_string_formatting`` - Highlight ``%`` string formatting -``python_highlight_string_format`` - Highlight syntax of ``str.format`` syntax -``python_highlight_string_templates`` - Highlight syntax of ``string.Template`` -``python_highlight_indent_errors`` - Highlight indentation errors -``python_highlight_space_errors`` - Highlight trailing spaces -``python_highlight_doctests`` - Highlight doc-tests -``python_print_as_function`` - Highlight ``print`` statement as function for Python 2 -``python_highlight_all`` - Enable all the options above. *NOTE: This option don't override any - previously set options* -``python_slow_sync`` - Can be set to 0 for slow machines - -Contributors ------------- - -List of the contributors in alphabetical order: - -- Andrea Riciputi -- Anton Butanaev -- Caleb Adamantine -- Jeroen Ruigrok van der Werven -- John Eikenberry -- Marc Weber -- Pedro Algarvio -- pydave at GitHub -- Will Gray -- Yuri Habrusiev From 95aae8c0229b5f80bb1c2129b12cac8b08dc184d Mon Sep 17 00:00:00 2001 From: Ayed Date: Mon, 21 Oct 2013 22:06:58 +0300 Subject: [PATCH 5/6] map r to exec python code --- after/indent/python.vim | 1 + 1 file changed, 1 insertion(+) diff --git a/after/indent/python.vim b/after/indent/python.vim index d36e6fe..c1ff445 100644 --- a/after/indent/python.vim +++ b/after/indent/python.vim @@ -5,3 +5,4 @@ setlocal indentkeys=!^F,o,O,<:>,0),0],0},=elif,=except setlocal foldmethod=expr setlocal foldexpr=folding#expr(v:lnum) setlocal foldtext=folding#text() +map r :w:!python % From 24c85dbbd71f8b083ab03ab92d3f2907e73be3e7 Mon Sep 17 00:00:00 2001 From: Griffin Smith Date: Sat, 30 Nov 2013 18:50:36 -0700 Subject: [PATCH 6/6] Add highlight groups for def and class block The method definition and class block are now highlight groups, which means we can highlight the name of classes and functions differently. Classes now HiLink to Type --- syntax/python.vim | 24 +++++++++++++++++++++--- 1 file changed, 21 insertions(+), 3 deletions(-) diff --git a/syntax/python.vim b/syntax/python.vim index e4e9ac6..29fb9a0 100644 --- a/syntax/python.vim +++ b/syntax/python.vim @@ -148,12 +148,13 @@ syn keyword pythonStatement pass raise syn keyword pythonStatement global assert syn keyword pythonStatement lambda syn keyword pythonStatement with -syn keyword pythonStatement def class nextgroup=pythonFunction skipwhite +"syn keyword pythonStatement def class nextgroup=pythonFunction skipwhite syn keyword pythonRepeat for while syn keyword pythonConditional if elif else syn keyword pythonImport import syn keyword pythonException try except finally syn keyword pythonOperator and in is not or +syn keyword pythonSelf self syn match pythonStatement "\" display syn match pythonImport "\" display @@ -171,6 +172,18 @@ else syn match pythonFunction "\%([^[:cntrl:][:space:][:punct:][:digit:]]\|_\)\%([^[:cntrl:][:punct:][:space:]]\|_\)*" display contained endif +" +" Class and method definitions +" +syn region pythonFuncDef start='^\s\{-}def ' end=':' contains=pythonDef,pythonFuncName,pythonSelf +syn keyword pythonDef def contained skipwhite +syn match pythonFuncName "\<[a-zA-Z_][a-zA-Z0-9_]\{-}\>\%((\)\@=" contained + +syn region pythonClassDef start='^\s\{-}class ' end=':' contains=pythonClass,pythonClassName +syn keyword pythonClass class contained skipwhite +syn match pythonClassName "\<[a-zA-Z_][a-zA-Z0-9_]\{-}\>\%((\)\@=" contained + "syn region pythonString start=+[bB]\='+ skip=+\\\\\|\\'\|\\$+ excludenl end=+'+ end=+$+ keepend contains=pythonBytesEscape,pythonBytesEscapeError,pythonUniEscape,pythonUniEscapeError,@Spell + " " Decorators (new in Python 2.4) " @@ -469,9 +482,9 @@ endif if version >= 508 || !exists("did_python_syn_inits") if version <= 508 let did_python_syn_inits = 1 - command -nargs=+ HiLink hi link + command! -nargs=+ HiLink hi link else - command -nargs=+ HiLink hi def link + command! -nargs=+ HiLink hi def link endif HiLink pythonStatement Statement @@ -481,6 +494,11 @@ if version >= 508 || !exists("did_python_syn_inits") HiLink pythonRepeat Repeat HiLink pythonException Exception HiLink pythonOperator Operator + HiLink pythonSelf Type + HiLink pythonDef RubyDefine + HiLink pythonFuncName Function + HiLink pythonClass Statement + HiLink pythonClassName Type HiLink pythonDecorator Define HiLink pythonDottedName Function