diff --git a/README.md b/README.md
index d60eca52..208657bf 100644
--- a/README.md
+++ b/README.md
@@ -126,9 +126,11 @@ I recommend reading the docs of these plugins to understand them better. Each pl
* [vim-markdown](https://github.com/tpope/vim-markdown)
* [nginx.vim](https://github.com/vim-scripts/nginx.vim): Highlights configuration files for nginx
* [vim-go](https://github.com/fatih/vim-go)
+* [rust.vim](https://github.com/rust-lang/rust.vim)
* [vim-ruby](https://github.com/vim-ruby/vim-ruby)
* [typescript-vim](https://github.com/leafgarland/typescript-vim)
* [vim-javascript](https://github.com/pangloss/vim-javascript)
+* [vim-python-pep8-indent](https://github.com/Vimjas/vim-python-pep8-indent)
## How to include your own stuff?
diff --git a/sources_non_forked/vim-python-pep8-indent/.circleci/config.yml b/sources_non_forked/vim-python-pep8-indent/.circleci/config.yml
new file mode 100644
index 00000000..8d54439b
--- /dev/null
+++ b/sources_non_forked/vim-python-pep8-indent/.circleci/config.yml
@@ -0,0 +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 --git a/sources_non_forked/vim-python-pep8-indent/.coveragerc b/sources_non_forked/vim-python-pep8-indent/.coveragerc
new file mode 100644
index 00000000..74cc24e8
--- /dev/null
+++ b/sources_non_forked/vim-python-pep8-indent/.coveragerc
@@ -0,0 +1,7 @@
+[run]
+plugins = covimerage
+data_file = .coverage_covimerage
+source = indent/python.vim
+
+[report]
+include = indent/python.vim
diff --git a/sources_non_forked/vim-python-pep8-indent/.dockerignore b/sources_non_forked/vim-python-pep8-indent/.dockerignore
new file mode 100644
index 00000000..1a99a797
--- /dev/null
+++ b/sources_non_forked/vim-python-pep8-indent/.dockerignore
@@ -0,0 +1,2 @@
+*
+!Gemfile
diff --git a/sources_non_forked/vim-python-pep8-indent/.gitignore b/sources_non_forked/vim-python-pep8-indent/.gitignore
new file mode 100644
index 00000000..e8035f64
--- /dev/null
+++ b/sources_non_forked/vim-python-pep8-indent/.gitignore
@@ -0,0 +1,3 @@
+.*.swp
+.coverage_covimerage
+Gemfile.lock
diff --git a/sources_non_forked/vim-python-pep8-indent/CONTRIBUTING.rst b/sources_non_forked/vim-python-pep8-indent/CONTRIBUTING.rst
new file mode 100644
index 00000000..094f20ad
--- /dev/null
+++ b/sources_non_forked/vim-python-pep8-indent/CONTRIBUTING.rst
@@ -0,0 +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 --git a/sources_non_forked/vim-python-pep8-indent/COPYING.txt b/sources_non_forked/vim-python-pep8-indent/COPYING.txt
new file mode 100644
index 00000000..0e259d42
--- /dev/null
+++ b/sources_non_forked/vim-python-pep8-indent/COPYING.txt
@@ -0,0 +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 --git a/sources_non_forked/vim-python-pep8-indent/Dockerfile b/sources_non_forked/vim-python-pep8-indent/Dockerfile
new file mode 100644
index 00000000..14e39ea1
--- /dev/null
+++ b/sources_non_forked/vim-python-pep8-indent/Dockerfile
@@ -0,0 +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 --git a/sources_non_forked/vim-python-pep8-indent/Gemfile b/sources_non_forked/vim-python-pep8-indent/Gemfile
new file mode 100644
index 00000000..9bbf5968
--- /dev/null
+++ b/sources_non_forked/vim-python-pep8-indent/Gemfile
@@ -0,0 +1,3 @@
+source 'https://rubygems.org'
+gem "vimrunner", "0.3.4"
+gem "rspec"
diff --git a/sources_non_forked/vim-python-pep8-indent/Makefile b/sources_non_forked/vim-python-pep8-indent/Makefile
new file mode 100644
index 00000000..2566d411
--- /dev/null
+++ b/sources_non_forked/vim-python-pep8-indent/Makefile
@@ -0,0 +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 --git a/sources_non_forked/vim-python-pep8-indent/README.rst b/sources_non_forked/vim-python-pep8-indent/README.rst
new file mode 100644
index 00000000..77be58cc
--- /dev/null
+++ b/sources_non_forked/vim-python-pep8-indent/README.rst
@@ -0,0 +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 --git a/sources_non_forked/vim-python-pep8-indent/docker-compose.yml b/sources_non_forked/vim-python-pep8-indent/docker-compose.yml
new file mode 100644
index 00000000..71760c2d
--- /dev/null
+++ b/sources_non_forked/vim-python-pep8-indent/docker-compose.yml
@@ -0,0 +1,6 @@
+version: '2'
+services:
+ rspec:
+ build: .
+ volumes:
+ - .:/vim-python-pep8-indent
diff --git a/sources_non_forked/vim-python-pep8-indent/indent/cython.vim b/sources_non_forked/vim-python-pep8-indent/indent/cython.vim
new file mode 100644
index 00000000..4407bc18
--- /dev/null
+++ b/sources_non_forked/vim-python-pep8-indent/indent/cython.vim
@@ -0,0 +1 @@
+python.vim
\ No newline at end of file
diff --git a/sources_non_forked/vim-python-pep8-indent/indent/python.vim b/sources_non_forked/vim-python-pep8-indent/indent/python.vim
new file mode 100644
index 00000000..aca216e7
--- /dev/null
+++ b/sources_non_forked/vim-python-pep8-indent/indent/python.vim
@@ -0,0 +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 lnum = a:lnum
+ let last_indent = indent(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 - 1, 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 --git a/sources_non_forked/vim-python-pep8-indent/spec/indent/bytes_spec.rb b/sources_non_forked/vim-python-pep8-indent/spec/indent/bytes_spec.rb
new file mode 100644
index 00000000..3d6744e8
--- /dev/null
+++ b/sources_non_forked/vim-python-pep8-indent/spec/indent/bytes_spec.rb
@@ -0,0 +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 --git a/sources_non_forked/vim-python-pep8-indent/spec/indent/cython_spec.rb b/sources_non_forked/vim-python-pep8-indent/spec/indent/cython_spec.rb
new file mode 100644
index 00000000..03dcbb2a
--- /dev/null
+++ b/sources_non_forked/vim-python-pep8-indent/spec/indent/cython_spec.rb
@@ -0,0 +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 --git a/sources_non_forked/vim-python-pep8-indent/spec/indent/indent_spec.rb b/sources_non_forked/vim-python-pep8-indent/spec/indent/indent_spec.rb
new file mode 100644
index 00000000..55e2fba4
--- /dev/null
+++ b/sources_non_forked/vim-python-pep8-indent/spec/indent/indent_spec.rb
@@ -0,0 +1,776 @@
+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
diff --git a/sources_non_forked/vim-python-pep8-indent/spec/make-coverage b/sources_non_forked/vim-python-pep8-indent/spec/make-coverage
new file mode 100644
index 00000000..f425496a
--- /dev/null
+++ b/sources_non_forked/vim-python-pep8-indent/spec/make-coverage
@@ -0,0 +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 --git a/sources_non_forked/vim-python-pep8-indent/spec/spec_helper.rb b/sources_non_forked/vim-python-pep8-indent/spec/spec_helper.rb
new file mode 100644
index 00000000..c6cc5174
--- /dev/null
+++ b/sources_non_forked/vim-python-pep8-indent/spec/spec_helper.rb
@@ -0,0 +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 --git a/sources_non_forked/vim-python-pep8-indent/spec/vimrc b/sources_non_forked/vim-python-pep8-indent/spec/vimrc
new file mode 100644
index 00000000..e549f80e
--- /dev/null
+++ b/sources_non_forked/vim-python-pep8-indent/spec/vimrc
@@ -0,0 +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
diff --git a/update_plugins.py b/update_plugins.py
index 7bafc2fa..a1145096 100644
--- a/update_plugins.py
+++ b/update_plugins.py
@@ -13,7 +13,7 @@ import requests
from os import path
-#--- Globals ----------------------------------------------
+# --- Globals ----------------------------------------------
PLUGINS = """
auto-pairs https://github.com/jiangmiao/auto-pairs
ale https://github.com/w0rp/ale
@@ -61,6 +61,7 @@ gist-vim https://github.com/mattn/gist-vim
vim-ruby https://github.com/vim-ruby/vim-ruby
typescript-vim https://github.com/leafgarland/typescript-vim
vim-javascript https://github.com/pangloss/vim-javascript
+vim-python-pep8-indent https://github.com/Vimjas/vim-python-pep8-indent
""".strip()
GITHUB_ZIP = '%s/archive/master.zip'
diff --git a/vimrcs/filetypes.vim b/vimrcs/filetypes.vim
index 9ce67913..33768bdf 100644
--- a/vimrcs/filetypes.vim
+++ b/vimrcs/filetypes.vim
@@ -17,9 +17,6 @@ au FileType python map 1 /class
au FileType python map 2 /def
au FileType python map C ?class
au FileType python map D ?def
-au FileType python set cindent
-au FileType python set cinkeys-=0#
-au FileType python set indentkeys-=0#
""""""""""""""""""""""""""""""