├── .bumpversion.cfg ├── .github ├── FUNDING.yml ├── stale.yml └── workflows │ └── test_pymode.yml ├── .gitignore ├── .gitmodules ├── AUTHORS ├── CHANGELOG.md ├── COPYING ├── after ├── ftplugin │ ├── pyrex.vim │ └── python.vim └── indent │ ├── pyrex.vim │ └── python.vim ├── autoload ├── pymode.vim └── pymode │ ├── breakpoint.vim │ ├── debug.vim │ ├── doc.vim │ ├── folding.vim │ ├── indent.vim │ ├── lint.vim │ ├── motion.vim │ ├── rope.vim │ ├── run.vim │ ├── tools │ ├── loclist.vim │ └── signs.vim │ └── virtualenv.vim ├── debugvimrc.vim ├── doc └── pymode.txt ├── ftplugin ├── pyrex.vim └── python │ └── pymode.vim ├── logo.png ├── plugin └── pymode.vim ├── pylama.ini ├── pymode ├── __init__.py ├── async.py ├── autopep8.py ├── environment.py ├── libs │ ├── __init__.py │ ├── appdirs.py │ ├── astroid │ ├── mccabe.py │ ├── pycodestyle.py │ ├── pydocstyle │ ├── pyflakes │ ├── pylama │ ├── pylint │ ├── pytoolconfig │ ├── rope │ ├── snowballstemmer │ ├── toml │ └── tomli ├── lint.py ├── rope.py ├── run.py ├── utils.py └── virtualenv.py ├── readme.md ├── syntax ├── pyrex.vim └── python.vim └── tests ├── motion_decorator.py ├── test.sh ├── test_bash ├── test_autocommands.sh ├── test_autopep8.sh ├── test_folding.sh ├── test_pymodelint.sh └── test_textobject.sh ├── test_helpers_bash ├── test_createvimrc.sh ├── test_prepare_between_tests.sh ├── test_prepare_once.sh └── test_variables.sh ├── test_helpers_vimscript ├── inserting_text.vim ├── md5sum.vim └── moving_around.vim ├── test_procedures_vimscript ├── autopep8.vim ├── folding1.vim ├── folding2.vim ├── folding3.vim ├── folding4.vim ├── pymodelint.vim ├── pymoderun.vim ├── pymodeversion.vim └── textobject.vim ├── test_python_sample_code ├── algorithms.py ├── folding1.py ├── folding2.py ├── from_autopep8.py └── pymoderun_sample.py └── utils ├── pymoderc └── vimrc /.bumpversion.cfg: -------------------------------------------------------------------------------- 1 | [bumpversion] 2 | commit = True 3 | current_version = 0.14.0 4 | files = plugin/pymode.vim 5 | tag = True 6 | tag_name = {new_version} 7 | 8 | [bumpversion:file:doc/pymode.txt] 9 | search = Version: {current_version} 10 | replace = Version: {new_version} 11 | 12 | [bumpversion:file:CHANGELOG.md] 13 | search = Version: {current_version} 14 | replace = Version: {new_version} 15 | -------------------------------------------------------------------------------- /.github/FUNDING.yml: -------------------------------------------------------------------------------- 1 | # These are supported funding model platforms 2 | 3 | liberapay: diraol 4 | -------------------------------------------------------------------------------- /.github/stale.yml: -------------------------------------------------------------------------------- 1 | # Number of days of inactivity before an issue becomes stale 2 | daysUntilStale: 150 3 | # Number of days of inactivity before a stale issue is closed 4 | daysUntilClose: 21 5 | # Issues with these labels will never be considered stale 6 | exemptLabels: 7 | - pinned 8 | - security 9 | # Label to use when marking an issue as stale 10 | staleLabel: inactive 11 | # Comment to post when marking an issue as stale. Set to `false` to disable 12 | markComment: > 13 | This issue has been automatically marked as stale because it has not had 14 | recent activity. It will be closed if no further activity occurs. Thank you 15 | for your contributions. 16 | # Comment to post when closing a stale issue. Set to `false` to disable 17 | closeComment: > 18 | Closed due to inactivity. 19 | -------------------------------------------------------------------------------- /.github/workflows/test_pymode.yml: -------------------------------------------------------------------------------- 1 | name: Testing python-mode 2 | 3 | on: [push] 4 | 5 | jobs: 6 | test-python-3_8: 7 | runs-on: ubuntu-latest 8 | steps: 9 | - uses: actions/checkout@v1 10 | - name: Install dependencies 11 | run: | 12 | sudo apt update 13 | export PYTHON_CONFIGURE_OPTS="--enable-shared" 14 | sudo apt install -yqq libncurses5-dev libgtk2.0-dev libatk1.0-dev libcairo2-dev libx11-dev libxpm-dev libxt-dev python3-dev lua5.2 liblua5.2-dev libperl-dev git 15 | sudo apt remove --purge -yqq vim vim-runtime gvim 16 | - name: build and install vim from source 17 | working-directory: /tmp 18 | run: | 19 | export PYTHON_CONFIGURE_OPTS="--enable-shared" 20 | git clone https://github.com/vim/vim.git 21 | cd vim 22 | ./configure --with-features=huge --enable-multibyte --enable-python3interp=yes --with-python3-config-dir=/usr/lib/python3.8/config-3.8m-x86_64-linux-gnu --enable-perlinterp=yes --enable-luainterp=yes --enable-cscope --prefix=/usr/local 23 | sudo make && sudo make install 24 | - name: Install python-mode 25 | run: | 26 | export PYMODE_DIR="${HOME}/work/python-mode/python-mode" 27 | mkdir -p ${HOME}/.vim/pack/foo/start/ 28 | ln -s ${PYMODE_DIR} ${HOME}/.vim/pack/foo/start/python-mode 29 | cp ${PYMODE_DIR}/tests/utils/pymoderc ${HOME}/.pymoderc 30 | cp ${PYMODE_DIR}/tests/utils/vimrc ${HOME}/.vimrc 31 | touch ${HOME}/.vimrc.before ${HOME}/.vimrc.after 32 | - name: Run python-mode test script 33 | run: | 34 | alias python=python3 35 | cd ${HOME}/work/python-mode/python-mode 36 | git submodule update --init --recursive 37 | git submodule sync 38 | bash tests/test.sh 39 | test-python-3_9: 40 | runs-on: ubuntu-latest 41 | steps: 42 | - uses: actions/checkout@v1 43 | - name: Install dependencies 44 | run: | 45 | sudo apt update 46 | export PYTHON_CONFIGURE_OPTS="--enable-shared" 47 | sudo apt install -yqq libncurses5-dev libgtk2.0-dev libatk1.0-dev libcairo2-dev libx11-dev libxpm-dev libxt-dev python3-dev lua5.2 liblua5.2-dev libperl-dev git 48 | sudo apt remove --purge -yqq vim vim-runtime gvim 49 | - name: build and install vim from source 50 | working-directory: /tmp 51 | run: | 52 | export PYTHON_CONFIGURE_OPTS="--enable-shared" 53 | git clone https://github.com/vim/vim.git 54 | cd vim 55 | ./configure --with-features=huge --enable-multibyte --enable-python3interp=yes --with-python3-config-dir=/usr/lib/python3.9/config-3.9m-x86_64-linux-gnu --enable-perlinterp=yes --enable-luainterp=yes --enable-cscope --prefix=/usr/local 56 | sudo make && sudo make install 57 | - name: Install python-mode 58 | run: | 59 | export PYMODE_DIR="${HOME}/work/python-mode/python-mode" 60 | mkdir -p ${HOME}/.vim/pack/foo/start/ 61 | ln -s ${PYMODE_DIR} ${HOME}/.vim/pack/foo/start/python-mode 62 | cp ${PYMODE_DIR}/tests/utils/pymoderc ${HOME}/.pymoderc 63 | cp ${PYMODE_DIR}/tests/utils/vimrc ${HOME}/.vimrc 64 | touch ${HOME}/.vimrc.before ${HOME}/.vimrc.after 65 | - name: Run python-mode test script 66 | run: | 67 | alias python=python3 68 | cd ${HOME}/work/python-mode/python-mode 69 | git submodule update --init --recursive 70 | git submodule sync 71 | bash tests/test.sh 72 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | *.py[cod] 2 | *.sw? 3 | *~ 4 | .DS_Store 5 | .bundle 6 | .ropeproject 7 | .vim-flavor 8 | .vimrc 9 | Gemfile.lock 10 | VimFlavor.lock 11 | _ 12 | build 13 | tags 14 | test.py 15 | todo.txt 16 | vendor 17 | vim.py 18 | vim_session_*.vim 19 | __*/ 20 | -------------------------------------------------------------------------------- /.gitmodules: -------------------------------------------------------------------------------- 1 | [submodule "submodules/autopep8"] 2 | path = submodules/autopep8 3 | url = https://github.com/hhatto/autopep8 4 | ignore = dirty 5 | shallow = true 6 | [submodule "submodules/pycodestyle"] 7 | path = submodules/pycodestyle 8 | url = https://github.com/PyCQA/pycodestyle 9 | ignore = dirty 10 | shallow = true 11 | [submodule "submodules/pydocstyle"] 12 | path = submodules/pydocstyle 13 | url = https://github.com/PyCQA/pydocstyle 14 | ignore = dirty 15 | shallow = true 16 | [submodule "submodules/mccabe"] 17 | path = submodules/mccabe 18 | url = https://github.com/PyCQA/mccabe 19 | ignore = dirty 20 | shallow = true 21 | [submodule "submodules/pyflakes"] 22 | path = submodules/pyflakes 23 | url = https://github.com/PyCQA/pyflakes 24 | ignore = dirty 25 | shallow = true 26 | [submodule "submodules/snowball_py"] 27 | path = submodules/snowball_py 28 | url = https://github.com/diraol/snowball_py 29 | ignore = dirty 30 | branch = develop 31 | shallow = true 32 | [submodule "submodules/pylint"] 33 | path = submodules/pylint 34 | url = https://github.com/PyCQA/pylint 35 | shallow = true 36 | [submodule "submodules/rope"] 37 | path = submodules/rope 38 | url = https://github.com/python-rope/rope 39 | shallow = true 40 | [submodule "submodules/astroid"] 41 | path = submodules/astroid 42 | url = https://github.com/PyCQA/astroid 43 | shallow = true 44 | [submodule "submodules/pylama"] 45 | path = submodules/pylama 46 | url = https://github.com/klen/pylama 47 | shallow = true 48 | [submodule "submodules/toml"] 49 | path = submodules/toml 50 | url = https://github.com/uiri/toml.git 51 | [submodule "submodules/pytoolconfig"] 52 | path = submodules/pytoolconfig 53 | url = https://github.com/bagel897/pytoolconfig.git 54 | [submodule "submodules/tomli"] 55 | path = submodules/tomli 56 | url = https://github.com/hukkin/tomli.git 57 | [submodule "submodules/appdirs"] 58 | path = submodules/appdirs 59 | url = https://github.com/ActiveState/appdirs.git 60 | -------------------------------------------------------------------------------- /AUTHORS: -------------------------------------------------------------------------------- 1 | Author: 2 | 3 | * Kirill Klenov 4 | 5 | Maintainers: 6 | 7 | * Diego Rabatone Oliveira (https://github.com/diraol); 8 | 9 | Contributors: 10 | 11 | * Alvin Francis (http://github.com/alvinfrancis); 12 | * Amir Eldor (https://github.com/amireldor); 13 | * Andriy Kohut (https://github.com/andriykohut); 14 | * Anler Hp (http://github.com/ikame); 15 | * Anton Parkhomenko (http://github.com/chuwy); 16 | * Ashley Hewson (http://github.com/ashleyh); 17 | * Ben Davis (https://github.com/bendavis78); 18 | * Benjamin Ruston (http://github.com/bruston); 19 | * Boatx (https://github.com/boatx); 20 | * Boris Filippov (http://github.com/frenzykryger); 21 | * Brad Belyeu (https://github.com/bbelyeu); 22 | * Brad Mease (http://github.com/bmease); 23 | * Brendan Maguire (https://github.com/brendanmaguire); 24 | * Bryce Guinta (https://github.com/brycepg); 25 | * Daniel Hahler (http://github.com/blueyed); 26 | * David Vogt (http://github.com/winged); 27 | * Denis Kasak (http://github.com/dkasak); 28 | * Dimitrios Semitsoglou-Tsiapos (https://github.com/dset0x); 29 | * Dirk Wallenstein (http://github.com/dirkwallenstein); 30 | * Felipe M. Vieira (https://github.com/fmv1992) 31 | * Filip Poboril (https://github.com/fpob); 32 | * Florent Xicluna (http://github.com/florentx); 33 | * Fredrik Henrysson (http://github.com/fhenrysson); 34 | * fwuzju (https://github.com/fwuzju); 35 | * Grzegorz Janik (http://github.com/glujan); 36 | * Igor Guerrero (http://github.com/igorgue); 37 | * Jacob Niehus (https://github.com/wilywampa); 38 | * Jason Harvey (http://github.com/alienth); 39 | * Jay Rainey (https://github.com/jawrainey); 40 | * Jonathan McCall (http://github.com/Jonnymcc); 41 | * Kevin Deldycke (http://github.com/kdeldycke); 42 | * Kurtis Rader (https://github.com/krader1961); 43 | * Lawrence Akka (https://github.com/lawrenceakka); 44 | * lee (https://github.com/loyalpartner); 45 | * Lie Ryan (https://github.com/lieryan/); 46 | * Lowe Thiderman (http://github.com/thiderman); 47 | * Martin Brochhaus (http://github.com/mbrochh); 48 | * Matt Dodge (https://github.com/mattdodge); 49 | * Matthew Moses (http://github.com/mlmoses); 50 | * Maxim (https://github.com/mpyatishev); 51 | * Mel Boyce (http://github.com/syngin); 52 | * Mohammed (http://github.com/mbadran); 53 | * Naoya Inada (http://github.com/naoina); 54 | * Nate Zhang (https://github.com/natezhang93); 55 | * nixon (https://github.com/nixon); 56 | * Paweł Korzeniewski (https://github.com/korzeniewskipl); 57 | * Pedro Algarvio (http://github.com/s0undt3ch); 58 | * Phillip Cloud (http://github.com/cpcloud); 59 | * Pi Delport (http://github.com/pjdelport); 60 | * Robert David Grant (http://github.com/bgrant); 61 | * Robin Schneider (https://github.com/ypid); 62 | * Ronald Andreu Kaiser (http://github.com/cathoderay);; 63 | * Samir Benmendil (https://github.com/Ram-Z); 64 | * Sorin Ionescu (sorin-ionescu); 65 | * sphaugh (https://github.com/sphaugh); 66 | * Steve Losh (http://github.com/sjl); 67 | * Tommy Allen (https://github.com/tweekmonster); 68 | * Tony Narlock (https://github.com/tony); 69 | * tramchamploo (https://github.com/tramchamploo); 70 | * Tyler Fenby (https://github.com/TFenby); 71 | * Vincent Driessen (https://github.com/nvie); 72 | * Wang Feng (https://github.com/mapler); 73 | * Wayne Ye (https://github.com/WayneYe); 74 | * Wes Turner (https://github.com/westurner); 75 | * Yury A. Kartynnik (https://github.com/kartynnik); 76 | * Xiangyu Xu (https://github.com/bkbncn); 77 | * Zach Himsel (https://github.com/zhimsel); 78 | * Nathan Pemberton (https://github.com/NathanTP); 79 | -------------------------------------------------------------------------------- /CHANGELOG.md: -------------------------------------------------------------------------------- 1 | # Changelog 2 | 3 | ## TODO 4 | 5 | ## 2023-07-02 0.14.0 6 | 7 | - Update submodules 8 | - Fix Errors related to these updates 9 | - Improve tests outputs 10 | - Fix Global and Module MoveRefactoring (#1141) Thanks to @lieryan 11 | - Text object/operator/motion mapping to select logical line (#1145). Thanks to 12 | @lieryan 13 | - Remove dead keywords and builtins; add match, case (#1149). Thanks to 14 | @NeilGirdhar 15 | - Add syntax highlight for walrus (#1147) Thanks to @fpob 16 | - Add configurable prefix for rope commands (#1137) TThanks to @NathanTP 17 | - Add option g:pymode_indent_hanging_width for different hanging indentation 18 | width (#1138). Thanks to @wookayin 19 | 20 | ## 2020-10-08 0.13.0 21 | 22 | - Add toml submodule 23 | 24 | ## 2020-10-08 0.12.0 25 | 26 | - Improve breakpoint feature 27 | - Improve debugging script 28 | - Update submodules 29 | - Improve tests 30 | 31 | ## 2020-05-28 0.11.0 32 | 33 | - Move changelog rst syntax to markdown 34 | - `pymode_rope`: check disables 35 | - BREAKING CHANGE: Remove supoort for python 2. From 0.11.0 on we will focus on 36 | supporting python 3+ (probably 3.5+). 37 | - Inspect why files starting with the following code do not get loaded: 38 | 39 | ```python 40 | def main(): 41 | pass 42 | 43 | if __name__ == '__main__': 44 | main() 45 | ``` 46 | 47 | - added github actions test suit and remove travis 48 | - improved submodules cloning (shallow) 49 | - Removes `six` submodule 50 | - Fix motion mapping 51 | - Fix breakpoint feature 52 | 53 | ## 2019-05-11 0.10.0 54 | 55 | After many changes, including moving most of our dependencies from copied 56 | source code to submodules, and lot's of problems maintaining Python 2 and 57 | Python 3 support, this (0.10.x) is the last version of python-mode that will 58 | support Python 2. Some patches may be done in order to fix issues related to 59 | Python 2 or some backward compatible changes that can be applied. 60 | 61 | ## 2017-07-xxx 0.9.5 62 | 63 | - pylama: migrated to submodule 64 | 65 | ## 2017-07-11 0.9.4 66 | 67 | - pylama: fixed erratic behavior of skip option causing unintended 68 | skipping of lint checkers 69 | 70 | - PEP257 requires `snowbalstemmer`: added as submodule 71 | 72 | - Fixed handling of `g:pymode_lint_ignore` and `g:pymode_lint_select`: from 73 | strings to list 74 | 75 | - Migrated modules from pymode/libs to 76 | [submodules/](https://github.com/fmv1992/python-mode/tree/develop/submodules) 77 | 78 | - Rationale: no need to single handedly update each module; 79 | removes burden from developers 80 | 81 | - Improved folding accuracy 82 | 83 | - Improved nested definitions folding 84 | - Improved block delimiting 85 | 86 | ## (changelog poorly maintained) 0.8.2 87 | 88 | - Pylama updated to version 5.0.5 89 | - Rope libs updated 90 | - Add wdb to debugger list in breakpoint cmd 91 | - Add `pymode_options_max_line_length` option 92 | - Add ability to set related checker options `:help pymode-lint-options` 93 | Options added: `pymode_lint_options_pep8`, `pymode_lint_options_pep257`, 94 | `pymode_lint_options_mccabe`, `pymode_lint_options_pyflakes`, 95 | `pymode_lint_options_pylint` 96 | - Highlight comments inside class/function arg lists 97 | - Don't fold single line def 98 | - Don't skip a line when the first docstring contains text 99 | - Add Python documentation vertical display option 100 | - Rope: correct refactoring function calls 101 | 102 | ## 2014-06-11 0.8.1 103 | 104 | - Pylama updated to version 3.3.2 105 | 106 | - Get fold's expression symbol from &fillchars; 107 | 108 | - Fixed error when setting `g:pymode_breakpoint_cmd` (expobrain); 109 | 110 | - Fixed code running; 111 | 112 | - Ability to override rope project root and .ropeproject folder 113 | 114 | - Added path argument to PymodeRopeNewProject which skips prompt 115 | 116 | - Disable `pymode_rope_lookup_project` by default 117 | 118 | - Options added: 119 | - `pymode_rope_project_root`, `pymode_rope_ropefolder` 120 | 121 | ## 2013-12-04 0.7.8b 122 | 123 | - Update indentation support; 124 | 125 | - Python3 support; 126 | 127 | - Removed pymode modeline support; 128 | 129 | - Disabled async code checking support; 130 | 131 | - Options changes: 132 | - `pymode_doc_key` -> `pymode_doc_bind` 133 | - `pymode_run_key` -> `pymode_run_bind` 134 | - `pymode_breakpoint_key` -> `pymode_breakpoint_bind` 135 | - `pymode_breakpoint_template` -> `pymode_breakpoint_cmd` 136 | - `pymode_lint_write` -> `pymode_lint_on_write` 137 | - `pymode_lint_onfly` -> `pymode_lint_on_fly` 138 | - `pymode_lint_checker` -> `pymode_lint_checkers` 139 | - `pymode_lint_minheight` -> `pymode_quickfix_minheight` 140 | - `pymode_lint_maxheight` -> `pymode_quickfix_maxheight` 141 | - `pymode_rope_autocomplete_map` -> `pymode_rope_completion_bind` 142 | - `pymode_rope_enable_autoimport` -> `pymode_rope_autoimport` 143 | 144 | - Options removed: 145 | 146 | - `pymode_lint_hold`, `pymode_lint_config`, `pymode_lint_jump`, 147 | `pymode_lint_signs_always_visible`, `pymode_rope_extended_complete`, 148 | `pymode_rope_auto_project`, `pymode_rope_autoimport_generate`, 149 | `pymode_rope_autoimport_underlines`, `pymode_rope_codeassist_maxfixes`, 150 | `pymode_rope_sorted_completions`, `pymode_rope_extended_complete`, 151 | `pymode_rope_confirm_saving`, `pymode_rope_global_prefix`, 152 | `pymode_rope_local_prefix`, `pymode_rope_vim_completion`, 153 | `pymode_rope_guess_project`, `pymode_rope_goto_def_newwin`, 154 | `pymode_rope_always_show_complete_menu` 155 | 156 | - Options added: 157 | 158 | - `pymode_rope_regenerate_on_write`, `pymode_rope_completion`, 159 | `pymode_rope_complete_on_dot`, `pymode_lint_sort`, 160 | `pymode_rope_lookup_project`, `pymode_lint_unmodified` 161 | 162 | - Commands added: 163 | 164 | - `PymodeVirtualenv` 165 | 166 | - Commands changed: 167 | 168 | - `PyDoc` -> `PymodeDoc` 169 | - `Pyrun` -> `PymodeRun` 170 | - `PyLintToggle` -> `PymodeLintToggle` 171 | - `PyLint` -> `PymodeLint` 172 | - `PyLintAuto` -> `PymodeLintAuto` 173 | - `RopeOpenProject` -> `PymodeRopeNewProject` 174 | - `RopeUndo` -> `PymodeRopeUndo` 175 | - `RopeRedo` -> `PymodeRopeRedo` 176 | - `RopeRenameCurrentModule` -> `PymodeRopeRenameModule` 177 | - `RopeModuleToPackage` -> `PymodeRopeModuleToPackage` 178 | - `RopeGenerateAutoimportCache` -> `PymodeRopeRegenerate` 179 | - `RopeOrgamizeImports` -> `PymodeRopeAutoImport` 180 | 181 | - Commands removed: 182 | - `PyLintCheckerToggle`, `RopeCloseProject`, `RopeProjectConfig`, 183 | `RopeRename`, `RopeCreate<...>`, `RopeWriteProject`, `RopeRename`, 184 | `RopeExtractVariable`, `RopeExtractMethod`, `RopeInline`, `RopeMove`, 185 | `RopeRestructure`, `RopeUseFunction`, `RopeIntroduceFactory`, 186 | `RopeChangeSignature`, `RopeMoveCurrentModule`, `RopeGenerate<...>`, 187 | `RopeAnalizeModule`, `RopeAutoImport` 188 | 189 | ## 2013-10-29 0.6.19 190 | 191 | - Added `g:pymode_rope_autocomplete_map` option; 192 | - Removed `g:pymode_rope_map_space` option; 193 | - Added PEP257 checker; 194 | - Support 'pudb' in breakpoints; 195 | - Pyrun can now operate on a range of lines, and does not need to save 196 | (c) lawrenceakka 197 | - Update pylama to version 1.5.0 198 | - Add a set of `g:pymode_lint_*_symbol` options (c) kdeldycke; 199 | - Support virtualenv for python3 (c) mlmoses; 200 | 201 | ## 2013-05-15 0.6.18 202 | 203 | - Fixed autopep8 (PyLintAuto) command; 204 | - Fix error on non-ascii characters in docstrings; 205 | - Update python syntax; 206 | 207 | ## 2013-05-03 0.6.17 208 | 209 | - Update Pylint to version 0.28.0; 210 | - Update pyflakes to version 0.7.3; 211 | - Fixed lint\_ignore options bug; 212 | - Fixed encoding problems when code running; 213 | 214 | ## 2013-04-26 0.6.16 215 | 216 | - Improvement folding (thanks @alvinfrancis); 217 | 218 | ## 2013-04-01 0.6.15 219 | 220 | - Bugfix release 221 | 222 | ## 2013-03-16 0.6.14 223 | 224 | - Update PEP8 to version 1.4.5; 225 | - Update Pylint to version 0.27.0; 226 | - Update pyflakes to version 0.6.1; 227 | - Update autopep8 to version 0.8.7; 228 | - Fix breakpoint definition; 229 | - Update python syntax; 230 | - Fixed run-time error when output non-ascii in multibyte locale; 231 | - Move initialization into ftplugin as it is python specific; 232 | - Pyrex (Cython) files support; 233 | - Support raw\_input in run python code; 234 | 235 | ## 2012-09-07 0.6.10 236 | 237 | - Dont raise an exception when Logger has no message handler (c) nixon 238 | - Improve performance of white space removal (c) Dave Smith 239 | - Improve ropemode support (c) s0undt3ch 240 | - Add `g:pymode_updatetime` option 241 | - Update autopep8 to version 0.8.1 242 | 243 | ## 2012-09-07 0.6.9 244 | 245 | - Update autopep8 246 | - Improve `pymode#troubleshooting#Test()` 247 | 248 | ## 2012-09-06 0.6.8 249 | 250 | - Add PEP8 indentation `:help pymode_indent` 251 | 252 | ## 2012-08-15 0.6.7 253 | 254 | - Fix documentation. Thanks (c) bgrant; 255 | - Fix pymode "async queue" support. 256 | 257 | ## 2012-08-02 0.6.6 258 | 259 | - Updated Pep8 to version 1.3.3 260 | - Updated Pylint to version 0.25.2 261 | - Fixed virtualenv support for windows users 262 | - Added pymode modeline `:help PythonModeModeline` 263 | - Added diagnostic tool `:call pymode#troubleshooting#Test()` 264 | - Added PyLintAuto command `:help PyLintAuto` 265 | - Code checking is async operation now 266 | - More, more fast the pymode folding 267 | - Repaired execution of python code 268 | 269 | ## 2012-05-24 0.6.4 270 | 271 | - Add `pymode_paths` option 272 | - Rope updated to version 0.9.4 273 | 274 | ## 2012-04-18 0.6.3 275 | 276 | - Fix pydocs integration 277 | 278 | ## 2012-04-10 0.6.2 279 | 280 | - Fix `pymode_run` for "unnamed" clipboard 281 | - Add `pymode_lint_mccabe_complexity` option 282 | - Update Pep8 to version 1.0.1 283 | - Warning! Change `pymode_rope_goto_def_newwin` option for open "goto 284 | definition" in new window, set it to 'new' or 'vnew' for horizontally or 285 | vertically split If you use default behaviour (in the same buffer), not 286 | changes needed. 287 | 288 | ## 2012-03-13 0.6.0 289 | 290 | - Add `pymode_lint_hold` option 291 | - Improve pymode loading speed 292 | - Add pep8, mccabe lint checkers 293 | - Now `g:pymode_lint_checker` can have many values Ex. "pep8,pyflakes,mccabe" 294 | - Add `pymode_lint_ignore` and `pymode_lint_select` options 295 | - Fix rope keys 296 | - Fix python motion in visual mode 297 | - Add folding `pymode_folding` 298 | - Warning: `pymode_lint_checker` now set to 'pyflakes,pep8,mccabe' by default 299 | 300 | ## 2012-02-12 0.5.8 301 | 302 | - Fix pylint for Windows users 303 | - Python documentation search running from Vim (delete `g:pydoc` option) 304 | - Python code execution running from Vim (delete `g:python` option) 305 | 306 | ## 2012-02-11 0.5.7 307 | 308 | - Fix `g:pymode_lint_message` mode error 309 | - Fix breakpoints 310 | - Fix python paths and virtualenv detection 311 | 312 | ## 2012-02-06 0.5.6 313 | 314 | - Fix `g:pymode_syntax` option 315 | - Show error message in bottom part of screen see `g:pymode_lint_message` 316 | - Fix pylint for windows users 317 | - Fix breakpoint command (Use pdb when idpb not installed) 318 | 319 | ## 2012-01-17 0.5.5 320 | 321 | - Add a sign for info messages from pylint. (c) Fredrik Henrysson 322 | - Change motion keys: vic - viC, dam - daM and etc 323 | - Add `g:pymode_lint_onfly` option 324 | 325 | ## 2012-01-09 0.5.3 326 | 327 | - Prevent the configuration from breaking python-mode (c) Dirk Wallenstein 328 | 329 | ## 2012-01-08 0.5.2 330 | 331 | - Fix ropeomnicompletion 332 | - Add preview documentation 333 | 334 | ## 2012-01-06 0.5.1 335 | 336 | - Happy new year! 337 | - Objects and motion fixes 338 | 339 | ## 2011-11-30 0.5.0 340 | 341 | - Add python objects and motions (beta) `:h pymode_motion` 342 | 343 | ## 2011-11-27 0.4.8 344 | 345 | - Add PyLintWindowToggle command 346 | - Fix some bugs 347 | 348 | ## 2011-11-23 0.4.6 349 | 350 | - Enable all syntax highlighting For old settings set in your vimrc: 351 | 352 | ``` 353 | let g:pymode_syntax_builtin_objs = 0 354 | let g:pymode_syntax_builtin_funcs = 0 355 | ``` 356 | 357 | - Change namespace of syntax variables See README 358 | 359 | ## 2011-11-18 0.4.5 360 | 361 | - Add `g:pymode_syntax` option 362 | - Highlight 'self' keyword 363 | 364 | ## 2011-11-16 0.4.4 365 | 366 | - Minor fixes 367 | 368 | ## 2011-11-11 0.4.3 369 | 370 | - Fix pyflakes 371 | 372 | ## 2011-11-09 0.4.2 373 | 374 | - Add FAQ 375 | - Some refactoring and fixes 376 | 377 | ## 2011-11-08 0.4.0 378 | 379 | - Add alternative code checker "pyflakes" See `:h pymode_lint_checker` 380 | - Update install docs 381 | 382 | ## 2011-10-30 0.3.3 383 | 384 | - Fix RopeShowDoc 385 | 386 | ## 2011-10-28 0.3.2 387 | 388 | - Add `g:pymode_options_*` stuff, for ability to disable default pymode options 389 | for python buffers 390 | 391 | ## 2011-10-27 0.3.1 392 | 393 | - Add `g:pymode_rope_always_show_complete_menu` option 394 | - Some pylint fixes 395 | 396 | ## 2011-10-25 0.3.0 397 | 398 | - Add `g:pymode_lint_minheight` and `g:pymode_lint_maxheight` options 399 | - Fix PyLintToggle 400 | - Fix Rope and PyLint libs loading 401 | 402 | ## 2011-10-21 0.2.12 403 | 404 | - Auto open cwindow with results on rope find operations 405 | 406 | ## 2011-10-20 0.2.11 407 | 408 | - Add `pymode_lint_jump` option 409 | 410 | ## 2011-10-19 0.2.10 411 | 412 | - Minor fixes (virtualenv loading, buffer commands) 413 | 414 | ## 2011-10-18 0.2.6 415 | 416 | - Add `` shortcut for macvim users. 417 | - Add VIRTUALENV support 418 | 419 | ## 2011-10-17 0.2.4 420 | 421 | - Add current work path to sys.path 422 | - Add `g:pymode` option (disable/enable pylint and rope) 423 | - Fix pylint copyright 424 | - Hotfix rope autocomplete 425 | 426 | ## 2011-10-15 0.2.1 427 | 428 | - Change rope variables (`ropevim_` -> `pymode_rope_`) 429 | - Add `pymode_rope_auto_project` option (default: 1) 430 | - Update and fix docs 431 | - `pymode_rope_extended_complete` set by default 432 | - Auto generate rope project and cache 433 | - `r a` for RopeAutoImport 434 | 435 | ## 2011-10-12 0.1.4 436 | 437 | - Add default pylint configuration 438 | 439 | ## 2011-10-12 0.1.3 440 | 441 | - Fix pylint and update docs 442 | 443 | ## 2011-10-11 0.1.2 444 | 445 | - First public release 446 | -------------------------------------------------------------------------------- /COPYING: -------------------------------------------------------------------------------- 1 | GNU LESSER GENERAL PUBLIC LICENSE 2 | Version 3, 29 June 2007 3 | 4 | Copyright (C) 2007 Free Software Foundation, Inc. 5 | Everyone is permitted to copy and distribute verbatim copies 6 | of this license document, but changing it is not allowed. 7 | 8 | 9 | This version of the GNU Lesser General Public License incorporates 10 | the terms and conditions of version 3 of the GNU General Public 11 | License, supplemented by the additional permissions listed below. 12 | 13 | 0. Additional Definitions. 14 | 15 | As used herein, "this License" refers to version 3 of the GNU Lesser 16 | General Public License, and the "GNU GPL" refers to version 3 of the GNU 17 | General Public License. 18 | 19 | "The Library" refers to a covered work governed by this License, 20 | other than an Application or a Combined Work as defined below. 21 | 22 | An "Application" is any work that makes use of an interface provided 23 | by the Library, but which is not otherwise based on the Library. 24 | Defining a subclass of a class defined by the Library is deemed a mode 25 | of using an interface provided by the Library. 26 | 27 | A "Combined Work" is a work produced by combining or linking an 28 | Application with the Library. The particular version of the Library 29 | with which the Combined Work was made is also called the "Linked 30 | Version". 31 | 32 | The "Minimal Corresponding Source" for a Combined Work means the 33 | Corresponding Source for the Combined Work, excluding any source code 34 | for portions of the Combined Work that, considered in isolation, are 35 | based on the Application, and not on the Linked Version. 36 | 37 | The "Corresponding Application Code" for a Combined Work means the 38 | object code and/or source code for the Application, including any data 39 | and utility programs needed for reproducing the Combined Work from the 40 | Application, but excluding the System Libraries of the Combined Work. 41 | 42 | 1. Exception to Section 3 of the GNU GPL. 43 | 44 | You may convey a covered work under sections 3 and 4 of this License 45 | without being bound by section 3 of the GNU GPL. 46 | 47 | 2. Conveying Modified Versions. 48 | 49 | If you modify a copy of the Library, and, in your modifications, a 50 | facility refers to a function or data to be supplied by an Application 51 | that uses the facility (other than as an argument passed when the 52 | facility is invoked), then you may convey a copy of the modified 53 | version: 54 | 55 | a) under this License, provided that you make a good faith effort to 56 | ensure that, in the event an Application does not supply the 57 | function or data, the facility still operates, and performs 58 | whatever part of its purpose remains meaningful, or 59 | 60 | b) under the GNU GPL, with none of the additional permissions of 61 | this License applicable to that copy. 62 | 63 | 3. Object Code Incorporating Material from Library Header Files. 64 | 65 | The object code form of an Application may incorporate material from 66 | a header file that is part of the Library. You may convey such object 67 | code under terms of your choice, provided that, if the incorporated 68 | material is not limited to numerical parameters, data structure 69 | layouts and accessors, or small macros, inline functions and templates 70 | (ten or fewer lines in length), you do both of the following: 71 | 72 | a) Give prominent notice with each copy of the object code that the 73 | Library is used in it and that the Library and its use are 74 | covered by this License. 75 | 76 | b) Accompany the object code with a copy of the GNU GPL and this license 77 | document. 78 | 79 | 4. Combined Works. 80 | 81 | You may convey a Combined Work under terms of your choice that, 82 | taken together, effectively do not restrict modification of the 83 | portions of the Library contained in the Combined Work and reverse 84 | engineering for debugging such modifications, if you also do each of 85 | the following: 86 | 87 | a) Give prominent notice with each copy of the Combined Work that 88 | the Library is used in it and that the Library and its use are 89 | covered by this License. 90 | 91 | b) Accompany the Combined Work with a copy of the GNU GPL and this license 92 | document. 93 | 94 | c) For a Combined Work that displays copyright notices during 95 | execution, include the copyright notice for the Library among 96 | these notices, as well as a reference directing the user to the 97 | copies of the GNU GPL and this license document. 98 | 99 | d) Do one of the following: 100 | 101 | 0) Convey the Minimal Corresponding Source under the terms of this 102 | License, and the Corresponding Application Code in a form 103 | suitable for, and under terms that permit, the user to 104 | recombine or relink the Application with a modified version of 105 | the Linked Version to produce a modified Combined Work, in the 106 | manner specified by section 6 of the GNU GPL for conveying 107 | Corresponding Source. 108 | 109 | 1) Use a suitable shared library mechanism for linking with the 110 | Library. A suitable mechanism is one that (a) uses at run time 111 | a copy of the Library already present on the user's computer 112 | system, and (b) will operate properly with a modified version 113 | of the Library that is interface-compatible with the Linked 114 | Version. 115 | 116 | e) Provide Installation Information, but only if you would otherwise 117 | be required to provide such information under section 6 of the 118 | GNU GPL, and only to the extent that such information is 119 | necessary to install and execute a modified version of the 120 | Combined Work produced by recombining or relinking the 121 | Application with a modified version of the Linked Version. (If 122 | you use option 4d0, the Installation Information must accompany 123 | the Minimal Corresponding Source and Corresponding Application 124 | Code. If you use option 4d1, you must provide the Installation 125 | Information in the manner specified by section 6 of the GNU GPL 126 | for conveying Corresponding Source.) 127 | 128 | 5. Combined Libraries. 129 | 130 | You may place library facilities that are a work based on the 131 | Library side by side in a single library together with other library 132 | facilities that are not Applications and are not covered by this 133 | License, and convey such a combined library under terms of your 134 | choice, if you do both of the following: 135 | 136 | a) Accompany the combined library with a copy of the same work based 137 | on the Library, uncombined with any other library facilities, 138 | conveyed under the terms of this License. 139 | 140 | b) Give prominent notice with the combined library that part of it 141 | is a work based on the Library, and explaining where to find the 142 | accompanying uncombined form of the same work. 143 | 144 | 6. Revised Versions of the GNU Lesser General Public License. 145 | 146 | The Free Software Foundation may publish revised and/or new versions 147 | of the GNU Lesser General Public License from time to time. Such new 148 | versions will be similar in spirit to the present version, but may 149 | differ in detail to address new problems or concerns. 150 | 151 | Each version is given a distinguishing version number. If the 152 | Library as you received it specifies that a certain numbered version 153 | of the GNU Lesser General Public License "or any later version" 154 | applies to it, you have the option of following the terms and 155 | conditions either of that published version or of any later version 156 | published by the Free Software Foundation. If the Library as you 157 | received it does not specify a version number of the GNU Lesser 158 | General Public License, you may choose any version of the GNU Lesser 159 | General Public License ever published by the Free Software Foundation. 160 | 161 | If the Library as you received it specifies that a proxy can decide 162 | whether future versions of the GNU Lesser General Public License shall 163 | apply, that proxy's public statement of acceptance of any version is 164 | permanent authorization for you to choose that version for the 165 | Library. 166 | -------------------------------------------------------------------------------- /after/ftplugin/pyrex.vim: -------------------------------------------------------------------------------- 1 | runtime after/ftplugin/python.vim 2 | -------------------------------------------------------------------------------- /after/ftplugin/python.vim: -------------------------------------------------------------------------------- 1 | if !g:pymode 2 | finish 3 | endif 4 | 5 | if g:pymode_motion 6 | 7 | if !&magic 8 | if g:pymode_warning 9 | call pymode#error("Pymode motion requires `&magic` option. Enable them or disable g:pymode_motion") 10 | endif 11 | finish 12 | endif 13 | 14 | nnoremap ]] :call pymode#motion#move('^(class%(asyncs+)=def)s', '') 15 | nnoremap [[ :call pymode#motion#move('^(class%(asyncs+)=def)s', 'b') 16 | nnoremap ]C :call pymode#motion#move('^(class%(asyncs+)=def)s', '') 17 | nnoremap [C :call pymode#motion#move('^(class%(asyncs+)=def)s', 'b') 18 | nnoremap ]M :call pymode#motion#move('^s*(asyncs+)=defs', '') 19 | nnoremap [M :call pymode#motion#move('^s*(asyncs+)=defs', 'b') 20 | 21 | onoremap ]] :call pymode#motion#move('^(class%(asyncs+)=def)s', '') 22 | onoremap [[ :call pymode#motion#move('^(class%(asyncs+)=def)s', 'b') 23 | onoremap ]C :call pymode#motion#move('^(class%(asyncs+)=def)s', '') 24 | onoremap [C :call pymode#motion#move('^(class%(asyncs+)=def)s', 'b') 25 | onoremap ]M :call pymode#motion#move('^s*(asyncs+)=defs', '') 26 | onoremap [M :call pymode#motion#move('^s*(asyncs+)=defs', 'b') 27 | 28 | vnoremap ]] :call pymode#motion#vmove('^(class%(asyncs+)=def)s', '') 29 | vnoremap [[ :call pymode#motion#vmove('^(class%(asyncs+)=def)s', 'b') 30 | vnoremap ]M :call pymode#motion#vmove('^s*(asyncs+)=defs', '') 31 | vnoremap [M :call pymode#motion#vmove('^s*(asyncs+)=defs', 'b') 32 | 33 | onoremap C :call pymode#motion#select_c('^s*classs', 0) 34 | onoremap aC :call pymode#motion#select_c('^s*classs', 0) 35 | onoremap iC :call pymode#motion#select_c('^s*classs', 1) 36 | vnoremap aC :call pymode#motion#select_c('^s*classs', 0) 37 | vnoremap iC :call pymode#motion#select_c('^s*classs', 1) 38 | 39 | onoremap M :call pymode#motion#select('^s*(asyncs+)=@', '^s*(asyncs+)=defs', 0) 40 | onoremap aM :call pymode#motion#select('^s*(asyncs+)=@', '^s*(asyncs+)=defs', 0) 41 | onoremap iM :call pymode#motion#select('^s*(asyncs+)=@', '^s*(asyncs+)=defs', 1) 42 | vnoremap aM :call pymode#motion#select('^s*(asyncs+)=@', '^s*(asyncs+)=defs', 0) 43 | vnoremap iM :call pymode#motion#select('^s*(asyncs+)=@', '^s*(asyncs+)=defs', 1) 44 | 45 | onoremap V :call pymode#rope#select_logical_line() 46 | 47 | endif 48 | 49 | if g:pymode_rope && g:pymode_rope_completion 50 | 51 | setlocal omnifunc=pymode#rope#completions 52 | 53 | if g:pymode_rope_completion_bind != "" 54 | exe "inoremap " . g:pymode_rope_completion_bind . " =pymode#rope#complete(0)" 55 | if tolower(g:pymode_rope_completion_bind) == '' 56 | exe "inoremap =pymode#rope#complete(0)" 57 | endif 58 | endif 59 | 60 | endif 61 | -------------------------------------------------------------------------------- /after/indent/pyrex.vim: -------------------------------------------------------------------------------- 1 | runtime after/indent/python.vim 2 | -------------------------------------------------------------------------------- /after/indent/python.vim: -------------------------------------------------------------------------------- 1 | if !g:pymode || !g:pymode_indent 2 | finish 3 | endif 4 | 5 | setlocal nolisp 6 | setlocal tabstop=4 7 | setlocal softtabstop=4 8 | setlocal shiftwidth=4 9 | setlocal shiftround 10 | setlocal expandtab 11 | setlocal autoindent 12 | setlocal indentexpr=pymode#indent#get_indent(v:lnum) 13 | setlocal indentkeys=!^F,o,O,<:>,0),0],0},=elif,=except 14 | -------------------------------------------------------------------------------- /autoload/pymode.vim: -------------------------------------------------------------------------------- 1 | " Pymode core functions 2 | 3 | " DESC: Check variable and set default value if it not exists 4 | fun! pymode#default(name, default) "{{{ 5 | if !exists(a:name) 6 | let {a:name} = a:default 7 | return 0 8 | endif 9 | return 1 10 | endfunction "}}} 11 | 12 | " DESC: Import python libs 13 | fun! pymode#init(plugin_root, paths) "{{{ 14 | 15 | PymodePython import sys, vim 16 | PymodePython sys.path.insert(0, vim.eval('a:plugin_root')) 17 | PymodePython sys.path = vim.eval('a:paths') + sys.path 18 | 19 | endfunction "}}} 20 | 21 | " DESC: Show wide message 22 | fun! pymode#wide_message(msg) "{{{ 23 | let x=&ruler | let y=&showcmd 24 | set noruler noshowcmd 25 | redraw 26 | echohl Debug | echo strpart("[Pymode] " . a:msg, 0, &columns-1) | echohl none 27 | let &ruler=x | let &showcmd=y 28 | endfunction "}}} 29 | 30 | " DESC: Show error 31 | fun! pymode#error(msg) "{{{ 32 | execute "normal \" 33 | echohl ErrorMsg 34 | echomsg "[Pymode]: error: " . a:msg 35 | echohl None 36 | endfunction "}}} 37 | 38 | " DESC: Open quickfix window 39 | fun! pymode#quickfix_open(onlyRecognized, maxHeight, minHeight, jumpError) "{{{ 40 | let numErrors = len(filter(getqflist(), 'v:val.valid')) 41 | let numOthers = len(getqflist()) - numErrors 42 | if numErrors > 0 || (!a:onlyRecognized && numOthers > 0) 43 | let num = winnr() 44 | botright copen 45 | exe max([min([line("$"), a:maxHeight]), a:minHeight]) . "wincmd _" 46 | if a:jumpError 47 | cc 48 | elseif num != winnr() 49 | wincmd p 50 | endif 51 | else 52 | cclose 53 | endif 54 | redraw 55 | if numOthers > 0 56 | call pymode#wide_message(printf('Quickfix: %d(+%d)', numErrors, numOthers)) 57 | elseif numErrors > 0 58 | call pymode#wide_message(printf('Quickfix: %d', numErrors)) 59 | endif 60 | endfunction "}}} 61 | 62 | " DESC: Open temp buffer. 63 | fun! pymode#tempbuffer_open(name) "{{{ 64 | pclose 65 | exe g:pymode_preview_position . " " . g:pymode_preview_height . "new " . a:name 66 | setlocal buftype=nofile bufhidden=delete noswapfile nowrap previewwindow 67 | redraw 68 | endfunction "}}} 69 | 70 | " DESC: Remove unused whitespaces 71 | fun! pymode#trim_whitespaces() "{{{ 72 | if g:pymode_trim_whitespaces 73 | let cursor_pos = getpos('.') 74 | silent! %s/\s\+$//e 75 | call setpos('.', cursor_pos) 76 | endif 77 | endfunction "}}} 78 | 79 | fun! pymode#save() "{{{ 80 | if &modifiable && &modified 81 | try 82 | noautocmd write 83 | catch /E212/ 84 | call pymode#error("File modified and I can't save it. Please save it manually.") 85 | return 0 86 | endtry 87 | endif 88 | return expand('%') != '' 89 | endfunction "}}} 90 | 91 | fun! pymode#reload_buf_by_nr(nr) "{{{ 92 | let cur = bufnr("") 93 | try 94 | exe "buffer " . a:nr 95 | catch /E86/ 96 | return 97 | endtry 98 | exe "e!" 99 | exe "buffer " . cur 100 | endfunction "}}} 101 | 102 | fun! pymode#buffer_pre_write() "{{{ 103 | let b:pymode_modified = &modified 104 | endfunction "}}} 105 | 106 | fun! pymode#buffer_post_write() "{{{ 107 | if g:pymode_rope 108 | if g:pymode_rope_regenerate_on_write && b:pymode_modified 109 | call pymode#debug('regenerate') 110 | call pymode#rope#regenerate() 111 | endif 112 | endif 113 | if g:pymode_lint 114 | if g:pymode_lint_unmodified || (g:pymode_lint_on_write && b:pymode_modified) 115 | call pymode#debug('check code') 116 | call pymode#lint#check() 117 | endif 118 | endif 119 | endfunction "}}} 120 | 121 | fun! pymode#debug(msg) "{{{ 122 | " Pymode's debug function. 123 | " Should be called by other pymode's functions to report outputs. See 124 | " the function PymodeDebugFolding for example. 125 | " TODO: why echom here creates a problem? 126 | " echom '' . a:msg + '|||||||||||' 127 | 128 | let l:info_separator = repeat('-', 79) 129 | 130 | if g:pymode_debug 131 | if ! exists('g:pymode_debug_counter') 132 | let g:pymode_debug_counter = 0 133 | endif 134 | let g:pymode_debug_counter += 1 135 | " NOTE: Print a separator for every message except folding ones (since 136 | " they could be many). 137 | if a:msg !~ 'has folding:' 138 | echom l:info_separator 139 | endif 140 | echom '' . 'pymode debug msg ' . g:pymode_debug_counter . ': ' . a:msg 141 | endif 142 | endfunction "}}} 143 | 144 | fun! pymode#quit() "{{{ 145 | augroup pymode 146 | au! * 147 | augroup END 148 | endfunction "}}} 149 | -------------------------------------------------------------------------------- /autoload/pymode/breakpoint.vim: -------------------------------------------------------------------------------- 1 | fun! pymode#breakpoint#init() "{{{ 2 | 3 | " If breakpoints are either disabled or already defined do nothing. 4 | if ! g:pymode_breakpoint || g:pymode_breakpoint_cmd != '' 5 | return 6 | 7 | " Else go for a 'smart scan' of the defaults. 8 | else 9 | 10 | PymodePython << EOF 11 | 12 | from importlib.util import find_spec 13 | 14 | if sys.version_info >= (3, 7): 15 | vim.command('let g:pymode_breakpoint_cmd = "breakpoint()"') 16 | 17 | else: 18 | for module in ('wdb', 'pudb', 'ipdb', 'pdb'): 19 | if find_spec(module): 20 | vim.command('let g:pymode_breakpoint_cmd = "import %s; %s.set_trace() # XXX BREAKPOINT"' % (module, module)) 21 | break 22 | EOF 23 | endif 24 | 25 | endfunction "}}} 26 | 27 | fun! pymode#breakpoint#operate(lnum) "{{{ 28 | if g:pymode_breakpoint_cmd == '' 29 | echoerr("g:pymode_breakpoint_cmd is empty") 30 | return -1 31 | endif 32 | let line = getline(a:lnum) 33 | if strridx(line, g:pymode_breakpoint_cmd) != -1 34 | normal dd 35 | else 36 | let plnum = prevnonblank(a:lnum) 37 | if &expandtab 38 | let indents = repeat(' ', indent(plnum)) 39 | else 40 | let indents = repeat("\t", plnum / &shiftwidth) 41 | endif 42 | 43 | call append(line('.')-1, indents.g:pymode_breakpoint_cmd) 44 | normal k 45 | endif 46 | 47 | " Save file without any events 48 | call pymode#save() 49 | 50 | endfunction "}}} 51 | -------------------------------------------------------------------------------- /autoload/pymode/debug.vim: -------------------------------------------------------------------------------- 1 | " Set debugging functions. 2 | 3 | " DESC: Get debug information about pymode problem. 4 | fun! pymode#debug#sysinfo() "{{{ 5 | " OS info. {{{ 6 | let l:os_name = "Unknown" 7 | if has('win16') || has('win32') || has('win64') 8 | let l:os_name = "Windows" 9 | else 10 | let l:os_name = substitute(system('uname'), "\n", "", "") 11 | endif 12 | call pymode#debug("Operating system: " . l:os_name) 13 | " }}} 14 | " Loaded scripts info. {{{ 15 | call pymode#debug("Scriptnames:") 16 | let l:scriptnames_var = execute('scriptnames') 17 | " }}} 18 | " Variables info. {{{ 19 | " Drop verbose file temporarily to prevent the 'let' from showing up. 20 | let l:tmp = &verbosefile 21 | set verbosefile= 22 | let l:all_variables = filter( 23 | \ split(execute('let', 'silent!'), '\n'), 24 | \ 'v:val =~ "^pymode"') 25 | let &verbosefile = l:tmp 26 | " NOTE: echom does not display multiline messages. Thus a for loop is 27 | " needed. 28 | call pymode#debug("Pymode variables:") 29 | for pymodevar in sort(l:all_variables) 30 | echom pymodevar 31 | endfor 32 | " }}} 33 | " Git commit info. {{{ 34 | " Find in the scriptnames the first occurence of 'python-mode'. Then parse 35 | " the result outputting its path. This is in turn fed into the git command. 36 | call pymode#debug("Git commit: ") 37 | let l:pymode_folder = substitute( 38 | \ filter( 39 | \ split(l:scriptnames_var, '\n'), 40 | \ 'v:val =~ "/python-mode/"')[0], 41 | \ '\(^\s\+[0-9]\+:\s\+\)\([/~].*python-mode\/\)\(.*\)', 42 | \ '\2', 43 | \ '') 44 | let l:git_head_sha1 = system('git -C ' . expand(l:pymode_folder). ' rev-parse HEAD ' ) 45 | echom join(filter(split(l:git_head_sha1, '\zs'), 'v:val =~? "[0-9A-Fa-f]"'), '') 46 | " }}} 47 | " Git submodules status. {{{ 48 | call pymode#debug("Git submodule status:") 49 | let l:git_submodule_status = system('git -C ' . expand(l:pymode_folder). ' submodule status') 50 | for submodule in split(l:git_submodule_status, '\n') 51 | echom submodule 52 | endfor 53 | " }}} 54 | call pymode#debug("End of pymode#debug#sysinfo") 55 | endfunction "}}} 56 | 57 | " DESC: Define debug folding function. 58 | function! pymode#debug#foldingexpr(lnum) "{{{ 59 | let l:get_folding_result = pymode#folding#foldcase(a:lnum) 60 | " NOTE: the 'has folding:' expression is special in the pymode#debug. 61 | call pymode#debug( 62 | \ 'line ' . a:lnum 63 | \ . ' has folding: ' . l:get_folding_result['foldlevel'] 64 | \ . ' with foldcase ' . l:get_folding_result['foldcase']) 65 | return l:get_folding_result['foldlevel'] 66 | endfunction 67 | " }}} 68 | -------------------------------------------------------------------------------- /autoload/pymode/doc.vim: -------------------------------------------------------------------------------- 1 | " Python-mode search by documentation 2 | " 3 | PymodePython import pymode 4 | 5 | fun! pymode#doc#find() "{{{ 6 | " Extract the 'word' at the cursor, expanding leftwards across identifiers 7 | " and the . operator, and rightwards across the identifier only. 8 | " 9 | " For example: 10 | " import xml.dom.minidom 11 | " ^ ! 12 | " 13 | " With the cursor at ^ this returns 'xml'; at ! it returns 'xml.dom'. 14 | let l:line = getline(".") 15 | let l:pre = l:line[:col(".") - 1] 16 | let l:suf = l:line[col("."):] 17 | let word = matchstr(pre, "[A-Za-z0-9_.]*$") . matchstr(suf, "^[A-Za-z0-9_]*") 18 | call pymode#doc#show(word) 19 | endfunction "}}} 20 | 21 | fun! pymode#doc#show(word) "{{{ 22 | if a:word == '' 23 | call pymode#error("No name/symbol under cursor!") 24 | return 0 25 | endif 26 | 27 | call pymode#tempbuffer_open('__doc__') 28 | PymodePython pymode.get_documentation() 29 | setlocal nomodifiable 30 | setlocal nomodified 31 | setlocal filetype=rst 32 | if g:pymode_doc_vertical 33 | wincmd L 34 | endif 35 | 36 | normal gg 37 | 38 | wincmd p 39 | 40 | endfunction "}}} 41 | -------------------------------------------------------------------------------- /autoload/pymode/folding.vim: -------------------------------------------------------------------------------- 1 | " Notice that folding is based on single line so complex regular expressions 2 | " that take previous line into consideration are not fit for the job. 3 | 4 | " Regex definitions for correct folding 5 | let s:def_regex = g:pymode_folding_regex 6 | let s:blank_regex = '^\s*$' 7 | " Spyder, a very popular IDE for python has a template which includes 8 | " '@author:' ; thus the regex below. 9 | let s:decorator_regex = '^\s*@\(author:\)\@!' 10 | let s:docstring_line_regex = '^\s*[uUrR]\=\("""\|''''''\).\+\1\s*$' 11 | let s:docstring_begin_regex = '^\s*[uUrR]\=\%("""\|''''''\).*\S' 12 | let s:docstring_end_regex = '\%("""\|''''''\)\s*$' 13 | " This one is needed for the while loop to count for opening and closing 14 | " docstrings. 15 | let s:docstring_general_regex = '\%("""\|''''''\)' 16 | let s:symbol = matchstr(&fillchars, 'fold:\zs.') " handles multibyte characters 17 | if s:symbol == '' 18 | let s:symbol = ' ' 19 | endif 20 | " '''''''' 21 | 22 | fun! pymode#folding#text() " {{{ 23 | let fs = v:foldstart 24 | while getline(fs) !~ s:def_regex && getline(fs) !~ s:docstring_begin_regex 25 | let fs = nextnonblank(fs + 1) 26 | endwhile 27 | if getline(fs) =~ s:docstring_end_regex && getline(fs) =~ s:docstring_begin_regex 28 | let fs = nextnonblank(fs + 1) 29 | endif 30 | let line = getline(fs) 31 | 32 | let has_numbers = &number || &relativenumber 33 | let nucolwidth = &fdc + has_numbers * &numberwidth 34 | let windowwidth = winwidth(0) - nucolwidth - 6 35 | let foldedlinecount = v:foldend - v:foldstart 36 | 37 | " expand tabs into spaces 38 | let onetab = strpart(' ', 0, &tabstop) 39 | let line = substitute(line, '\t', onetab, 'g') 40 | 41 | let line = strpart(line, 0, windowwidth - 2 -len(foldedlinecount)) 42 | let line = substitute(line, '[uUrR]\=\%("""\|''''''\)', '', '') 43 | let fillcharcount = windowwidth - len(line) - len(foldedlinecount) + 1 44 | return line . ' ' . repeat(s:symbol, fillcharcount) . ' ' . foldedlinecount 45 | endfunction "}}} 46 | 47 | fun! pymode#folding#expr(lnum) "{{{ 48 | 49 | let l:return_value = pymode#folding#foldcase(a:lnum)['foldlevel'] 50 | 51 | return l:return_value 52 | 53 | endfunction "}}} 54 | 55 | fun! pymode#folding#foldcase(lnum) "{{{ 56 | " Return a dictionary with a brief description of the foldcase and the 57 | " evaluated foldlevel: {'foldcase': 'case description', 'foldlevel': 1}. 58 | 59 | let l:foldcase = 'general' 60 | let l:foldlevel = 0 61 | 62 | let line = getline(a:lnum) 63 | let indent = indent(a:lnum) 64 | let prev_line = getline(a:lnum - 1) 65 | let next_line = getline(a:lnum + 1) 66 | 67 | " Decorators {{{ 68 | if line =~ s:decorator_regex 69 | let l:foldcase = 'decorator declaration' 70 | let l:foldlevel = '>'.(indent / &shiftwidth + 1) 71 | return {'foldcase': l:foldcase, 'foldlevel': l:foldlevel} 72 | endif "}}} 73 | 74 | " Definition {{{ 75 | if line =~ s:def_regex 76 | 77 | " TODO: obscure case. 78 | " If indent of this line is greater or equal than line below 79 | " and previous non blank line does not end with : (that is, is not a 80 | " definition) 81 | " Keep the same indentation 82 | " xxx " if indent(a:lnum) >= indent(a:lnum+1) 83 | " xxx " \ && getline(prevnonblank(a:lnum)) !~ ':\s*$' 84 | " xxx " let l:foldcase = 'definition' 85 | " xxx " let l:foldlevel = '=' 86 | " xxx " return {'foldcase': l:foldcase, 'foldlevel': l:foldlevel} 87 | " xxx " endif 88 | 89 | " Check if last decorator is before the last def 90 | let decorated = 0 91 | let lnum = a:lnum - 1 92 | while lnum > 0 93 | if getline(lnum) =~ s:def_regex 94 | break 95 | elseif getline(lnum) =~ s:decorator_regex 96 | let decorated = 1 97 | break 98 | endif 99 | let lnum -= 1 100 | endwhile 101 | if decorated 102 | let l:foldcase = 'decorated function declaration' 103 | let l:foldlevel = '=' 104 | else 105 | let l:foldcase = 'function declaration' 106 | let l:foldlevel = '>'.(indent / &shiftwidth + 1) 107 | endif 108 | return {'foldcase': l:foldcase, 'foldlevel': l:foldlevel} 109 | endif "}}} 110 | 111 | " Docstrings {{{ 112 | 113 | " TODO: A while loop now counts the number of open and closed folding in 114 | " order to determine if it is a closing or opening folding. 115 | " It is working but looks like it is an overkill. 116 | 117 | " Notice that an effect of this is that other docstring matches will not 118 | " be one liners. 119 | if line =~ s:docstring_line_regex 120 | let l:foldcase = 'one-liner docstring' 121 | let l:foldlevel = '=' 122 | return {'foldcase': l:foldcase, 'foldlevel': l:foldlevel} 123 | endif 124 | if line =~ s:docstring_begin_regex 125 | if s:Is_opening_folding(a:lnum) 126 | let l:foldcase = 'open multiline docstring' 127 | let l:foldlevel = 'a1' 128 | endif 129 | return {'foldcase': l:foldcase, 'foldlevel': l:foldlevel} 130 | endif 131 | if line =~ s:docstring_end_regex 132 | if !s:Is_opening_folding(a:lnum) 133 | let l:foldcase = 'close multiline docstring' 134 | let l:foldlevel = 's1' 135 | endif 136 | return {'foldcase': l:foldcase, 'foldlevel': l:foldlevel} 137 | endif "}}} 138 | 139 | " Blocks. {{{ 140 | let s:save_cursor = getcurpos() 141 | let line_block_start = s:BlockStart(a:lnum) 142 | let line_block_end = s:BlockEnd(a:lnum) 143 | let prev_line_block_start = s:BlockStart(a:lnum - 1) 144 | if line !~ s:blank_regex 145 | if line_block_start == prev_line_block_start 146 | \ || a:lnum - line_block_start == 1 147 | let l:foldcase = 'non blank line; first line of block or part of it' 148 | let l:foldlevel = '=' 149 | elseif indent < indent(prevnonblank(a:lnum - 1)) 150 | if indent == 0 151 | let l:foldcase = 'non blank line; zero indent' 152 | let l:foldlevel = 0 153 | else 154 | let l:foldcase = 'non blank line; non zero indent' 155 | let l:foldlevel = indent(line_block_start) / &shiftwidth + 1 156 | endif 157 | endif 158 | call setpos('.', s:save_cursor) 159 | return {'foldcase': l:foldcase, 'foldlevel': l:foldlevel} 160 | else 161 | call setpos('.', s:save_cursor) 162 | endif 163 | " endif " }}} 164 | 165 | " Blank Line {{{ 166 | " Comments: cases of blank lines: 167 | " 1. After non blank line: gets folded with previous line. 168 | " 1. Just after a block; in this case it gets folded with the block. 169 | " 1. Between docstrings and imports. 170 | " 1. Inside docstrings. 171 | " 2. Inside functions/methods. 172 | " 3. Between functions/methods. 173 | if line =~ s:blank_regex 174 | if prev_line !~ s:blank_regex 175 | let l:foldcase = 'blank line after non blank line' 176 | let l:foldlevel = '=' 177 | return {'foldcase': l:foldcase, 'foldlevel': l:foldlevel} 178 | elseif a:lnum > line_block_start && a:lnum < line_block_end 179 | let l:foldcase = 'blank line inside block' 180 | let l:foldlevel = '=' 181 | return {'foldcase': l:foldcase, 'foldlevel': l:foldlevel} 182 | endif 183 | " if prev_line =~ s:blank_regex 184 | " if indent(a:lnum + 1) == 0 && next_line !~ s:blank_regex && next_line !~ s:docstring_general_regex 185 | " if s:Is_opening_folding(a:lnum) 186 | " let l:foldcase = 'case 1' 187 | " let l:foldlevel = '=' 188 | " return {'foldcase': l:foldcase, 'foldlevel': l:foldlevel} 189 | " else 190 | " let l:foldcase = 'case 2' 191 | " let l:foldlevel = 0 192 | " return {'foldcase': l:foldcase, 'foldlevel': l:foldlevel} 193 | " endif 194 | " endif 195 | " let l:foldcase = 'case 3' 196 | " let l:foldlevel = -1 197 | " return {'foldcase': l:foldcase, 'foldlevel': l:foldlevel} 198 | " else 199 | " let l:foldcase = 'case 4' 200 | " let l:foldlevel = '=' 201 | " return {'foldcase': l:foldcase, 'foldlevel': l:foldlevel} 202 | " endif 203 | endif " }}} 204 | 205 | return {'foldcase': l:foldcase, 'foldlevel': l:foldlevel} 206 | 207 | endfunction "}}} 208 | 209 | fun! s:BlockStart(lnum) "{{{ 210 | " Returns the definition statement line which encloses the current line. 211 | 212 | let line = getline(a:lnum) 213 | if line !~ s:blank_regex 214 | let l:inferred_indent = indent(a:lnum) 215 | else 216 | let l:inferred_indent = prevnonblank(a:lnum) 217 | endif 218 | 219 | " Note: Make sure to reset cursor position after using this function. 220 | call cursor(a:lnum, 0) 221 | 222 | " In case the end of the block is indented to a higher level than the def 223 | " statement plus one shiftwidth, we need to find the indent level at the 224 | " bottom of that if/for/try/while/etc. block. 225 | " Flags from searchpos() (same as search()): 226 | " b: search Backward instead of forward 227 | " n: do Not move the cursor 228 | " W: don't Wrap around the end of the file 229 | let previous_definition = searchpos(s:def_regex, 'bnW') 230 | 231 | while previous_definition[0] != 1 && previous_definition != [0, 0] 232 | \ && indent(previous_definition[0]) >= l:inferred_indent 233 | let previous_definition = searchpos(s:def_regex, 'bnW') 234 | call cursor(previous_definition[0] - 1, 0) 235 | endwhile 236 | let last_def = previous_definition[0] 237 | if last_def 238 | call cursor(last_def, 0) 239 | let last_def_indent = indent(last_def) 240 | call cursor(last_def, 0) 241 | let next_stmt_at_def_indent = searchpos('\v^\s{'.last_def_indent.'}[^[:space:]#]', 'nW')[0] 242 | else 243 | let next_stmt_at_def_indent = -1 244 | endif 245 | 246 | " Now find the class/def one shiftwidth lower than the start of the 247 | " aforementioned indent block. 248 | if next_stmt_at_def_indent && (next_stmt_at_def_indent < a:lnum) 249 | let max_indent = max([indent(next_stmt_at_def_indent) - &shiftwidth, 0]) 250 | else 251 | let max_indent = max([indent(prevnonblank(a:lnum)) - &shiftwidth, 0]) 252 | endif 253 | 254 | let result = searchpos('\v^\s{,'.max_indent.'}(def |class )\w', 'bcnW')[0] 255 | 256 | return result 257 | 258 | endfunction "}}} 259 | function! Blockstart(x) 260 | let save_cursor = getcurpos() 261 | return s:BlockStart(a:x) 262 | call setpos('.', save_cursor) 263 | endfunction 264 | 265 | fun! s:BlockEnd(lnum) "{{{ 266 | " Note: Make sure to reset cursor position after using this function. 267 | call cursor(a:lnum, 0) 268 | return searchpos('\v^\s{,'.indent('.').'}\S', 'nW')[0] - 1 269 | endfunction "}}} 270 | function! Blockend(lnum) 271 | let save_cursor = getcurpos() 272 | return s:BlockEnd(a:lnum) 273 | call setpos('.', save_cursor) 274 | endfunction 275 | 276 | function! s:Is_opening_folding(lnum) "{{{ 277 | " Helper function to see if multi line docstring is opening or closing. 278 | 279 | " Cache the result so the loop runs only once per change. 280 | if get(b:, 'fold_changenr', -1) == changenr() 281 | return b:fold_cache[a:lnum - 1] "If odd then it is an opening 282 | else 283 | let b:fold_changenr = changenr() 284 | let b:fold_cache = [] 285 | endif 286 | 287 | " To be analized if odd/even to inform if it is opening or closing. 288 | let fold_odd_even = 0 289 | " To inform is already has an open docstring. 290 | let has_open_docstring = 0 291 | " To help skipping ''' and """ which are not docstrings. 292 | let extra_docstrings = 0 293 | 294 | " The idea of this part of the function is to identify real docstrings and 295 | " not just triple quotes (that could be a regular string). 296 | 297 | " Iterater over all lines from the start until current line (inclusive) 298 | for i in range(1, line('$')) 299 | 300 | let i_line = getline(i) 301 | 302 | if i_line =~ s:docstring_begin_regex && ! has_open_docstring 303 | " This causes the loop to continue if there is a triple quote which 304 | " is not a docstring. 305 | if extra_docstrings > 0 306 | let extra_docstrings = extra_docstrings - 1 307 | else 308 | let has_open_docstring = 1 309 | let fold_odd_even = fold_odd_even + 1 310 | endif 311 | " If it is an end doc and has an open docstring. 312 | elseif i_line =~ s:docstring_end_regex && has_open_docstring 313 | let has_open_docstring = 0 314 | let fold_odd_even = fold_odd_even + 1 315 | 316 | elseif i_line =~ s:docstring_general_regex 317 | let extra_docstrings = extra_docstrings + 1 318 | endif 319 | 320 | call add(b:fold_cache, fold_odd_even % 2) 321 | 322 | endfor 323 | 324 | return b:fold_cache[a:lnum] 325 | 326 | endfunction "}}} 327 | 328 | " vim: fdm=marker:fdl=0 329 | -------------------------------------------------------------------------------- /autoload/pymode/indent.vim: -------------------------------------------------------------------------------- 1 | " PEP8 compatible Python indent file 2 | " Language: Python 3 | " Maintainer: Hynek Schlawack 4 | " Prev Maintainer: Eric Mc Sween (address invalid) 5 | " Original Author: David Bustos (address invalid) 6 | " Last Change: 2012-06-21 7 | " License: Public Domain 8 | 9 | 10 | function! pymode#indent#get_indent(lnum) 11 | 12 | " First line has indent 0 13 | if a:lnum == 1 14 | return 0 15 | endif 16 | 17 | " If we can find an open parenthesis/bracket/brace, line up with it. 18 | call cursor(a:lnum, 1) 19 | let parlnum = s:SearchParensPair() 20 | if parlnum > 0 21 | let parcol = col('.') 22 | let closing_paren = match(getline(a:lnum), '^\s*[])}]') != -1 23 | if match(getline(parlnum), '[([{]\s*$', parcol - 1) != -1 24 | if closing_paren 25 | return indent(parlnum) 26 | else 27 | let l:indent_width = (g:pymode_indent_hanging_width > 0 ? 28 | \ g:pymode_indent_hanging_width : &shiftwidth) 29 | return indent(parlnum) + l:indent_width 30 | endif 31 | else 32 | return parcol 33 | endif 34 | endif 35 | 36 | " Examine this line 37 | let thisline = getline(a:lnum) 38 | let thisindent = indent(a:lnum) 39 | 40 | " If the line starts with 'elif' or 'else', line up with 'if' or 'elif' 41 | if thisline =~ '^\s*\(elif\|else\)\>' 42 | let bslnum = s:BlockStarter(a:lnum, '^\s*\(if\|elif\)\>') 43 | if bslnum > 0 44 | return indent(bslnum) 45 | else 46 | return -1 47 | endif 48 | endif 49 | 50 | " If the line starts with 'except' or 'finally', line up with 'try' 51 | " or 'except' 52 | if thisline =~ '^\s*\(except\|finally\)\>' 53 | let bslnum = s:BlockStarter(a:lnum, '^\s*\(try\|except\)\>') 54 | if bslnum > 0 55 | return indent(bslnum) 56 | else 57 | return -1 58 | endif 59 | endif 60 | 61 | " Examine previous line 62 | let plnum = a:lnum - 1 63 | let pline = getline(plnum) 64 | let sslnum = s:StatementStart(plnum) 65 | 66 | " If the previous line is blank, keep the same indentation 67 | if pline =~ '^\s*$' 68 | return -1 69 | endif 70 | 71 | " If this line is explicitly joined, find the first indentation that is a 72 | " multiple of four and will distinguish itself from next logical line. 73 | if pline =~ '\\$' 74 | let maybe_indent = indent(sslnum) + &sw 75 | let control_structure = '^\s*\(if\|while\|for\s.*\sin\|except\)\s*' 76 | if match(getline(sslnum), control_structure) != -1 77 | " add extra indent to avoid E125 78 | return maybe_indent + &sw 79 | else 80 | " control structure not found 81 | return maybe_indent 82 | endif 83 | endif 84 | 85 | " If the previous line ended with a colon and is not a comment, indent 86 | " relative to statement start. 87 | if pline =~ '^[^#]*:\s*\(#.*\)\?$' 88 | return indent(sslnum) + &sw 89 | endif 90 | 91 | " If the previous line was a stop-execution statement or a pass 92 | if getline(sslnum) =~ '^\s*\(break\|continue\|raise\|return\|pass\)\>' 93 | " See if the user has already dedented 94 | if indent(a:lnum) > indent(sslnum) - &sw 95 | " If not, recommend one dedent 96 | return indent(sslnum) - &sw 97 | endif 98 | " Otherwise, trust the user 99 | return -1 100 | endif 101 | 102 | " In all other cases, line up with the start of the previous statement. 103 | return indent(sslnum) 104 | endfunction 105 | 106 | 107 | " Find backwards the closest open parenthesis/bracket/brace. 108 | function! s:SearchParensPair() " {{{ 109 | let line = line('.') 110 | let col = col('.') 111 | 112 | " Skip strings and comments and don't look too far 113 | let skip = "line('.') < " . (line - 50) . " ? dummy :" . 114 | \ 'synIDattr(synID(line("."), col("."), 0), "name") =~? ' . 115 | \ '"string\\|comment\\|doctest"' 116 | 117 | " Search for parentheses 118 | call cursor(line, col) 119 | let parlnum = searchpair('(', '', ')', 'bW', skip) 120 | let parcol = col('.') 121 | 122 | " Search for brackets 123 | call cursor(line, col) 124 | let par2lnum = searchpair('\[', '', '\]', 'bW', skip) 125 | let par2col = col('.') 126 | 127 | " Search for braces 128 | call cursor(line, col) 129 | let par3lnum = searchpair('{', '', '}', 'bW', skip) 130 | let par3col = col('.') 131 | 132 | " Get the closest match 133 | if par2lnum > parlnum || (par2lnum == parlnum && par2col > parcol) 134 | let parlnum = par2lnum 135 | let parcol = par2col 136 | endif 137 | if par3lnum > parlnum || (par3lnum == parlnum && par3col > parcol) 138 | let parlnum = par3lnum 139 | let parcol = par3col 140 | endif 141 | 142 | " Put the cursor on the match 143 | if parlnum > 0 144 | call cursor(parlnum, parcol) 145 | endif 146 | return parlnum 147 | endfunction " }}} 148 | 149 | 150 | " Find the start of a multi-line statement 151 | function! s:StatementStart(lnum) " {{{ 152 | let lnum = a:lnum 153 | while 1 154 | if getline(lnum - 1) =~ '\\$' 155 | let lnum = lnum - 1 156 | else 157 | call cursor(lnum, 1) 158 | let maybe_lnum = s:SearchParensPair() 159 | if maybe_lnum < 1 160 | return lnum 161 | else 162 | let lnum = maybe_lnum 163 | endif 164 | endif 165 | endwhile 166 | endfunction " }}} 167 | 168 | 169 | " Find the block starter that matches the current line 170 | function! s:BlockStarter(lnum, block_start_re) " {{{ 171 | let lnum = a:lnum 172 | let maxindent = 10000 " whatever 173 | while lnum > 1 174 | let lnum = prevnonblank(lnum - 1) 175 | if indent(lnum) < maxindent 176 | if getline(lnum) =~ a:block_start_re 177 | return lnum 178 | else 179 | let maxindent = indent(lnum) 180 | " It's not worth going further if we reached the top level 181 | if maxindent == 0 182 | return -1 183 | endif 184 | endif 185 | endif 186 | endwhile 187 | return -1 188 | endfunction " }}} 189 | -------------------------------------------------------------------------------- /autoload/pymode/lint.vim: -------------------------------------------------------------------------------- 1 | PymodePython from pymode.lint import code_check 2 | 3 | call pymode#tools#signs#init() 4 | call pymode#tools#loclist#init() 5 | 6 | 7 | fun! pymode#lint#auto() "{{{ 8 | if ! pymode#save() 9 | return 0 10 | endif 11 | PymodePython from pymode import auto 12 | PymodePython auto() 13 | cclose 14 | call g:PymodeSigns.clear() 15 | edit 16 | call pymode#wide_message("AutoPep8 done.") 17 | endfunction "}}} 18 | 19 | 20 | fun! pymode#lint#show_errormessage() "{{{ 21 | let loclist = g:PymodeLocList.current() 22 | if loclist.is_empty() 23 | return 24 | endif 25 | 26 | let l = line('.') 27 | if l == b:pymode_error_line 28 | return 29 | endif 30 | let b:pymode_error_line = l 31 | if has_key(loclist._messages, l) 32 | call pymode#wide_message(loclist._messages[l]) 33 | else 34 | echo 35 | endif 36 | endfunction "}}} 37 | 38 | 39 | fun! pymode#lint#toggle() "{{{ 40 | let g:pymode_lint = g:pymode_lint ? 0 : 1 41 | if g:pymode_lint 42 | call pymode#wide_message("Code checking is enabled.") 43 | else 44 | call pymode#wide_message("Code checking is disabled.") 45 | endif 46 | endfunction "}}} 47 | 48 | 49 | fun! pymode#lint#check() "{{{ 50 | " DESC: Run checkers on current file. 51 | " 52 | let loclist = g:PymodeLocList.current() 53 | 54 | let b:pymode_error_line = -1 55 | 56 | call loclist.clear() 57 | 58 | call pymode#wide_message('Code checking is running ...') 59 | 60 | PymodePython code_check() 61 | 62 | if loclist.is_empty() 63 | call pymode#wide_message('Code checking is completed. No errors found.') 64 | call g:PymodeSigns.refresh(loclist) 65 | call loclist.show() 66 | return 67 | endif 68 | 69 | call g:PymodeSigns.refresh(loclist) 70 | 71 | call loclist.show() 72 | 73 | call pymode#lint#show_errormessage() 74 | call pymode#wide_message('Found ' . loclist.num_errors() . ' error(s) and ' . loclist.num_warnings() . ' warning(s)') 75 | 76 | endfunction " }}} 77 | 78 | 79 | fun! pymode#lint#tick_queue() "{{{ 80 | 81 | python import time 82 | python print time.time() 83 | 84 | if mode() == 'i' 85 | if col('.') == 1 86 | call feedkeys("\\", "n") 87 | else 88 | call feedkeys("\\", "n") 89 | endif 90 | else 91 | call feedkeys("f\e", "n") 92 | endif 93 | endfunction "}}} 94 | 95 | 96 | fun! pymode#lint#stop() "{{{ 97 | au! pymode CursorHold 98 | endfunction "}}} 99 | 100 | 101 | fun! pymode#lint#start() "{{{ 102 | au! pymode CursorHold call pymode#lint#tick_queue() 103 | call pymode#lint#tick_queue() 104 | endfunction "}}} 105 | -------------------------------------------------------------------------------- /autoload/pymode/motion.vim: -------------------------------------------------------------------------------- 1 | " Python-mode motion functions 2 | 3 | 4 | fun! pymode#motion#move(pattern, flags, ...) "{{{ 5 | let cnt = v:count1 - 1 6 | let [line, column] = searchpos(a:pattern, a:flags . 'sW') 7 | let indent = indent(line) 8 | while cnt && line 9 | let [line, column] = searchpos(a:pattern, a:flags . 'W') 10 | if indent(line) == indent 11 | let cnt = cnt - 1 12 | endif 13 | endwhile 14 | return [line, column] 15 | endfunction "}}} 16 | 17 | 18 | fun! pymode#motion#vmove(pattern, flags) range "{{{ 19 | call cursor(a:lastline, 0) 20 | let end = pymode#motion#move(a:pattern, a:flags) 21 | call cursor(a:firstline, 0) 22 | normal! v 23 | call cursor(end) 24 | endfunction "}}} 25 | 26 | 27 | fun! pymode#motion#pos_le(pos1, pos2) "{{{ 28 | return ((a:pos1[0] < a:pos2[0]) || (a:pos1[0] == a:pos2[0] && a:pos1[1] <= a:pos2[1])) 29 | endfunction "}}} 30 | 31 | fun! pymode#motion#select(first_pattern, second_pattern, inner) "{{{ 32 | let cnt = v:count1 - 1 33 | let orig = getpos('.')[1:2] 34 | let posns = s:BlockStart(orig[0], a:first_pattern, a:second_pattern) 35 | if getline(posns[0]) !~ a:first_pattern && getline(posns[0]) !~ a:second_pattern 36 | return 0 37 | endif 38 | let snum = posns[0] 39 | let enum = s:BlockEnd(posns[1], indent(posns[1])) 40 | while cnt 41 | let lnum = search(a:second_pattern, 'nW') 42 | if lnum 43 | let enum = s:BlockEnd(lnum, indent(lnum)) 44 | call cursor(enum, 1) 45 | endif 46 | let cnt = cnt - 1 47 | endwhile 48 | if pymode#motion#pos_le([snum, 0], orig) && pymode#motion#pos_le(orig, [enum+1, 0]) 49 | if a:inner 50 | let snum = posns[1] + 1 51 | endif 52 | 53 | call cursor(snum, 1) 54 | normal! V 55 | call cursor(enum, len(getline(enum))) 56 | endif 57 | endfunction "}}} 58 | 59 | fun! pymode#motion#select_c(pattern, inner) "{{{ 60 | call pymode#motion#select(a:pattern, a:pattern, a:inner) 61 | endfunction "}}} 62 | 63 | fun! s:BlockStart(lnum, first_pattern, second_pattern) "{{{ 64 | let lnum = a:lnum + 1 65 | let indent = 100 66 | while lnum 67 | let lnum = prevnonblank(lnum - 1) 68 | let test = indent(lnum) 69 | let line = getline(lnum) 70 | " Skip comments, deeper or equal lines 71 | if line =~ '^\s*#' || test >= indent 72 | continue 73 | endif 74 | let indent = indent(lnum) 75 | 76 | " Indent is strictly less at this point: check for def/class/@ 77 | if line =~ a:first_pattern || line =~ a:second_pattern 78 | while getline(lnum-1) =~ a:first_pattern 79 | let lnum = lnum - 1 80 | endwhile 81 | let first_pos = lnum 82 | while getline(lnum) !~ a:second_pattern 83 | let lnum = lnum + 1 84 | endwhile 85 | let second_pos = lnum 86 | return [first_pos, second_pos] 87 | endif 88 | endwhile 89 | return [0, 0] 90 | endfunction "}}} 91 | 92 | 93 | fun! s:BlockEnd(lnum, ...) "{{{ 94 | let indent = a:0 ? a:1 : indent(a:lnum) 95 | let lnum = a:lnum 96 | while lnum 97 | let lnum = nextnonblank(lnum + 1) 98 | if getline(lnum) =~ '^\s*#' | continue 99 | elseif lnum && indent(lnum) <= indent 100 | return prevnonblank(lnum - 1) 101 | endif 102 | endwhile 103 | return line('$') 104 | endfunction "}}} 105 | " vim: fdm=marker:fdl=0 106 | -------------------------------------------------------------------------------- /autoload/pymode/rope.vim: -------------------------------------------------------------------------------- 1 | " Python-mode Rope support 2 | 3 | if ! g:pymode_rope 4 | finish 5 | endif 6 | 7 | PymodePython from pymode import rope 8 | 9 | call pymode#tools#loclist#init() 10 | 11 | 12 | fun! pymode#rope#completions(findstart, base) 13 | PymodePython rope.completions() 14 | endfunction 15 | 16 | fun! pymode#rope#complete(dot) 17 | if pumvisible() 18 | if stridx('noselect', &completeopt) != -1 19 | return "\" 20 | else 21 | return "" 22 | endif 23 | endif 24 | if a:dot 25 | PymodePython rope.complete(True) 26 | else 27 | PymodePython rope.complete() 28 | endif 29 | return pumvisible() && stridx('noselect', &completeopt) != -1 ? "\\" : "" 30 | endfunction 31 | 32 | fun! pymode#rope#complete_on_dot() "{{{ 33 | if !exists("*synstack") 34 | return "" 35 | endif 36 | for group in map(synstack(line('.'), col('.') - 1), 'synIDattr(v:val, "name")') 37 | for name in ['pythonString', 'pythonComment', 'pythonNumber', 'pythonDocstring'] 38 | if group == name 39 | return "" 40 | endif 41 | endfor 42 | endfor 43 | if g:pymode_rope_autoimport_import_after_complete 44 | PymodePython rope.complete_check() 45 | endif 46 | return pymode#rope#complete(1) 47 | endfunction "}}} 48 | 49 | fun! pymode#rope#goto_definition() 50 | PymodePython rope.goto() 51 | endfunction 52 | 53 | 54 | fun! pymode#rope#organize_imports() 55 | if !pymode#save() 56 | return 0 57 | endif 58 | call pymode#wide_message('Organize imports ... ') 59 | PymodePython rope.organize_imports() 60 | endfunction 61 | 62 | 63 | fun! pymode#rope#find_it() 64 | let loclist = g:PymodeLocList.current() 65 | let loclist._title = "Occurrences" 66 | call pymode#wide_message('Finding Occurrences ...') 67 | PymodePython rope.find_it() 68 | call loclist.show() 69 | endfunction 70 | 71 | 72 | fun! pymode#rope#show_doc() 73 | let l:output = [] 74 | 75 | PymodePython rope.show_doc() 76 | 77 | if !empty(l:output) 78 | call pymode#tempbuffer_open('__doc____rope__') 79 | call append(0, l:output) 80 | setlocal nomodifiable 81 | setlocal nomodified 82 | setlocal filetype=rst 83 | 84 | normal gg 85 | 86 | wincmd p 87 | endif 88 | endfunction 89 | 90 | 91 | fun! pymode#rope#regenerate() "{{{ 92 | call pymode#wide_message('Regenerate Rope cache ... ') 93 | PymodePython rope.regenerate() 94 | endfunction "}}} 95 | 96 | 97 | fun! pymode#rope#new(...) "{{{ 98 | PymodePython rope.new() 99 | endfunction "}}} 100 | 101 | 102 | fun! pymode#rope#rename() "{{{ 103 | if !pymode#save() 104 | return 0 105 | endif 106 | PymodePython rope.RenameRefactoring().run() 107 | endfunction "}}} 108 | 109 | fun! pymode#rope#rename_module() "{{{ 110 | if !pymode#save() 111 | return 0 112 | endif 113 | PymodePython rope.RenameRefactoring(True).run() 114 | endfunction "}}} 115 | 116 | fun! pymode#rope#extract_method() range "{{{ 117 | if !pymode#save() 118 | return 0 119 | endif 120 | PymodePython rope.ExtractMethodRefactoring().run() 121 | endfunction "}}} 122 | 123 | fun! pymode#rope#extract_variable() range "{{{ 124 | if !pymode#save() 125 | return 0 126 | endif 127 | PymodePython rope.ExtractVariableRefactoring().run() 128 | endfunction "}}} 129 | 130 | fun! pymode#rope#undo() "{{{ 131 | PymodePython rope.undo() 132 | endfunction "}}} 133 | 134 | fun! pymode#rope#redo() "{{{ 135 | PymodePython rope.redo() 136 | endfunction "}}} 137 | 138 | fun! pymode#rope#inline() "{{{ 139 | if !pymode#save() 140 | return 0 141 | endif 142 | PymodePython rope.InlineRefactoring().run() 143 | endfunction "}}} 144 | 145 | fun! pymode#rope#move() "{{{ 146 | if !pymode#save() 147 | return 0 148 | endif 149 | PymodePython rope.MoveRefactoring().run() 150 | endfunction "}}} 151 | 152 | fun! pymode#rope#signature() "{{{ 153 | if !pymode#save() 154 | return 0 155 | endif 156 | PymodePython rope.ChangeSignatureRefactoring().run() 157 | endfunction "}}} 158 | 159 | fun! pymode#rope#use_function() "{{{ 160 | if !pymode#save() 161 | return 0 162 | endif 163 | PymodePython rope.UseFunctionRefactoring().run() 164 | endfunction "}}} 165 | 166 | fun! pymode#rope#module_to_package() "{{{ 167 | if !pymode#save() 168 | return 0 169 | endif 170 | PymodePython rope.ModuleToPackageRefactoring().run() 171 | endfunction "}}} 172 | 173 | fun! pymode#rope#autoimport(word) "{{{ 174 | PymodePython rope.autoimport() 175 | endfunction "}}} 176 | 177 | fun! pymode#rope#generate_function() "{{{ 178 | if !pymode#save() 179 | return 0 180 | endif 181 | PymodePython rope.GenerateElementRefactoring('function').run() 182 | endfunction "}}} 183 | 184 | fun! pymode#rope#generate_class() "{{{ 185 | if !pymode#save() 186 | return 0 187 | endif 188 | PymodePython rope.GenerateElementRefactoring('class').run() 189 | endfunction "}}} 190 | 191 | fun! pymode#rope#generate_package() "{{{ 192 | if !pymode#save() 193 | return 0 194 | endif 195 | PymodePython rope.GenerateElementRefactoring('package').run() 196 | endfunction "}}} 197 | 198 | fun! pymode#rope#select_logical_line() "{{{ 199 | PymodePython rope.select_logical_line() 200 | endfunction "}}} 201 | -------------------------------------------------------------------------------- /autoload/pymode/run.vim: -------------------------------------------------------------------------------- 1 | " The following lines set Vim's errorformat variable, to allow the 2 | " quickfix window to show Python tracebacks properly. It is much 3 | " easier to use let than set, because set requires many more 4 | " characters to be escaped. This is much easier to read and 5 | " maintain. % escapes are still needed however before any regex meta 6 | " characters. Hence \S (non-whitespace) becomes %\S etc. Note that 7 | " * becomes %#, so .* (match any character) becomes %.%# Commas must 8 | " also be escaped, with a backslash (\,). See the Vim help on 9 | " quickfix for details. 10 | " 11 | " Python errors are multi-lined. They often start with 'Traceback', so 12 | " we want to capture that (with +G) and show it in the quickfix window 13 | " because it explains the order of error messages. 14 | let s:efm = '%+GTraceback%.%#,' 15 | 16 | " The error message itself starts with a line with 'File' in it. There 17 | " are a couple of variations, and we need to process a line beginning 18 | " with whitespace followed by File, the filename in "", a line number, 19 | " and optional further text. %E here indicates the start of a multi-line 20 | " error message. The %\C at the end means that a case-sensitive search is 21 | " required. 22 | let s:efm .= '%E File "%f"\, line %l\,%m%\C,' 23 | let s:efm .= '%E File "%f"\, line %l%\C,' 24 | 25 | " The possible continutation lines are idenitifed to Vim by %C. We deal 26 | " with these in order of most to least specific to ensure a proper 27 | " match. A pointer (^) identifies the column in which the error occurs 28 | " (but will not be entirely accurate due to indention of Python code). 29 | let s:efm .= '%C%p^,' 30 | 31 | " Any text, indented by more than two spaces contain useful information. 32 | " We want this to appear in the quickfix window, hence %+. 33 | let s:efm .= '%+C %.%#,' 34 | let s:efm .= '%+C %.%#,' 35 | 36 | " The last line (%Z) does not begin with any whitespace. We use a zero 37 | " width lookahead (\&) to check this. The line contains the error 38 | " message itself (%m) 39 | let s:efm .= '%Z%\S%\&%m,' 40 | 41 | " We can ignore any other lines (%-G) 42 | let s:efm .= '%-G%.%#' 43 | 44 | PymodePython from pymode.run import run_code 45 | 46 | 47 | " DESC: Run python code 48 | fun! pymode#run#code_run(line1, line2) "{{{ 49 | 50 | let l:output = [] 51 | let l:traceback = [] 52 | call setqflist([]) 53 | 54 | call pymode#wide_message("Code running ...") 55 | 56 | try 57 | 58 | PymodePython run_code() 59 | 60 | if len(l:output) 61 | call pymode#tempbuffer_open('__run__') 62 | call append(line('$'), l:output) 63 | normal dd 64 | wincmd p 65 | else 66 | call pymode#wide_message("No output.") 67 | endif 68 | 69 | cexpr "" 70 | 71 | let l:_efm = &efm 72 | 73 | let &efm = s:efm 74 | 75 | cgetexpr(l:traceback) 76 | 77 | " If a range is run (starting other than at line 1), fix the reported 78 | " error line numbers for the current buffer 79 | if a:line1 > 1 80 | let qflist = getqflist() 81 | for i in qflist 82 | if i.bufnr == bufnr("") 83 | let i.lnum = i.lnum - 1 + a:line1 84 | endif 85 | endfor 86 | call setqflist(qflist) 87 | endif 88 | 89 | call pymode#quickfix_open(0, g:pymode_quickfix_maxheight, g:pymode_quickfix_maxheight, 0) 90 | 91 | let &efm = l:_efm 92 | 93 | catch /E234/ 94 | 95 | echohl Error | echo "Run-time error." | echohl none 96 | 97 | endtry 98 | 99 | endfunction "}}} 100 | -------------------------------------------------------------------------------- /autoload/pymode/tools/loclist.vim: -------------------------------------------------------------------------------- 1 | let g:PymodeLocList= {} 2 | 3 | 4 | fun! pymode#tools#loclist#init() "{{{ 5 | return 6 | endfunction "}}} 7 | 8 | 9 | fun! g:PymodeLocList.init(raw_list) "{{{ 10 | let obj = copy(self) 11 | let loc_list = filter(copy(a:raw_list), 'v:val["valid"] == 1') 12 | call obj.clear() 13 | let obj._title = 'CodeCheck' 14 | return obj 15 | endfunction "}}} 16 | 17 | 18 | fun! g:PymodeLocList.current() "{{{ 19 | if !exists("b:pymode_loclist") 20 | let b:pymode_loclist = g:PymodeLocList.init([]) 21 | endif 22 | return b:pymode_loclist 23 | endfunction "}}} 24 | 25 | 26 | fun! g:PymodeLocList.is_empty() "{{{ 27 | return empty(self._errlist) && empty(self._warnlist) 28 | endfunction "}}} 29 | 30 | fun! g:PymodeLocList.loclist() "{{{ 31 | let loclist = copy(self._errlist) 32 | call extend(loclist, self._warnlist) 33 | return loclist 34 | endfunction "}}} 35 | 36 | fun! g:PymodeLocList.num_errors() "{{{ 37 | return len(self._errlist) 38 | endfunction "}}} 39 | 40 | fun! g:PymodeLocList.num_warnings() "{{{ 41 | return len(self._warnlist) 42 | endfunction "}}} 43 | 44 | 45 | fun! g:PymodeLocList.clear() "{{{ 46 | let self._errlist = [] 47 | let self._warnlist = [] 48 | let self._messages = {} 49 | let self._name = expand('%:t') 50 | endfunction "}}} 51 | 52 | 53 | fun! g:PymodeLocList.extend(raw_list) "{{{ 54 | let err_list = filter(copy(a:raw_list), 'v:val["type"] == "E"') 55 | let warn_list = filter(copy(a:raw_list), 'v:val["type"] != "E"') 56 | call extend(self._errlist, err_list) 57 | call extend(self._warnlist, warn_list) 58 | for issue in a:raw_list 59 | let self._messages[issue.lnum] = issue.text 60 | endfor 61 | return self 62 | endfunction "}}} 63 | 64 | 65 | fun! g:PymodeLocList.filter(filters) "{{{ 66 | let loclist = [] 67 | for error in self.loclist() 68 | let passes_filters = 1 69 | for key in keys(a:filters) 70 | if get(error, key, '') !=? a:filters[key] 71 | let passes_filters = 0 72 | break 73 | endif 74 | endfor 75 | 76 | if passes_filters 77 | call add(loclist, error) 78 | endif 79 | 80 | endfor 81 | return loclist 82 | endfunction "}}} 83 | 84 | 85 | fun! g:PymodeLocList.show() "{{{ 86 | call setloclist(0, self.loclist()) 87 | if self.is_empty() 88 | lclose 89 | elseif g:pymode_lint_cwindow 90 | let num = winnr() 91 | lopen 92 | setl nowrap 93 | execute max([min([line("$"), g:pymode_quickfix_maxheight]), g:pymode_quickfix_minheight]) . "wincmd _" 94 | if num != winnr() 95 | call setwinvar(winnr(), 'quickfix_title', self._title . ' <' . self._name . '>') 96 | exe num . "wincmd w" 97 | endif 98 | end 99 | endfunction "}}} 100 | -------------------------------------------------------------------------------- /autoload/pymode/tools/signs.vim: -------------------------------------------------------------------------------- 1 | let g:PymodeSigns = {} 2 | 3 | 4 | fun! pymode#tools#signs#init() "{{{ 5 | call g:PymodeSigns.setup() 6 | endfunction "}}} 7 | 8 | 9 | fun! g:PymodeSigns.enabled() "{{{ 10 | return (g:pymode_lint_signs && has('signs')) 11 | endfunction "}}} 12 | 13 | 14 | fun! g:PymodeSigns.setup() "{{{ 15 | if self.enabled() 16 | execute 'sign define PymodeW text=' . g:pymode_lint_todo_symbol . " texthl=Todo" 17 | execute 'sign define PymodeD text=' . g:pymode_lint_docs_symbol . " texthl=String" 18 | execute 'sign define PymodeC text=' . g:pymode_lint_comment_symbol . " texthl=Comment" 19 | execute 'sign define PymodeR text=' . g:pymode_lint_visual_symbol . " texthl=Visual" 20 | execute 'sign define PymodeE text=' . g:pymode_lint_error_symbol . " texthl=Error" 21 | execute 'sign define PymodeI text=' . g:pymode_lint_info_symbol . " texthl=Info" 22 | execute 'sign define PymodeF text=' . g:pymode_lint_pyflakes_symbol . " texthl=Info" 23 | endif 24 | let self._sign_ids = [] 25 | let self._next_id = 10000 26 | let self._messages = {} 27 | endfunction "}}} 28 | 29 | 30 | fun! g:PymodeSigns.refresh(loclist) "{{{ 31 | if self.enabled() 32 | call self.clear() 33 | call self.place(a:loclist) 34 | endif 35 | endfunction "}}} 36 | 37 | 38 | fun! g:PymodeSigns.clear() "{{{ 39 | let ids = copy(self._sign_ids) 40 | for i in ids 41 | execute "sign unplace " . i 42 | call remove(self._sign_ids, index(self._sign_ids, i)) 43 | endfor 44 | endfunction "}}} 45 | 46 | 47 | fun! g:PymodeSigns.place(loclist) "{{{ 48 | let seen = {} 49 | for issue in a:loclist.loclist() 50 | if !has_key(seen, issue.lnum) 51 | let seen[issue.lnum] = 1 52 | call add(self._sign_ids, self._next_id) 53 | execute printf('sign place %d line=%d name=%s buffer=%d', self._next_id, issue.lnum, "Pymode".issue.type[0], issue.bufnr) 54 | let self._next_id += 1 55 | endif 56 | endfor 57 | endfunction "}}} 58 | -------------------------------------------------------------------------------- /autoload/pymode/virtualenv.vim: -------------------------------------------------------------------------------- 1 | " Support virtualenv 2 | " 3 | PymodePython from pymode.virtualenv import enable_virtualenv 4 | 5 | fun! pymode#virtualenv#init() "{{{ 6 | if !g:pymode_virtualenv || g:pymode_virtualenv_path == "" 7 | return 8 | endif 9 | 10 | PymodePython enable_virtualenv() 11 | 12 | endfunction "}}} 13 | 14 | fun! pymode#virtualenv#activate(path) "{{{ 15 | let g:pymode_virtualenv_path = a:path 16 | call pymode#virtualenv#init() 17 | endfunction "}}} 18 | -------------------------------------------------------------------------------- /debugvimrc.vim: -------------------------------------------------------------------------------- 1 | " Use this settings for testing the plugin. 2 | " 3 | " Run vim with command: 4 | " 5 | " $ vim -u ./debug.vim /my/py/file.py 6 | " 7 | " Only python-mode will be loaded. 8 | 9 | " Disable all persistence between sessions. 10 | let skip_defaults_vim=1 11 | " TODO XXX: this nevertheless keeps viminfo enabled. As a workaround the flag 12 | " '-i NONE' should be added to vim's loading. 13 | set viminfo= 14 | set nobackup 15 | set noswapfile 16 | 17 | " Modify vimrc configuration. 18 | execute('set rtp+='. expand(':p:h')) 19 | set rtp -=$HOME/.vim 20 | set rtp -=$HOME/.vim/after 21 | set nocompatible 22 | 23 | " Activate debugging. 24 | let g:pymode_debug = 1 25 | 26 | " Define a common shell for non Windows systems. 27 | if ! (has('win16') || has('win32') || has('win64')) 28 | set shell=/bin/bash 29 | endif 30 | 31 | " IMPORTANT: Do note that the history of this session is saved on the log file. 32 | " See the augroup in ./ftplugin/python/pymode.vim file. 33 | -------------------------------------------------------------------------------- /ftplugin/pyrex.vim: -------------------------------------------------------------------------------- 1 | runtime ftplugin/python/pymode.vim 2 | -------------------------------------------------------------------------------- /ftplugin/python/pymode.vim: -------------------------------------------------------------------------------- 1 | if !g:pymode || pymode#default('b:pymode', 1) 2 | finish 3 | endif 4 | 5 | if g:pymode_python == 'disable' 6 | 7 | if g:pymode_warning 8 | call pymode#error("Pymode requires vim compiled with +python3 (exclusively). Most of features will be disabled.") 9 | endif 10 | 11 | finish 12 | 13 | else 14 | 15 | 16 | let b:pymode_modified = &modified 17 | 18 | " Init paths 19 | if !pymode#default('g:pymode_init', 1) 20 | 21 | call pymode#init(expand(':p:h:h:h'), g:pymode_paths) 22 | call pymode#virtualenv#init() 23 | call pymode#breakpoint#init() 24 | 25 | PymodePython from pymode.utils import patch_paths 26 | PymodePython patch_paths() 27 | 28 | endif 29 | 30 | endif 31 | 32 | command! -buffer -nargs=1 PymodeVirtualenv call pymode#virtualenv#activate() 33 | 34 | " Setup events for pymode 35 | au! pymode BufWritePre call pymode#buffer_pre_write() 36 | au! pymode BufWritePost call pymode#buffer_post_write() 37 | 38 | " Run python code 39 | if g:pymode_run 40 | 41 | command! -buffer -nargs=0 -range=% PymodeRun call pymode#run#code_run(, ) 42 | 43 | exe "nnoremap " g:pymode_run_bind ":PymodeRun" 44 | exe "vnoremap " g:pymode_run_bind ":PymodeRun" 45 | 46 | endif 47 | 48 | " Add/remove breakpoints 49 | if g:pymode_breakpoint 50 | 51 | exe "nnoremap " g:pymode_breakpoint_bind ":call pymode#breakpoint#operate(line('.'))" 52 | 53 | endif 54 | 55 | " Python folding 56 | if g:pymode_folding 57 | 58 | setlocal foldmethod=expr 59 | setlocal foldexpr=pymode#folding#expr(v:lnum) 60 | setlocal foldtext=pymode#folding#text() 61 | 62 | endif 63 | 64 | " Remove unused whitespaces 65 | if g:pymode_trim_whitespaces 66 | au BufWritePre call pymode#trim_whitespaces() 67 | endif 68 | 69 | " Custom options 70 | if g:pymode_options 71 | setlocal complete+=t 72 | setlocal formatoptions-=t 73 | if v:version > 702 && !&relativenumber 74 | setlocal number 75 | endif 76 | setlocal nowrap 77 | exe "setlocal textwidth=" . g:pymode_options_max_line_length 78 | if g:pymode_options_colorcolumn && exists('+colorcolumn') 79 | setlocal colorcolumn=+1 80 | endif 81 | setlocal commentstring=#%s 82 | setlocal define=^\s*\\(def\\\\|class\\) 83 | endif 84 | 85 | if g:pymode_lint 86 | 87 | command! -buffer -nargs=0 PymodeLintAuto :call pymode#lint#auto() 88 | command! -buffer -nargs=0 PymodeLintToggle :call pymode#lint#toggle() 89 | command! -buffer -nargs=0 PymodeLint :call pymode#lint#check() 90 | 91 | if v:version > 703 || (v:version == 703 && has('patch544')) 92 | au! QuitPre call pymode#quit() 93 | else 94 | au! pymode BufWinLeave * silent! lclose 95 | endif 96 | 97 | let b:pymode_error_line = -1 98 | 99 | if g:pymode_lint_on_fly 100 | au! pymode InsertLeave PymodeLint 101 | endif 102 | 103 | if g:pymode_lint_message 104 | au! pymode CursorMoved 105 | au! pymode CursorMoved call pymode#lint#show_errormessage() 106 | endif 107 | 108 | " Disabled for current release 109 | if g:pymode_lint_async 110 | " let &l:updatetime = g:pymode_lint_async_updatetime 111 | " au! BufEnter call pymode#lint#start() 112 | " au! BufLeave call pymode#lint#stop() 113 | endif 114 | 115 | endif 116 | 117 | " Show python documentation 118 | if g:pymode_doc 119 | 120 | " Set commands 121 | command! -buffer -nargs=1 PymodeDoc call pymode#doc#show("") 122 | 123 | " Set keys 124 | exe "nnoremap " g:pymode_doc_bind ":call pymode#doc#find()" 125 | exe "vnoremap " g:pymode_doc_bind ":call pymode#doc#show(@*)" 126 | 127 | endif 128 | 129 | " Rope support 130 | if g:pymode_rope 131 | 132 | if g:pymode_rope_goto_definition_bind != "" 133 | exe "noremap " . g:pymode_rope_goto_definition_bind . " :call pymode#rope#goto_definition()" 134 | endif 135 | if g:pymode_rope_show_doc_bind != "" 136 | exe "noremap " . g:pymode_rope_show_doc_bind . " :call pymode#rope#show_doc()" 137 | endif 138 | if g:pymode_rope_find_it_bind != "" 139 | exe "noremap " . g:pymode_rope_find_it_bind . " :call pymode#rope#find_it()" 140 | endif 141 | if g:pymode_rope_organize_imports_bind != "" 142 | exe "noremap " . g:pymode_rope_organize_imports_bind . " :call pymode#rope#organize_imports()" 143 | endif 144 | 145 | if g:pymode_rope_rename_bind != "" 146 | exe "noremap " . g:pymode_rope_rename_bind . " :call pymode#rope#rename()" 147 | endif 148 | 149 | if g:pymode_rope_rename_module_bind != "" 150 | exe "noremap " . g:pymode_rope_rename_module_bind . " :call pymode#rope#rename_module()" 151 | endif 152 | 153 | if g:pymode_rope_extract_method_bind != "" 154 | exe "vnoremap " . g:pymode_rope_extract_method_bind . " :call pymode#rope#extract_method()" 155 | endif 156 | 157 | if g:pymode_rope_extract_variable_bind != "" 158 | exe "vnoremap " . g:pymode_rope_extract_variable_bind . " :call pymode#rope#extract_variable()" 159 | endif 160 | 161 | if g:pymode_rope_inline_bind != "" 162 | exe "noremap " . g:pymode_rope_inline_bind . " :call pymode#rope#inline()" 163 | endif 164 | 165 | if g:pymode_rope_move_bind != "" 166 | exe "noremap " . g:pymode_rope_move_bind . " :call pymode#rope#move()" 167 | endif 168 | 169 | if g:pymode_rope_change_signature_bind != "" 170 | exe "noremap " . g:pymode_rope_change_signature_bind . " :call pymode#rope#signature()" 171 | endif 172 | 173 | if g:pymode_rope_use_function_bind != "" 174 | exe "noremap " . g:pymode_rope_use_function_bind . " :call pymode#rope#use_function()" 175 | endif 176 | 177 | if g:pymode_rope_generate_function_bind != "" 178 | exe "noremap " . g:pymode_rope_generate_function_bind . " :call pymode#rope#generate_function()" 179 | endif 180 | 181 | if g:pymode_rope_generate_package_bind != "" 182 | exe "noremap " . g:pymode_rope_generate_package_bind . " :call pymode#rope#generate_package()" 183 | endif 184 | 185 | if g:pymode_rope_generate_class_bind != "" 186 | exe "noremap " . g:pymode_rope_generate_class_bind . " :call pymode#rope#generate_class()" 187 | endif 188 | 189 | if g:pymode_rope_module_to_package_bind != "" 190 | exe "noremap " . g:pymode_rope_module_to_package_bind . " :call pymode#rope#module_to_package()" 191 | endif 192 | 193 | if g:pymode_rope_autoimport_bind != "" 194 | exe "noremap " . g:pymode_rope_autoimport_bind . " :PymodeRopeAutoImport" 195 | endif 196 | 197 | if g:pymode_rope_completion && g:pymode_rope_complete_on_dot 198 | inoremap . .=pymode#rope#complete_on_dot() 199 | endif 200 | 201 | command! -buffer -nargs=? PymodeRopeNewProject call pymode#rope#new() 202 | command! -buffer PymodeRopeUndo call pymode#rope#undo() 203 | command! -buffer PymodeRopeRedo call pymode#rope#redo() 204 | command! -buffer PymodeRopeRenameModule call pymode#rope#rename_module() 205 | command! -buffer PymodeRopeModuleToPackage call pymode#rope#module_to_package() 206 | command! -buffer PymodeRopeRegenerate call pymode#rope#regenerate() 207 | 208 | if g:pymode_rope_autoimport 209 | command! -buffer PymodeRopeAutoImport call pymode#rope#autoimport(expand('')) 210 | endif 211 | 212 | endif 213 | 214 | 215 | if g:pymode_debug 216 | " Redefine functions to be debugged here functions here. 217 | 218 | " NOTE: The redraw seems to be necessary to force messages to get echoed to 219 | " the screen. See: 220 | " https://groups.google.com/forum/#!topic/vim_use/EfcXOjq_rKE 221 | " for details. 222 | " silent! redraw! 223 | " TODO: when loading with 'vim -u ./debug.vim' the messages shown in vim 224 | " are unduly cleared. Need a fix. 225 | 226 | " Start debbuging environment. {{{ 227 | if ! &verbosefile 228 | " Get a system independent temporary filename. The 'marker' variable is 229 | " used to get rid of a null character getting inserted at position. 230 | " substitute() was not able to remove it. 231 | " TODO: see https://superuser.com/questions/935574/get-rid-of-null-character-in-vim-variable 232 | let g:pymode_debug_tempfile=matchstr( 233 | \ execute( 234 | \ g:pymode_python 235 | \ . " import os;import tempfile; marker='|';" 236 | \ . " print(marker, tempfile.gettempdir(), os.sep, " 237 | \ . "'pymode_debug_file.txt', marker, sep='', end='')"), 238 | \ '|\zs.*\ze|') 239 | execute "set verbosefile=" . g:pymode_debug_tempfile 240 | endif 241 | call pymode#debug('Starting debug on: ' 242 | \ . strftime("\%Y-\%m-\%d \%H:\%M:\%S") 243 | \ . ' with file ' . &verbosefile) 244 | " }}} 245 | " Redefine folding expression. {{{ 246 | if g:pymode_folding 247 | setlocal foldexpr=pymode#debug#foldingexpr(v:lnum) 248 | endif 249 | call pymode#debug#sysinfo() 250 | " }}} 251 | " Define auto commands for vim. {{{ 252 | augroup augroup_save_issue_commands 253 | autocmd! 254 | autocmd VimLeave *.py | call pymode#debug('Session history:') | silent! history 255 | augroup END 256 | " }}} 257 | 258 | endif 259 | -------------------------------------------------------------------------------- /logo.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/KsushaBell/python-mode/e01c27e8c17b3af2b9df7f6fc5a8a44afc3ad020/logo.png -------------------------------------------------------------------------------- /plugin/pymode.vim: -------------------------------------------------------------------------------- 1 | " vi: fdl=1 2 | let g:pymode_version = "0.14.0" 3 | 4 | 5 | " Enable pymode by default :) 6 | call pymode#default('g:pymode', 1) 7 | call pymode#default('g:pymode_debug', 0) 8 | 9 | " DESC: Disable script loading 10 | if !g:pymode || &cp || &diff 11 | " Update pymode status to prevent loading in other files and adding this 12 | " condition to all of them. 13 | let g:pymode = 0 14 | finish 15 | endif 16 | 17 | " Pymode needs 18 | filetype plugin on 19 | 20 | " OPTIONS: {{{ 21 | 22 | " Vim Python interpreter. Set to 'disable' for remove python features. 23 | if has("python3") && executable('python3') 24 | call pymode#default('g:pymode_python', 'python3') 25 | else 26 | call pymode#default('g:pymode_python', 'disable') 27 | endif 28 | 29 | " Disable pymode warnings 30 | call pymode#default('g:pymode_warning', 1) 31 | 32 | " Additional python paths 33 | call pymode#default('g:pymode_paths', []) 34 | 35 | " Python documentation support 36 | call pymode#default('g:pymode_doc', 1) 37 | call pymode#default('g:pymode_doc_bind', 'K') 38 | 39 | " Enable/Disable pymode PEP8 indentation 40 | call pymode#default("g:pymode_indent", 1) 41 | 42 | " Customize hanging indent size different than &shiftwidth 43 | call pymode#default("g:pymode_indent_hanging_width", -1) 44 | 45 | " TODO: currently folding suffers from a bad performance and incorrect 46 | " implementation. This feature should be considered experimental. 47 | " Enable/disable pymode folding for pyfiles. 48 | call pymode#default("g:pymode_folding", 0) 49 | " Maximum file length to check for nested class/def statements 50 | call pymode#default("g:pymode_folding_nest_limit", 1000) 51 | " Change for folding customization (by example enable fold for 'if', 'for') 52 | call pymode#default("g:pymode_folding_regex", '^\s*\%(class\|def\|async\s\+def\) .\+\(:\s\+\w\)\@!') 53 | " call pymode#default("g:pymode_folding_regex", '^\s*\%(class\|def\|async\s\+def\)') 54 | 55 | " Enable/disable python motion operators 56 | call pymode#default("g:pymode_motion", 1) 57 | 58 | " Auto remove unused whitespaces on save 59 | call pymode#default("g:pymode_trim_whitespaces", 1) 60 | 61 | " Set recomended python options 62 | call pymode#default("g:pymode_options", 1) 63 | call pymode#default("g:pymode_options_max_line_length", 79) 64 | call pymode#default("g:pymode_options_colorcolumn", 1) 65 | 66 | " Enable/disable vertical display of python documentation 67 | call pymode#default("g:pymode_doc_vertical", 0) 68 | 69 | " Minimal height of pymode quickfix window 70 | call pymode#default('g:pymode_quickfix_maxheight', 6) 71 | 72 | " Maximal height of pymode quickfix window 73 | call pymode#default('g:pymode_quickfix_minheight', 3) 74 | 75 | " Height of preview window 76 | call pymode#default('g:pymode_preview_height', &previewheight) 77 | 78 | " Position of preview window 79 | call pymode#default('g:pymode_preview_position', 'botright') 80 | 81 | " LOAD VIRTUALENV {{{ 82 | " 83 | " Enable virtualenv support 84 | call pymode#default('g:pymode_virtualenv', 1) 85 | 86 | " Get path to virtualenv (by default take from shell) 87 | call pymode#default('g:pymode_virtualenv_path', $VIRTUAL_ENV) 88 | 89 | " Service variable (don't set it manually) 90 | call pymode#default('g:pymode_virtualenv_enabled', '') 91 | 92 | " }}} 93 | 94 | " RUN PYTHON {{{ 95 | " 96 | " Enable code running support 97 | call pymode#default('g:pymode_run', 1) 98 | 99 | " Key's map for run python code 100 | call pymode#default('g:pymode_run_bind', 'r') 101 | 102 | " }}} 103 | 104 | " CHECK CODE {{{ 105 | " 106 | " Code checking 107 | call pymode#default('g:pymode_lint', 1) 108 | 109 | " Check code asynchronously 110 | call pymode#default('g:pymode_lint_async', 1) 111 | call pymode#default('g:pymode_lint_async_updatetime', 1000) 112 | 113 | " Check code every save if file has been modified 114 | call pymode#default("g:pymode_lint_on_write", 1) 115 | 116 | " Check code every save (every) 117 | call pymode#default("g:pymode_lint_unmodified", 0) 118 | 119 | " Check code on fly 120 | call pymode#default("g:pymode_lint_on_fly", 0) 121 | 122 | " Show message about error in command line 123 | call pymode#default("g:pymode_lint_message", 1) 124 | 125 | " Choices are: pylint, pyflakes, pycodestyle, mccabe and pep257 126 | call pymode#default("g:pymode_lint_checkers", ['pyflakes', 'pycodestyle', 'mccabe']) 127 | 128 | " Skip errors and warnings (e.g. E4,W) 129 | call pymode#default("g:pymode_lint_ignore", []) 130 | 131 | " Select errors and warnings (e.g. E4,W) 132 | call pymode#default("g:pymode_lint_select", []) 133 | 134 | " Auto open cwindow if any errors has been finded 135 | call pymode#default("g:pymode_lint_cwindow", 1) 136 | 137 | " If not emply, errors will be sort by defined relevance 138 | " E.g. let g:pymode_lint_sort = ['E', 'C', 'I'] " Errors first 'E', 139 | " after them 'C' and ... 140 | call pymode#default("g:pymode_lint_sort", []) 141 | 142 | " Place error signs 143 | call pymode#default("g:pymode_lint_signs", 1) 144 | 145 | " Symbol's definitions 146 | call pymode#default("g:pymode_lint_todo_symbol", "WW") 147 | call pymode#default("g:pymode_lint_docs_symbol", "DD") 148 | call pymode#default("g:pymode_lint_comment_symbol", "CC") 149 | call pymode#default("g:pymode_lint_visual_symbol", "RR") 150 | call pymode#default("g:pymode_lint_error_symbol", "EE") 151 | call pymode#default("g:pymode_lint_info_symbol", "II") 152 | call pymode#default("g:pymode_lint_pyflakes_symbol", "FF") 153 | 154 | " Code checkers options 155 | " TODO: check if most adequate name name is pycodestyle. 156 | call pymode#default("g:pymode_lint_options_pycodestyle", 157 | \ {'max_line_length': g:pymode_options_max_line_length}) 158 | 159 | call pymode#default("g:pymode_lint_options_pylint", 160 | \ {'max-line-length': g:pymode_options_max_line_length}) 161 | 162 | call pymode#default("g:pymode_lint_options_mccabe", 163 | \ {'complexity': 12}) 164 | 165 | call pymode#default("g:pymode_lint_options_pep257", {}) 166 | call pymode#default("g:pymode_lint_options_pyflakes", { 'builtins': '_' }) 167 | 168 | 169 | " }}} 170 | 171 | " SET/UNSET BREAKPOINTS {{{ 172 | " 173 | 174 | " Create/remove breakpoints 175 | call pymode#default('g:pymode_breakpoint', 1) 176 | 177 | " Key's map for add/remove breakpoint 178 | call pymode#default('g:pymode_breakpoint_bind', 'b') 179 | 180 | " Default pattern for making breakpoints. Leave this empty for auto search available debuggers (pdb, ipdb, ...) 181 | call pymode#default('g:pymode_breakpoint_cmd', '') 182 | 183 | " }}} 184 | 185 | " ROPE (refactoring, codeassist) {{{ 186 | " 187 | " Rope support 188 | call pymode#default('g:pymode_rope', 0) 189 | call pymode#default('g:pymode_rope_prefix', '') 190 | 191 | " System plugin variable 192 | if g:pymode_rope 193 | call pymode#default('g:pymode_rope_current', '') 194 | 195 | " Configurable rope project root 196 | call pymode#default('g:pymode_rope_project_root', '') 197 | 198 | " Configurable rope project folder (always relative to project root) 199 | call pymode#default('g:pymode_rope_ropefolder', '.ropeproject') 200 | 201 | " If project hasnt been finded in current working directory, look at parents directory 202 | call pymode#default('g:pymode_rope_lookup_project', 0) 203 | 204 | " Enable Rope completion 205 | call pymode#default('g:pymode_rope_completion', 1) 206 | 207 | " Complete keywords from not imported modules (could make completion slower) 208 | " Enable autoimport used modules 209 | call pymode#default('g:pymode_rope_autoimport', 0) 210 | 211 | " Offer to import object after complete (if that not be imported before) 212 | call pymode#default('g:pymode_rope_autoimport_import_after_complete', 0) 213 | 214 | " Autoimported modules 215 | call pymode#default('g:pymode_rope_autoimport_modules', ['os', 'shutil', 'datetime']) 216 | 217 | " Bind keys to autoimport module for object under cursor 218 | call pymode#default('g:pymode_rope_autoimport_bind', g:pymode_rope_prefix . 'ra') 219 | 220 | " Automatic completion on dot 221 | call pymode#default('g:pymode_rope_complete_on_dot', 1) 222 | 223 | " Bind keys for autocomplete (leave empty for disable) 224 | call pymode#default('g:pymode_rope_completion_bind', '') 225 | 226 | " Bind keys for goto definition (leave empty for disable) 227 | call pymode#default('g:pymode_rope_goto_definition_bind', g:pymode_rope_prefix . 'g') 228 | 229 | " set command for open definition (e, new, vnew) 230 | call pymode#default('g:pymode_rope_goto_definition_cmd', 'new') 231 | 232 | " Bind keys for show documentation (leave empty for disable) 233 | call pymode#default('g:pymode_rope_show_doc_bind', g:pymode_rope_prefix . 'd') 234 | 235 | " Bind keys for find occurencies (leave empty for disable) 236 | call pymode#default('g:pymode_rope_find_it_bind', g:pymode_rope_prefix . 'f') 237 | 238 | " Bind keys for organize imports (leave empty for disable) 239 | call pymode#default('g:pymode_rope_organize_imports_bind', g:pymode_rope_prefix . 'ro') 240 | 241 | " Bind keys for rename variable/method/class in the project (leave empty for disable) 242 | call pymode#default('g:pymode_rope_rename_bind', g:pymode_rope_prefix . 'rr') 243 | 244 | " Bind keys for rename module 245 | call pymode#default('g:pymode_rope_rename_module_bind', g:pymode_rope_prefix . 'r1r') 246 | 247 | " Bind keys for convert module to package 248 | call pymode#default('g:pymode_rope_module_to_package_bind', g:pymode_rope_prefix . 'r1p') 249 | 250 | " Creates a new function or method (depending on the context) from the selected lines 251 | call pymode#default('g:pymode_rope_extract_method_bind', g:pymode_rope_prefix . 'rm') 252 | 253 | " Creates a variable from the selected lines 254 | call pymode#default('g:pymode_rope_extract_variable_bind', g:pymode_rope_prefix . 'rl') 255 | 256 | " Inline refactoring 257 | call pymode#default('g:pymode_rope_inline_bind', g:pymode_rope_prefix . 'ri') 258 | 259 | " Move refactoring 260 | call pymode#default('g:pymode_rope_move_bind', g:pymode_rope_prefix . 'rv') 261 | 262 | " Generate function 263 | call pymode#default('g:pymode_rope_generate_function_bind', g:pymode_rope_prefix . 'rnf') 264 | 265 | " Generate class 266 | call pymode#default('g:pymode_rope_generate_class_bind', g:pymode_rope_prefix . 'rnc') 267 | 268 | " Generate package 269 | call pymode#default('g:pymode_rope_generate_package_bind', g:pymode_rope_prefix . 'rnp') 270 | 271 | " Change signature 272 | call pymode#default('g:pymode_rope_change_signature_bind', g:pymode_rope_prefix . 'rs') 273 | 274 | " Tries to find the places in which a function can be used and changes the 275 | " code to call it instead 276 | call pymode#default('g:pymode_rope_use_function_bind', g:pymode_rope_prefix . 'ru') 277 | 278 | " Regenerate project cache on every save 279 | call pymode#default('g:pymode_rope_regenerate_on_write', 1) 280 | endif 281 | 282 | " }}} 283 | 284 | " }}} 285 | 286 | " Prepare to plugin loading 287 | if &compatible 288 | set nocompatible 289 | endif 290 | filetype plugin on 291 | 292 | " UltiSnips Fixes 293 | if !len(g:pymode_python) 294 | if (exists('g:_uspy') && g:_uspy == ':py3') || has("python3") 295 | let g:pymode_python = 'python3' 296 | else 297 | let g:pymode_python = 'disable' 298 | endif 299 | endif 300 | 301 | if g:pymode_python == 'python3' 302 | 303 | command! -nargs=1 PymodePython python3 304 | let g:UltiSnipsUsePythonVersion = 3 305 | 306 | else 307 | 308 | let g:pymode_doc = 0 309 | let g:pymode_lint = 0 310 | let g:pymode_path = 0 311 | let g:pymode_rope = 0 312 | let g:pymode_run = 0 313 | let g:pymode_virtualenv = 0 314 | 315 | command! -nargs=1 PymodePython echo 316 | 317 | endif 318 | 319 | command! PymodeVersion echomsg "Pymode version: " . g:pymode_version . " interpreter: " . g:pymode_python . " lint: " . g:pymode_lint . " rope: " . g:pymode_rope 320 | 321 | augroup pymode 322 | -------------------------------------------------------------------------------- /pylama.ini: -------------------------------------------------------------------------------- 1 | [pylama] 2 | ignore=D213 3 | linters=pep8,pyflakes,pylint 4 | 5 | [pylama:pymode/libs*] 6 | skip=1 7 | 8 | [pylama:pylint] 9 | disable=E1120,E1130,E1103,W1401,F0001 10 | -------------------------------------------------------------------------------- /pymode/__init__.py: -------------------------------------------------------------------------------- 1 | """Pymode support functions.""" 2 | 3 | import sys 4 | from importlib.machinery import PathFinder as _PathFinder 5 | 6 | import vim # noqa 7 | 8 | if not hasattr(vim, 'find_module'): 9 | try: 10 | vim.find_module = _PathFinder.find_module # deprecated 11 | except AttributeError: 12 | def _find_module(package_name): 13 | spec = _PathFinder.find_spec(package_name) 14 | return spec.loader if spec else None 15 | vim.find_module = _find_module 16 | 17 | 18 | def auto(): 19 | """Fix PEP8 erorrs in current buffer. 20 | 21 | pymode: uses it in command PymodeLintAuto with pymode#lint#auto() 22 | 23 | """ 24 | from .autopep8 import fix_file 25 | 26 | class Options(object): 27 | aggressive = 1 28 | diff = False 29 | experimental = True 30 | ignore = vim.eval('g:pymode_lint_ignore') 31 | in_place = True 32 | indent_size = int(vim.eval('&tabstop')) 33 | line_range = None 34 | hang_closing = False 35 | max_line_length = int(vim.eval('g:pymode_options_max_line_length')) 36 | pep8_passes = 100 37 | recursive = False 38 | select = vim.eval('g:pymode_lint_select') 39 | verbose = 0 40 | 41 | fix_file(vim.current.buffer.name, Options) 42 | 43 | 44 | def get_documentation(): 45 | """Search documentation and append to current buffer.""" 46 | from io import StringIO 47 | 48 | sys.stdout, _ = StringIO(), sys.stdout 49 | help(vim.eval('a:word')) 50 | sys.stdout, out = _, sys.stdout.getvalue() 51 | vim.current.buffer.append(str(out).splitlines(), 0) 52 | -------------------------------------------------------------------------------- /pymode/async.py: -------------------------------------------------------------------------------- 1 | """ Python-mode async support. """ 2 | 3 | from queue import Queue # noqa 4 | 5 | 6 | RESULTS = Queue() 7 | -------------------------------------------------------------------------------- /pymode/autopep8.py: -------------------------------------------------------------------------------- 1 | ../submodules/autopep8/autopep8.py -------------------------------------------------------------------------------- /pymode/environment.py: -------------------------------------------------------------------------------- 1 | """Define interfaces.""" 2 | 3 | import json 4 | import os.path 5 | import time 6 | import vim # noqa 7 | 8 | 9 | class VimPymodeEnviroment(object): 10 | 11 | """Vim User interface.""" 12 | 13 | prefix = '[Pymode]' 14 | 15 | def __init__(self): 16 | """Init VIM environment.""" 17 | self.current = vim.current 18 | self.options = dict(encoding=vim.eval('&enc')) 19 | self.options['debug'] = self.var('g:pymode_debug', True) 20 | 21 | @property 22 | def curdir(self): 23 | """Return current working directory.""" 24 | return self.var('getcwd()') 25 | 26 | @property 27 | def curbuf(self): 28 | """Return current buffer.""" 29 | return self.current.buffer 30 | 31 | @property 32 | def cursor(self): 33 | """Return current window position. 34 | 35 | :return tuple: (row, col) 36 | 37 | """ 38 | return self.current.window.cursor 39 | 40 | @property 41 | def source(self): 42 | """Return source of current buffer.""" 43 | return "\n".join(self.lines) 44 | 45 | @property 46 | def lines(self): 47 | """Iterate by lines in current file. 48 | 49 | :return list: 50 | 51 | """ 52 | return self.curbuf 53 | 54 | @staticmethod 55 | def var(name, to_bool=False, silence=False, default=None): 56 | """Get vim variable. 57 | 58 | :return vimobj: 59 | 60 | """ 61 | try: 62 | value = vim.eval(name) 63 | except vim.error: 64 | if silence: 65 | return default 66 | raise 67 | 68 | if to_bool: 69 | try: 70 | value = bool(int(value)) 71 | except ValueError: 72 | value = value 73 | return value 74 | 75 | @staticmethod 76 | def message(msg, history=False): 77 | """Show message to user. 78 | 79 | :return: :None 80 | 81 | """ 82 | if history: 83 | return vim.command('echom "%s"' % str(msg)) 84 | 85 | return vim.command('call pymode#wide_message("%s")' % str(msg)) 86 | 87 | def user_input(self, msg='', default=''): 88 | """Return user input or default. 89 | 90 | :return str: 91 | 92 | """ 93 | prompt = [] 94 | prompt.append(str(self.prefix.strip())) 95 | prompt.append(str(msg).strip()) 96 | 97 | if default != '': 98 | prompt.append('[%s]' % default) 99 | 100 | prompt.append('> ') 101 | prompt = ' '.join([s for s in prompt if s]) 102 | 103 | vim.command('echohl Debug') 104 | 105 | try: 106 | input_str = vim.eval('input(%r)' % (prompt,)) 107 | except KeyboardInterrupt: 108 | input_str = '' 109 | 110 | vim.command('echohl none') 111 | 112 | return input_str or default 113 | 114 | def user_confirm(self, msg, yes=False): 115 | """Get user confirmation. 116 | 117 | :return bool: 118 | 119 | """ 120 | default = 'yes' if yes else 'no' 121 | action = self.user_input(msg, default) 122 | return action and 'yes'.startswith(action) 123 | 124 | def user_input_choices(self, msg, *options): 125 | """Get one of many options. 126 | 127 | :return str: A choosen option 128 | 129 | """ 130 | choices = ['%s %s' % (self.prefix, msg)] 131 | choices += [ 132 | "%s. %s" % (num, opt) for num, opt in enumerate(options, 1)] 133 | try: 134 | input_str = int( 135 | vim.eval('inputlist(%s)' % self.prepare_value(choices))) 136 | except (KeyboardInterrupt, ValueError): 137 | input_str = 0 138 | 139 | if not input_str: 140 | self.message('Cancelled!') 141 | return False 142 | 143 | try: 144 | return options[input_str - 1] 145 | except (IndexError, ValueError): 146 | self.error('Invalid option: %s' % input_str) 147 | return self.user_input_choices(msg, *options) 148 | 149 | @staticmethod 150 | def error(msg): 151 | """Show error to user.""" 152 | vim.command('call pymode#error("%s")' % str(msg)) 153 | 154 | def debug(self, msg, *args): 155 | """Print debug information.""" 156 | if self.options.get('debug'): 157 | print("%s %s [%s]" % ( 158 | int(time.time()), msg, ', '.join([str(a) for a in args]))) 159 | 160 | def stop(self, value=None): 161 | """Break Vim function.""" 162 | cmd = 'return' 163 | if value is not None: 164 | cmd += ' ' + self.prepare_value(value) 165 | vim.command(cmd) 166 | 167 | def catch_exceptions(self, func): 168 | """Decorator. Make execution more silence. 169 | 170 | :return func: 171 | 172 | """ 173 | def _wrapper(*args, **kwargs): 174 | try: 175 | return func(*args, **kwargs) 176 | except (Exception, vim.error) as e: # noqa 177 | if self.options.get('debug'): 178 | raise 179 | self.error(e) 180 | return None 181 | return _wrapper 182 | 183 | def run(self, name, *args): 184 | """Run vim function.""" 185 | vim.command('call %s(%s)' % (name, ", ".join([ 186 | self.prepare_value(a) for a in args 187 | ]))) 188 | 189 | def let(self, name, value): 190 | """Set variable.""" 191 | cmd = 'let %s = %s' % (name, self.prepare_value(value)) 192 | self.debug(cmd) 193 | vim.command(cmd) 194 | 195 | def prepare_value(self, value, dumps=True): 196 | """Decode bstr to vim encoding. 197 | 198 | :return unicode string: 199 | 200 | """ 201 | if dumps: 202 | value = json.dumps(value) 203 | 204 | return value 205 | 206 | def get_offset_params(self, cursor=None, base=""): 207 | """Calculate current offset. 208 | 209 | :return tuple: (source, offset) 210 | 211 | """ 212 | row, col = cursor or env.cursor 213 | source = "" 214 | offset = 0 215 | for i, line in enumerate(self.lines, 1): 216 | if i == row: 217 | source += line[:col] + base 218 | offset = len(source) 219 | source += line[col:] 220 | else: 221 | source += line 222 | source += '\n' 223 | env.debug('Get offset', base or None, row, col, offset) 224 | return source, offset 225 | 226 | @staticmethod 227 | def goto_line(line): 228 | """Go to line.""" 229 | vim.command('normal %sggzz' % line) 230 | 231 | def goto_file(self, path, cmd='e', force=False): 232 | """Open file by path.""" 233 | if force or os.path.abspath(path) != self.curbuf.name: 234 | self.debug('read', path) 235 | if ' ' in path and os.name == 'posix': 236 | path = path.replace(' ', '\\ ') 237 | vim.command("%s %s" % (cmd, path)) 238 | 239 | @staticmethod 240 | def goto_buffer(bufnr): 241 | """Open buffer.""" 242 | if str(bufnr) != '-1': 243 | vim.command('buffer %s' % bufnr) 244 | 245 | def select_line(self, start, end): 246 | vim.command('normal %sggV%sgg' % (start, end)) 247 | 248 | 249 | env = VimPymodeEnviroment() 250 | -------------------------------------------------------------------------------- /pymode/libs/__init__.py: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/KsushaBell/python-mode/e01c27e8c17b3af2b9df7f6fc5a8a44afc3ad020/pymode/libs/__init__.py -------------------------------------------------------------------------------- /pymode/libs/appdirs.py: -------------------------------------------------------------------------------- 1 | ../../submodules/appdirs/appdirs.py -------------------------------------------------------------------------------- /pymode/libs/astroid: -------------------------------------------------------------------------------- 1 | ../../submodules/astroid/astroid -------------------------------------------------------------------------------- /pymode/libs/mccabe.py: -------------------------------------------------------------------------------- 1 | ../../submodules/mccabe/mccabe.py -------------------------------------------------------------------------------- /pymode/libs/pycodestyle.py: -------------------------------------------------------------------------------- 1 | ../../submodules/pycodestyle/pycodestyle.py -------------------------------------------------------------------------------- /pymode/libs/pydocstyle: -------------------------------------------------------------------------------- 1 | ../../submodules/pydocstyle/src/pydocstyle/ -------------------------------------------------------------------------------- /pymode/libs/pyflakes: -------------------------------------------------------------------------------- 1 | ../../submodules/pyflakes/pyflakes/ -------------------------------------------------------------------------------- /pymode/libs/pylama: -------------------------------------------------------------------------------- 1 | ../../submodules/pylama/pylama/ -------------------------------------------------------------------------------- /pymode/libs/pylint: -------------------------------------------------------------------------------- 1 | ../../submodules/pylint/pylint -------------------------------------------------------------------------------- /pymode/libs/pytoolconfig: -------------------------------------------------------------------------------- 1 | ../../submodules/pytoolconfig/pytoolconfig/ -------------------------------------------------------------------------------- /pymode/libs/rope: -------------------------------------------------------------------------------- 1 | ../../submodules/rope/rope -------------------------------------------------------------------------------- /pymode/libs/snowballstemmer: -------------------------------------------------------------------------------- 1 | ../../submodules/snowball_py/snowballstemmer -------------------------------------------------------------------------------- /pymode/libs/toml: -------------------------------------------------------------------------------- 1 | ../../submodules/toml/toml -------------------------------------------------------------------------------- /pymode/libs/tomli: -------------------------------------------------------------------------------- 1 | ../../submodules/tomli/src/tomli -------------------------------------------------------------------------------- /pymode/lint.py: -------------------------------------------------------------------------------- 1 | """Pylama integration.""" 2 | 3 | from .environment import env 4 | from .utils import silence_stderr 5 | 6 | import os.path 7 | 8 | 9 | from pylama.lint import LINTERS 10 | 11 | try: 12 | from pylama.lint.pylama_pylint import Linter 13 | LINTERS['pylint'] = Linter() 14 | except Exception: # noqa 15 | pass 16 | 17 | 18 | def code_check(): 19 | """Run pylama and check current file. 20 | 21 | :return bool: 22 | 23 | """ 24 | with silence_stderr(): 25 | 26 | from pylama.core import run 27 | from pylama.config import parse_options 28 | 29 | if not env.curbuf.name: 30 | return env.stop() 31 | 32 | linters = env.var('g:pymode_lint_checkers') 33 | env.debug(linters) 34 | 35 | # Fixed in v0.9.3: these two parameters may be passed as strings. 36 | # DEPRECATE: v:0.10.0: need to be set as lists. 37 | if isinstance(env.var('g:pymode_lint_ignore'), str): 38 | raise ValueError('g:pymode_lint_ignore should have a list type') 39 | else: 40 | ignore = env.var('g:pymode_lint_ignore') 41 | if isinstance(env.var('g:pymode_lint_select'), str): 42 | raise ValueError('g:pymode_lint_select should have a list type') 43 | else: 44 | select = env.var('g:pymode_lint_select') 45 | if 'pep8' in linters: 46 | # TODO: Add a user visible deprecation warning here 47 | env.message('pep8 linter is deprecated, please use pycodestyle.') 48 | linters.remove('pep8') 49 | linters.append('pycodestyle') 50 | 51 | options = parse_options( 52 | linters=linters, force=1, 53 | ignore=ignore, 54 | select=select, 55 | ) 56 | env.debug(options) 57 | 58 | for linter in linters: 59 | opts = env.var('g:pymode_lint_options_%s' % linter, silence=True) 60 | if opts: 61 | options.linters_params[linter] = options.linters_params.get( 62 | linter, {}) 63 | options.linters_params[linter].update(opts) 64 | 65 | path = os.path.relpath(env.curbuf.name, env.curdir) 66 | env.debug("Start code check: ", path) 67 | 68 | if getattr(options, 'skip', None) and any(p.match(path) for p in options.skip): # noqa 69 | env.message('Skip code checking.') 70 | env.debug("Skipped") 71 | return env.stop() 72 | 73 | if env.options.get('debug'): 74 | import logging 75 | from pylama.core import LOGGER 76 | LOGGER.setLevel(logging.DEBUG) 77 | 78 | errors = run(path, code='\n'.join(env.curbuf) + '\n', options=options) 79 | 80 | env.debug("Find errors: ", len(errors)) 81 | sort_rules = env.var('g:pymode_lint_sort') 82 | 83 | def __sort(e): 84 | try: 85 | return sort_rules.index(e.get('type')) 86 | except ValueError: 87 | return 999 88 | 89 | if sort_rules: 90 | env.debug("Find sorting: ", sort_rules) 91 | errors = sorted(errors, key=__sort) 92 | 93 | errors_list = [] 94 | for e in errors: 95 | if e.col is None: 96 | e.col = 1 97 | err_dict = e.to_dict() 98 | err_dict['bufnr'] = env.curbuf.number 99 | err_dict['type'] = e.etype 100 | err_dict['text'] = e.message 101 | errors_list.append(err_dict) 102 | 103 | env.run('g:PymodeLocList.current().extend', errors_list) 104 | 105 | # pylama:ignore=W0212,E1103 106 | -------------------------------------------------------------------------------- /pymode/run.py: -------------------------------------------------------------------------------- 1 | """ Code runnning support. """ 2 | import sys 3 | from io import StringIO 4 | from re import compile as re 5 | 6 | from .environment import env 7 | 8 | 9 | encoding = re(r'#.*coding[:=]\s*([-\w.]+)') 10 | 11 | 12 | def run_code(): 13 | """ Run python code in current buffer. 14 | 15 | :returns: None 16 | 17 | """ 18 | errors, err = [], '' 19 | line1, line2 = env.var('a:line1'), env.var('a:line2') 20 | lines = __prepare_lines(line1, line2) 21 | if encoding.match(lines[0]): 22 | lines.pop(0) 23 | if encoding.match(lines[0]): 24 | lines.pop(0) 25 | elif encoding.match(lines[1]): 26 | lines.pop(1) 27 | 28 | context = dict( 29 | __name__='__main__', 30 | __file__=env.var('expand("%:p")'), 31 | input=env.user_input, 32 | raw_input=env.user_input) 33 | 34 | sys.stdout, stdout_ = StringIO(), sys.stdout 35 | sys.stderr, stderr_ = StringIO(), sys.stderr 36 | 37 | try: 38 | code = compile('\n'.join(lines) + '\n', env.curbuf.name, 'exec') 39 | sys.path.insert(0, env.curdir) 40 | exec(code, context) # noqa 41 | sys.path.pop(0) 42 | 43 | except SystemExit as e: 44 | if e.code: 45 | # A non-false code indicates abnormal termination. 46 | # A false code will be treated as a 47 | # successful run, and the error will be hidden from Vim 48 | env.error("Script exited with code %s" % e.code) 49 | return env.stop() 50 | 51 | except Exception: 52 | import traceback 53 | err = traceback.format_exc() 54 | 55 | else: 56 | err = sys.stderr.getvalue() 57 | 58 | output = sys.stdout.getvalue() 59 | output = env.prepare_value(output, dumps=False) 60 | sys.stdout, sys.stderr = stdout_, stderr_ 61 | 62 | errors += [er for er in err.splitlines() if er and "" not in er] 63 | 64 | env.let('l:traceback', errors[2:]) 65 | env.let('l:output', [s for s in output.splitlines()]) 66 | 67 | 68 | def __prepare_lines(line1, line2): 69 | 70 | lines = [l.rstrip() for l in env.lines[int(line1) - 1:int(line2)]] 71 | 72 | indent = 0 73 | for line in lines: 74 | if line: 75 | indent = len(line) - len(line.lstrip()) 76 | break 77 | 78 | if len(lines) == 1: 79 | lines.append('') 80 | return [l[indent:] for l in lines] 81 | -------------------------------------------------------------------------------- /pymode/utils.py: -------------------------------------------------------------------------------- 1 | """Pymode utils.""" 2 | import os.path 3 | import sys 4 | import threading 5 | import warnings 6 | from contextlib import contextmanager 7 | from io import StringIO 8 | 9 | import vim # noqa 10 | 11 | 12 | DEBUG = int(vim.eval('g:pymode_debug')) 13 | 14 | warnings.filterwarnings('ignore') 15 | 16 | 17 | @contextmanager 18 | def silence_stderr(): 19 | """Redirect stderr.""" 20 | if DEBUG: 21 | yield 22 | 23 | else: 24 | with threading.Lock(): 25 | stderr = sys.stderr 26 | sys.stderr = StringIO() 27 | 28 | yield 29 | 30 | with threading.Lock(): 31 | sys.stderr = stderr 32 | 33 | 34 | def patch_paths(): 35 | """Patch python sys.path. 36 | 37 | Load required modules from the plugin's sources. 38 | """ 39 | dir_script = os.path.dirname(os.path.abspath(__file__)) 40 | sys.path.insert(0, os.path.join(dir_script, 'libs')) 41 | if sys.platform == 'win32' or sys.platform == 'msys': 42 | dir_submodule = os.path.abspath(os.path.join(dir_script, 43 | '..', 'submodules')) 44 | sub_modules = os.listdir(dir_submodule) 45 | for module in sub_modules: 46 | module_full_path = os.path.join(dir_submodule, module) 47 | if module_full_path not in sys.path: 48 | sys.path.insert(0, module_full_path) 49 | -------------------------------------------------------------------------------- /pymode/virtualenv.py: -------------------------------------------------------------------------------- 1 | """Support virtualenv in pymode.""" 2 | 3 | import os 4 | import sys 5 | import site 6 | 7 | from .environment import env 8 | 9 | 10 | @env.catch_exceptions 11 | def enable_virtualenv(): 12 | """Enable virtualenv for vim. 13 | 14 | :return bool: 15 | 16 | """ 17 | path = env.var('g:pymode_virtualenv_path') 18 | # Normalize path to be an absolute path 19 | # If an absolute path is provided, that path will be returned, otherwise 20 | # the returned path will be an absolute path but computed relative 21 | # to the current working directory 22 | path = os.path.abspath(path) 23 | enabled = env.var('g:pymode_virtualenv_enabled') 24 | if path == enabled: 25 | env.message('Virtualenv %s already enabled.' % path) 26 | return env.stop() 27 | 28 | activate_env_from_path(path) 29 | env.message('Activate virtualenv: ' + path) 30 | env.let('g:pymode_virtualenv_enabled', path) 31 | return True 32 | 33 | 34 | def activate_env_from_path(env_path): 35 | """Activate given virtualenv.""" 36 | prev_sys_path = list(sys.path) 37 | 38 | if sys.platform == 'win32': 39 | site_packages_paths = [os.path.join(env_path, 'Lib', 'site-packages')] 40 | else: 41 | lib_path = os.path.join(env_path, 'lib') 42 | site_packages_paths = [os.path.join(lib_path, lib, 'site-packages') 43 | for lib in os.listdir(lib_path)] 44 | for site_packages_path in site_packages_paths: 45 | site.addsitedir(site_packages_path) 46 | 47 | sys.real_prefix = sys.prefix 48 | sys.prefix = env_path 49 | sys.exec_prefix = env_path 50 | 51 | # Move the added items to the front of the path: 52 | new_sys_path = [] 53 | for item in list(sys.path): 54 | if item not in prev_sys_path: 55 | new_sys_path.append(item) 56 | sys.path.remove(item) 57 | sys.path[:0] = new_sys_path 58 | -------------------------------------------------------------------------------- /readme.md: -------------------------------------------------------------------------------- 1 | [![Testing python-mode](https://github.com/python-mode/python-mode/workflows/Testing%20python-mode/badge.svg?branch=develop)](https://github.com/python-mode/python-mode/actions?query=workflow%3A%22Testing+python-mode%22+branch%3Adevelop) 2 | 3 | ![](https://raw.github.com/python-mode/python-mode/develop/logo.png) 4 | # Python-mode, a Python IDE for Vim 5 | 6 | ------------------------------------------------------------------------------- 7 | 8 | *This project needs contributors.* 9 | 10 | **Documentation:** 11 | - ``:help pymode`` 12 | - 13 | 14 | ------------------------------------------------------------------------------- 15 | 16 |

