From: martin f. krafft Date: Thu, 14 Oct 2021 02:01:27 +0000 (+1300) Subject: Add '.vim/bundle/vim-python-pep8-indent/' from commit '60ba5e11a61618c0344e2db1902101... X-Git-Url: https://git.madduck.net/etc/vim.git/commitdiff_plain/3f68af9813542a5e277b7a51b316644241c372d7?hp=-c Add '.vim/bundle/vim-python-pep8-indent/' from commit '60ba5e11a61618c0344e2db190210145083c91f8' git-subtree-dir: .vim/bundle/vim-python-pep8-indent git-subtree-mainline: 2de20d9c659d6350a6408dc1ec4aa6e0b1dea6ac git-subtree-split: 60ba5e11a61618c0344e2db190210145083c91f8 --- 3f68af9813542a5e277b7a51b316644241c372d7 diff --combined .vim/bundle/vim-python-pep8-indent/.circleci/config.yml index 0000000,8d54439..8d54439 mode 000000,100644..100644 --- a/.vim/bundle/vim-python-pep8-indent/.circleci/config.yml +++ b/.vim/bundle/vim-python-pep8-indent/.circleci/config.yml @@@ -1,0 -1,37 +1,37 @@@ + version: 2 + + common: &common + working_directory: ~/repo + docker: + - image: blueyed/vim-python-pep8-indent-vims-for-test:3@sha256:e7e3c4f4b021954a40f2f1d88dc470f119dc65603c63724d1c58cbe437fdc2d4 + + jobs: + test: + <<: *common + steps: + - checkout + - run: + name: Run tests + command: | + spec/make-coverage + - run: + name: Report coverage + command: | + covimerage xml + codecov -X search gcov pycov -f coverage.xml + + checkqa: + <<: *common + steps: + - checkout + - run: + name: Lint + command: | + vint **/*.vim + + workflows: + version: 2 + test: + jobs: + - test + - checkqa diff --combined .vim/bundle/vim-python-pep8-indent/.coveragerc index 0000000,74cc24e..74cc24e mode 000000,100644..100644 --- a/.vim/bundle/vim-python-pep8-indent/.coveragerc +++ b/.vim/bundle/vim-python-pep8-indent/.coveragerc @@@ -1,0 -1,7 +1,7 @@@ + [run] + plugins = covimerage + data_file = .coverage_covimerage + source = indent/python.vim + + [report] + include = indent/python.vim diff --combined .vim/bundle/vim-python-pep8-indent/.dockerignore index 0000000,1a99a79..1a99a79 mode 000000,100644..100644 --- a/.vim/bundle/vim-python-pep8-indent/.dockerignore +++ b/.vim/bundle/vim-python-pep8-indent/.dockerignore @@@ -1,0 -1,2 +1,2 @@@ + * + !Gemfile diff --combined .vim/bundle/vim-python-pep8-indent/.gitignore index 0000000,e8035f6..e8035f6 mode 000000,100644..100644 --- a/.vim/bundle/vim-python-pep8-indent/.gitignore +++ b/.vim/bundle/vim-python-pep8-indent/.gitignore @@@ -1,0 -1,3 +1,3 @@@ + .*.swp + .coverage_covimerage + Gemfile.lock diff --combined .vim/bundle/vim-python-pep8-indent/CONTRIBUTING.rst index 0000000,094f20a..094f20a mode 000000,100644..100644 --- a/.vim/bundle/vim-python-pep8-indent/CONTRIBUTING.rst +++ b/.vim/bundle/vim-python-pep8-indent/CONTRIBUTING.rst @@@ -1,0 -1,37 +1,37 @@@ + How To Contribute + ================= + + ``vim-python-pep8-indent`` is always open for suggestions and contributions by generous developers. + I’ve collected a few tips to get you started. + + Please: + + - *Always* add tests for your code. + - Write `good commit messages`_. + + + Running Tests + ------------- + + - They are written in Ruby_ (sorry :() using vimrunner_ which requires rspec_. + - The tests go into ``spec/indent/indent_spec.rb``. + Look at the ``describe`` blocks to get the hang of it. + - Run the tests with the command:: + + $ rspec spec + - Alternatively you can use Docker:: + + $ make test_docker + + - You can select tests based on line numbers, e.g.:: + + $ rspec ./spec/indent/indent_spec.rb:385 + $ make test_docker RSPEC_ARGS=./spec/indent/indent_spec.rb:385 + + Thank you for considering to contribute! + + + .. _Ruby: https://www.ruby-lang.org/ + .. _`good commit messages`: http://tbaggery.com/2008/04/19/a-note-about-git-commit-messages.html + .. _vimrunner: https://github.com/AndrewRadev/vimrunner + .. _rspec: https://github.com/rspec/rspec diff --combined .vim/bundle/vim-python-pep8-indent/COPYING.txt index 0000000,0e259d4..0e259d4 mode 000000,100644..100644 --- a/.vim/bundle/vim-python-pep8-indent/COPYING.txt +++ b/.vim/bundle/vim-python-pep8-indent/COPYING.txt @@@ -1,0 -1,121 +1,121 @@@ + Creative Commons Legal Code + + CC0 1.0 Universal + + CREATIVE COMMONS CORPORATION IS NOT A LAW FIRM AND DOES NOT PROVIDE + LEGAL SERVICES. DISTRIBUTION OF THIS DOCUMENT DOES NOT CREATE AN + ATTORNEY-CLIENT RELATIONSHIP. CREATIVE COMMONS PROVIDES THIS + INFORMATION ON AN "AS-IS" BASIS. CREATIVE COMMONS MAKES NO WARRANTIES + REGARDING THE USE OF THIS DOCUMENT OR THE INFORMATION OR WORKS + PROVIDED HEREUNDER, AND DISCLAIMS LIABILITY FOR DAMAGES RESULTING FROM + THE USE OF THIS DOCUMENT OR THE INFORMATION OR WORKS PROVIDED + HEREUNDER. + + Statement of Purpose + + The laws of most jurisdictions throughout the world automatically confer + exclusive Copyright and Related Rights (defined below) upon the creator + and subsequent owner(s) (each and all, an "owner") of an original work of + authorship and/or a database (each, a "Work"). + + Certain owners wish to permanently relinquish those rights to a Work for + the purpose of contributing to a commons of creative, cultural and + scientific works ("Commons") that the public can reliably and without fear + of later claims of infringement build upon, modify, incorporate in other + works, reuse and redistribute as freely as possible in any form whatsoever + and for any purposes, including without limitation commercial purposes. + These owners may contribute to the Commons to promote the ideal of a free + culture and the further production of creative, cultural and scientific + works, or to gain reputation or greater distribution for their Work in + part through the use and efforts of others. + + For these and/or other purposes and motivations, and without any + expectation of additional consideration or compensation, the person + associating CC0 with a Work (the "Affirmer"), to the extent that he or she + is an owner of Copyright and Related Rights in the Work, voluntarily + elects to apply CC0 to the Work and publicly distribute the Work under its + terms, with knowledge of his or her Copyright and Related Rights in the + Work and the meaning and intended legal effect of CC0 on those rights. + + 1. Copyright and Related Rights. A Work made available under CC0 may be + protected by copyright and related or neighboring rights ("Copyright and + Related Rights"). Copyright and Related Rights include, but are not + limited to, the following: + + i. the right to reproduce, adapt, distribute, perform, display, + communicate, and translate a Work; + ii. moral rights retained by the original author(s) and/or performer(s); + iii. publicity and privacy rights pertaining to a person's image or + likeness depicted in a Work; + iv. rights protecting against unfair competition in regards to a Work, + subject to the limitations in paragraph 4(a), below; + v. rights protecting the extraction, dissemination, use and reuse of data + in a Work; + vi. database rights (such as those arising under Directive 96/9/EC of the + European Parliament and of the Council of 11 March 1996 on the legal + protection of databases, and under any national implementation + thereof, including any amended or successor version of such + directive); and + vii. other similar, equivalent or corresponding rights throughout the + world based on applicable law or treaty, and any national + implementations thereof. + + 2. Waiver. To the greatest extent permitted by, but not in contravention + of, applicable law, Affirmer hereby overtly, fully, permanently, + irrevocably and unconditionally waives, abandons, and surrenders all of + Affirmer's Copyright and Related Rights and associated claims and causes + of action, whether now known or unknown (including existing as well as + future claims and causes of action), in the Work (i) in all territories + worldwide, (ii) for the maximum duration provided by applicable law or + treaty (including future time extensions), (iii) in any current or future + medium and for any number of copies, and (iv) for any purpose whatsoever, + including without limitation commercial, advertising or promotional + purposes (the "Waiver"). Affirmer makes the Waiver for the benefit of each + member of the public at large and to the detriment of Affirmer's heirs and + successors, fully intending that such Waiver shall not be subject to + revocation, rescission, cancellation, termination, or any other legal or + equitable action to disrupt the quiet enjoyment of the Work by the public + as contemplated by Affirmer's express Statement of Purpose. + + 3. Public License Fallback. Should any part of the Waiver for any reason + be judged legally invalid or ineffective under applicable law, then the + Waiver shall be preserved to the maximum extent permitted taking into + account Affirmer's express Statement of Purpose. In addition, to the + extent the Waiver is so judged Affirmer hereby grants to each affected + person a royalty-free, non transferable, non sublicensable, non exclusive, + irrevocable and unconditional license to exercise Affirmer's Copyright and + Related Rights in the Work (i) in all territories worldwide, (ii) for the + maximum duration provided by applicable law or treaty (including future + time extensions), (iii) in any current or future medium and for any number + of copies, and (iv) for any purpose whatsoever, including without + limitation commercial, advertising or promotional purposes (the + "License"). The License shall be deemed effective as of the date CC0 was + applied by Affirmer to the Work. Should any part of the License for any + reason be judged legally invalid or ineffective under applicable law, such + partial invalidity or ineffectiveness shall not invalidate the remainder + of the License, and in such case Affirmer hereby affirms that he or she + will not (i) exercise any of his or her remaining Copyright and Related + Rights in the Work or (ii) assert any associated claims and causes of + action with respect to the Work, in either case contrary to Affirmer's + express Statement of Purpose. + + 4. Limitations and Disclaimers. + + a. No trademark or patent rights held by Affirmer are waived, abandoned, + surrendered, licensed or otherwise affected by this document. + b. Affirmer offers the Work as-is and makes no representations or + warranties of any kind concerning the Work, express, implied, + statutory or otherwise, including without limitation warranties of + title, merchantability, fitness for a particular purpose, non + infringement, or the absence of latent or other defects, accuracy, or + the present or absence of errors, whether or not discoverable, all to + the greatest extent permissible under applicable law. + c. Affirmer disclaims responsibility for clearing rights of other persons + that may apply to the Work or any use thereof, including without + limitation any person's Copyright and Related Rights in the Work. + Further, Affirmer disclaims responsibility for obtaining any necessary + consents, permissions or other rights required for any use of the + Work. + d. Affirmer understands and acknowledges that Creative Commons is not a + party to this document and has no duty or obligation with respect to + this CC0 or use of the Work. diff --combined .vim/bundle/vim-python-pep8-indent/Dockerfile index 0000000,14e39ea..14e39ea mode 000000,100644..100644 --- a/.vim/bundle/vim-python-pep8-indent/Dockerfile +++ b/.vim/bundle/vim-python-pep8-indent/Dockerfile @@@ -1,0 -1,24 +1,24 @@@ + FROM testbed/vim:latest + + RUN apk --no-cache add gtk+2.0-dev libx11-dev libxt-dev mcookie xauth xvfb + # NOTE: +profile needs huge features. + RUN install_vim -tag v8.1.0129 -name vim --with-features=huge \ + --disable-channel --disable-netbeans --disable-xim \ + --enable-gui=gtk2 --with-x -build + RUN ln -s /vim-build/bin/vim /usr/bin/gvim + RUN gvim --version + + # Install covimerage and vint. + # NOTE: we have py2 already via gtk+2.0-dev. + # NOTE: enum34+pathlib+typing gets installed as workaround for broken vim-vint wheel. + RUN apk --no-cache add py2-pip \ + && pip install --no-cache-dir codecov covimerage==0.0.9 vim-vint enum34 pathlib typing \ + && rm -rf /usr/include /usr/lib/python*/turtle* /usr/lib/python*/tkinter + + WORKDIR /vim-python-pep8-indent + + ADD Gemfile . + RUN apk --no-cache add coreutils ruby-bundler + RUN bundle install + + ENTRYPOINT ["rspec", "spec"] diff --combined .vim/bundle/vim-python-pep8-indent/Gemfile index 0000000,9bbf596..9bbf596 mode 000000,100644..100644 --- a/.vim/bundle/vim-python-pep8-indent/Gemfile +++ b/.vim/bundle/vim-python-pep8-indent/Gemfile @@@ -1,0 -1,3 +1,3 @@@ + source 'https://rubygems.org' + gem "vimrunner", "0.3.4" + gem "rspec" diff --combined .vim/bundle/vim-python-pep8-indent/Makefile index 0000000,2566d41..2566d41 mode 000000,100644..100644 --- a/.vim/bundle/vim-python-pep8-indent/Makefile +++ b/.vim/bundle/vim-python-pep8-indent/Makefile @@@ -1,0 -1,25 +1,25 @@@ + test: + VIMRUNNER_REUSE_SERVER=1 xvfb-run bundle exec rspec + + # Run tests in dockerized Vims. + DOCKER_REPO:=blueyed/vim-python-pep8-indent-vims-for-test + DOCKER_TAG:=3 + DOCKER_IMAGE:=$(DOCKER_REPO):$(DOCKER_TAG) + + docker_image: + docker build -t $(DOCKER_REPO):$(DOCKER_TAG) . + docker_push: + docker push $(DOCKER_REPO):$(DOCKER_TAG) + docker_update_latest: + docker tag $(DOCKER_REPO):$(DOCKER_TAG) $(DOCKER_REPO):latest + docker push $(DOCKER_REPO):latest + + test_docker: XVFB_ERRORFILE:=/dev/null + test_docker: + @set -x; export DISPLAY=$(if $(VIMRUNNER_TEST_DISPLAY),$(VIMRUNNER_TEST_DISPLAY),172.17.0.1:99; Xvfb -ac -listen tcp :99 >$(XVFB_ERRORFILE) 2>&1 & XVFB_PID=$$!); \ + docker run --rm -ti -e DISPLAY -e VIMRUNNER_REUSE_SERVER=1 \ + -v $(CURDIR):/vim-python-pep8-indent $(DOCKER_IMAGE) $(RSPEC_ARGS) \ + $(if $(VIMRUNNER_TEST_DISPLAY),,; ret=$$?; kill $$XVFB_PID; exit $$ret) + + test_coverage: + spec/make-coverage diff --combined .vim/bundle/vim-python-pep8-indent/README.rst index 0000000,77be58c..77be58c mode 000000,100644..100644 --- a/.vim/bundle/vim-python-pep8-indent/README.rst +++ b/.vim/bundle/vim-python-pep8-indent/README.rst @@@ -1,0 -1,169 +1,169 @@@ + vim-python-pep8-indent + ====================== + + .. image:: https://circleci.com/gh/Vimjas/vim-python-pep8-indent.svg?style=svg + :target: https://circleci.com/gh/Vimjas/vim-python-pep8-indent + .. image:: https://codecov.io/gh/Vimjas/vim-python-pep8-indent/branch/master/graph/badge.svg + :target: https://codecov.io/gh/Vimjas/vim-python-pep8-indent + + This small script modifies Vim_’s indentation behavior to comply with PEP8_ and my aesthetic preferences. + Most importantly:: + + foobar(foo, + bar) + + and:: + + foobar( + foo, + bar + ) + + + Installation + ------------ + + Install the plugin using your favorite plugin manager / method, a few examples + follow: + + Pathogen + ^^^^^^^^ + + Follow the instructions on installing Pathogen_ and then: + + .. code-block:: shell-session + + $ cd ~/.vim/bundle + $ git clone https://github.com/Vimjas/vim-python-pep8-indent.git + + + Vundle + ^^^^^^ + + Follow the instructions on installing Vundle_ and add the appropriate plugin line into your ``.vimrc``: + + .. code-block:: vim + + Plugin 'Vimjas/vim-python-pep8-indent' + + + NeoBundle + ^^^^^^^^^ + + Follow the instructions on installing NeoBundle_ and add the appropriate NeoBundle line into your ``.vimrc``: + + .. code-block:: vim + + NeoBundle 'Vimjas/vim-python-pep8-indent' + + + Configuration + ------------- + + g:python_pep8_indent_multiline_string + ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + + You can configure the initial indentation of multiline strings using ``g:python_pep8_indent_multiline_string`` (which can also be set per buffer). + This defaults to ``0``, which means that multiline strings are not indented. + ``-1`` and positive values will be used as-is, where ``-1`` is a special value for Vim's ``indentexpr``, and will keep the existing indent (using Vim's ``autoindent`` setting). + ``-2`` is meant to be used for strings that are wrapped with ``textwrap.dedent`` etc. It will add a level of indentation if the multiline string started in the previous line, without any content in it already:: + + testdir.makeconftest(""" + _ + + With content already, it will be aligned to the opening parenthesis:: + + testdir.makeconftest("""def pytest_addoption(parser): + _ + + Existing indentation (including ``0``) in multiline strings will be kept, so this setting only applies to the indentation of new/empty lines. + + g:python_pep8_indent_hang_closing + ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + + Control closing bracket indentation with ``python_pep8_indent_hang_closing``, set globally or per buffer. + + By default (set to ``0``), closing brackets line up with the opening line:: + + my_list = [ + 1, 2, 3, + 4, 5, 6, + ] + result = some_function_that_takes_arguments( + 'a', 'b', 'c', + 'd', 'e', 'f', + ) + + With ``python_pep8_indent_hang_closing = 1``, closing brackets line up with the items:: + + my_list = [ + 1, 2, 3, + 4, 5, 6, + ] + result = some_function_that_takes_arguments( + 'a', 'b', 'c', + 'd', 'e', 'f', + ) + + + Troubleshooting + --------------- + + In case it is not working, please make sure your Vim is configured to load + indent files (``filetype indent on``). + This is typically the case when using a plugin manager, but check its docs. + + Check ``:verbose set indentexpr?`` in a Python file, which should show + something like the following: + + indentexpr=GetPythonPEPIndent(v:lnum) + Last set from ~/…/plugged/vim-python-pep8-indent/indent/python.vim + + + Notes + ----- + + Please note that Kirill Klenov’s python-mode_ ships its own version of this bundle. + Therefore, if you want to use this version specifically, you’ll have to disable python-mode’s using: + + .. code-block:: vim + + let g:pymode_indent = 0 + + + License and Authorship + ---------------------- + + This script is based on one from Vim’s official `script repo`_ that was *not* originally written by me. + Unfortunately the indentation was off by one character in one case and the script hasn’t been updated since 2005. + + Even more unfortunately, I wasn’t able to reach any of the original authors/maintainers: + **David Bustos** and **Eric Mc Sween**. + + So I fixed the annoyance with the help of `Steve Losh`_ and am putting it out here so you don’t have to patch the original yourself. + The original patch is still available here_. + + Over the time a lot more improvements have been contributed_ by `generous people`_. + + I’d like to thank the original authors here for their work and release it hereby to the *Public Domain* (using the CC0_ licence) since I hope that would be in their spirit. + If anyone with a say in this objects, please let me_ know immediately. + Also, if someone is in contact with one of them, I would appreciate being introduced. + + While my Vimscript_ skills are still feeble, I intend to maintain it for now. + This mainly means that I’ll triage through bugs and pull requests but won’t be fixing much myself. + + + .. _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 + .. _Neobundle: https://github.com/Shougo/neobundle.vim + .. _Pathogen: https://github.com/tpope/vim-pathogen + .. _python-mode: https://github.com/klen/python-mode + .. _`Vimscript`: http://learnvimscriptthehardway.stevelosh.com/ + .. _vundle: https://github.com/gmarik/Vundle.vim + .. _me: https://hynek.me/ + .. _CC0: http://creativecommons.org/publicdomain/zero/1.0/ + .. _contributed: https://github.com/hynek/vim-python-pep8-indent/blob/master/CONTRIBUTING.rst + .. _`generous people`: https://github.com/hynek/vim-python-pep8-indent/graphs/contributors diff --combined .vim/bundle/vim-python-pep8-indent/docker-compose.yml index 0000000,71760c2..71760c2 mode 000000,100644..100644 --- a/.vim/bundle/vim-python-pep8-indent/docker-compose.yml +++ b/.vim/bundle/vim-python-pep8-indent/docker-compose.yml @@@ -1,0 -1,6 +1,6 @@@ + version: '2' + services: + rspec: + build: . + volumes: + - .:/vim-python-pep8-indent diff --combined .vim/bundle/vim-python-pep8-indent/indent/cython.vim index 0000000,4407bc1..4407bc1 mode 000000,120000..120000 --- a/.vim/bundle/vim-python-pep8-indent/indent/cython.vim +++ b/.vim/bundle/vim-python-pep8-indent/indent/cython.vim @@@ -1,0 -1,1 +1,1 @@@ + python.vim diff --combined .vim/bundle/vim-python-pep8-indent/indent/python.vim index 0000000,047ae3d..047ae3d mode 000000,100644..100644 --- a/.vim/bundle/vim-python-pep8-indent/indent/python.vim +++ b/.vim/bundle/vim-python-pep8-indent/indent/python.vim @@@ -1,0 -1,454 +1,454 @@@ + " PEP8 compatible Python indent file + " Language: Python + " Maintainer: Daniel Hahler + " Prev Maintainer: Hynek Schlawack + " Prev Maintainer: Eric Mc Sween (address invalid) + " Original Author: David Bustos (address invalid) + " License: CC0 + " + " vim-python-pep8-indent - A nicer Python indentation style for vim. + " Written in 2004 by David Bustos + " Maintained from 2004-2005 by Eric Mc Sween + " Maintained from 2013 by Hynek Schlawack + " Maintained from 2017 by Daniel Hahler + " + " To the extent possible under law, the author(s) have dedicated all copyright + " and related and neighboring rights to this software to the public domain + " worldwide. This software is distributed without any warranty. + " You should have received a copy of the CC0 Public Domain Dedication along + " with this software. If not, see + " . + + " Only load this indent file when no other was loaded. + if exists('b:did_indent') + finish + endif + let b:did_indent = 1 + + setlocal nolisp + setlocal autoindent + setlocal indentexpr=GetPythonPEPIndent(v:lnum) + setlocal indentkeys=!^F,o,O,<:>,0),0],0},=elif,=except + + if !exists('g:python_pep8_indent_multiline_string') + let g:python_pep8_indent_multiline_string = 0 + endif + + if !exists('g:python_pep8_indent_hang_closing') + let g:python_pep8_indent_hang_closing = 0 + endif + + " TODO: check required patch for timeout argument, likely lower than 7.3.429 though. + if !exists('g:python_pep8_indent_searchpair_timeout') + if has('patch-8.0.1483') + let g:python_pep8_indent_searchpair_timeout = 150 + else + let g:python_pep8_indent_searchpair_timeout = 0 + endif + endif + + let s:block_rules = { + \ '^\s*elif\>': [['if', 'elif'], ['else']], + \ '^\s*except\>': [['try', 'except'], []], + \ '^\s*finally\>': [['try', 'except', 'else'], []] + \ } + let s:block_rules_multiple = { + \ '^\s*else\>': [['if', 'elif', 'for', 'try', 'except'], []] + \ } + " Pairs to look for when searching for opening parenthesis. + " The value is the maximum offset in lines. + let s:paren_pairs = {'()': 50, '[]': 100, '{}': 1000} + + if &filetype ==# 'pyrex' || &filetype ==# 'cython' + let b:control_statement = '\v^\s*(class|def|if|while|with|for|except|cdef|cpdef)>' + else + let b:control_statement = '\v^\s*(class|def|if|while|with|for|except)>' + endif + let s:stop_statement = '^\s*\(break\|continue\|raise\|return\|pass\)\>' + + let s:skip_after_opening_paren = 'synIDattr(synID(line("."), col("."), 0), "name") ' . + \ '=~? "\\vcomment|jedi\\S"' + + let s:special_chars_syn_pattern = "\\vstring|comment|^pythonbytes%(contents)=$|pythonTodo|jedi\\S" + + if !get(g:, 'python_pep8_indent_skip_concealed', 0) || !has('conceal') + " Skip strings and comments. Return 1 for chars to skip. + " jedi* refers to syntax definitions from jedi-vim for call signatures, which + " are inserted temporarily into the buffer. + function! s:_skip_special_chars(line, col) + return synIDattr(synID(a:line, a:col, 0), 'name') + \ =~? s:special_chars_syn_pattern + endfunction + else + " Also ignore anything concealed. + " TODO: doc; likely only necessary with jedi-vim, where a better version is + " planned (https://github.com/Vimjas/vim-python-pep8-indent/pull/98). + + " Wrapper around synconcealed for older Vim (7.3.429, used on Travis CI). + function! s:is_concealed(line, col) + let concealed = synconcealed(a:line, a:col) + return len(concealed) && concealed[0] + endfunction + + function! s:_skip_special_chars(line, col) + return synIDattr(synID(a:line, a:col, 0), 'name') + \ =~? s:special_chars_syn_pattern + \ || s:is_concealed(a:line, a:col) + endfunction + endif + + " Use 'shiftwidth()' instead of '&sw'. + " (Since Vim patch 7.3.629, 'shiftwidth' can be set to 0 to follow 'tabstop'). + if exists('*shiftwidth') + function! s:sw() + return shiftwidth() + endfunction + else + function! s:sw() + return &shiftwidth + endfunction + endif + + " Find backwards the closest open parenthesis/bracket/brace. + function! s:find_opening_paren(lnum, col) + " Return if cursor is in a comment. + if synIDattr(synID(a:lnum, a:col, 0), 'name') =~? 'comment' + return [0, 0] + endif + + call cursor(a:lnum, a:col) + + let nearest = [0, 0] + let timeout = g:python_pep8_indent_searchpair_timeout + let skip_special_chars = 's:_skip_special_chars(line("."), col("."))' + for [p, maxoff] in items(s:paren_pairs) + let stopline = max([0, line('.') - maxoff, nearest[0]]) + let next = searchpairpos( + \ '\V'.p[0], '', '\V'.p[1], 'bnW', skip_special_chars, stopline, timeout) + if next[0] && (next[0] > nearest[0] || (next[0] == nearest[0] && next[1] > nearest[1])) + let nearest = next + endif + endfor + return nearest + endfunction + + " Find the start of a multi-line statement + function! s:find_start_of_multiline_statement(lnum) + let lnum = a:lnum + while lnum > 0 + if getline(lnum - 1) =~# '\\$' + let lnum = prevnonblank(lnum - 1) + else + let [paren_lnum, _] = s:find_opening_paren(lnum, 1) + if paren_lnum < 1 + return lnum + else + let lnum = paren_lnum + endif + endif + endwhile + endfunction + + " Find possible indent(s) of the block starter that matches the current line. + function! s:find_start_of_block(lnum, types, skip, multiple) abort + let r = [] + let re = '\V\^\s\*\('.join(a:types, '\|').'\)\>' + if !empty(a:skip) + let re_skip = '\V\^\s\*\('.join(a:skip, '\|').'\)\>' + else + let re_skip = '' + endif + let last_indent = indent(a:lnum) + 1 + let lnum = a:lnum - 1 + while lnum > 0 && last_indent > 0 + let indent = indent(lnum) + if indent < last_indent + let line = getline(lnum) + if !empty(re_skip) && line =~# re_skip + let last_indent = indent + elseif line =~# re + if !a:multiple + return [indent] + endif + if index(r, indent) == -1 + let r += [indent] + endif + let last_indent = indent + endif + endif + let lnum = prevnonblank(lnum - 1) + endwhile + return r + endfunction + + " Is "expr" true for every position in "lnum", beginning at "start"? + " (optionally up to a:1 / 4th argument) + function! s:match_expr_on_line(expr, lnum, start, ...) + let text = getline(a:lnum) + let end = a:0 ? a:1 : len(text) + if a:start > end + return 1 + endif + let save_pos = getpos('.') + let r = 1 + for i in range(a:start, end) + call cursor(a:lnum, i) + if !(eval(a:expr) || text[i-1] =~# '\s') + let r = 0 + break + endif + endfor + call setpos('.', save_pos) + return r + endfunction + + " Line up with open parenthesis/bracket/brace. + function! s:indent_like_opening_paren(lnum) + let [paren_lnum, paren_col] = s:find_opening_paren(a:lnum, 1) + if paren_lnum <= 0 + return -2 + endif + let text = getline(paren_lnum) + let base = indent(paren_lnum) + + let nothing_after_opening_paren = s:match_expr_on_line( + \ s:skip_after_opening_paren, paren_lnum, paren_col+1) + let starts_with_closing_paren = getline(a:lnum) =~# '^\s*[])}]' + + let hang_closing = get(b:, 'python_pep8_indent_hang_closing', + \ get(g:, 'python_pep8_indent_hang_closing', 0)) + + if nothing_after_opening_paren + if starts_with_closing_paren && !hang_closing + let res = base + else + let res = base + s:sw() + + " Special case for parenthesis. + if text[paren_col-1] ==# '(' && getline(a:lnum) !~# '\v\)\s*:?\s*$' + return res + endif + endif + else + " Indent to match position of opening paren. + let res = paren_col + endif + + " If this line is the continuation of a control statement + " indent further to distinguish the continuation line + " from the next logical line. + if text =~# b:control_statement && res == base + s:sw() + " But only if not inside parens itself (Flake's E127). + let [paren_lnum, _] = s:find_opening_paren(paren_lnum, 1) + if paren_lnum <= 0 + return res + s:sw() + endif + endif + return res + endfunction + + " Match indent of first block of this type. + function! s:indent_like_block(lnum) + let text = getline(a:lnum) + for [multiple, block_rules] in [ + \ [0, s:block_rules], + \ [1, s:block_rules_multiple], + \ ] + for [line_re, blocks_ignore] in items(block_rules) + if text !~# line_re + continue + endif + + let [blocks, skip] = blocks_ignore + let indents = s:find_start_of_block(a:lnum, blocks, skip, multiple) + if empty(indents) + return -1 + endif + if len(indents) == 1 + return indents[0] + endif + + " Multiple valid indents, e.g. for 'else' with both try and if. + let indent = indent(a:lnum) + if index(indents, indent) != -1 + " The indent is valid, keep it. + return indent + endif + " Fallback to the first/nearest one. + return indents[0] + endfor + endfor + return -2 + endfunction + + function! s:indent_like_previous_line(lnum) + let lnum = prevnonblank(a:lnum - 1) + + " No previous line, keep current indent. + if lnum < 1 + return -1 + endif + + let text = getline(lnum) + let start = s:find_start_of_multiline_statement(lnum) + let base = indent(start) + let current = indent(a:lnum) + + " Ignore last character in previous line? + let lastcol = len(text) + let col = lastcol + + " Search for final colon that is not inside something to be ignored. + while 1 + if col == 1 | break | endif + if text[col-1] =~# '\s' || s:_skip_special_chars(lnum, col) + let col = col - 1 + continue + elseif text[col-1] ==# ':' + return base + s:sw() + endif + break + endwhile + + if text =~# '\\$' && !s:_skip_special_chars(lnum, lastcol) + " If this line is the continuation of a control statement + " indent further to distinguish the continuation line + " from the next logical line. + if getline(start) =~# b:control_statement + return base + s:sw() * 2 + endif + + " Nest (other) explicit continuations only one level deeper. + return base + s:sw() + endif + + let empty = getline(a:lnum) =~# '^\s*$' + + " Current and prev line are empty, next is not -> indent like next. + if empty && a:lnum > 1 && + \ (getline(a:lnum - 1) =~# '^\s*$') && + \ !(getline(a:lnum + 1) =~# '^\s*$') + return indent(a:lnum + 1) + endif + + " If the previous statement was a stop-execution statement or a pass + if getline(start) =~# s:stop_statement + " Remove one level of indentation if the user hasn't already dedented + if empty || current > base - s:sw() + return base - s:sw() + endif + " Otherwise, trust the user + return -1 + endif + + if (current || !empty) && s:is_dedented_already(current, base) + return -1 + endif + + " In all other cases, line up with the start of the previous statement. + return base + endfunction + + " If this line is dedented and the number of indent spaces is valid + " (multiple of the indentation size), trust the user. + function! s:is_dedented_already(current, base) + let dedent_size = a:current - a:base + return (dedent_size < 0 && a:current % s:sw() == 0) ? 1 : 0 + endfunction + + " Is the syntax at lnum (and optionally cnum) a python string? + function! s:is_python_string(lnum, ...) + let line = getline(a:lnum) + if a:0 + let cols = type(a:1) != type([]) ? [a:1] : a:1 + else + let cols = range(1, max([1, len(line)])) + endif + for cnum in cols + if match(map(synstack(a:lnum, cnum), + \ "synIDattr(v:val, 'name')"), 'python\S*String') == -1 + return 0 + end + endfor + return 1 + endfunction + + function! GetPythonPEPIndent(lnum) + " First line has indent 0 + if a:lnum == 1 + return 0 + endif + + let line = getline(a:lnum) + let prevline = getline(a:lnum-1) + + " Multilinestrings: continous, docstring or starting. + if s:is_python_string(a:lnum-1, max([1, len(prevline)])) + \ && (s:is_python_string(a:lnum, 1) + \ || match(line, '^\%("""\|''''''\)') != -1) + + " Indent closing quotes as the line with the opening ones. + let match_quotes = match(line, '^\s*\zs\%("""\|''''''\)') + if match_quotes != -1 + " closing multiline string + let quotes = line[match_quotes:(match_quotes+2)] + call cursor(a:lnum, 1) + let pairpos = searchpairpos(quotes, '', quotes, 'bW', '', 0, g:python_pep8_indent_searchpair_timeout) + if pairpos[0] != 0 + return indent(pairpos[0]) + else + return -1 + endif + endif + + if s:is_python_string(a:lnum-1) + " Previous line is (completely) a string: keep current indent. + return -1 + endif + + if match(prevline, '^\s*\%("""\|''''''\)') != -1 + " docstring. + return indent(a:lnum-1) + endif + + let indent_multi = get(b:, 'python_pep8_indent_multiline_string', + \ get(g:, 'python_pep8_indent_multiline_string', 0)) + if match(prevline, '\v%("""|'''''')$') != -1 + " Opening multiline string, started in previous line. + if (&autoindent && indent(a:lnum) == indent(a:lnum-1)) + \ || match(line, '\v^\s+$') != -1 + " with empty line or to split up 'foo("""bar' into + " 'foo("""' and 'bar'. + if indent_multi == -2 + return indent(a:lnum-1) + s:sw() + endif + return indent_multi + endif + endif + + " Keep existing indent. + if match(line, '\v^\s*\S') != -1 + return -1 + endif + + if indent_multi != -2 + return indent_multi + endif + + return s:indent_like_opening_paren(a:lnum) + endif + + " Parens: If we can find an open parenthesis/bracket/brace, line up with it. + let indent = s:indent_like_opening_paren(a:lnum) + if indent >= -1 + return indent + endif + + " Blocks: Match indent of first block of this type. + let indent = s:indent_like_block(a:lnum) + if indent >= -1 + return indent + endif + + return s:indent_like_previous_line(a:lnum) + endfunction diff --combined .vim/bundle/vim-python-pep8-indent/spec/indent/bytes_spec.rb index 0000000,3d6744e..3d6744e mode 000000,100644..100644 --- a/.vim/bundle/vim-python-pep8-indent/spec/indent/bytes_spec.rb +++ b/.vim/bundle/vim-python-pep8-indent/spec/indent/bytes_spec.rb @@@ -1,0 -1,36 +1,36 @@@ + require "spec_helper" + + describe "handles byte strings" do + before(:all) { + vim.command 'syn region pythonBytes start=+[bB]"+ skip=+\\\\\|\\"\|\\$+ excludenl end=+"+ end=+$+ keepend contains=pythonBytesError,pythonBytesContent,@Spell' + vim.command "syn match pythonBytesEscape '\\\\$'" + } + + before(:each) { + # clear buffer + vim.normal 'gg"_dG' + + # Insert two blank lines. + # The first line is a corner case in this plugin that would shadow the + # correct behaviour of other tests. Thus we explicitly jump to the first + # line when we require so. + vim.feedkeys 'i\\\' + } + + it "it does not indent to bracket in byte string" do + vim.feedkeys 'ireg = b"["\' + vim.echo('map(synstack(line("."), col(".")), "synIDattr(v:val, \"name\")")' + ).should == "['pythonBytes']" + vim.feedkeys 'o' + indent.should == 0 + end + + it "it indents backslash continuation correctly" do + vim.feedkeys 'iwith foo, \\' + vim.echo('getline(".")').should == "with foo, \\" + vim.echo('map(synstack(line("."), col(".")), "synIDattr(v:val, \"name\")")' + ).should == "['pythonBytesEscape']" + vim.feedkeys 'o' + indent.should == 8 + end + end diff --combined .vim/bundle/vim-python-pep8-indent/spec/indent/cython_spec.rb index 0000000,03dcbb2..03dcbb2 mode 000000,100644..100644 --- a/.vim/bundle/vim-python-pep8-indent/spec/indent/cython_spec.rb +++ b/.vim/bundle/vim-python-pep8-indent/spec/indent/cython_spec.rb @@@ -1,0 -1,36 +1,36 @@@ + require "spec_helper" + + describe "vim for cython" do + before(:all) { + vim.command "new" + vim.command "set ft=cython" + vim.command("set indentexpr?").should include "GetPythonPEPIndent(" + } + before(:each) { + # clear buffer + vim.normal 'gg"_dG' + + # Insert two blank lines. + # The first line is a corner case in this plugin that would shadow the + # correct behaviour of other tests. Thus we explicitly jump to the first + # line when we require so. + vim.feedkeys 'i\\\' + } + after(:all) { + vim.command "bwipe!" + } + + describe "when using a cdef function definition" do + it "indents shiftwidth spaces" do + vim.feedkeys 'icdef long_function_name(\arg' + indent.should == shiftwidth + end + end + + describe "when using a cpdef function definition" do + it "indents shiftwidth spaces" do + vim.feedkeys 'icpdef long_function_name(\arg' + indent.should == shiftwidth + end + end + end diff --combined .vim/bundle/vim-python-pep8-indent/spec/indent/indent_spec.rb index 0000000,745e939..745e939 mode 000000,100644..100644 --- a/.vim/bundle/vim-python-pep8-indent/spec/indent/indent_spec.rb +++ b/.vim/bundle/vim-python-pep8-indent/spec/indent/indent_spec.rb @@@ -1,0 -1,796 +1,796 @@@ + require "spec_helper" + + shared_examples_for "vim" do + before(:each) { + # clear buffer + vim.normal 'gg"_dG' + + # Insert two blank lines. + # The first line is a corner case in this plugin that would shadow the + # correct behaviour of other tests. Thus we explicitly jump to the first + # line when we require so. + vim.feedkeys 'i\\\' + } + + describe "when using the indent plugin" do + it "sets the indentexpr and indentkeys options" do + vim.command("set indentexpr?").should include "GetPythonPEPIndent(" + vim.command("set indentkeys?").should include "=elif" + end + + it "sets autoindent and expandtab" do + vim.command("set autoindent?").should match(/\s*autoindent/) + vim.command("set expandtab?").should match(/\s*expandtab/) + end + end + + describe "when entering the first line" do + before { vim.feedkeys '0ggipass' } + + it "does not indent" do + indent.should == 0 + proposed_indent.should == 0 + end + + it "does not indent when using '=='" do + vim.normal "==" + indent.should == 0 + end + end + + describe "when after a '(' that is at the end of its line" do + before { vim.feedkeys 'itest(\' } + + it "indents by one level" do + proposed_indent.should == shiftwidth + vim.feedkeys 'something' + indent.should == shiftwidth + vim.normal '==' + indent.should == shiftwidth + end + + it "puts the closing parenthesis at the same level" do + vim.feedkeys ')' + indent.should == (hang_closing ? shiftwidth : 0) + end + end + + describe "when after an '(' that is followed by something" do + before { vim.feedkeys 'itest(something,\' } + + it "lines up on following lines" do + indent.should == 5 + vim.feedkeys 'more,\' + indent.should == 5 + end + + it "lines up the closing parenthesis" do + vim.feedkeys ')' + indent.should == 5 + end + + it "does not touch the closing parenthesis if it is already indented further" do + vim.feedkeys ' )' + indent.should == 7 + end + end + + describe "when after an '{' that is followed by a comment" do + before { vim.feedkeys 'imydict = { # comment\' } + + it "indent by one level" do + indent.should == shiftwidth + vim.feedkeys '1: 1,\' + indent.should == shiftwidth + end + + it "lines up the closing parenthesis" do + vim.feedkeys '}' + indent.should == (hang_closing ? shiftwidth : 0) + end + end + + describe "when using gq to reindent a '(' that is" do + before { vim.feedkeys 'itest(' } + it "something and has a string without spaces at the end" do + vim.feedkeys 'something_very_long_blaaaaaaaaa, "some_very_long_string_blaaaaaaaaaaaaaaaaaaaa"\gqq' + indent.should == 5 + end + end + + describe "when after multiple parens of different types" do + it "indents by one level" do + vim.feedkeys 'if({\' + indent.should == shiftwidth + end + + it "lines up with the last paren" do + vim.feedkeys 'ifff({123: 456,\' + indent.should == 5 + end + end + + describe "when '#' is contained in a string that is followed by a colon" do + it "indents by one level" do + vim.feedkeys 'iif "some#thing" == "test":#test\pass' + indent.should == shiftwidth + end + end + + describe "when '#' is not contained in a string and is followed by a colon" do + it "does not indent" do + vim.feedkeys 'iif "some#thing" == "test"#:test\' + indent.should == 0 + end + end + + describe "when inside an unfinished string" do + it "does not indent" do + vim.feedkeys 'i"test:\' + vim.echo('synIDattr(synID(line("."), col("."), 0), "name")' + ).downcase.should include 'string' + vim.feedkeys 'a\' + proposed_indent.should == -1 + indent.should == 0 + end + + it "does not dedent" do + vim.feedkeys 'iif True:\"test:\' + vim.echo('synIDattr(synID(line("."), col("."), 0), "name")' + ).downcase.should include 'string' + proposed_indent.should == shiftwidth + indent.should == shiftwidth + end + end + + describe "when the previous line has a colon in a string" do + before { vim.feedkeys 'itest(":".join(["1","2"]))\' } + it "does not indent" do + vim.feedkeys 'if True:' + indent.should == 0 + proposed_indent.should == 0 + end + end + + describe "when the previous line has a list slice" do + it "does not indent" do + vim.feedkeys 'ib = a[2:]\' + indent.should == 0 + proposed_indent.should == 0 + end + end + + describe "when line is empty inside a block" do + it "is indented like the previous line" do + vim.feedkeys 'idef a():\1\\2\kcc' + indent.should == shiftwidth + end + end + + describe "when an empty line is after empty line / before non-empty" do + it "is indented like the next line" do + vim.feedkeys 'idef a():\1\\\2\<1\\\\0i\2\kcc' + indent.should == shiftwidth + end + end + + describe "when line is empty inside a block following multi-line statement" do + it "is indented like the previous line" do + vim.feedkeys 'idef a():\x = (1 +\2)\\y\kcc' + indent.should == shiftwidth + end + end + + describe "when line is empty inside a block following stop statement" do + it "is indented like the previous line minus shiftwidth" do + vim.feedkeys 'iif x:\if y:\pass\\z\kcc' + indent.should == shiftwidth + end + end + + describe "when using simple control structures" do + it "indents shiftwidth spaces" do + vim.feedkeys 'iwhile True:\pass' + indent.should == shiftwidth + end + end + + describe "when using a function definition" do + it "handles indent with closing parenthesis on same line" do + vim.feedkeys 'idef long_function_name(\arg' + indent.should == shiftwidth + vim.feedkeys '):' + indent.should == shiftwidth * 2 + end + + it "handles indent with closing parenthesis on new line" do + vim.feedkeys 'idef long_function_name(\arg' + indent.should == shiftwidth + vim.feedkeys '\' + indent.should == shiftwidth + vim.feedkeys ')' + indent.should == (hang_closing ? shiftwidth * 2 : 0) + vim.feedkeys ':' + indent.should == (hang_closing ? shiftwidth * 2 : 0) + vim.feedkeys '\k' + indent.should == shiftwidth + end + end + + describe "when using a class definition" do + it "indents shiftwidth spaces" do + vim.feedkeys 'iclass Foo(\' + indent.should == shiftwidth + end + end + + describe "when writing an 'else' block" do + it "aligns to the preceeding 'for' block" do + vim.feedkeys 'ifor x in "abc":\pass\else:' + indent.should == 0 + end + + it "aligns to the preceeding 'if' block" do + vim.feedkeys 'ifor x in "abc":\if True:\pass\else:' + indent.should == shiftwidth + end + end + + describe "when using parens and control statements" do + it "avoids ambiguity by using extra indentation" do + vim.feedkeys 'iif (111 and\' + if shiftwidth == 4 + indent.should == shiftwidth * 2 + else + indent.should == 4 + end + vim.feedkeys '222):\' + indent.should == shiftwidth + vim.feedkeys 'pass\' + indent.should == 0 + end + + it "still aligns parens properly if not ambiguous" do + vim.feedkeys 'iwhile (111 and\' + indent.should == 7 + vim.feedkeys '222):\' + indent.should == shiftwidth + vim.feedkeys 'pass\' + indent.should == 0 + end + + it "handles nested expressions (Flake8's E127)" do + vim.feedkeys 'i[\x for x in foo\if (\' + indent.should == shiftwidth * 2 + end + + it "still handles multiple parens correctly" do + vim.feedkeys 'iif (111 and (222 and 333\' + indent.should == 13 + vim.feedkeys 'and 444\' + indent.should == 13 + vim.feedkeys ')\' + if shiftwidth == 4 + indent.should == shiftwidth * 2 + else + indent.should == 4 + end + vim.feedkeys 'and 555):\' + indent.should == shiftwidth + vim.feedkeys 'pass\' + indent.should == 0 + end + end + + describe "when a line breaks with a manual '\\'" do + it "indents shiftwidth spaces on normal line" do + vim.feedkeys 'ivalue = test + \\\\\' + indent.should == shiftwidth + end + + it "indents 2x shiftwidth spaces for control structures" do + vim.feedkeys 'iif somevalue == xyz and \\\\\' + indent.should == shiftwidth * 2 + end + + it "indents relative to line above" do + vim.feedkeys 'i\value = test + \\\\\' + indent.should == shiftwidth * 2 + end + end + + describe "when current line is dedented compared to previous line" do + before { vim.feedkeys 'i\\if x:\y = True\\' } + it "and current line has a valid indentation (Part 1)" do + vim.feedkeys '0i\if y:' + proposed_indent.should == -1 + end + + it "and current line has a valid indentation (Part 2)" do + vim.feedkeys '0i\\if y:' + proposed_indent.should == -1 + end + + it "and current line has an invalid indentation" do + vim.feedkeys 'i while True:\' + indent.should == previous_indent + shiftwidth + end + end + + describe "when current line is dedented compared to the last non-empty line" do + before { vim.feedkeys 'i\\if x:\y = True\\\' } + it "and current line has a valid indentation" do + vim.feedkeys '0i\if y:' + proposed_indent.should == -1 + end + end + + describe "when an 'if' is followed by" do + before { vim.feedkeys 'i\\if x:\' } + it "an elif, it lines up with the 'if'" do + vim.feedkeys 'elif y:' + indent.should == shiftwidth * 2 + end + + it "an 'else', it lines up with the 'if'" do + vim.feedkeys 'else:' + indent.should == shiftwidth * 2 + end + end + + describe "when an 'if' contains a try-except" do + before { + vim.feedkeys 'iif x:\try:\pass\except:\pass\' + indent.should == shiftwidth + } + it "an 'else' should be indented to the try" do + vim.feedkeys 'else:' + indent.should == shiftwidth + proposed_indent.should == shiftwidth + end + it "an 'else' should keep the indent of the 'if'" do + vim.feedkeys 'else:\<<' + indent.should == 0 + proposed_indent.should == 0 + end + end + + describe "when a 'for' is followed by" do + before { vim.feedkeys 'i\\for x in y:\' } + it "an 'else', it lines up with the 'for'" do + vim.feedkeys 'else:' + indent.should == shiftwidth * 2 + end + end + + describe "when an 'else' is followed by" do + before { vim.feedkeys 'i\\else:\XXX\' } + it "a 'finally', it lines up with the 'else'" do + vim.feedkeys 'finally:' + indent.should == shiftwidth * 2 + end + end + + + describe "when a 'try' is followed by" do + before { vim.feedkeys 'i\\try:\' } + it "an 'except', it lines up with the 'try'" do + vim.feedkeys 'except:' + indent.should == shiftwidth * 2 + end + + it "an 'else', it lines up with the 'try'" do + vim.feedkeys 'else:' + indent.should == shiftwidth * 2 + end + + it "a 'finally', it lines up with the 'try'" do + vim.feedkeys 'finally:' + indent.should == shiftwidth * 2 + end + end + + describe "when an 'except' is followed by" do + before { vim.feedkeys 'i\\except:\' } + it "an 'else', it lines up with the 'except'" do + vim.feedkeys 'else:' + indent.should == shiftwidth * 2 + end + + it "another 'except', it lines up with the previous 'except'" do + vim.feedkeys 'except:' + indent.should == shiftwidth * 2 + end + + it "a 'finally', it lines up with the 'except'" do + vim.feedkeys 'finally:' + indent.should == shiftwidth * 2 + end + end + + describe "when an else is used inside of a nested if" do + before { vim.feedkeys 'iif foo:\if bar:\pass\' } + it "indents the else to the inner if" do + vim.feedkeys 'else:' + indent.should == shiftwidth + end + end + + describe "when an else is used outside of a nested if" do + before { vim.feedkeys 'iif True:\if True:\pass\\0' } + it "indents the else to the outer if" do + indent.should == 0 + proposed_indent.should == shiftwidth + + vim.feedkeys 'ielse:' + indent.should == 0 + proposed_indent.should == 0 + end + end + + describe "when jedi-vim call signatures are used" do + before { vim.command 'syn match jediFunction "JEDI_CALL_SIGNATURE" keepend extend' } + + it "ignores the call signature after a colon" do + vim.feedkeys 'iif True: JEDI_CALL_SIGNATURE\' + indent.should == shiftwidth + end + + it "ignores the call signature after a function" do + vim.feedkeys 'idef f( JEDI_CALL_SIGNATURE\' + indent.should == shiftwidth + end + end + end + + shared_examples_for "multiline strings" do + before(:each) { + # clear buffer + vim.normal 'gg"_dG' + + # Insert two blank lines. + # The first line is a corner case in this plugin that would shadow the + # correct behaviour of other tests. Thus we explicitly jump to the first + # line when we require so. + vim.feedkeys 'i\\\' + } + + describe "when after an '(' that is followed by an unfinished string" do + before { vim.feedkeys 'itest("""' } + + it "it indents the next line" do + vim.feedkeys '\' + expected_proposed, expected_indent = multiline_indent(0, shiftwidth) + proposed_indent.should == expected_proposed + indent.should == expected_indent + end + + it "with contents it indents the second line to the parenthesis" do + vim.feedkeys 'second line\' + expected_proposed, expected_indent = multiline_indent(0, 5) + proposed_indent.should == expected_proposed + indent.should == expected_indent + end + end + + describe "when after assigning an unfinished string" do + before { vim.feedkeys 'itest = """' } + + it "it indents the next line" do + vim.feedkeys '\' + expected_proposed, expected_indent = multiline_indent(0, shiftwidth) + proposed_indent.should == expected_proposed + indent.should == expected_indent + end + end + + describe "when after assigning an indented unfinished string" do + before { vim.feedkeys 'i test = """' } + + it "it indents the next line" do + vim.feedkeys '\' + expected_proposed, expected_indent = multiline_indent(4, shiftwidth + 4) + proposed_indent.should == expected_proposed + indent.should == expected_indent + end + end + + describe "when after assigning an indented finished string" do + before { vim.feedkeys 'i test = ""' } + + it "it does indent the next line" do + vim.feedkeys '\' + indent.should == 4 + end + + it "and writing a new string, it does indent the next line" do + vim.feedkeys '\""' + indent.should == 4 + end + end + + describe "when after a docstring" do + it "it does indent the next line to the docstring" do + vim.feedkeys 'i """\' + indent.should == 4 + proposed_indent.should == 4 + end + + it "indents the closing docstring quotes" do + vim.feedkeys 'i """\\"""' + indent.should == 4 + proposed_indent.should == 4 + vim.echo('getline(3)').should == ' """' + end + + it "indents non-matching docstring quotes" do + vim.feedkeys 'i """\\' + vim.feedkeys "0C'''" + vim.echo('line(".")').should == "4" + vim.echo('getline(".")').should == "'''" + indent.should == 0 + proposed_indent.should == -1 + end + end + + describe "when after a docstring with contents" do + before { vim.feedkeys 'i """First line' } + it "it does indent the next line to the docstring" do + vim.feedkeys '\' + indent.should == 4 + proposed_indent.should == 4 + end + end + + describe "when breaking a string after opening parenthesis" do + before { vim.feedkeys 'i foo("""bar\\\' } + it "it does indent the next line as after an opening multistring" do + vim.feedkeys '\' + _, expected_indent = multiline_indent(4, 4 + shiftwidth) + indent.should == expected_indent + proposed_indent.should == -1 + + # it keeps the indent after an empty line + vim.feedkeys '\' + proposed_indent, expected_indent = multiline_indent(4, 4 + shiftwidth) + indent.should == expected_indent + proposed_indent.should == proposed_indent + + # it keeps the indent of nonblank above + vim.feedkeys '\\' + proposed_indent, expected_indent = multiline_indent(4, 4 + shiftwidth) + indent.should == expected_indent + proposed_indent.should == proposed_indent + + # it keeps the indent of nonblank above before an empty line + vim.feedkeys '\' + proposed_indent, expected_indent = multiline_indent(4, 4 + shiftwidth) + indent.should == expected_indent + proposed_indent.should == proposed_indent + end + end + end + + SUITE_SHIFTWIDTHS = [4, 3] + SUITE_HANG_CLOSINGS = [false, true] + + SUITE_SHIFTWIDTHS.each do |sw| + describe "vim when using width of #{sw}" do + before { + vim.command("set sw=#{sw} ts=#{sw} sts=#{sw} et") + } + it "sets shiftwidth to #{sw}" do + shiftwidth.should == sw + end + + SUITE_HANG_CLOSINGS.each do |hc| + describe "vim when hang_closing is set to #{hc}" do + before { + set_hang_closing hc + } + it "sets hang_closing to #{hc}" do + hang_closing.should == !!hc + end + + it_behaves_like "vim" + end + end + end + end + + describe "vim when not using python_pep8_indent_multiline_string" do + before { + vim.command("set sw=4 ts=4 sts=4 et") + vim.command("unlet! g:python_pep8_indent_multiline_string") + } + it_behaves_like "multiline strings" + end + + describe "vim when using python_pep8_indent_multiline_first=0" do + before { + vim.command("set sw=4 ts=4 sts=4 et") + vim.command("let g:python_pep8_indent_multiline_string=0") + } + it_behaves_like "multiline strings" + end + + describe "vim when using python_pep8_indent_multiline_string=-1" do + before { + vim.command("set sw=4 ts=4 sts=4 et") + vim.command("let g:python_pep8_indent_multiline_string=-1") + } + it_behaves_like "multiline strings" + end + + describe "vim when using python_pep8_indent_multiline_string=-2" do + before { + vim.command("set sw=4 ts=4 sts=4 et") + vim.command("let g:python_pep8_indent_multiline_string=-2") + } + it_behaves_like "multiline strings" + end + + describe "Handles far away opening parens" do + before { vim.feedkeys '\ggdGifrom foo import (' } + + it "indents by one level" do + vim.feedkeys '\' + proposed_indent.should == shiftwidth + end + + it "indents by one level for 10 lines" do + vim.command('set paste | exe "norm 9o" | set nopaste') + vim.feedkeys '\o' + indent.should == shiftwidth + end + + it "indents by one level for 50 lines" do + vim.command('set paste | exe "norm 49o" | set nopaste') + vim.feedkeys '\o' + indent.should == shiftwidth + end + end + + describe "Handles far away opening square brackets" do + before { vim.feedkeys '\ggdGibar = [' } + + it "indents by one level" do + vim.feedkeys '\' + proposed_indent.should == shiftwidth + end + + it "indents by one level for 10 lines" do + vim.command('set paste | exe "norm 9o" | set nopaste') + vim.feedkeys '\o' + indent.should == shiftwidth + end + + it "indents by one level for 100 lines" do + vim.command('set paste | exe "norm 99o" | set nopaste') + vim.feedkeys '\o' + indent.should == shiftwidth + end + end + + describe "Handles far away opening curly brackets" do + before { vim.feedkeys '\ggdGijson = {' } + + it "indents by one level" do + vim.feedkeys '\' + vim.feedkeys '\o' + proposed_indent.should == shiftwidth + end + + it "indents by one level for 10 lines" do + vim.command('set paste | exe "norm 9o" | set nopaste') + vim.feedkeys '\o' + indent.should == shiftwidth + end + + it "indents by one level for 1000 lines" do + vim.command('set paste | exe "norm 999o" | set nopaste') + vim.feedkeys '\o' + indent.should == shiftwidth + end + end + + describe "Compact multiline dict" do + before { vim.feedkeys '\ggdGid = {"one": 1,' } + + it "gets indented correctly" do + vim.feedkeys '\' + proposed_indent.should == 5 + + vim.feedkeys '"two": 2}' + proposed_indent.should == 5 + + vim.feedkeys '\' + proposed_indent.should == 0 + end + end + + describe "Using O" do + before { + vim.feedkeys '\ggdG' + vim.feedkeys 'iif foo:\' + } + + it "respects autoindent" do + vim.feedkeys '1\\' + indent.should == shiftwidth + vim.feedkeys '\ko' + indent.should == shiftwidth + vim.feedkeys '\kO' + indent.should == shiftwidth + # Uses/keeps indent from line above + vim.feedkeys '\i2\O' + indent.should == shiftwidth + # Uses/keeps indent from line above + vim.feedkeys '\j\O' + indent.should == 0 + end + end + + describe "searchpairpos" do + before { vim.feedkeys '\ggdG' } + it "handles nested parenthesis" do + vim.feedkeys 'iif foo.startswith("("):\' + indent.should == shiftwidth + end + end + + describe "o within TODO" do + before { + vim.feedkeys '\ggdG' + vim.feedkeys 'iif 1: # TODO\' + # Assertion that we have a pythonTodo here. + vim.echo('synIDattr(synID(line("."), col("."), 0), "name")').should match 'pythonTodo' + } + + it "respects autoindent" do + vim.feedkeys 'o' + indent.should == shiftwidth + end + end + + describe "elif after else" do + before { + vim.feedkeys '\ggdG' + } + + it "is indented to the outer if" do + vim.feedkeys 'iif 1:\if 2:\pass\else:\pass\elif 3:\' + indent.should == 0 + + vim.feedkeys '\ggdG' + vim.feedkeys 'i if 1:\if 2:\pass\else:\pass\elif 3:\' + indent.should == 4 + end + end + + describe "elif after two ifs" do + before { + vim.feedkeys '\ggdG' + } + + it "keeps its indent to the outer if" do + vim.feedkeys 'iif 1:\if 2:\pass\elif 3:\pass\' + indent.should == 4 + vim.feedkeys '\' + indent.should == 0 + proposed_indent.should == shiftwidth + vim.feedkeys 'ielif 4:' + indent.should == 0 + proposed_indent.should == 0 + vim.feedkeys '\' + indent.should == 4 + proposed_indent.should == 4 + end + end diff --combined .vim/bundle/vim-python-pep8-indent/spec/make-coverage index 0000000,f425496..f425496 mode 000000,100755..100755 --- a/.vim/bundle/vim-python-pep8-indent/spec/make-coverage +++ b/.vim/bundle/vim-python-pep8-indent/spec/make-coverage @@@ -1,0 -1,24 +1,24 @@@ + #!/bin/sh + + set -ex + + rm -f .coverage_covimerage + export PYTHON_PEP8_INDENT_TEST_PROFILE_BASE=/tmp/vim-python-pep8-profile + + Xvfb :99 2>/dev/null >&2 & + export DISPLAY=:99 + + export VIMRUNNER_REUSE_SERVER=1 + + ret=0 + for file in ./spec/indent/*_spec.rb; do + # shellcheck disable=SC2086 + bundle exec rspec "$file" $RSPEC_OPTIONS || ret=1 + + for p in "${PYTHON_PEP8_INDENT_TEST_PROFILE_BASE}".*; do + covimerage write_coverage --append "$p" + rm "$p" + covimerage report -m + done + done + exit $ret diff --combined .vim/bundle/vim-python-pep8-indent/spec/spec_helper.rb index 0000000,c6cc517..c6cc517 mode 000000,100644..100644 --- a/.vim/bundle/vim-python-pep8-indent/spec/spec_helper.rb +++ b/.vim/bundle/vim-python-pep8-indent/spec/spec_helper.rb @@@ -1,0 -1,70 +1,70 @@@ + require 'vimrunner' + require 'vimrunner/rspec' + require 'vimrunner/server' + + # Explicitly enable usage of "should". + RSpec.configure do |config| + config.expect_with(:rspec) { |c| c.syntax = :should } + end + + Vimrunner::RSpec.configure do |config| + # Use a single Vim instance for the test suite. Set to false to use an + # instance per test (slower, but can be easier to manage). + # This requires using gvim, otherwise it hangs after a few tests. + config.reuse_server = ENV['VIMRUNNER_REUSE_SERVER'] == '1' ? true : false + + config.start_vim do + exe = config.reuse_server ? Vimrunner::Platform.gvim : Vimrunner::Platform.vim + vimrc = File.expand_path("../vimrc", __FILE__) + vim = Vimrunner::Server.new(:executable => exe, + :vimrc => vimrc).start + # More friendly killing. + # Otherwise profiling information might not be written. + def vim.kill + normal(':qall!') + + Timeout.timeout(5) do + sleep 0.1 while server.running? + end + end + + plugin_path = File.expand_path('../..', __FILE__) + vim.command "set rtp^=#{plugin_path}" + vim.command "set filetype=python" + + def shiftwidth + @shiftwidth ||= vim.echo("exists('*shiftwidth') ? shiftwidth() : &sw").to_i + end + def tabstop + @tabstop ||= vim.echo("&tabstop").to_i + end + def indent + vim.echo("indent('.')").to_i + end + def previous_indent + pline = vim.echo("line('.')").to_i - 1 + vim.echo("indent('#{pline}')").to_i + end + def proposed_indent + line = vim.echo("line('.')") + col = vim.echo("col('.')") + indent_value = vim.echo("GetPythonPEPIndent(#{line})").to_i + vim.command("call cursor(#{line}, #{col})") + return indent_value + end + def multiline_indent(prev, default) + i = vim.echo("get(g:, 'python_pep8_indent_multiline_string', 0)").to_i + return (i == -2 ? default : i), i < 0 ? (i == -1 ? prev : default) : i + end + def hang_closing + i = vim.echo("get(g:, 'python_pep8_indent_hang_closing', 0)").to_i + return (i != 0) + end + def set_hang_closing(value) + i = value ? 1 : 0 + vim.command("let g:python_pep8_indent_hang_closing=#{i}") + end + + vim + end + end diff --combined .vim/bundle/vim-python-pep8-indent/spec/vimrc index 0000000,e549f80..e549f80 mode 000000,100644..100644 --- a/.vim/bundle/vim-python-pep8-indent/spec/vimrc +++ b/.vim/bundle/vim-python-pep8-indent/spec/vimrc @@@ -1,0 -1,22 +1,22 @@@ + " vint: -ProhibitSetNoCompatible + set nocompatible + + filetype plugin on + filetype indent on + syntax on + + set noswapfile nobackup + + " remove default ~/.vim directories to avoid loading plugins + set runtimepath-=~/.vim + set runtimepath-=~/.vim/after + + let sfile = expand('') + let plugin_path = fnamemodify(sfile, ':p:h:h') + exe 'set runtimepath^='.plugin_path + + if !empty($PYTHON_PEP8_INDENT_TEST_PROFILE_BASE) + execute printf('profile start %s.%s', + \ $PYTHON_PEP8_INDENT_TEST_PROFILE_BASE, getpid()) + execute 'profile! file '. plugin_path . '/indent/python.vim' + endif