17 | 18 |

19 | 20 | ***Important notes***: 21 | 22 | * From 2017-11-19 onwards python-mode uses submodules instead of 23 | hard coding 3rd party libraries into its codebase. Please issue the command: 24 | `git submodule update --init --recursive` inside your python-mode folder. 25 | 26 | * From 2019-12-14 onwards `python-mode` **dropped python2 support**. If you 27 | still need to use it with python2 you should look for the `last-py2-support` 28 | branch and/or tag. 29 | 30 | If you are a new user please clone the repos using the recursive flag: 31 | 32 | > git clone --recurse-submodules https://github.com/python-mode/python-mode 33 | 34 | ------------------------------------------------------------------------------- 35 | 36 | Python-mode is a Vim plugin that magically converts Vim into a Python IDE. 37 | 38 | Why Python-mode? 39 | 40 | 1. **Be more productive**: Pymode saves time by bringing all the tools 41 | necessary for professional developers so that you can focus on bigger 42 | things. It has been finely tuned based on decades of experience working 43 | with Vim and is constantly kept up to date. 44 | 2. **Get smart assistance**: Pymode knows all about your code. We use the 45 | best-in-class intellisense code completion, on-the-fly error checking and 46 | quick-fixes; easy project navigation and much more. 47 | 3. **Use the full power and capabilities of Vim**: Unlike traditional IDEs 48 | which can only provide a small subset of Vim functionalities, you can do 49 | everything and anything that you can in Vim. 50 | 4. **Modular structure**: We attempt to create Python-mode with the same 51 | principles of python: i.e. have a modular structure, so that as and when 52 | better libraries evolve, we can provide you the best experience, while 53 | abstracting the details so that you can get back to what you do best. 54 | 5. **Written mostly in Python**: 96.1% written in Python. Well, we love Python 55 | :) 56 | 57 | The plugin contains all you need to develop python applications in Vim. 58 | 59 | * Support Python and 3.6+ 60 | * Syntax highlighting 61 | * Virtualenv support 62 | * Run python code (`r`) 63 | * Add/remove breakpoints (`b`) 64 | * Improved Python indentation 65 | * Python motions and operators (`]]`, `3[[`, `]]M`, `vaC`, `viM`, 66 | `daC`, `ciM`, ...) 67 | * Improved Python folding 68 | * Run multiple code checkers simultaneously (`:PymodeLint`) 69 | * Autofix PEP8 errors (`:PymodeLintAuto`) 70 | * Search in python documentation (`K`) 71 | * Code refactoring 72 | * Intellisense code-completion 73 | * Go to definition (`g`) 74 | * And more, more ... 75 | 76 | See a screencast here: . 77 | 78 | Another old presentation here: . 79 | 80 | **To read python-mode documentation in Vim, use** `:help pymode`. 81 | 82 | # Requirements 83 | 84 | Vim >= 7.3 (most features needed +python3 support) (also 85 | `--with-features=big` if you want `g:pymode_lint_signs`). 86 | 87 | # How to install 88 | 89 | ## Manually (according to vim's package structure) 90 | 91 | As of vim8 there is an officially supported way of adding plugins. See `:tab 92 | help packages` in vim for details. 93 | 94 | cd ~/.vim/pack/python-mode/start 95 | git clone --recurse-submodules https://github.com/python-mode/python-mode.git 96 | cd python-mode 97 | 98 | Note. Windows OS users need to add `-c core.symlinks=true`. See below. 99 | 100 | ## pathogen 101 | 102 | cd ~/.vim 103 | mkdir -p bundle && cd bundle 104 | git clone --recurse-submodules https://github.com/python-mode/python-mode.git 105 | 106 | 107 | Enable [pathogen](https://github.com/tpope/vim-pathogen) in your `~/.vimrc`: 108 | 109 | " Pathogen load 110 | filetype off 111 | 112 | call pathogen#infect() 113 | call pathogen#helptags() 114 | 115 | filetype plugin indent on 116 | syntax on 117 | 118 | ## vim-plug 119 | 120 | Include the following in the [vim-plug](https://github.com/junegunn/vim-plug) 121 | section of your `~/.vimrc`: 122 | 123 | Plug 'python-mode/python-mode', { 'for': 'python', 'branch': 'develop' } 124 | 125 | ## NeoBundle 126 | 127 | Add the following: 128 | 129 | " python-mode: PyLint, Rope, Pydoc, breakpoints from box. 130 | " https://github.com/python-mode/python-mode 131 | NeoBundleLazy 'python-mode/python-mode', { 'on_ft': 'python' } 132 | 133 | ## Manually 134 | 135 | % git clone --recurse-submodules https://github.com/python-mode/python-mode.git 136 | % cd python-mode 137 | % cp -R * ~/.vim 138 | 139 | Then rebuild **helptags** in vim: 140 | 141 | :helptags ~/.vim/doc/ 142 | 143 | **filetype-plugin** (`:help filetype-plugin-on`) and **filetype-indent** 144 | (`:help filetype-indent-on`) must be enabled to use python-mode. 145 | 146 | # Troubleshooting/Debugging 147 | 148 | First read our short 149 | [FAQ](https://github.com/python-mode/python-mode/blob/develop/doc/pymode.txt) 150 | or using `:help pymode-faq`. 151 | If your question is not described there then you already know what to do 152 | (because you read the first item of our FAQ :) ). 153 | 154 | Nevertheless just a refresher on how to submit bugs: 155 | 156 | **(From the FAQ)** 157 | 158 | Clear all python cache/compiled files (`*.pyc` files and `__pycache__` 159 | directory and everything under it) from your _python-mode_ install directory. 160 | 161 | In Linux/Unix/MacOS you can run: 162 | 163 | `find -type f -iname '*.pyc' -o -iname '*.pyo' -delete && find . -type d -name '__pycache__' -delete` 164 | 165 | Then start python mode with: 166 | 167 | `vim -i NONE -u /debugvimrc.vim` 168 | 169 | Reproduce the error and submit your python mode debug file. You can check its 170 | location with `:messages` for something like: 171 | 172 | > pymode debug msg 1: Starting debug on: 2017-11-18 16:44:13 with file /tmp/pymode_debug_file.txt 173 | 174 | Please submit the entire content of the file along with a reasoning of why the 175 | plugin seems broken. 176 | 177 | ***Do check for sensitive information in the file before submitting.*** 178 | 179 | Please, also provide more contextual information such as: 180 | 181 | * your Operational System (Linux, WIndows, Mac) and which version 182 | * the `vim --version` output 183 | * which is your default python (`python --version`) 184 | * the python version that vim has loaded in your tests: 185 | * `:PymodePython import sys; print(sys.version_info)` output. 186 | * and if you are using virtualenvs and/or conda, also state that, please. 187 | * It would be good also to provide the output of the two following commands: 188 | * `git status` (under your _python-mode_ directory) 189 | * `tree ` or something similar (such as `ls -lR`) 190 | 191 | # Frequent problems 192 | 193 | Read this section before opening an issue on the tracker. 194 | 195 | ## Python 2/3 vim support 196 | 197 | Vim [has issues](https://github.com/vim/vim/issues/3585) to work with both 198 | python2 and python3 at the same time, so if your VIM is compiled with support 199 | to both version you may find problems. The best way to handle it is to build 200 | your vim again with only python3 support. 201 | [Here](https://github.com/ycm-core/YouCompleteMe/wiki/Building-Vim-from-source) 202 | is a good reference on how to build vim from source. 203 | 204 | ## Python 3 syntax 205 | 206 | `python-mode` supports only python3, so, if you are using python2 we cannot 207 | help you that much. Look for our branch with python2-support (old version, 208 | not maintained anymore) (`last-py2-support`). 209 | 210 | ## Symlinks on Windows 211 | 212 | Users on Windows OS might need to add `-c core.symlinks=true` switch to 213 | correctly clone / pull repository. Example: `git clone --recurse-submodules 214 | https://github.com/python-mode/python-mode -c core.symlinks=true` 215 | 216 | ## Error updating the plugin 217 | 218 | If you are trying to update the plugin (using a plugin manager or manually) and 219 | you are seeing an error such as: 220 | 221 | > Server does not allow request for unadvertised object 222 | 223 | Then we probably changed some repo reference or some of our dependencies had a 224 | `git push --force` in its git history. So the best way for you to handle it is 225 | to run, inside the `python-mode` directory: 226 | 227 | * `git submodule update --recursive --init --force` 228 | * `git submodule sync --recursive` 229 | 230 | # Documentation 231 | 232 | Documentation is available in your vim `:help pymode`. 233 | 234 | # Bugtracker 235 | 236 | If you have any suggestions, bug reports or annoyances please report them to 237 | the issue tracker at: 238 | 239 | 240 | # Contributing 241 | 242 | The contributing guidelines for this plugin are outlined at 243 | `:help pymode-development`. 244 | 245 | * Author: Kirill Klenov () 246 | * Maintainers: 247 | * Felipe Vieira () 248 | * Diego Rabatone Oliveira () 249 | 250 | Also see the AUTHORS file. 251 | 252 | Development of python-mode happens at github: 253 | 254 | 255 | Please make a pull request to development branch and add yourself to AUTHORS. 256 | 257 | ### Python libraries 258 | 259 | Vendored Python modules are located mostly in 260 | [pymode/libs/](https://github.com/python-mode/python-mode/tree/develop/pymode/libs). 261 | 262 | # Copyright 263 | 264 | Copyright © 2013-2015 Kirill Klenov (). 265 | 266 | # License 267 | 268 | Licensed under a [GNU lesser general public license](). 269 | 270 | If you like this plugin, I would very appreciated if you kindly send me 271 | a postcard :) My address is here: "Russia, 143500, MO, Istra, pos. Severny 8-3" 272 | to "Kirill Klenov". **Thanks for support!** 273 | -------------------------------------------------------------------------------- /syntax/pyrex.vim: -------------------------------------------------------------------------------- 1 | " Vim syntax file 2 | " Language: Pyrex 3 | " Maintainer: John Tyree 4 | " Last Change: 2012 Nov 06 5 | 6 | " For version 5.x: Clear all syntax items 7 | " For version 6.x: Quit when a syntax file was already loaded 8 | if version < 600 9 | syntax clear 10 | elseif exists("b:current_syntax") 11 | finish 12 | endif 13 | 14 | " Read the Python syntax to start with 15 | if version < 600 16 | so :p:h/python.vim 17 | else 18 | runtime! syntax/python.vim 19 | unlet b:current_syntax 20 | endif 21 | 22 | " Pyrex extentions 23 | syn keyword pyrexStatement nogil inline typedef ctypedef sizeof 24 | syn keyword pyrexType Py_ssize_t int long short float double char object void 25 | " Here we want slightly different behavior depending on whether we're declaring 26 | " variables or functions. c[p]def should work on the top level as a keyword, but 27 | " should ALSO work to identify functions and classes. 28 | syn match pyrexStatement "\" 29 | syn match pyrexStatement "\[^=]*(\@=" contains=pythonStatement,pyrexStatement,pythonFunction,pyrexType skipwhite 30 | syn keyword pyrexType signed unsigned 31 | syn keyword pyrexStructure struct union enum 32 | syn keyword pyrexInclude include cimport 33 | syn keyword pyrexAccess public private property readonly extern 34 | " If someome wants Python's built-ins highlighted probably he 35 | " also wants Pyrex's built-ins highlighted 36 | if exists("python_highlight_builtins") || exists("pyrex_highlight_builtins") 37 | syn keyword pyrexBuiltin NULL 38 | endif 39 | 40 | " This deletes "from" from the keywords and re-adds it as a 41 | " match with lower priority than pyrexForFrom 42 | syn clear pythonInclude 43 | syn keyword pythonInclude import 44 | syn match pythonInclude "\" 45 | 46 | " With "for[^:]*\zsfrom" VIM does not match "for" anymore, so 47 | " I used the slower "\@<=" form 48 | syn match pyrexForFrom "\(\[^:]*\)\@<=\" 49 | 50 | " Default highlighting 51 | if version >= 508 || !exists("did_pyrex_syntax_inits") 52 | if version < 508 53 | let did_pyrex_syntax_inits = 1 54 | command -nargs=+ HiLink hi link 55 | else 56 | command -nargs=+ HiLink hi def link 57 | endif 58 | HiLink pyrexStatement Statement 59 | HiLink pyrexType Type 60 | HiLink pyrexStructure Structure 61 | HiLink pyrexInclude PreCondit 62 | HiLink pyrexAccess pyrexStatement 63 | if exists("python_highlight_builtins") || exists("pyrex_highlight_builtins") 64 | HiLink pyrexBuiltin Function 65 | endif 66 | HiLink pyrexForFrom Statement 67 | 68 | delcommand HiLink 69 | endif 70 | 71 | let b:current_syntax = "pyrex" 72 | -------------------------------------------------------------------------------- /syntax/python.vim: -------------------------------------------------------------------------------- 1 | " vim: ft=vim:fdm=marker 2 | 3 | " Enable pymode syntax for python files 4 | call pymode#default('g:pymode', 1) 5 | call pymode#default('g:pymode_syntax', g:pymode) 6 | 7 | " DESC: Disable script loading 8 | if !g:pymode || !g:pymode_syntax || pymode#default('b:current_syntax', 'pymode') 9 | finish 10 | endif 11 | 12 | " OPTIONS: {{{ 13 | 14 | " Highlight all by default 15 | call pymode#default('g:pymode_syntax_all', 1) 16 | 17 | " Highlight 'print' as function 18 | call pymode#default("g:pymode_syntax_print_as_function", 0) 19 | " 20 | " Highlight 'async/await' keywords 21 | call pymode#default("g:pymode_syntax_highlight_async_await", g:pymode_syntax_all) 22 | 23 | " Highlight '=' operator 24 | call pymode#default('g:pymode_syntax_highlight_equal_operator', g:pymode_syntax_all) 25 | 26 | " Highlight ':=' operator 27 | call pymode#default('g:pymode_syntax_highlight_walrus_operator', g:pymode_syntax_all) 28 | 29 | " Highlight '*' operator 30 | call pymode#default('g:pymode_syntax_highlight_stars_operator', g:pymode_syntax_all) 31 | 32 | " Highlight 'self' keyword 33 | call pymode#default('g:pymode_syntax_highlight_self', g:pymode_syntax_all) 34 | 35 | " Highlight indent's errors 36 | call pymode#default('g:pymode_syntax_indent_errors', g:pymode_syntax_all) 37 | 38 | " Highlight space's errors 39 | call pymode#default('g:pymode_syntax_space_errors', g:pymode_syntax_all) 40 | 41 | " Highlight string formatting 42 | call pymode#default('g:pymode_syntax_string_formatting', g:pymode_syntax_all) 43 | call pymode#default('g:pymode_syntax_string_format', g:pymode_syntax_all) 44 | call pymode#default('g:pymode_syntax_string_templates', g:pymode_syntax_all) 45 | call pymode#default('g:pymode_syntax_doctests', g:pymode_syntax_all) 46 | 47 | " Support docstrings in syntax highlighting 48 | call pymode#default('g:pymode_syntax_docstrings', 1) 49 | 50 | " Highlight builtin objects (True, False, ...) 51 | call pymode#default('g:pymode_syntax_builtin_objs', g:pymode_syntax_all) 52 | 53 | " Highlight builtin types (str, list, ...) 54 | call pymode#default('g:pymode_syntax_builtin_types', g:pymode_syntax_all) 55 | 56 | " Highlight builtin types (div, eval, ...) 57 | call pymode#default('g:pymode_syntax_builtin_funcs', g:pymode_syntax_all) 58 | 59 | " Highlight exceptions (TypeError, ValueError, ...) 60 | call pymode#default('g:pymode_syntax_highlight_exceptions', g:pymode_syntax_all) 61 | 62 | " More slow synchronizing. Disable on the slow machine, but code in docstrings 63 | " could be broken. 64 | call pymode#default('g:pymode_syntax_slow_sync', 1) 65 | 66 | " }}} 67 | 68 | " For version 5.x: Clear all syntax items 69 | if version < 600 70 | syntax clear 71 | endif 72 | 73 | " Keywords {{{ 74 | " ============ 75 | 76 | syn keyword pythonStatement break continue del 77 | syn keyword pythonStatement exec return 78 | syn keyword pythonStatement pass raise 79 | syn keyword pythonStatement global nonlocal assert 80 | syn keyword pythonStatement yield 81 | syn keyword pythonLambdaExpr lambda 82 | syn keyword pythonStatement with as 83 | 84 | syn keyword pythonStatement def nextgroup=pythonFunction skipwhite 85 | syn match pythonFunction "\%(\%(def\s\|@\)\s*\)\@<=\h\%(\w\|\.\)*" contained nextgroup=pythonVars 86 | syn region pythonVars start="(" skip=+\(".*"\|'.*'\)+ end=")" contained contains=pythonParameters transparent keepend 87 | syn match pythonParameters "[^,]*" contained contains=pythonParam skipwhite 88 | syn match pythonParam "[^,]*" contained contains=pythonExtraOperator,pythonLambdaExpr,pythonBuiltinObj,pythonBuiltinType,pythonConstant,pythonString,pythonNumber,pythonBrackets,pythonSelf,pythonComment skipwhite 89 | syn match pythonBrackets "{[(|)]}" contained skipwhite 90 | 91 | syn keyword pythonStatement class nextgroup=pythonClass skipwhite 92 | syn match pythonClass "\%(\%(class\s\)\s*\)\@<=\h\%(\w\|\.\)*" contained nextgroup=pythonClassVars 93 | syn region pythonClassVars start="(" end=")" contained contains=pythonClassParameters transparent keepend 94 | syn match pythonClassParameters "[^,\*]*" contained contains=pythonBuiltin,pythonBuiltinObj,pythonBuiltinType,pythonExtraOperatorpythonStatement,pythonBrackets,pythonString,pythonComment skipwhite 95 | 96 | syn keyword pythonRepeat for while 97 | syn keyword pythonConditional if elif else match case 98 | syn keyword pythonInclude import from 99 | syn keyword pythonException try except finally 100 | syn keyword pythonOperator and in is not or 101 | 102 | syn match pythonExtraOperator "\%([~!^&|/%+-]\|\%(class\s*\)\@\|<=\|\%(<\|\>\|>=\|=\@\|\.\.\.\|\.\.\|::\)" 103 | syn match pythonExtraPseudoOperator "\%(-=\|/=\|\*\*=\|\*=\|&&=\|&=\|&&\|||=\||=\|||\|%=\|+=\|!\~\|!=\)" 104 | 105 | if !g:pymode_syntax_print_as_function 106 | syn keyword pythonStatement print 107 | endif 108 | 109 | if g:pymode_syntax_highlight_async_await 110 | syn keyword pythonStatement async await 111 | syn match pythonStatement "\" nextgroup=pythonFunction skipwhite 112 | syn match pythonStatement "\" display 113 | syn match pythonStatement "\" nextgroup=pythonRepeat skipwhite 114 | endif 115 | 116 | if g:pymode_syntax_highlight_equal_operator 117 | syn match pythonExtraOperator "\%(=\)" 118 | endif 119 | 120 | if g:pymode_syntax_highlight_walrus_operator 121 | syn match pythonExtraOperator "\%(:=\)" 122 | endif 123 | 124 | if g:pymode_syntax_highlight_stars_operator 125 | syn match pythonExtraOperator "\%(\*\|\*\*\)" 126 | endif 127 | 128 | if g:pymode_syntax_highlight_self 129 | syn keyword pythonSelf self cls 130 | endif 131 | 132 | " }}} 133 | 134 | " Decorators {{{ 135 | " ============== 136 | 137 | syn match pythonDecorator "@" display nextgroup=pythonDottedName skipwhite 138 | syn match pythonDottedName "[a-zA-Z_][a-zA-Z0-9_]*\(\.[a-zA-Z_][a-zA-Z0-9_]*\)*" display contained 139 | 140 | " }}} 141 | 142 | " Comments {{{ 143 | " ============ 144 | 145 | syn match pythonComment "#.*$" display contains=pythonTodo,@Spell 146 | syn match pythonRun "\%^#!.*$" 147 | syn match pythonCoding "\%^.*\(\n.*\)\?#.*coding[:=]\s*[0-9A-Za-z-_.]\+.*$" 148 | syn keyword pythonTodo TODO FIXME XXX contained 149 | 150 | " }}} 151 | 152 | " Errors {{{ 153 | " ========== 154 | 155 | syn match pythonError "\<\d\+\D\+\>" display 156 | syn match pythonError "[$?]" display 157 | syn match pythonError "[&|]\{2,}" display 158 | syn match pythonError "[=]\{3,}" display 159 | 160 | " Indent errors (mix space and tabs) 161 | if g:pymode_syntax_indent_errors 162 | syn match pythonIndentError "^\s*\( \t\|\t \)\s*\S"me=e-1 display 163 | endif 164 | 165 | " Trailing space errors 166 | if g:pymode_syntax_space_errors 167 | syn match pythonSpaceError "\s\+$" display 168 | endif 169 | 170 | " }}} 171 | 172 | " Strings {{{ 173 | " =========== 174 | 175 | syn region pythonString start=+[bB]\='+ skip=+\\\\\|\\'\|\\$+ excludenl end=+'+ end=+$+ keepend contains=pythonEscape,pythonEscapeError,@Spell 176 | syn region pythonString start=+[bB]\="+ skip=+\\\\\|\\"\|\\$+ excludenl end=+"+ end=+$+ keepend contains=pythonEscape,pythonEscapeError,@Spell 177 | syn region pythonString start=+[bB]\="""+ end=+"""+ keepend contains=pythonEscape,pythonEscapeError,pythonDocTest2,pythonSpaceError,@Spell 178 | syn region pythonString start=+[bB]\='''+ end=+'''+ keepend contains=pythonEscape,pythonEscapeError,pythonDocTest,pythonSpaceError,@Spell 179 | 180 | syn match pythonEscape +\\[abfnrtv'"\\]+ display contained 181 | syn match pythonEscape "\\\o\o\=\o\=" display contained 182 | syn match pythonEscapeError "\\\o\{,2}[89]" display contained 183 | syn match pythonEscape "\\x\x\{2}" display contained 184 | syn match pythonEscapeError "\\x\x\=\X" display contained 185 | syn match pythonEscape "\\$" 186 | 187 | " Unicode 188 | syn region pythonUniString start=+[uU]'+ skip=+\\\\\|\\'\|\\$+ excludenl end=+'+ end=+$+ keepend contains=pythonEscape,pythonUniEscape,pythonEscapeError,pythonUniEscapeError,@Spell 189 | syn region pythonUniString start=+[uU]"+ skip=+\\\\\|\\"\|\\$+ excludenl end=+"+ end=+$+ keepend contains=pythonEscape,pythonUniEscape,pythonEscapeError,pythonUniEscapeError,@Spell 190 | syn region pythonUniString start=+[uU]"""+ end=+"""+ keepend contains=pythonEscape,pythonUniEscape,pythonEscapeError,pythonUniEscapeError,pythonDocTest2,pythonSpaceError,@Spell 191 | syn region pythonUniString start=+[uU]'''+ end=+'''+ keepend contains=pythonEscape,pythonUniEscape,pythonEscapeError,pythonUniEscapeError,pythonDocTest,pythonSpaceError,@Spell 192 | 193 | syn match pythonUniEscape "\\u\x\{4}" display contained 194 | syn match pythonUniEscapeError "\\u\x\{,3}\X" display contained 195 | syn match pythonUniEscape "\\U\x\{8}" display contained 196 | syn match pythonUniEscapeError "\\U\x\{,7}\X" display contained 197 | syn match pythonUniEscape "\\N{[A-Z ]\+}" display contained 198 | syn match pythonUniEscapeError "\\N{[^A-Z ]\+}" display contained 199 | 200 | " Raw strings 201 | syn region pythonRawString start=+[rR]'+ skip=+\\\\\|\\'\|\\$+ excludenl end=+'+ end=+$+ keepend contains=pythonRawEscape,@Spell 202 | syn region pythonRawString start=+[rR]"+ skip=+\\\\\|\\"\|\\$+ excludenl end=+"+ end=+$+ keepend contains=pythonRawEscape,@Spell 203 | syn region pythonRawString start=+[rR]"""+ end=+"""+ keepend contains=pythonDocTest2,pythonSpaceError,@Spell 204 | syn region pythonRawString start=+[rR]'''+ end=+'''+ keepend contains=pythonDocTest,pythonSpaceError,@Spell 205 | 206 | syn match pythonRawEscape +\\['"]+ display transparent contained 207 | 208 | " Unicode raw strings 209 | syn region pythonUniRawString start=+[uU][rR]'+ skip=+\\\\\|\\'\|\\$+ excludenl end=+'+ end=+$+ keepend contains=pythonRawEscape,pythonUniRawEscape,pythonUniRawEscapeError,@Spell 210 | syn region pythonUniRawString start=+[uU][rR]"+ skip=+\\\\\|\\"\|\\$+ excludenl end=+"+ end=+$+ keepend contains=pythonRawEscape,pythonUniRawEscape,pythonUniRawEscapeError,@Spell 211 | syn region pythonUniRawString start=+[uU][rR]"""+ end=+"""+ keepend contains=pythonUniRawEscape,pythonUniRawEscapeError,pythonDocTest2,pythonSpaceError,@Spell 212 | syn region pythonUniRawString start=+[uU][rR]'''+ end=+'''+ keepend contains=pythonUniRawEscape,pythonUniRawEscapeError,pythonDocTest,pythonSpaceError,@Spell 213 | 214 | syn match pythonUniRawEscape "\([^\\]\(\\\\\)*\)\@<=\\u\x\{4}" display contained 215 | syn match pythonUniRawEscapeError "\([^\\]\(\\\\\)*\)\@<=\\u\x\{,3}\X" display contained 216 | 217 | " String formatting 218 | if g:pymode_syntax_string_formatting 219 | syn match pythonStrFormatting "%\(([^)]\+)\)\=[-#0 +]*\d*\(\.\d\+\)\=[hlL]\=[diouxXeEfFgGcrs%]" contained containedin=pythonString,pythonUniString,pythonRawString,pythonUniRawString 220 | syn match pythonStrFormatting "%[-#0 +]*\(\*\|\d\+\)\=\(\.\(\*\|\d\+\)\)\=[hlL]\=[diouxXeEfFgGcrs%]" contained containedin=pythonString,pythonUniString,pythonRawString,pythonUniRawString 221 | endif 222 | 223 | " Str.format syntax 224 | if g:pymode_syntax_string_format 225 | syn match pythonStrFormat "{{\|}}" contained containedin=pythonString,pythonUniString,pythonRawString,pythonUniRawString 226 | syn match pythonStrFormat "{\([a-zA-Z0-9_]*\|\d\+\)\(\.[a-zA-Z_][a-zA-Z0-9_]*\|\[\(\d\+\|[^!:\}]\+\)\]\)*\(![rs]\)\=\(:\({\([a-zA-Z_][a-zA-Z0-9_]*\|\d\+\)}\|\([^}]\=[<>=^]\)\=[ +-]\=#\=0\=\d*\(\.\d\+\)\=[bcdeEfFgGnoxX%]\=\)\=\)\=}" contained containedin=pythonString,pythonUniString,pythonRawString,pythonUniRawString 227 | endif 228 | 229 | " String templates 230 | if g:pymode_syntax_string_templates 231 | syn match pythonStrTemplate "\$\$" contained containedin=pythonString,pythonUniString,pythonRawString,pythonUniRawString 232 | syn match pythonStrTemplate "\${[a-zA-Z_][a-zA-Z0-9_]*}" contained containedin=pythonString,pythonUniString,pythonRawString,pythonUniRawString 233 | syn match pythonStrTemplate "\$[a-zA-Z_][a-zA-Z0-9_]*" contained containedin=pythonString,pythonUniString,pythonRawString,pythonUniRawString 234 | endif 235 | 236 | " DocTests 237 | if g:pymode_syntax_doctests 238 | syn region pythonDocTest start="^\s*>>>" end=+'''+he=s-1 end="^\s*$" contained 239 | syn region pythonDocTest2 start="^\s*>>>" end=+"""+he=s-1 end="^\s*$" contained 240 | endif 241 | 242 | " DocStrings 243 | if g:pymode_syntax_docstrings 244 | syn region pythonDocstring start=+^\s*[uU]\?[rR]\?"""+ end=+"""+ keepend excludenl contains=pythonEscape,@Spell,pythonDoctest,pythonDocTest2,pythonSpaceError 245 | syn region pythonDocstring start=+^\s*[uU]\?[rR]\?'''+ end=+'''+ keepend excludenl contains=pythonEscape,@Spell,pythonDoctest,pythonDocTest2,pythonSpaceError 246 | endif 247 | 248 | 249 | " }}} 250 | 251 | " Numbers {{{ 252 | " =========== 253 | 254 | syn match pythonHexError "\<0[xX][0-9a-fA-F_]*[g-zG-Z][0-9a-fA-F_]*[lL]\=\>" display 255 | syn match pythonHexNumber "\<0[xX][0-9a-fA-F_]*[0-9a-fA-F][0-9a-fA-F_]*[lL]\=\>" display 256 | syn match pythonOctNumber "\<0[oO][0-7_]*[0-7][0-7_]*[lL]\=\>" display 257 | syn match pythonBinNumber "\<0[bB][01_]*[01][01_]*[lL]\=\>" display 258 | syn match pythonNumber "\<[0-9][0-9_]*[lLjJ]\=\>" display 259 | syn match pythonFloat "\.[0-9_]*[0-9][0-9_]*\([eE][+-]\=[0-9_]*[0-9][0-9_]*\)\=[jJ]\=\>" display 260 | syn match pythonFloat "\<[0-9][0-9_]*[eE][+-]\=[0-9_]\+[jJ]\=\>" display 261 | syn match pythonFloat "\<[0-9][0-9_]*\.[0-9_]*\([eE][+-]\=[0-9_]*[0-9][0-9_]*\)\=[jJ]\=" display 262 | syn match pythonOctError "\<0[oO]\=[0-7_]*[8-9][0-9_]*[lL]\=\>" display 263 | syn match pythonBinError "\<0[bB][01_]*[2-9][0-9_]*[lL]\=\>" display 264 | 265 | " }}} 266 | 267 | " Builtins {{{ 268 | " ============ 269 | 270 | " Builtin objects and types 271 | if g:pymode_syntax_builtin_objs 272 | " True, False, Ellipsis, and None are in fact keywords. 273 | syn keyword pythonBuiltinObj True False Ellipsis None 274 | syn keyword pythonBuiltinObj NotImplemented 275 | syn keyword pythonBuiltinObj __debug__ __doc__ __file__ __name__ __package__ __loader__ 276 | syn keyword pythonBuiltinObj __spec__ __cached__ __annotations__ 277 | endif 278 | 279 | if g:pymode_syntax_builtin_types 280 | syn keyword pythonBuiltinType type object 281 | syn keyword pythonBuiltinType str bytearray bytes chr 282 | syn keyword pythonBuiltinType dict int bool float complex set frozenset list tuple 283 | syn keyword pythonBuiltinType super 284 | endif 285 | 286 | " Builtin functions 287 | if g:pymode_syntax_builtin_funcs 288 | syn keyword pythonBuiltinFunc __import__ abs all any 289 | syn keyword pythonBuiltinFunc bin callable classmethod compile 290 | syn keyword pythonBuiltinFunc delattr dir divmod enumerate eval execfile filter 291 | syn keyword pythonBuiltinFunc format getattr globals locals hasattr hash help hex id 292 | syn keyword pythonBuiltinFunc input isinstance issubclass iter len map max min 293 | syn keyword pythonBuiltinFunc next oct open ord pow property range 294 | syn keyword pythonBuiltinFunc repr reversed round setattr 295 | syn keyword pythonBuiltinFunc slice sorted staticmethod sum vars zip 296 | 297 | if g:pymode_syntax_print_as_function 298 | syn keyword pythonBuiltinFunc print 299 | endif 300 | 301 | endif 302 | 303 | " Builtin exceptions and warnings 304 | if g:pymode_syntax_highlight_exceptions 305 | syn keyword pythonExClass BaseException Exception ArithmeticError 306 | syn keyword pythonExClass BufferError LookupError 307 | syn keyword pythonExClass AssertionError AttributeError EOFError 308 | syn keyword pythonExClass FloatingPointError GeneratorExit 309 | syn keyword pythonExClass ImportError ModuleNotFoundError IndexError 310 | syn keyword pythonExClass KeyError KeyboardInterrupt MemoryError NameError 311 | syn keyword pythonExClass NotImplementedError OSError OverflowError 312 | syn keyword pythonExClass RecursionError ReferenceError RuntimeError StopIteration 313 | syn keyword pythonExClass StopAsyncIteration SyntaxError IndentationError TabError 314 | syn keyword pythonExClass SystemError SystemExit TypeError 315 | syn keyword pythonExClass UnboundLocalError UnicodeError 316 | syn keyword pythonExClass UnicodeEncodeError UnicodeDecodeError 317 | syn keyword pythonExClass UnicodeTranslateError ValueError 318 | syn keyword pythonExClass ZeroDivisionError EnvironmentError IOError 319 | syn keyword pythonExClass WindowsError 320 | syn keyword pythonExClass BlockingIOError ChildProcessError ConnectionError 321 | syn keyword pythonExClass BrokenPipeError ConnectionAbortedError 322 | syn keyword pythonExClass ConnectionRefusedError ConnectionResetError 323 | syn keyword pythonExClass FileExistsError FileNotFoundError InterruptedError 324 | syn keyword pythonExClass IsADirectoryError NotADirectoryError PermissionError 325 | syn keyword pythonExClass ProcessLookupError TimeoutError 326 | syn keyword pythonExClass Warning UserWarning DeprecationWarning PendingDeprecationWarning 327 | syn keyword pythonExClass SyntaxWarning RuntimeWarning FutureWarning 328 | syn keyword pythonExClass ImportWarning UnicodeWarning EncodingWarning 329 | syn keyword pythonExClass BytesWarning ResourceWarning 330 | endif 331 | 332 | " }}} 333 | 334 | if g:pymode_syntax_slow_sync 335 | syn sync minlines=2000 336 | else 337 | " This is fast but code inside triple quoted strings screws it up. It 338 | " is impossible to fix because the only way to know if you are inside a 339 | " triple quoted string is to start from the beginning of the file. 340 | syn sync match pythonSync grouphere NONE "):$" 341 | syn sync maxlines=200 342 | endif 343 | 344 | " Highlight {{{ 345 | " ============= 346 | 347 | hi def link pythonStatement Statement 348 | hi def link pythonLambdaExpr Statement 349 | hi def link pythonInclude Include 350 | hi def link pythonFunction Function 351 | hi def link pythonClass Type 352 | hi def link pythonParameters Normal 353 | hi def link pythonParam Normal 354 | hi def link pythonBrackets Normal 355 | hi def link pythonClassParameters Normal 356 | hi def link pythonSelf Identifier 357 | 358 | hi def link pythonConditional Conditional 359 | hi def link pythonRepeat Repeat 360 | hi def link pythonException Exception 361 | hi def link pythonOperator Operator 362 | hi def link pythonExtraOperator Operator 363 | hi def link pythonExtraPseudoOperator Operator 364 | 365 | hi def link pythonDecorator Define 366 | hi def link pythonDottedName Function 367 | 368 | hi def link pythonComment Comment 369 | hi def link pythonCoding Special 370 | hi def link pythonRun Special 371 | hi def link pythonTodo Todo 372 | 373 | hi def link pythonError Error 374 | hi def link pythonIndentError Error 375 | hi def link pythonSpaceError Error 376 | 377 | hi def link pythonString String 378 | hi def link pythonDocstring String 379 | hi def link pythonUniString String 380 | hi def link pythonRawString String 381 | hi def link pythonUniRawString String 382 | 383 | hi def link pythonEscape Special 384 | hi def link pythonEscapeError Error 385 | hi def link pythonUniEscape Special 386 | hi def link pythonUniEscapeError Error 387 | hi def link pythonUniRawEscape Special 388 | hi def link pythonUniRawEscapeError Error 389 | 390 | hi def link pythonStrFormatting Special 391 | hi def link pythonStrFormat Special 392 | hi def link pythonStrTemplate Special 393 | 394 | hi def link pythonDocTest Special 395 | hi def link pythonDocTest2 Special 396 | 397 | hi def link pythonNumber Number 398 | hi def link pythonHexNumber Number 399 | hi def link pythonOctNumber Number 400 | hi def link pythonBinNumber Number 401 | hi def link pythonFloat Float 402 | hi def link pythonOctError Error 403 | hi def link pythonHexError Error 404 | hi def link pythonBinError Error 405 | 406 | hi def link pythonBuiltinType Type 407 | hi def link pythonBuiltinObj Structure 408 | hi def link pythonBuiltinFunc Function 409 | 410 | hi def link pythonExClass Structure 411 | 412 | " }}} 413 | -------------------------------------------------------------------------------- /tests/motion_decorator.py: -------------------------------------------------------------------------------- 1 | #!coding=utf-8 2 | """ 3 | to test pymode motions, please put cursor on each of the lines 4 | and press "vaM" for selecting methods or 5 | "vaC" for selection class. 6 | """ 7 | 8 | def a_decorator(func): 9 | print("chamando func") 10 | def wrapped(*args, **kw): 11 | return func(*args, **kw) 12 | print("Pós func") 13 | return wrapped 14 | 15 | def b_decorator(func): 16 | print("second chamando func") 17 | def wrapped(*args, **kw): 18 | return func(*args, **kw) 19 | print("second Pós func") 20 | return wrapped 21 | 22 | @b_decorator 23 | @a_decorator 24 | def teste(): 25 | print("Not Selecting Decorator") 26 | 27 | class Teste: 28 | @a_decorator 29 | @b_decorator 30 | def metodo(self): 31 | print("Meu método") 32 | 33 | 34 | teste() 35 | 36 | testinho = Teste() 37 | testinho.metodo() 38 | -------------------------------------------------------------------------------- /tests/test.sh: -------------------------------------------------------------------------------- 1 | #! /bin/bash 2 | 3 | # Check before starting. 4 | set -e 5 | which vim 1>/dev/null 2>/dev/null 6 | 7 | cd "$(dirname "$0")" 8 | 9 | # Source common variables. 10 | source ./test_helpers_bash/test_variables.sh 11 | 12 | # Prepare tests by cleaning up all files. 13 | source ./test_helpers_bash/test_prepare_once.sh 14 | 15 | # Initialize permanent files.. 16 | source ./test_helpers_bash/test_createvimrc.sh 17 | 18 | # Execute tests. 19 | declare -a TEST_ARRAY=( 20 | "./test_bash/test_autopep8.sh" 21 | "./test_bash/test_autocommands.sh" 22 | "./test_bash/test_folding.sh" 23 | "./test_bash/test_textobject.sh" 24 | ) 25 | MAIN_RETURN=0 26 | ## now loop through the above array 27 | set +e 28 | for TEST in "${TEST_ARRAY[@]}" 29 | do 30 | echo "Starting test: ${TEST}" | tee -a "${VIM_OUTPUT_FILE}" 31 | bash "${TEST}" 32 | R=$? 33 | MAIN_RETURN=$(( MAIN_RETURN + R )) 34 | echo -e "${TEST}: Return code: ${R}\n" | tee -a "${VIM_OUTPUT_FILE}" 35 | bash ./test_helpers_bash/test_prepare_between_tests.sh 36 | done 37 | 38 | echo "=========================================================================" 39 | echo " RESULTS" 40 | echo "=========================================================================" 41 | 42 | # Show return codes. 43 | RETURN_CODES=$(grep -i "Return code" < "${VIM_OUTPUT_FILE}" | grep -v "Return code: 0") 44 | echo -e "${RETURN_CODES}" 45 | 46 | # Show errors: 47 | E1=$(grep -E "^E[0-9]+:" "${VIM_OUTPUT_FILE}") 48 | E2=$(grep -Ei "^Error" "${VIM_OUTPUT_FILE}") 49 | if [[ "${MAIN_RETURN}" == "0" ]]; then 50 | echo "No errors." 51 | else 52 | echo "Errors:" 53 | echo -e "${E1}\n${E2}" 54 | fi 55 | 56 | # Exit the script with error if there are any return codes different from 0. 57 | exit ${MAIN_RETURN} 58 | # vim: set fileformat=unix filetype=sh wrap tw=0 : 59 | -------------------------------------------------------------------------------- /tests/test_bash/test_autocommands.sh: -------------------------------------------------------------------------------- 1 | #! /bin/bash 2 | 3 | # TODO XXX: improve python-mode testing asap. 4 | # Test all python commands. 5 | 6 | # Execute tests. 7 | declare -a TEST_PYMODE_COMMANDS_ARRAY=( 8 | "./test_procedures_vimscript/pymodeversion.vim" 9 | "./test_procedures_vimscript/pymodelint.vim" 10 | "./test_procedures_vimscript/pymoderun.vim" 11 | ) 12 | 13 | ### Enable the following to execute one test at a time. 14 | ### FOR PINPOINT TESTING ### declare -a TEST_PYMODE_COMMANDS_ARRAY=( 15 | ### FOR PINPOINT TESTING ### "./test_procedures_vimscript/pymoderun.vim" 16 | ### FOR PINPOINT TESTING ### ) 17 | 18 | RETURN_CODE=0 19 | 20 | ## now loop through the above array 21 | set +e 22 | for ONE_PYMODE_COMMANDS_TEST in "${TEST_PYMODE_COMMANDS_ARRAY[@]}" 23 | do 24 | CONTENT="$(vim --clean -i NONE -u "${VIM_TEST_VIMRC}" -c "source ${ONE_PYMODE_COMMANDS_TEST}" "${VIM_DISPOSABLE_PYFILE}" 2>&1)" 25 | 26 | ### Enable the following to execute one test at a time. 27 | ### FOR PINPOINT TESTING ### vim --clean -i NONE -u $VIM_TEST_VIMRC -c "source $ONE_PYMODE_COMMANDS_TEST" $VIM_DISPOSABLE_PYFILE 28 | ### FOR PINPOINT TESTING ### exit 1 29 | 30 | SUB_TEST_RETURN_CODE=$? 31 | echo -e "${CONTENT}" >> "${VIM_OUTPUT_FILE}" 32 | RETURN_CODE=$(( RETURN_CODE + SUB_TEST_RETURN_CODE )) 33 | echo -e "\tSubTest: $0:${ONE_PYMODE_COMMANDS_TEST}: Return code: ${SUB_TEST_RETURN_CODE}" | tee -a "${VIM_OUTPUT_FILE}" 34 | bash ./test_helpers_bash/test_prepare_between_tests.sh 35 | done 36 | 37 | exit ${RETURN_CODE} 38 | # vim: set fileformat=unix filetype=sh wrap tw=0 : 39 | -------------------------------------------------------------------------------- /tests/test_bash/test_autopep8.sh: -------------------------------------------------------------------------------- 1 | #! /bin/bash 2 | 3 | # Source file. 4 | set +e 5 | CONTENT="$(vim --clean -i NONE -u "${VIM_TEST_VIMRC}" -c "source ./test_procedures_vimscript/autopep8.vim" "${VIM_DISPOSABLE_PYFILE}" 2>&1)" 6 | RETURN_CODE=$? 7 | echo -e "${CONTENT}" >> "${VIM_OUTPUT_FILE}" 8 | set -e 9 | 10 | exit ${RETURN_CODE} 11 | # vim: set fileformat=unix filetype=sh wrap tw=0 : 12 | -------------------------------------------------------------------------------- /tests/test_bash/test_folding.sh: -------------------------------------------------------------------------------- 1 | #! /bin/bash 2 | 3 | # Note: a solution with unix 'timeout' program was tried but it was unsuccessful. The problem with folding 4 is that in the case of a crash one expects the folding to just stay in an infinite loop, thus never existing with error. An improvement is suggested to this case. 4 | 5 | declare -a TEST_PYMODE_FOLDING_TESTS_ARRAY=( 6 | "./test_procedures_vimscript/folding1.vim" 7 | "./test_procedures_vimscript/folding2.vim" 8 | # "./test_procedures_vimscript/folding3.vim" 9 | "./test_procedures_vimscript/folding4.vim" 10 | ) 11 | 12 | RETURN_CODE=0 13 | 14 | set +e 15 | for SUB_TEST in "${TEST_PYMODE_FOLDING_TESTS_ARRAY[@]}"; do 16 | CONTENT="$(vim --clean -i NONE -u "${VIM_TEST_VIMRC}" -c "source ${SUB_TEST}" "${VIM_DISPOSABLE_PYFILE}" 2>&1)" 17 | SUB_TEST_RETURN_CODE=$? 18 | echo -e "${CONTENT}" >> "${VIM_OUTPUT_FILE}" 19 | RETURN_CODE=$(( RETURN_CODE + SUB_TEST_RETURN_CODE )) 20 | echo -e "\tSubTest: $0:${SUB_TEST}: Return code: ${SUB_TEST_RETURN_CODE}" | tee -a "${VIM_OUTPUT_FILE}" 21 | bash ./test_helpers_bash/test_prepare_between_tests.sh 22 | done 23 | 24 | exit ${RETURN_CODE} 25 | # vim: set fileformat=unix filetype=sh wrap tw=0 : 26 | -------------------------------------------------------------------------------- /tests/test_bash/test_pymodelint.sh: -------------------------------------------------------------------------------- 1 | #! /bin/bash 2 | 3 | # TODO XXX: improve python-mode testing asap. 4 | # Test all python commands. 5 | 6 | # Source file. 7 | set +e 8 | # vim --clean -i NONE -u "${VIM_TEST_VIMRC}" -c "source ./test_procedures_vimscript/pymodelint.vim" "${VIM_DISPOSABLE_PYFILE}" >> "${VIM_OUTPUT_FILE}" 2>&1 9 | CONTENT="$(vim --clean -i NONE -u "${VIM_TEST_VIMRC}" -c "source ./test_procedures_vimscript/pymodeversion.vim" "${VIM_DISPOSABLE_PYFILE}" 2>&1)" 10 | RETURN_CODE=$? 11 | echo -e "${CONTENT}" >> "${VIM_OUTPUT_FILE}" 12 | set -e 13 | 14 | exit ${RETURN_CODE} 15 | # vim: set fileformat=unix filetype=sh wrap tw=0 : 16 | -------------------------------------------------------------------------------- /tests/test_bash/test_textobject.sh: -------------------------------------------------------------------------------- 1 | #! /bin/bash 2 | 3 | # Source file. 4 | set +e 5 | # shellcheck source=../test_helpers_bash/test_prepare_between_tests.sh 6 | source ./test_helpers_bash/test_prepare_between_tests.sh 7 | CONTENT="$(vim --clean -i NONE -u "${VIM_TEST_VIMRC}" -c "source ./test_procedures_vimscript/textobject.vim" "${VIM_DISPOSABLE_PYFILE}" 2>&1)" 8 | RETURN_CODE=$? 9 | echo -e "${CONTENT}" >> "${VIM_OUTPUT_FILE}" 10 | set -e 11 | 12 | exit ${RETURN_CODE} 13 | # vim: set fileformat=unix filetype=sh wrap tw=0 : 14 | -------------------------------------------------------------------------------- /tests/test_helpers_bash/test_createvimrc.sh: -------------------------------------------------------------------------------- 1 | #! /bin/bash 2 | 3 | # Create minimal vimrc. 4 | cat <<-EOF >> "${VIM_TEST_VIMRC}" 5 | syntax on 6 | filetype plugin indent on 7 | set nocompatible 8 | call has('python3') 9 | set paste 10 | set shortmess=at 11 | set cmdheight=10 12 | set ft=python 13 | set shell=bash 14 | set noswapfile 15 | set backupdir= 16 | set undodir= 17 | set viewdir= 18 | set directory= 19 | set runtimepath= 20 | set runtimepath+="$(dirname "${PWD}")" 21 | set packpath+=/tmp 22 | " redir! >> "${VIM_OUTPUT_FILE}" 23 | set verbosefile="${VIM_OUTPUT_FILE}" 24 | let g:pymode_debug = 1 25 | set nomore 26 | EOF 27 | # vim: set fileformat=unix filetype=sh wrap tw=0 : 28 | -------------------------------------------------------------------------------- /tests/test_helpers_bash/test_prepare_between_tests.sh: -------------------------------------------------------------------------------- 1 | #! /bin/bash 2 | 3 | # Prepare tests. 4 | set +e 5 | if [ -f "${VIM_DISPOSABLE_PYFILE}" ]; then 6 | rm "${VIM_DISPOSABLE_PYFILE}" 7 | fi 8 | VIM_DISPOSABLE_PYFILE="$(mktemp /tmp/pymode.tmpfile.XXXXXXXXXX.py)" 9 | export VIM_DISPOSABLE_PYFILE 10 | set -e 11 | touch "${VIM_DISPOSABLE_PYFILE}" 12 | 13 | # vim: set fileformat=unix filetype=sh wrap tw=0 : 14 | -------------------------------------------------------------------------------- /tests/test_helpers_bash/test_prepare_once.sh: -------------------------------------------------------------------------------- 1 | #! /bin/bash 2 | 3 | # Prepare tests. 4 | set +e 5 | rm "${VIM_OUTPUT_FILE}" "${VIM_TEST_VIMRC}" "${VIM_TEST_PYMODECOMMANDS}" "${VIM_DISPOSABLE_PYFILE}" 2&>/dev/null 6 | rm /tmp/*pymode* 2&>/dev/null 7 | rm -rf /tmp/pack 8 | mkdir -p /tmp/pack/test_plugins/start 9 | ln -s "$(dirname "$(pwd)")" /tmp/pack/test_plugins/start/ 10 | set -e 11 | 12 | # vim: set fileformat=unix filetype=sh wrap tw=0 : 13 | -------------------------------------------------------------------------------- /tests/test_helpers_bash/test_variables.sh: -------------------------------------------------------------------------------- 1 | #! /bin/bash 2 | 3 | # Define variables for common test scripts. 4 | 5 | # Set variables. 6 | VIM_DISPOSABLE_PYFILE="$(mktemp /tmp/pymode.tmpfile.XXXXXXXXXX.py)" 7 | export VIM_DISPOSABLE_PYFILE 8 | VIM_OUTPUT_FILE=/tmp/pymode.out 9 | export VIM_OUTPUT_FILE 10 | VIM_TEST_VIMRC=/tmp/pymode_vimrc 11 | export VIM_TEST_VIMRC 12 | VIM_TEST_PYMODECOMMANDS=/tmp/pymode_commands.txt 13 | export VIM_TEST_PYMODECOMMANDS 14 | 15 | # vim: set fileformat=unix filetype=sh wrap tw=0 : 16 | -------------------------------------------------------------------------------- /tests/test_helpers_vimscript/inserting_text.vim: -------------------------------------------------------------------------------- 1 | function! InsertRandomText(low_range, high_range) " {{{ 2 | " Insert random ascii visible table text at cursor position. 3 | " Return the number of characters inserted. 4 | 5 | python3 << EOF 6 | import random, string, vim 7 | # Text has to large from a larger sample in order to avoid errors. 8 | text = random.sample( 9 | (10 * string.ascii_lowercase + string.digits + ' '), 10 | random.randint(int(vim.eval('a:low_range')), int(vim.eval('a:high_range')))) 11 | vim.current.buffer.vars['random_text'] = ''.join(text) 12 | EOF 13 | let l:textwidth = &tw 14 | set tw=0 15 | execute "normal! i" . b:random_text 16 | let &tw = l:textwidth 17 | 18 | return len(b:random_text) 19 | 20 | endfunction " }}} 21 | 22 | function! DeleteChars(nchars) " {{{ 23 | " Delete n chars at cursor position. 24 | " It is the inverse of InsertRandomText(). 25 | 26 | let l:textwidth = &tw 27 | set tw=0 28 | execute "normal! " . (repeat('h', a:nchars - 1)) 29 | execute "normal! " . repeat('x', a:nchars) 30 | let &tw = l:textwidth 31 | 32 | endfunction " }}} 33 | 34 | function! JumpToRandomPosition() " {{{ 35 | " Jump cursor to a random position in current buffer. 36 | 37 | python3 << EOF 38 | import random, vim 39 | cw = vim.current.window 40 | cb = vim.current.buffer 41 | rand_line = random.randint(1, len(cb) - 1) 42 | rand_line_len = len(cb[rand_line]) 43 | rand_col = random.randint(0, rand_line_len) if rand_line_len > 0 else 0 44 | cw.cursor = (rand_line, rand_col) 45 | EOF 46 | endfunction " }}} 47 | 48 | function! DeleteRandomLines(low_range, high_range) " {{{ 49 | " Delete random lines between low_range and high_range. 50 | " Return the number of lines deleted. 51 | 52 | python3 << EOF 53 | import random, vim 54 | del_lines = random.randint( 55 | int(vim.eval('a:low_range')), int(vim.eval('a:high_range'))) 56 | vim.current.buffer.vars['del_lines'] = del_lines 57 | EOF 58 | 59 | execute "normal! " . b:del_lines . "dd" 60 | 61 | return b:del_lines 62 | 63 | endfunction "}}} 64 | 65 | function! InsertTextAtRandomPositions(ntimes) " {{{ 66 | " Insert text at random positions. May either insert in insert mode or in 67 | " normal mode. 68 | 69 | let l:total_lines = line('$') 70 | for i in range(a:ntimes) 71 | 72 | python3 << EOF 73 | import random, vim 74 | del_method = random.randint(0, 1) 75 | vim.current.buffer.vars['del_method'] = del_method 76 | EOF 77 | 78 | call JumpToRandomPosition() 79 | " b:del_method is set to either change the buffer via insert mode or 80 | " via normal mode. 81 | if b:del_method 82 | " This uses insert mode. 83 | let l:inserted_chars = InsertRandomText(3, 100) 84 | call DeleteChars(l:inserted_chars) 85 | else 86 | " This uses normal mode. 87 | let l:current_line = getpos('.')[1] 88 | let l:deleted_lines = DeleteRandomLines(1, 5) 89 | if l:current_line + l:deleted_lines <= l:total_lines 90 | execute "normal! P" 91 | else 92 | execute "normal! p" 93 | endif 94 | endif 95 | 96 | endfor 97 | 98 | endfunction " }}} 99 | -------------------------------------------------------------------------------- /tests/test_helpers_vimscript/md5sum.vim: -------------------------------------------------------------------------------- 1 | " Define md5sum hash function. 2 | function! Md5() 3 | python3 << EOF 4 | import vim 5 | from hashlib import md5 6 | hasher = md5() 7 | cb = vim.current.buffer 8 | with open(cb.name, 'rb') as f: 9 | hasher.update(f.read()) 10 | cb.vars['calculated_md5'] = hasher.hexdigest() 11 | # vim.command('let md5digest = ' + hasher.hexdigest()) 12 | EOF 13 | " echom md5digest 14 | endfunction 15 | -------------------------------------------------------------------------------- /tests/test_helpers_vimscript/moving_around.vim: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/KsushaBell/python-mode/e01c27e8c17b3af2b9df7f6fc5a8a44afc3ad020/tests/test_helpers_vimscript/moving_around.vim -------------------------------------------------------------------------------- /tests/test_procedures_vimscript/autopep8.vim: -------------------------------------------------------------------------------- 1 | " Test that the PymodeLintAuto changes a badly formated buffer. 2 | 3 | " Load sample python file. 4 | read ./test_python_sample_code/from_autopep8.py 5 | 6 | " Load auxiliary code. 7 | source ./test_helpers_vimscript/md5sum.vim 8 | 9 | " Delete the first line (which is not present in the original file) and save 10 | " loaded file. 11 | execute "normal! gg" 12 | execute "normal! dd" 13 | noautocmd write! 14 | 15 | " Get original md5sum for script. 16 | call Md5() 17 | let s:md5orig = b:calculated_md5 18 | unlet b:calculated_md5 19 | 20 | " Change the buffer. 21 | PymodeLintAuto 22 | write! 23 | 24 | " Get different md5sum for script. 25 | call Md5() 26 | let s:md5mod = b:calculated_md5 27 | 28 | " Assert changes. 29 | call assert_notequal(s:md5orig, s:md5mod) 30 | if len(v:errors) > 0 31 | cquit! 32 | else 33 | quit! 34 | endif 35 | -------------------------------------------------------------------------------- /tests/test_procedures_vimscript/folding1.vim: -------------------------------------------------------------------------------- 1 | " Test that the PymodeLintAuto changes a badly formated buffer. 2 | 3 | " For safety empty current buffer. 4 | execute "normal! :%d\" 5 | 6 | " Load sample python file. 7 | read ./test_python_sample_code/folding1.py 8 | 9 | " Delete the first line (which is not present in the original file) and save 10 | " loaded file. 11 | execute "normal! gg" 12 | execute "normal! dd" 13 | noautocmd write! 14 | 15 | set fdm=marker 16 | set fdm=expr 17 | 18 | let foldlevels = ['a1', '=', '=', '=', '=', '=', 's1', '=', '=', '=', '0', 19 | \ '>1', '=', '=', '=', '=', '=', '0', '0', '0',] 20 | 21 | if len(foldlevels) != line('$') 22 | echoerr 'Unmatching loaded file and foldlevels list.' 23 | endif 24 | 25 | let i = 1 26 | for fdl in foldlevels 27 | let calc = pymode#debug#foldingexpr(i) 28 | let stored = fdl 29 | call assert_true(calc == stored) 30 | let i += 1 31 | endfor 32 | 33 | " Assert changes. 34 | if len(v:errors) > 0 35 | cquit! 36 | else 37 | quit! 38 | endif 39 | -------------------------------------------------------------------------------- /tests/test_procedures_vimscript/folding2.vim: -------------------------------------------------------------------------------- 1 | " Test that the PymodeLintAuto changes a badly formated buffer. 2 | 3 | " For safety empty current buffer. 4 | execute "normal! :%d\" 5 | 6 | " Load sample python file. 7 | read ./test_python_sample_code/folding2.py 8 | 9 | " Delete the first line (which is not present in the original file) and save 10 | " loaded file. 11 | execute "normal! gg" 12 | execute "normal! dd" 13 | noautocmd write! 14 | 15 | set fdm=marker 16 | set fdm=expr 17 | 18 | let foldlevels = ['a1', '=', '=', '=', '=', '=', 's1', '=', '=', '=', '=', 19 | \ '0', '>1', '=', '>2', '=', '=', '=', '=', '=', '1', '=', 20 | \ '0', '>1', 'a1', '=', 's1', '=', '=', '>2', '=', '>3', '=', 21 | \ 'a1', '=', '=', '=', 's1', '=', '=', '=', '=', '=', '=', 22 | \'=', '=', '=', '=', '2', '=', '=', '1', '=', '0', '0', '0'] 23 | 24 | if len(foldlevels) != line('$') 25 | echoerr 'Unmatching loaded file and foldlevels list.' 26 | endif 27 | 28 | let i = 1 29 | for fdl in foldlevels 30 | let calc = pymode#debug#foldingexpr(i) 31 | let stored = fdl 32 | call assert_true(calc == stored) 33 | let i += 1 34 | endfor 35 | 36 | " Assert changes. 37 | if len(v:errors) > 0 38 | cquit! 39 | else 40 | quit! 41 | endif 42 | -------------------------------------------------------------------------------- /tests/test_procedures_vimscript/folding3.vim: -------------------------------------------------------------------------------- 1 | " Test that doing (reversible) changes in insert mode or normal mode to a 2 | " buffer do not alter their folding. 3 | 4 | " Load sample python file. 5 | read ./test_python_sample_code/algorithms.py 6 | 7 | " Delete the first line (which is not present in the original file) and save 8 | " loaded file. 9 | execute "normal! gg" 10 | execute "normal! dd" 11 | noautocmd write! 12 | 13 | " Load auxiliary code. 14 | source ./test_helpers_vimscript/inserting_text.vim 15 | source ./test_helpers_vimscript/md5sum.vim 16 | 17 | " Get original md5sum for script. 18 | noautocmd write! 19 | call Md5() 20 | let s:md5orig = b:calculated_md5 21 | unlet b:calculated_md5 22 | 23 | " Define a convenient function to map line numbers to their folding values. 24 | function Pymodefoldingfuncref(key, val) 25 | let l:retval = pymode#folding#expr(a:val) 26 | return l:retval 27 | endfunction! 28 | 29 | 30 | " Force recomputation of all foldings. 31 | " TODO: inspect why causes trouble. 32 | " set fdm=expr 33 | " set fdm=marker 34 | " set fdm=expr 35 | let b:old_fold_vals = map(range(1, line('$')), function('Pymodefoldingfuncref')) 36 | 37 | " Change folding in numerous ways. 38 | call InsertTextAtRandomPositions(10) 39 | 40 | " Force recomputation of all foldings. 41 | " set fdm=expr 42 | " set fdm=marker 43 | " set fdm=expr 44 | let b:new_fold_vals = map(range(1, line('$')), function('Pymodefoldingfuncref')) 45 | 46 | " Get original md5sum for script. 47 | noautocmd write! 48 | call Md5() 49 | let s:md5mod = b:calculated_md5 50 | unlet b:calculated_md5 51 | 52 | " echom s:md5orig == s:md5mod 53 | " echom b:new_fold_vals == b:old_fold_vals 54 | 55 | " set fdm=expr 56 | " set fdm=marker 57 | " set fdm=expr 58 | 59 | " Assert changes. 60 | call assert_equal(s:md5orig, s:md5mod) 61 | call assert_equal(b:new_fold_vals, b:old_fold_vals) 62 | if len(v:errors) > 0 63 | cquit! 64 | else 65 | quit! 66 | endif 67 | -------------------------------------------------------------------------------- /tests/test_procedures_vimscript/folding4.vim: -------------------------------------------------------------------------------- 1 | " Test that doing (reversible) changes in insert mode or normal mode to a 2 | " buffer do not alter their folding. 3 | 4 | " Load sample python file. 5 | " With 'def'. 6 | execute "normal! idef myfunc():\ a=1" 7 | execute "normal! A; a= 2;" 8 | 9 | " Clean file. 10 | execute "normal! :%d\" 11 | 12 | " With 'class'. 13 | execute "normal! iclass MyClass():\ a=1" 14 | execute "normal! A; a= 2;" 15 | 16 | quit! 17 | -------------------------------------------------------------------------------- /tests/test_procedures_vimscript/pymodelint.vim: -------------------------------------------------------------------------------- 1 | " Test that the PymodeLintAuto changes a badly formated buffer. 2 | 3 | " Load sample python file. 4 | read ./test_python_sample_code/from_autopep8.py 5 | 6 | " Delete the first line (which is not present in the original file) and save 7 | " loaded file. 8 | execute "normal! gg" 9 | execute "normal! dd" 10 | noautocmd write! 11 | 12 | " HOW TO BREAK: Remove very wrong python code leading to a short loclist of 13 | " errors. 14 | " Introduce errors. 15 | " execute "normal! :%d\" 16 | 17 | " Start with an empty loclist. 18 | call assert_true(len(getloclist(0)) == 0) 19 | PymodeLint 20 | call assert_true(len(getloclist(0)) > 5) 21 | write! 22 | 23 | " Assert changes. 24 | if len(v:errors) > 0 25 | cquit! 26 | else 27 | quitall! 28 | endif 29 | -------------------------------------------------------------------------------- /tests/test_procedures_vimscript/pymoderun.vim: -------------------------------------------------------------------------------- 1 | " Test that the PymodeLintAuto changes a badly formated buffer. 2 | 3 | " Load sample python file. 4 | read ./test_python_sample_code/pymoderun_sample.py 5 | 6 | " Delete the first line (which is not present in the original file) and save 7 | " loaded file. 8 | execute "normal! gg" 9 | execute "normal! dd" 10 | noautocmd write! 11 | 12 | " Allow switching to windows with buffer command. 13 | let s:curr_buffer = bufname("%") 14 | set switchbuf+=useopen 15 | 16 | " Change the buffer. 17 | PymodeRun 18 | write! 19 | let run_buffer = bufname("run") 20 | execute "buffer " . run_buffer 21 | 22 | " Assert changes. 23 | 24 | " There exists a buffer. 25 | call assert_true(len(run_buffer) > 0) 26 | 27 | " This buffer has more than five lines. 28 | call assert_true(line('$') > 5) 29 | 30 | if len(v:errors) > 0 31 | cquit! 32 | else 33 | quit! 34 | endif 35 | -------------------------------------------------------------------------------- /tests/test_procedures_vimscript/pymodeversion.vim: -------------------------------------------------------------------------------- 1 | " Test that the PymodeLintAuto changes a badly formated buffer. 2 | 3 | " Clear messages. 4 | messages clear 5 | 6 | " Produce expected message. 7 | PymodeVersion 8 | let s:msg = execute('messages') 9 | 10 | " Assert changes. 11 | call assert_match('pymode version', tolower(s:msg)) 12 | 13 | if len(v:errors) > 0 14 | cquit! 15 | else 16 | quit! 17 | endif 18 | -------------------------------------------------------------------------------- /tests/test_procedures_vimscript/textobject.vim: -------------------------------------------------------------------------------- 1 | set noautoindent 2 | let g:pymode_rope=1 3 | 4 | " Load sample python file. 5 | " With 'def'. 6 | execute "normal! idef func1():\ a = 1\" 7 | execute "normal! idef func2():\ b = 2" 8 | normal 3ggdaMggf(P 9 | 10 | " Assert changes. 11 | let content=getline('^', '$') 12 | call assert_true(content == ['def func2():', ' b = 2', 'def func1():', ' a = 1']) 13 | 14 | 15 | " Clean file. 16 | %delete 17 | 18 | " With 'class'. 19 | execute "normal! iclass Class1():\ a = 1\" 20 | execute "normal! iclass Class2():\ b = 2\" 21 | normal 3ggdaCggf(P 22 | 23 | " Assert changes. 24 | let content=getline('^', '$') 25 | call assert_true(content == ['class Class2():', ' b = 2', '', 'class Class1():', ' a = 1']) 26 | 27 | 28 | " Clean file. 29 | %delete 30 | 31 | " With 'def'. 32 | execute "normal! iprint(\ 1\)\" 33 | execute "normal! iprint(\ 2\)\" 34 | execute "normal! iprint(\ 3\)\" 35 | normal 4ggdV 36 | 37 | let content=getline('^', '$') 38 | call assert_true(content == [ 39 | \ "print(", " 1", ")", 40 | \ "print(", " 3", ")", 41 | \ "" 42 | \]) 43 | 44 | 45 | " Clean file. 46 | %delete 47 | 48 | " With 'def'. 49 | execute "normal! iprint(\ 1\)\" 50 | execute "normal! iprint(\ 2\)\" 51 | execute "normal! iprint(\ 3\)\" 52 | execute "normal! iprint(\ 4\)\" 53 | normal 5ggd2V 54 | 55 | let content=getline('^', '$') 56 | call assert_true(content == [ 57 | \ "print(", " 1", ")", 58 | \ "print(", " 4", ")", 59 | \ "" 60 | \]) 61 | 62 | " Clean file. 63 | %delete 64 | 65 | " With 'def'. 66 | execute "normal! iprint(\ 1\)\" 67 | execute "normal! iprint(\ 2\)\" 68 | execute "normal! iprint(\ 3\)\" 69 | execute "normal! iprint(\ 4\)\" 70 | normal 5ggd2V 71 | 72 | let content=getline('^', '$') 73 | call assert_true(content == [ 74 | \ "print(", " 1", ")", 75 | \ "print(", " 4", ")", 76 | \ "" 77 | \]) 78 | 79 | if len(v:errors) > 0 80 | cquit! 81 | else 82 | quit! 83 | endif 84 | -------------------------------------------------------------------------------- /tests/test_python_sample_code/algorithms.py: -------------------------------------------------------------------------------- 1 | # This file is part of DEAP. 2 | # 3 | # DEAP is free software: you can redistribute it and/or modify 4 | # it under the terms of the GNU Lesser General Public License as 5 | # published by the Free Software Foundation, either version 3 of 6 | # the License, or (at your option) any later version. 7 | # 8 | # DEAP is distributed in the hope that it will be useful, 9 | # but WITHOUT ANY WARRANTY; without even the implied warranty of 10 | # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 11 | # GNU Lesser General Public License for more details. 12 | # 13 | # You should have received a copy of the GNU Lesser General Public 14 | # License along with DEAP. If not, see . 15 | 16 | """The :mod:`algorithms` module is intended to contain some specific algorithms 17 | in order to execute very common evolutionary algorithms. The method used here 18 | are more for convenience than reference as the implementation of every 19 | evolutionary algorithm may vary infinitely. Most of the algorithms in this 20 | module use operators registered in the toolbox. Generally, the keyword used are 21 | :meth:`mate` for crossover, :meth:`mutate` for mutation, :meth:`~deap.select` 22 | for selection and :meth:`evaluate` for evaluation. 23 | 24 | You are encouraged to write your own algorithms in order to make them do what 25 | you really want them to do. 26 | """ 27 | 28 | import random 29 | 30 | import tools 31 | 32 | 33 | def varAnd(population, toolbox, cxpb, mutpb): 34 | """Part of an evolutionary algorithm applying only the variation part 35 | (crossover **and** mutation). The modified individuals have their 36 | fitness invalidated. The individuals are cloned so returned population is 37 | independent of the input population. 38 | 39 | :param population: A list of individuals to vary. 40 | :param toolbox: A :class:`~deap.base.Toolbox` that contains the evolution 41 | operators. 42 | :param cxpb: The probability of mating two individuals. 43 | :param mutpb: The probability of mutating an individual. 44 | :returns: A list of varied individuals that are independent of their 45 | parents. 46 | 47 | The variation goes as follow. First, the parental population 48 | :math:`P_\mathrm{p}` is duplicated using the :meth:`toolbox.clone` method 49 | and the result is put into the offspring population :math:`P_\mathrm{o}`. A 50 | first loop over :math:`P_\mathrm{o}` is executed to mate pairs of 51 | consecutive individuals. According to the crossover probability *cxpb*, the 52 | individuals :math:`\mathbf{x}_i` and :math:`\mathbf{x}_{i+1}` are mated 53 | using the :meth:`toolbox.mate` method. The resulting children 54 | :math:`\mathbf{y}_i` and :math:`\mathbf{y}_{i+1}` replace their respective 55 | parents in :math:`P_\mathrm{o}`. A second loop over the resulting 56 | :math:`P_\mathrm{o}` is executed to mutate every individual with a 57 | probability *mutpb*. When an individual is mutated it replaces its not 58 | mutated version in :math:`P_\mathrm{o}`. The resulting :math:`P_\mathrm{o}` 59 | is returned. 60 | 61 | This variation is named *And* beceause of its propention to apply both 62 | crossover and mutation on the individuals. Note that both operators are 63 | not applied systematically, the resulting individuals can be generated from 64 | crossover only, mutation only, crossover and mutation, and reproduction 65 | according to the given probabilities. Both probabilities should be in 66 | :math:`[0, 1]`. 67 | """ 68 | offspring = [toolbox.clone(ind) for ind in population] 69 | 70 | # Apply crossover and mutation on the offspring 71 | for i in range(1, len(offspring), 2): 72 | if random.random() < cxpb: 73 | offspring[i - 1], offspring[i] = toolbox.mate(offspring[i - 1], 74 | offspring[i]) 75 | del offspring[i - 1].fitness.values, offspring[i].fitness.values 76 | 77 | for i in range(len(offspring)): 78 | if random.random() < mutpb: 79 | offspring[i], = toolbox.mutate(offspring[i]) 80 | del offspring[i].fitness.values 81 | 82 | return offspring 83 | 84 | 85 | def eaSimple(population, toolbox, cxpb, mutpb, ngen, stats=None, 86 | halloffame=None, verbose=__debug__): 87 | """This algorithm reproduce the simplest evolutionary algorithm as 88 | presented in chapter 7 of [Back2000]_. 89 | 90 | :param population: A list of individuals. 91 | :param toolbox: A :class:`~deap.base.Toolbox` that contains the evolution 92 | operators. 93 | :param cxpb: The probability of mating two individuals. 94 | :param mutpb: The probability of mutating an individual. 95 | :param ngen: The number of generation. 96 | :param stats: A :class:`~deap.tools.Statistics` object that is updated 97 | inplace, optional. 98 | :param halloffame: A :class:`~deap.tools.HallOfFame` object that will 99 | contain the best individuals, optional. 100 | :param verbose: Whether or not to log the statistics. 101 | :returns: The final population 102 | :returns: A class:`~deap.tools.Logbook` with the statistics of the 103 | evolution 104 | 105 | The algorithm takes in a population and evolves it in place using the 106 | :meth:`varAnd` method. It returns the optimized population and a 107 | :class:`~deap.tools.Logbook` with the statistics of the evolution. The 108 | logbook will contain the generation number, the number of evalutions for 109 | each generation and the statistics if a :class:`~deap.tools.Statistics` is 110 | given as argument. The *cxpb* and *mutpb* arguments are passed to the 111 | :func:`varAnd` function. The pseudocode goes as follow :: 112 | 113 | evaluate(population) 114 | for g in range(ngen): 115 | population = select(population, len(population)) 116 | offspring = varAnd(population, toolbox, cxpb, mutpb) 117 | evaluate(offspring) 118 | population = offspring 119 | 120 | As stated in the pseudocode above, the algorithm goes as follow. First, it 121 | evaluates the individuals with an invalid fitness. Second, it enters the 122 | generational loop where the selection procedure is applied to entirely 123 | replace the parental population. The 1:1 replacement ratio of this 124 | algorithm **requires** the selection procedure to be stochastic and to 125 | select multiple times the same individual, for example, 126 | :func:`~deap.tools.selTournament` and :func:`~deap.tools.selRoulette`. 127 | Third, it applies the :func:`varAnd` function to produce the next 128 | generation population. Fourth, it evaluates the new individuals and 129 | compute the statistics on this population. Finally, when *ngen* 130 | generations are done, the algorithm returns a tuple with the final 131 | population and a :class:`~deap.tools.Logbook` of the evolution. 132 | 133 | .. note:: 134 | 135 | Using a non-stochastic selection method will result in no selection as 136 | the operator selects *n* individuals from a pool of *n*. 137 | 138 | This function expects the :meth:`toolbox.mate`, :meth:`toolbox.mutate`, 139 | :meth:`toolbox.select` and :meth:`toolbox.evaluate` aliases to be 140 | registered in the toolbox. 141 | 142 | .. [Back2000] Back, Fogel and Michalewicz, "Evolutionary Computation 1 : 143 | Basic Algorithms and Operators", 2000. 144 | """ 145 | logbook = tools.Logbook() 146 | logbook.header = ['gen', 'nevals'] + (stats.fields if stats else []) 147 | 148 | # Evaluate the individuals with an invalid fitness 149 | invalid_ind = [ind for ind in population if not ind.fitness.valid] 150 | fitnesses = toolbox.map(toolbox.evaluate, invalid_ind) 151 | for ind, fit in zip(invalid_ind, fitnesses): 152 | ind.fitness.values = fit 153 | 154 | if halloffame is not None: 155 | halloffame.update(population) 156 | 157 | record = stats.compile(population) if stats else {} 158 | logbook.record(gen=0, nevals=len(invalid_ind), **record) 159 | if verbose: 160 | print logbook.stream 161 | 162 | # Begin the generational process 163 | for gen in range(1, ngen + 1): 164 | # Select the next generation individuals 165 | offspring = toolbox.select(population, len(population)) 166 | 167 | # Vary the pool of individuals 168 | offspring = varAnd(offspring, toolbox, cxpb, mutpb) 169 | 170 | # Evaluate the individuals with an invalid fitness 171 | invalid_ind = [ind for ind in offspring if not ind.fitness.valid] 172 | fitnesses = toolbox.map(toolbox.evaluate, invalid_ind) 173 | for ind, fit in zip(invalid_ind, fitnesses): 174 | ind.fitness.values = fit 175 | 176 | # Update the hall of fame with the generated individuals 177 | if halloffame is not None: 178 | halloffame.update(offspring) 179 | 180 | # Replace the current population by the offspring 181 | population[:] = offspring 182 | 183 | # Append the current generation statistics to the logbook 184 | record = stats.compile(population) if stats else {} 185 | logbook.record(gen=gen, nevals=len(invalid_ind), **record) 186 | if verbose: 187 | print logbook.stream 188 | 189 | return population, logbook 190 | 191 | 192 | def varOr(population, toolbox, lambda_, cxpb, mutpb): 193 | """Part of an evolutionary algorithm applying only the variation part 194 | (crossover, mutation **or** reproduction). The modified individuals have 195 | their fitness invalidated. The individuals are cloned so returned 196 | population is independent of the input population. 197 | 198 | :param population: A list of individuals to vary. 199 | :param toolbox: A :class:`~deap.base.Toolbox` that contains the evolution 200 | operators. 201 | :param lambda\_: The number of children to produce 202 | :param cxpb: The probability of mating two individuals. 203 | :param mutpb: The probability of mutating an individual. 204 | :returns: The final population 205 | :returns: A class:`~deap.tools.Logbook` with the statistics of the 206 | evolution 207 | 208 | The variation goes as follow. On each of the *lambda_* iteration, it 209 | selects one of the three operations; crossover, mutation or reproduction. 210 | In the case of a crossover, two individuals are selected at random from 211 | the parental population :math:`P_\mathrm{p}`, those individuals are cloned 212 | using the :meth:`toolbox.clone` method and then mated using the 213 | :meth:`toolbox.mate` method. Only the first child is appended to the 214 | offspring population :math:`P_\mathrm{o}`, the second child is discarded. 215 | In the case of a mutation, one individual is selected at random from 216 | :math:`P_\mathrm{p}`, it is cloned and then mutated using using the 217 | :meth:`toolbox.mutate` method. The resulting mutant is appended to 218 | :math:`P_\mathrm{o}`. In the case of a reproduction, one individual is 219 | selected at random from :math:`P_\mathrm{p}`, cloned and appended to 220 | :math:`P_\mathrm{o}`. 221 | 222 | This variation is named *Or* beceause an offspring will never result from 223 | both operations crossover and mutation. The sum of both probabilities 224 | shall be in :math:`[0, 1]`, the reproduction probability is 225 | 1 - *cxpb* - *mutpb*. 226 | """ 227 | assert (cxpb + mutpb) <= 1.0, ( 228 | "The sum of the crossover and mutation probabilities must be smaller " 229 | "or equal to 1.0.") 230 | 231 | offspring = [] 232 | for _ in xrange(lambda_): 233 | op_choice = random.random() 234 | if op_choice < cxpb: # Apply crossover 235 | ind1, ind2 = map(toolbox.clone, random.sample(population, 2)) 236 | ind1, ind2 = toolbox.mate(ind1, ind2) 237 | del ind1.fitness.values 238 | offspring.append(ind1) 239 | elif op_choice < cxpb + mutpb: # Apply mutation 240 | ind = toolbox.clone(random.choice(population)) 241 | ind, = toolbox.mutate(ind) 242 | del ind.fitness.values 243 | offspring.append(ind) 244 | else: # Apply reproduction 245 | offspring.append(random.choice(population)) 246 | 247 | return offspring 248 | 249 | 250 | def eaMuPlusLambda(population, toolbox, mu, lambda_, cxpb, mutpb, ngen, 251 | stats=None, halloffame=None, verbose=__debug__): 252 | """This is the :math:`(\mu + \lambda)` evolutionary algorithm. 253 | 254 | :param population: A list of individuals. 255 | :param toolbox: A :class:`~deap.base.Toolbox` that contains the evolution 256 | operators. 257 | :param mu: The number of individuals to select for the next generation. 258 | :param lambda\_: The number of children to produce at each generation. 259 | :param cxpb: The probability that an offspring is produced by crossover. 260 | :param mutpb: The probability that an offspring is produced by mutation. 261 | :param ngen: The number of generation. 262 | :param stats: A :class:`~deap.tools.Statistics` object that is updated 263 | inplace, optional. 264 | :param halloffame: A :class:`~deap.tools.HallOfFame` object that will 265 | contain the best individuals, optional. 266 | :param verbose: Whether or not to log the statistics. 267 | :returns: The final population 268 | :returns: A class:`~deap.tools.Logbook` with the statistics of the 269 | evolution. 270 | 271 | The algorithm takes in a population and evolves it in place using the 272 | :func:`varOr` function. It returns the optimized population and a 273 | :class:`~deap.tools.Logbook` with the statistics of the evolution. The 274 | logbook will contain the generation number, the number of evalutions for 275 | each generation and the statistics if a :class:`~deap.tools.Statistics` is 276 | given as argument. The *cxpb* and *mutpb* arguments are passed to the 277 | :func:`varOr` function. The pseudocode goes as follow :: 278 | 279 | evaluate(population) 280 | for g in range(ngen): 281 | offspring = varOr(population, toolbox, lambda_, cxpb, mutpb) 282 | evaluate(offspring) 283 | population = select(population + offspring, mu) 284 | 285 | First, the individuals having an invalid fitness are evaluated. Second, 286 | the evolutionary loop begins by producing *lambda_* offspring from the 287 | population, the offspring are generated by the :func:`varOr` function. The 288 | offspring are then evaluated and the next generation population is 289 | selected from both the offspring **and** the population. Finally, when 290 | *ngen* generations are done, the algorithm returns a tuple with the final 291 | population and a :class:`~deap.tools.Logbook` of the evolution. 292 | 293 | This function expects :meth:`toolbox.mate`, :meth:`toolbox.mutate`, 294 | :meth:`toolbox.select` and :meth:`toolbox.evaluate` aliases to be 295 | registered in the toolbox. This algorithm uses the :func:`varOr` 296 | variation. 297 | """ 298 | logbook = tools.Logbook() 299 | logbook.header = ['gen', 'nevals'] + (stats.fields if stats else []) 300 | 301 | # Evaluate the individuals with an invalid fitness 302 | invalid_ind = [ind for ind in population if not ind.fitness.valid] 303 | fitnesses = toolbox.map(toolbox.evaluate, invalid_ind) 304 | for ind, fit in zip(invalid_ind, fitnesses): 305 | ind.fitness.values = fit 306 | 307 | if halloffame is not None: 308 | halloffame.update(population) 309 | 310 | record = stats.compile(population) if stats is not None else {} 311 | logbook.record(gen=0, nevals=len(invalid_ind), **record) 312 | if verbose: 313 | print logbook.stream 314 | 315 | # Begin the generational process 316 | for gen in range(1, ngen + 1): 317 | # Vary the population 318 | offspring = varOr(population, toolbox, lambda_, cxpb, mutpb) 319 | 320 | # Evaluate the individuals with an invalid fitness 321 | invalid_ind = [ind for ind in offspring if not ind.fitness.valid] 322 | fitnesses = toolbox.map(toolbox.evaluate, invalid_ind) 323 | for ind, fit in zip(invalid_ind, fitnesses): 324 | ind.fitness.values = fit 325 | 326 | # Update the hall of fame with the generated individuals 327 | if halloffame is not None: 328 | halloffame.update(offspring) 329 | 330 | # Select the next generation population 331 | population[:] = toolbox.select(population + offspring, mu) 332 | 333 | # Update the statistics with the new population 334 | record = stats.compile(population) if stats is not None else {} 335 | logbook.record(gen=gen, nevals=len(invalid_ind), **record) 336 | if verbose: 337 | print logbook.stream 338 | 339 | return population, logbook 340 | 341 | 342 | def eaMuCommaLambda(population, toolbox, mu, lambda_, cxpb, mutpb, ngen, 343 | stats=None, halloffame=None, verbose=__debug__): 344 | """This is the :math:`(\mu~,~\lambda)` evolutionary algorithm. 345 | 346 | :param population: A list of individuals. 347 | :param toolbox: A :class:`~deap.base.Toolbox` that contains the evolution 348 | operators. 349 | :param mu: The number of individuals to select for the next generation. 350 | :param lambda\_: The number of children to produce at each generation. 351 | :param cxpb: The probability that an offspring is produced by crossover. 352 | :param mutpb: The probability that an offspring is produced by mutation. 353 | :param ngen: The number of generation. 354 | :param stats: A :class:`~deap.tools.Statistics` object that is updated 355 | inplace, optional. 356 | :param halloffame: A :class:`~deap.tools.HallOfFame` object that will 357 | contain the best individuals, optional. 358 | :param verbose: Whether or not to log the statistics. 359 | :returns: The final population 360 | :returns: A class:`~deap.tools.Logbook` with the statistics of the 361 | evolution 362 | 363 | The algorithm takes in a population and evolves it in place using the 364 | :func:`varOr` function. It returns the optimized population and a 365 | :class:`~deap.tools.Logbook` with the statistics of the evolution. The 366 | logbook will contain the generation number, the number of evalutions for 367 | each generation and the statistics if a :class:`~deap.tools.Statistics` is 368 | given as argument. The *cxpb* and *mutpb* arguments are passed to the 369 | :func:`varOr` function. The pseudocode goes as follow :: 370 | 371 | evaluate(population) 372 | for g in range(ngen): 373 | offspring = varOr(population, toolbox, lambda_, cxpb, mutpb) 374 | evaluate(offspring) 375 | population = select(offspring, mu) 376 | 377 | First, the individuals having an invalid fitness are evaluated. Second, 378 | the evolutionary loop begins by producing *lambda_* offspring from the 379 | population, the offspring are generated by the :func:`varOr` function. The 380 | offspring are then evaluated and the next generation population is 381 | selected from **only** the offspring. Finally, when 382 | *ngen* generations are done, the algorithm returns a tuple with the final 383 | population and a :class:`~deap.tools.Logbook` of the evolution. 384 | 385 | .. note:: 386 | 387 | Care must be taken when the lambda:mu ratio is 1 to 1 as a 388 | non-stochastic selection will result in no selection at all as the 389 | operator selects *lambda* individuals from a pool of *mu*. 390 | 391 | 392 | This function expects :meth:`toolbox.mate`, :meth:`toolbox.mutate`, 393 | :meth:`toolbox.select` and :meth:`toolbox.evaluate` aliases to be 394 | registered in the toolbox. This algorithm uses the :func:`varOr` 395 | variation. 396 | """ 397 | assert lambda_ >= mu, "lambda must be greater or equal to mu." 398 | 399 | # Evaluate the individuals with an invalid fitness 400 | invalid_ind = [ind for ind in population if not ind.fitness.valid] 401 | fitnesses = toolbox.map(toolbox.evaluate, invalid_ind) 402 | for ind, fit in zip(invalid_ind, fitnesses): 403 | ind.fitness.values = fit 404 | 405 | if halloffame is not None: 406 | halloffame.update(population) 407 | 408 | logbook = tools.Logbook() 409 | logbook.header = ['gen', 'nevals'] + (stats.fields if stats else []) 410 | 411 | record = stats.compile(population) if stats is not None else {} 412 | logbook.record(gen=0, nevals=len(invalid_ind), **record) 413 | if verbose: 414 | print logbook.stream 415 | 416 | # Begin the generational process 417 | for gen in range(1, ngen + 1): 418 | # Vary the population 419 | offspring = varOr(population, toolbox, lambda_, cxpb, mutpb) 420 | 421 | # Evaluate the individuals with an invalid fitness 422 | invalid_ind = [ind for ind in offspring if not ind.fitness.valid] 423 | fitnesses = toolbox.map(toolbox.evaluate, invalid_ind) 424 | for ind, fit in zip(invalid_ind, fitnesses): 425 | ind.fitness.values = fit 426 | 427 | # Update the hall of fame with the generated individuals 428 | if halloffame is not None: 429 | halloffame.update(offspring) 430 | 431 | # Select the next generation population 432 | population[:] = toolbox.select(offspring, mu) 433 | 434 | # Update the statistics with the new population 435 | record = stats.compile(population) if stats is not None else {} 436 | logbook.record(gen=gen, nevals=len(invalid_ind), **record) 437 | if verbose: 438 | print logbook.stream 439 | return population, logbook 440 | 441 | 442 | def eaGenerateUpdate(toolbox, ngen, halloffame=None, stats=None, 443 | verbose=__debug__): 444 | """This is algorithm implements the ask-tell model proposed in 445 | [Colette2010]_, where ask is called `generate` and tell is called `update`. 446 | 447 | :param toolbox: A :class:`~deap.base.Toolbox` that contains the evolution 448 | operators. 449 | :param ngen: The number of generation. 450 | :param stats: A :class:`~deap.tools.Statistics` object that is updated 451 | inplace, optional. 452 | :param halloffame: A :class:`~deap.tools.HallOfFame` object that will 453 | contain the best individuals, optional. 454 | :param verbose: Whether or not to log the statistics. 455 | :returns: The final population 456 | :returns: A class:`~deap.tools.Logbook` with the statistics of the 457 | evolution 458 | 459 | The algorithm generates the individuals using the :func:`toolbox.generate` 460 | function and updates the generation method with the :func:`toolbox.update` 461 | function. It returns the optimized population and a 462 | :class:`~deap.tools.Logbook` with the statistics of the evolution. The 463 | logbook will contain the generation number, the number of evalutions for 464 | each generation and the statistics if a :class:`~deap.tools.Statistics` is 465 | given as argument. The pseudocode goes as follow :: 466 | 467 | for g in range(ngen): 468 | population = toolbox.generate() 469 | evaluate(population) 470 | toolbox.update(population) 471 | 472 | .. [Colette2010] Collette, Y., N. Hansen, G. Pujol, D. Salazar Aponte and 473 | R. Le Riche (2010). On Object-Oriented Programming of Optimizers - 474 | Examples in Scilab. In P. Breitkopf and R. F. Coelho, eds.: 475 | Multidisciplinary Design Optimization in Computational Mechanics, 476 | Wiley, pp. 527-565; 477 | 478 | """ 479 | logbook = tools.Logbook() 480 | logbook.header = ['gen', 'nevals'] + (stats.fields if stats else []) 481 | 482 | for gen in xrange(ngen): 483 | # Generate a new population 484 | population = toolbox.generate() 485 | # Evaluate the individuals 486 | fitnesses = toolbox.map(toolbox.evaluate, population) 487 | for ind, fit in zip(population, fitnesses): 488 | ind.fitness.values = fit 489 | 490 | if halloffame is not None: 491 | halloffame.update(population) 492 | 493 | # Update the strategy with the evaluated individuals 494 | toolbox.update(population) 495 | 496 | record = stats.compile(population) if stats is not None else {} 497 | logbook.record(gen=gen, nevals=len(population), **record) 498 | if verbose: 499 | print logbook.stream 500 | 501 | return population, logbook 502 | -------------------------------------------------------------------------------- /tests/test_python_sample_code/folding1.py: -------------------------------------------------------------------------------- 1 | """One liner. 2 | 3 | Multi line. 4 | 5 | Docstring. 6 | 7 | """ 8 | 9 | import math 10 | 11 | 12 | def top_function(a, b, c): 13 | """One liner docstring.""" 14 | print(a) 15 | print(b) 16 | print(c) 17 | 18 | 19 | if __name__ == '__main__': 20 | top_function(math.e, 1, 'si') 21 | -------------------------------------------------------------------------------- /tests/test_python_sample_code/folding2.py: -------------------------------------------------------------------------------- 1 | """Module level docstring. 2 | 3 | Multi line. 4 | 5 | Docstring. 6 | 7 | """ 8 | 9 | import math 10 | import functools 11 | 12 | 13 | def dec_logger(func): 14 | """One liner.""" 15 | @functools.wraps(func) 16 | def wrapper(*arg, **kargs): 17 | """Imperative one liner.""" 18 | result = func(*arg, **kargs) 19 | print(result) 20 | return result 21 | return wrapper 22 | 23 | 24 | def n1(x): # noqa 25 | """Multi line 26 | Docstring. 27 | """ 28 | a = x + 1 29 | 30 | def n2(y): 31 | """Single line docstring.""" 32 | @dec_logger 33 | def n3(z): 34 | """Have multiline. 35 | Docstring 36 | As 37 | Well 38 | """ 39 | 40 | 41 | # Leave some blank spaces 42 | 43 | 44 | 45 | 46 | 47 | return str(z) + 'expanded' 48 | 49 | b = y + 1 50 | n3(b) 51 | return b 52 | n2(a) 53 | 54 | 55 | if __name__ == '__main__': 56 | n1(math.pi) 57 | -------------------------------------------------------------------------------- /tests/test_python_sample_code/from_autopep8.py: -------------------------------------------------------------------------------- 1 | import math, sys; 2 | 3 | def example1(): 4 | ####This is a long comment. This should be wrapped to fit within 72 characters. 5 | some_tuple=( 1,2, 3,'a' ); 6 | some_variable={'long':'Long code lines should be wrapped within 79 characters.', 7 | 'other':[math.pi, 100,200,300,9876543210,'This is a long string that goes on'], 8 | 'more':{'inner':'This whole logical line should be wrapped.',some_tuple:[1, 9 | 20,300,40000,500000000,60000000000000000]}} 10 | return (some_tuple, some_variable) 11 | def example2(): return {'has_key() is deprecated':True}.has_key({'f':2}.has_key('')); 12 | class Example3( object ): 13 | def __init__ ( self, bar ): 14 | #Comments should have a space after the hash. 15 | if bar : bar+=1; bar=bar* bar ; return bar 16 | else: 17 | some_string = """ 18 | Indentation in multiline strings should not be touched. 19 | Only actual code should be reindented. 20 | """ 21 | return (sys.path, some_string) 22 | -------------------------------------------------------------------------------- /tests/test_python_sample_code/pymoderun_sample.py: -------------------------------------------------------------------------------- 1 | # Output more than 5 lines to stdout. 2 | a = 10 3 | for z in range(a): 4 | print(z) 5 | -------------------------------------------------------------------------------- /tests/utils/pymoderc: -------------------------------------------------------------------------------- 1 | " These are all pymode configs. You can read about them using :help pymode 2 | let g:pymode = 1 3 | let g:pymode_warnings = 1 4 | let g:pymode_paths = [] 5 | let g:pymode_trim_whitespaces = 1 6 | let g:pymode_options = 1 7 | let g:pymode_options_max_line_length = 79 8 | let g:pymode_options_colorcolumn = 1 9 | let g:pymode_quickfix_minheight = 3 10 | let g:pymode_quickfix_maxheight = 6 11 | let g:pymode_indent = 1 12 | let g:pymode_folding = 0 13 | let g:pymode_motion = 1 14 | let g:pymode_doc = 1 15 | let g:pymode_doc_bind = 'K' 16 | let g:pymode_virtualenv = 1 17 | let g:pymode_virtualenv_path = $VIRTUAL_ENV 18 | let g:pymode_run = 1 19 | let g:pymode_run_bind = 'r' 20 | let g:pymode_breakpoint = 1 21 | let g:pymode_breakpoint_bind = 'b' 22 | let g:pymode_breakpoint_cmd = '' 23 | let g:pymode_lint = 1 24 | let g:pymode_lint_on_write = 1 25 | let g:pymode_lint_unmodified = 0 26 | let g:pymode_lint_on_fly = 0 27 | let g:pymode_lint_message = 1 28 | let g:pymode_lint_checkers = ['pyflakes', 'pycodestyle', 'mccabe'] 29 | let g:pymode_lint_ignore = ["E501", "W",] 30 | let g:pymode_lint_select = ["E501", "W0011", "W430"] 31 | let g:pymode_lint_sort = [] 32 | let g:pymode_lint_cwindow = 1 33 | let g:pymode_lint_signs = 1 34 | let g:pymode_lint_todo_symbol = 'WW' 35 | let g:pymode_lint_comment_symbol = 'CC' 36 | let g:pymode_lint_visual_symbol = 'RR' 37 | let g:pymode_lint_error_symbol = 'EE' 38 | let g:pymode_lint_info_symbol = 'II' 39 | let g:pymode_lint_pyflakes_symbol = 'FF' 40 | let g:pymode_lint_options_pycodestyle = 41 | \ {'max_line_length': g:pymode_options_max_line_length} 42 | let g:pymode_lint_options_pyflakes = { 'builtins': '_' } 43 | let g:pymode_lint_options_mccabe = { 'complexity': 12 } 44 | let g:pymode_lint_options_pep257 = {} 45 | let g:pymode_lint_options_pylint = 46 | \ {'max-line-length': g:pymode_options_max_line_length} 47 | let g:pymode_rope = 1 48 | let g:pymode_rope_lookup_project = 0 49 | let g:pymode_rope_project_root = "" 50 | let g:pymode_rope_ropefolder='.ropeproject' 51 | let g:pymode_rope_show_doc_bind = 'd' 52 | let g:pymode_rope_regenerate_on_write = 1 53 | let g:pymode_rope_completion = 1 54 | let g:pymode_rope_complete_on_dot = 1 55 | let g:pymode_rope_completion_bind = '' 56 | let g:pymode_rope_autoimport = 0 57 | let g:pymode_rope_autoimport_modules = ['os', 'shutil', 'datetime'] 58 | let g:pymode_rope_autoimport_import_after_complete = 0 59 | let g:pymode_rope_goto_definition_bind = 'g' 60 | let g:pymode_rope_goto_definition_cmd = 'new' 61 | let g:pymode_rope_rename_bind = 'rr' 62 | let g:pymode_rope_rename_module_bind = 'r1r' 63 | let g:pymode_rope_organize_imports_bind = 'ro' 64 | let g:pymode_rope_autoimport_bind = 'ra' 65 | let g:pymode_rope_module_to_package_bind = 'r1p' 66 | let g:pymode_rope_extract_method_bind = 'rm' 67 | let g:pymode_rope_extract_variable_bind = 'rl' 68 | let g:pymode_rope_use_function_bind = 'ru' 69 | let g:pymode_rope_move_bind = 'rv' 70 | let g:pymode_rope_change_signature_bind = 'rs' 71 | let g:pymode_syntax = 1 72 | let g:pymode_syntax_slow_sync = 1 73 | let g:pymode_syntax_all = 1 74 | let g:pymode_syntax_print_as_function = 0 75 | let g:pymode_syntax_highlight_async_await = g:pymode_syntax_all 76 | let g:pymode_syntax_highlight_equal_operator = g:pymode_syntax_all 77 | let g:pymode_syntax_highlight_stars_operator = g:pymode_syntax_all 78 | let g:pymode_syntax_highlight_self = g:pymode_syntax_all 79 | let g:pymode_syntax_indent_errors = g:pymode_syntax_all 80 | let g:pymode_syntax_space_errors = g:pymode_syntax_all 81 | let g:pymode_syntax_string_formatting = g:pymode_syntax_all 82 | let g:pymode_syntax_string_format = g:pymode_syntax_all 83 | let g:pymode_syntax_string_templates = g:pymode_syntax_all 84 | let g:pymode_syntax_doctests = g:pymode_syntax_all 85 | let g:pymode_syntax_builtin_objs = g:pymode_syntax_all 86 | let g:pymode_syntax_builtin_types = g:pymode_syntax_all 87 | let g:pymode_syntax_highlight_exceptions = g:pymode_syntax_all 88 | let g:pymode_syntax_docstrings = g:pymode_syntax_all 89 | 90 | " vim:tw=79:ts=8:ft=help:norl: 91 | -------------------------------------------------------------------------------- /tests/utils/vimrc: -------------------------------------------------------------------------------- 1 | source /root/.vimrc.before 2 | source /root/.pymoderc 3 | 4 | syntax on 5 | filetype plugin indent on 6 | set shortmess=at 7 | set cmdheight=10 8 | set ft=python 9 | set shell=bash 10 | set rtp+=/root/.vim/pack/foo/start/python-mode 11 | set term=xterm-256color 12 | set wrap " visually wrap lines 13 | set smartindent " smart indenting 14 | set shiftwidth=4 " default to two spaces 15 | set tabstop=4 " default to two spaces 16 | set softtabstop=4 " default to two spaces 17 | set shiftround " always round indentation to shiftwidth 18 | set mouse= " disable mouse 19 | set expandtab 20 | set backspace=indent,eol,start 21 | 22 | source /root/.vimrc.after 23 | --------------------------------------------------------------------------------