From d3209333839f29e4bfa7f34ba8dd38cbec154b9c Mon Sep 17 00:00:00 2001 From: Daniel Hahler Date: Sat, 29 Jul 2017 14:35:28 +0200 Subject: [PATCH 01/16] Lint fixes (vint) --- indent/python.vim | 24 ++++++++++++------------ 1 file changed, 12 insertions(+), 12 deletions(-) diff --git a/indent/python.vim b/indent/python.vim index 939968e..19b649e 100644 --- a/indent/python.vim +++ b/indent/python.vim @@ -20,7 +20,7 @@ " . " Only load this indent file when no other was loaded. -if exists("b:did_indent") +if exists('b:did_indent') finish endif let b:did_indent = 1 @@ -44,7 +44,7 @@ let s:block_rules_multiple = { \ '^\s*else\>': ['if', 'elif', 'for', 'try', 'except'], \ } let s:paren_pairs = ['()', '{}', '[]'] -if &ft == 'pyrex' || &ft == 'cython' +if &filetype ==# 'pyrex' || &filetype ==# 'cython' let b:control_statement = '\v^\s*(class|def|if|while|with|for|except|cdef|cpdef)>' else let b:control_statement = '\v^\s*(class|def|if|while|with|for|except)>' @@ -82,7 +82,7 @@ if exists('*shiftwidth') endfunction else function! s:sw() - return &sw + return &shiftwidth endfunction endif @@ -127,7 +127,7 @@ endfunction function! s:find_start_of_multiline_statement(lnum) let lnum = a:lnum while lnum > 0 - if getline(lnum - 1) =~ '\\$' + if getline(lnum - 1) =~# '\\$' let lnum = prevnonblank(lnum - 1) else let [paren_lnum, _] = s:find_opening_paren(lnum) @@ -182,7 +182,7 @@ function! s:match_expr_on_line(expr, lnum, start, ...) let r = 1 for i in range(a:start, end) call cursor(a:lnum, i) - if !(eval(a:expr) || text[i-1] =~ '\s') + if !(eval(a:expr) || text[i-1] =~# '\s') let r = 0 break endif @@ -202,7 +202,7 @@ function! s:indent_like_opening_paren(lnum) let nothing_after_opening_paren = s:match_expr_on_line( \ s:skip_after_opening_paren, paren_lnum, paren_col+1) - let starts_with_closing_paren = getline(a:lnum) =~ '^\s*[])}]' + let starts_with_closing_paren = getline(a:lnum) =~# '^\s*[])}]' if nothing_after_opening_paren if starts_with_closing_paren @@ -276,18 +276,18 @@ function! s:indent_like_previous_line(lnum) " Search for final colon that is not inside something to be ignored. while 1 - let curpos = getpos(".")[2] + let curpos = getpos('.')[2] if curpos == 1 | break | endif - if eval(s:skip_special_chars) || text[curpos-1] =~ '\s' + if eval(s:skip_special_chars) || text[curpos-1] =~# '\s' normal! h continue - elseif text[curpos-1] == ':' + elseif text[curpos-1] ==# ':' return base + s:sw() endif break endwhile - if text =~ '\\$' && !ignore_last_char + if text =~# '\\$' && !ignore_last_char " If this line is the continuation of a control statement " indent further to distinguish the continuation line " from the next logical line. @@ -336,7 +336,7 @@ function! s:is_python_string(lnum, ...) let cols = a:0 ? type(a:1) != type([]) ? [a:1] : a:1 : range(1, linelen) for cnum in cols if match(map(synstack(a:lnum, cnum), - \ 'synIDattr(v:val,"name")'), 'python\S*String') == -1 + \ "synIDattr(v:val, 'name')"), 'python\S*String') == -1 return 0 end endfor @@ -361,7 +361,7 @@ function! GetPythonPEPIndent(lnum) let match_quotes = match(line, '^\s*\zs\%("""\|''''''\)') if match_quotes != -1 " closing multiline string - let quotes = line[match_quotes:match_quotes+2] + let quotes = line[match_quotes:(match_quotes+2)] let pairpos = searchpairpos(quotes, '', quotes, 'b') if pairpos[0] != 0 return indent(pairpos[0]) -- 2.39.5 From f8c5096fa2bf656035f5b61cce1f4007cac35df5 Mon Sep 17 00:00:00 2001 From: Daniel Hahler Date: Sat, 29 Jul 2017 14:50:37 +0200 Subject: [PATCH 02/16] Travis: run vint, build only master branch --- .travis.yml | 21 ++++++++++++++------- 1 file changed, 14 insertions(+), 7 deletions(-) diff --git a/.travis.yml b/.travis.yml index e31bfcd..c43dd5f 100644 --- a/.travis.yml +++ b/.travis.yml @@ -1,10 +1,17 @@ +branches: + only: + - master language: ruby rvm: - - 1.9.3 -before_install: sudo apt-get install vim-gtk + - 1.9.3 +before_install: + - sudo apt-get install vim-gtk before_script: - - "export DISPLAY=:99.0" - - "sh -e /etc/init.d/xvfb start" - - "bundle install" - - "vim --version" -script: bundle exec rspec + - export DISPLAY=:99.0 + - sh -e /etc/init.d/xvfb start + - bundle install + - sudo pip install vim-vint + - vim --version +script: + - bundle exec rspec + - vint **/*.vim -- 2.39.5 From 6bce13b458b959064bafe07e73a5686be1b8bd18 Mon Sep 17 00:00:00 2001 From: Daniel Hahler Date: Sat, 29 Jul 2017 15:28:39 +0200 Subject: [PATCH 03/16] Upgrade vimrunner to 0.3.3 (#85) --- Gemfile | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Gemfile b/Gemfile index 3696729..b3c8d69 100644 --- a/Gemfile +++ b/Gemfile @@ -1,3 +1,3 @@ source 'https://rubygems.org' -gem "vimrunner", "0.3.2" +gem "vimrunner", "0.3.3" gem "rspec" -- 2.39.5 From db2ce3b774b3d24d9aa6d51874fa5f863fd82b83 Mon Sep 17 00:00:00 2001 From: Daniel Hahler Date: Sat, 29 Jul 2017 15:43:28 +0200 Subject: [PATCH 04/16] README: add g: prefix to config section --- README.rst | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/README.rst b/README.rst index 3a8bf3c..92fed3b 100644 --- a/README.rst +++ b/README.rst @@ -56,8 +56,8 @@ Follow the instructions on installing NeoBundle_ and add the appropriate NeoBund Configuration ------------- -python_pep8_indent_multiline_string -^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ +g:python_pep8_indent_multiline_string +^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ You can configure the initial indentation of multiline strings using ``g:python_pep8_indent_multiline_string`` (which can also be set per buffer). This defaults to ``0``, which means that multiline strings are not indented. -- 2.39.5 From 56f3e54cea8cdd868e1d3b7b68d4c3cd02708c77 Mon Sep 17 00:00:00 2001 From: Daniel Hahler Date: Sun, 30 Jul 2017 16:17:23 +0200 Subject: [PATCH 05/16] tests: insert blank lines before each test (#89) This is required with reuse_server. --- spec/indent/indent_spec.rb | 17 +++++++++++++++++ 1 file changed, 17 insertions(+) diff --git a/spec/indent/indent_spec.rb b/spec/indent/indent_spec.rb index 0bd57b2..85bc04b 100644 --- a/spec/indent/indent_spec.rb +++ b/spec/indent/indent_spec.rb @@ -406,6 +406,17 @@ shared_examples_for "vim" do end shared_examples_for "multiline strings" do + before(:each) { + # clear buffer + vim.normal 'gg"_dG' + + # Insert two blank lines. + # The first line is a corner case in this plugin that would shadow the + # correct behaviour of other tests. Thus we explicitly jump to the first + # line when we require so. + vim.feedkeys 'i\\\' + } + describe "when after an '(' that is followed by an unfinished string" do before { vim.feedkeys 'itest("""' } @@ -540,6 +551,12 @@ describe "vim for cython" do vim.command "enew" vim.command "set ft=cython" vim.command "runtime indent/python.vim" + + # Insert two blank lines. + # The first line is a corner case in this plugin that would shadow the + # correct behaviour of other tests. Thus we explicitly jump to the first + # line when we require so. + vim.feedkeys 'i\\\' } describe "when using a cdef function definition" do -- 2.39.5 From 90e00b6189ace2b85192d74ce40929fe9d665062 Mon Sep 17 00:00:00 2001 From: Daniel Hahler Date: Sun, 30 Jul 2017 16:34:15 +0200 Subject: [PATCH 06/16] Travis: update config (#87) * Travis: update config based on splitjoin's config * rvm: 2.4.1 * Add VIMRUNNER_REUSE_SERVER, and a wrapper Makefile * Travis: VIMRUNNER_REUSE_SERVER=1 * Start Xvfb manually --- .travis.yml | 23 +++++++++++++---------- Makefile | 8 ++++++++ spec/spec_helper.rb | 10 +++------- 3 files changed, 24 insertions(+), 17 deletions(-) create mode 100644 Makefile diff --git a/.travis.yml b/.travis.yml index c43dd5f..53118ab 100644 --- a/.travis.yml +++ b/.travis.yml @@ -1,17 +1,20 @@ +language: ruby +dist: trusty +sudo: false +cache: bundler +rvm: + - 2.4.1 +addons: + apt: + packages: + - vim-gtk branches: only: - master -language: ruby -rvm: - - 1.9.3 -before_install: - - sudo apt-get install vim-gtk before_script: - - export DISPLAY=:99.0 - - sh -e /etc/init.d/xvfb start - - bundle install - - sudo pip install vim-vint + - pip install --user vim-vint - vim --version + - Xvfb :99 & script: - - bundle exec rspec + - VIMRUNNER_REUSE_SERVER=1 DISPLAY=:99 bundle exec rspec spec - vint **/*.vim diff --git a/Makefile b/Makefile new file mode 100644 index 0000000..8822dca --- /dev/null +++ b/Makefile @@ -0,0 +1,8 @@ +test: + VIMRUNNER_REUSE_SERVER=0 bundle exec rspec + +test_fast: + VIMRUNNER_REUSE_SERVER=1 xvfb-run bundle exec rspec + +test_visible: + VIMRUNNER_REUSE_SERVER=1 bundle exec rspec diff --git a/spec/spec_helper.rb b/spec/spec_helper.rb index 46ad026..9191526 100644 --- a/spec/spec_helper.rb +++ b/spec/spec_helper.rb @@ -4,15 +4,11 @@ require 'vimrunner/rspec' Vimrunner::RSpec.configure do |config| # Use a single Vim instance for the test suite. Set to false to use an # instance per test (slower, but can be easier to manage). - # FIXME: reuse_server = true seems to hang after a certain number of test cases - # - Travis CI hangs after 15 successful tests. - # - Locally it may hang also, with Vim and Xorg using 100% CPU. - # Therefore default to false in both cases. - config.reuse_server = ENV['CI'] ? false : false + # This requires using gvim, otherwise it hangs after a few tests. + config.reuse_server = ENV['VIMRUNNER_REUSE_SERVER'] == '1' ? true : false config.start_vim do - vim = Vimrunner.start - + vim = config.reuse_server ? Vimrunner.start_gvim : Vimrunner.start plugin_path = File.expand_path('../..', __FILE__) # add_plugin appends the path to the rtp... :( -- 2.39.5 From e0be8bfc4ff68e6eb26662fe3a1881cba225a44e Mon Sep 17 00:00:00 2001 From: Ivan Smirnov Date: Mon, 21 Aug 2017 16:59:17 +0100 Subject: [PATCH 07/16] Indent next line if prev line is empty (+tests) (#88) --- indent/python.vim | 7 +++++++ spec/indent/indent_spec.rb | 14 ++++++++++++++ 2 files changed, 21 insertions(+) diff --git a/indent/python.vim b/indent/python.vim index 19b649e..347e60d 100644 --- a/indent/python.vim +++ b/indent/python.vim @@ -301,6 +301,13 @@ function! s:indent_like_previous_line(lnum) let empty = getline(a:lnum) =~# '^\s*$' + " Current and prev line are empty, next is not -> indent like next. + if empty && a:lnum > 1 && + \ (getline(a:lnum - 1) =~# '^\s*$') && + \ !(getline(a:lnum + 1) =~# '^\s*$') + return indent(a:lnum + 1) + endif + " If the previous statement was a stop-execution statement or a pass if getline(start) =~# s:stop_statement " Remove one level of indentation if the user hasn't already dedented diff --git a/spec/indent/indent_spec.rb b/spec/indent/indent_spec.rb index 85bc04b..23c1629 100644 --- a/spec/indent/indent_spec.rb +++ b/spec/indent/indent_spec.rb @@ -168,6 +168,20 @@ shared_examples_for "vim" do end end + describe "when an empty line is after empty line / before non-empty" do + it "is indented like the next line" do + vim.feedkeys 'idef a():\1\\\2\<1\\\\0i\2\kcc' + indent.should == shiftwidth + end + end + describe "when line is empty inside a block following multi-line statement" do it "is indented like the previous line" do vim.feedkeys 'idef a():\x = (1 +\2)\\y\kcc' -- 2.39.5 From 720eb2b9821a4147dbd124ff595e36fa2b9b45b2 Mon Sep 17 00:00:00 2001 From: Daniel Hahler Date: Sat, 7 Oct 2017 21:29:10 +0200 Subject: [PATCH 08/16] tests: explicitly enable old "should" syntax to fix deprecation warnings (#92) MIME-Version: 1.0 Content-Type: text/plain; charset=utf8 Content-Transfer-Encoding: 8bit > Deprecation Warnings: > > Using `should` from rspec-expectations' old `:should` syntax without > explicitly enabling the syntax is deprecated. Use the new `:expect` > syntax or explicitly enable `:should` with `config.expect_with(:rspec) { > |c| c.syntax = :should }` instead. Called from > …/vim-python-pep8-indent/spec/indent/indent_spec.rb:141:in > `block (3 levels) in '. --- spec/spec_helper.rb | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/spec/spec_helper.rb b/spec/spec_helper.rb index 9191526..8636f41 100644 --- a/spec/spec_helper.rb +++ b/spec/spec_helper.rb @@ -1,6 +1,11 @@ require 'vimrunner' require 'vimrunner/rspec' +# Explicitly enable usage of "should". +RSpec.configure do |config| + config.expect_with(:rspec) { |c| c.syntax = :should } +end + Vimrunner::RSpec.configure do |config| # Use a single Vim instance for the test suite. Set to false to use an # instance per test (slower, but can be easier to manage). -- 2.39.5 From e1b71a2f196d566a81c85d1bce02acb8d252086c Mon Sep 17 00:00:00 2001 From: Daniel Hahler Date: Sat, 7 Oct 2017 21:45:40 +0200 Subject: [PATCH 09/16] Improve tests (#93) * Travis: use "make test" * Travis: do not start Xvfb * Makefile: make test fast, add test_slow --- .travis.yml | 3 +-- Makefile | 6 +++--- 2 files changed, 4 insertions(+), 5 deletions(-) diff --git a/.travis.yml b/.travis.yml index 53118ab..c9b29ca 100644 --- a/.travis.yml +++ b/.travis.yml @@ -14,7 +14,6 @@ branches: before_script: - pip install --user vim-vint - vim --version - - Xvfb :99 & script: - - VIMRUNNER_REUSE_SERVER=1 DISPLAY=:99 bundle exec rspec spec + - make test - vint **/*.vim diff --git a/Makefile b/Makefile index 8822dca..5099a58 100644 --- a/Makefile +++ b/Makefile @@ -1,8 +1,8 @@ test: - VIMRUNNER_REUSE_SERVER=0 bundle exec rspec - -test_fast: VIMRUNNER_REUSE_SERVER=1 xvfb-run bundle exec rspec +test_slow: + VIMRUNNER_REUSE_SERVER=0 bundle exec rspec + test_visible: VIMRUNNER_REUSE_SERVER=1 bundle exec rspec -- 2.39.5 From d6c602fcad59f58df00dc86e2609c9791a19ba71 Mon Sep 17 00:00:00 2001 From: Daniel Hahler Date: Thu, 5 Oct 2017 23:12:24 +0200 Subject: [PATCH 10/16] Intermediate fix for indenting huge dicts This uses different offsets for the type of pairs: '()' and '[]' will only look for just 20 lines above, while 1000 lines are used for '{}', which might be a huge dict. Ref: https://github.com/Vimjas/vim-python-pep8-indent/pull/64. --- indent/python.vim | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/indent/python.vim b/indent/python.vim index 347e60d..b1ae8a2 100644 --- a/indent/python.vim +++ b/indent/python.vim @@ -34,7 +34,6 @@ if !exists('g:python_pep8_indent_multiline_string') let g:python_pep8_indent_multiline_string = 0 endif -let s:maxoff = 50 let s:block_rules = { \ '^\s*elif\>': ['if', 'elif'], \ '^\s*except\>': ['try', 'except'], @@ -43,7 +42,9 @@ let s:block_rules = { let s:block_rules_multiple = { \ '^\s*else\>': ['if', 'elif', 'for', 'try', 'except'], \ } -let s:paren_pairs = ['()', '{}', '[]'] +" Pairs to look for when searching for opening parenthesis. +" The value is the maximum offset in lines. +let s:paren_pairs = {'()': 10, '[]': 100, '{}': 1000} if &filetype ==# 'pyrex' || &filetype ==# 'cython' let b:control_statement = '\v^\s*(class|def|if|while|with|for|except|cdef|cpdef)>' else @@ -105,13 +106,12 @@ function! s:find_opening_paren(...) return ret endif - let stopline = max([0, line('.') - s:maxoff]) - " Return if cursor is in a comment. exe 'if' s:skip_search '| return [0, 0] | endif' let positions = [] - for p in s:paren_pairs + for [p, maxoff] in items(s:paren_pairs) + let stopline = max([0, line('.') - maxoff]) call add(positions, searchpairpos( \ '\V'.p[0], '', '\V'.p[1], 'bnW', s:skip_special_chars, stopline)) endfor -- 2.39.5 From 782b0f03dab8080df9d62d9a2014b19d9d738e09 Mon Sep 17 00:00:00 2001 From: Daniel Hahler Date: Thu, 5 Oct 2017 23:20:50 +0200 Subject: [PATCH 11/16] s:find_opening_paren: use known nearest for stopline --- indent/python.vim | 18 ++++++++---------- 1 file changed, 8 insertions(+), 10 deletions(-) diff --git a/indent/python.vim b/indent/python.vim index b1ae8a2..20469e2 100644 --- a/indent/python.vim +++ b/indent/python.vim @@ -109,18 +109,16 @@ function! s:find_opening_paren(...) " Return if cursor is in a comment. exe 'if' s:skip_search '| return [0, 0] | endif' - let positions = [] + let nearest = [0, 0] for [p, maxoff] in items(s:paren_pairs) - let stopline = max([0, line('.') - maxoff]) - call add(positions, searchpairpos( - \ '\V'.p[0], '', '\V'.p[1], 'bnW', s:skip_special_chars, stopline)) + let stopline = max([0, line('.') - maxoff, nearest[0]]) + let next = searchpairpos( + \ '\V'.p[0], '', '\V'.p[1], 'bnW', s:skip_special_chars, stopline) + if next[0] && (next[0] > nearest[0] || (next[0] == nearest[0] && next[1] > nearest[1])) + let nearest = next + endif endfor - - " Remove empty matches and return the type with the closest match - call filter(positions, 'v:val[0]') - call sort(positions, 's:pair_sort') - - return get(positions, -1, [0, 0]) + return nearest endfunction " Find the start of a multi-line statement -- 2.39.5 From 922268fbd89a49991b5b5b73e969f8daa8a10263 Mon Sep 17 00:00:00 2001 From: Daniel Hahler Date: Mon, 9 Oct 2017 04:18:35 +0200 Subject: [PATCH 12/16] Improve s:find_start_of_multiline_statement: only look for round parens --- indent/python.vim | 18 ++++++++++++------ 1 file changed, 12 insertions(+), 6 deletions(-) diff --git a/indent/python.vim b/indent/python.vim index 20469e2..22ca76f 100644 --- a/indent/python.vim +++ b/indent/python.vim @@ -45,6 +45,10 @@ let s:block_rules_multiple = { " Pairs to look for when searching for opening parenthesis. " The value is the maximum offset in lines. let s:paren_pairs = {'()': 10, '[]': 100, '{}': 1000} + +" Maximum offset when looking for multiline statements (in round parenthesis). +let s:maxoff_multiline_statement = 50 + if &filetype ==# 'pyrex' || &filetype ==# 'cython' let b:control_statement = '\v^\s*(class|def|if|while|with|for|except|cdef|cpdef)>' else @@ -121,19 +125,21 @@ function! s:find_opening_paren(...) return nearest endfunction -" Find the start of a multi-line statement +" Find the start of a multi-line statement (based on surrounding parens). function! s:find_start_of_multiline_statement(lnum) let lnum = a:lnum while lnum > 0 + " XXX: not tested?! if getline(lnum - 1) =~# '\\$' let lnum = prevnonblank(lnum - 1) else - let [paren_lnum, _] = s:find_opening_paren(lnum) - if paren_lnum < 1 - return lnum - else - let lnum = paren_lnum + call cursor(lnum, 1) + let stopline = max([1, lnum - s:maxoff_multiline_statement]) + let pos = searchpairpos('\V(', '', '\V)', 'bnW', s:skip_special_chars, stopline) + if pos[0] + return pos[0] endif + return lnum endif endwhile endfunction -- 2.39.5 From 5e955165c22ec1bb874728195a7ce2a48b2edbac Mon Sep 17 00:00:00 2001 From: Daniel Hahler Date: Thu, 16 Nov 2017 17:28:46 +0100 Subject: [PATCH 13/16] use 50 for round parens, add tests --- indent/python.vim | 2 +- spec/indent/indent_spec.rb | 64 ++++++++++++++++++++++++++++++++++++++ 2 files changed, 65 insertions(+), 1 deletion(-) diff --git a/indent/python.vim b/indent/python.vim index 22ca76f..e251ce2 100644 --- a/indent/python.vim +++ b/indent/python.vim @@ -44,7 +44,7 @@ let s:block_rules_multiple = { \ } " Pairs to look for when searching for opening parenthesis. " The value is the maximum offset in lines. -let s:paren_pairs = {'()': 10, '[]': 100, '{}': 1000} +let s:paren_pairs = {'()': 50, '[]': 100, '{}': 1000} " Maximum offset when looking for multiline statements (in round parenthesis). let s:maxoff_multiline_statement = 50 diff --git a/spec/indent/indent_spec.rb b/spec/indent/indent_spec.rb index 23c1629..b08203b 100644 --- a/spec/indent/indent_spec.rb +++ b/spec/indent/indent_spec.rb @@ -587,3 +587,67 @@ describe "vim for cython" do end end end + +describe "Handles far away opening parens" do + before { vim.feedkeys '\ggdGifrom foo import (' } + + it "indents by one level" do + vim.feedkeys '\' + proposed_indent.should == shiftwidth + end + + it "indents by one level for 10 lines" do + vim.command('set paste | exe "norm 9o" | set nopaste') + vim.feedkeys '\o' + indent.should == shiftwidth + end + + it "indents by one level for 50 lines" do + vim.command('set paste | exe "norm 49o" | set nopaste') + vim.feedkeys '\o' + indent.should == shiftwidth + end +end + +describe "Handles far away opening square brackets" do + before { vim.feedkeys '\ggdGibar = [' } + + it "indents by one level" do + vim.feedkeys '\' + proposed_indent.should == shiftwidth + end + + it "indents by one level for 10 lines" do + vim.command('set paste | exe "norm 9o" | set nopaste') + vim.feedkeys '\o' + indent.should == shiftwidth + end + + it "indents by one level for 100 lines" do + vim.command('set paste | exe "norm 99o" | set nopaste') + vim.feedkeys '\o' + indent.should == shiftwidth + end +end + +describe "Handles far away opening curly brackets" do + before { vim.feedkeys '\ggdGijson = {' } + + it "indents by one level" do + vim.feedkeys '\' + vim.feedkeys '\o' + proposed_indent.should == shiftwidth + end + + it "indents by one level for 10 lines" do + vim.command('set paste | exe "norm 9o" | set nopaste') + vim.feedkeys '\o' + indent.should == shiftwidth + end + + it "indents by one level for 1000 lines" do + vim.command('set paste | exe "norm 999o" | set nopaste') + vim.feedkeys '\o' + indent.should == shiftwidth + end +end -- 2.39.5 From 5f4184fb1200b329e810c1e4c866c86fdf44c135 Mon Sep 17 00:00:00 2001 From: Daniel Hahler Date: Fri, 17 Nov 2017 14:58:22 +0100 Subject: [PATCH 14/16] Revert "Improve s:find_start_of_multiline_statement: only look for round parens" (#95) This reverts commit 922268fbd89a49991b5b5b73e969f8daa8a10263. Add a regression test. Conflicts: indent/python.vim --- indent/python.vim | 17 ++++++----------- spec/indent/indent_spec.rb | 15 +++++++++++++++ 2 files changed, 21 insertions(+), 11 deletions(-) diff --git a/indent/python.vim b/indent/python.vim index e251ce2..86155cf 100644 --- a/indent/python.vim +++ b/indent/python.vim @@ -46,9 +46,6 @@ let s:block_rules_multiple = { " The value is the maximum offset in lines. let s:paren_pairs = {'()': 50, '[]': 100, '{}': 1000} -" Maximum offset when looking for multiline statements (in round parenthesis). -let s:maxoff_multiline_statement = 50 - if &filetype ==# 'pyrex' || &filetype ==# 'cython' let b:control_statement = '\v^\s*(class|def|if|while|with|for|except|cdef|cpdef)>' else @@ -125,21 +122,19 @@ function! s:find_opening_paren(...) return nearest endfunction -" Find the start of a multi-line statement (based on surrounding parens). +" Find the start of a multi-line statement function! s:find_start_of_multiline_statement(lnum) let lnum = a:lnum while lnum > 0 - " XXX: not tested?! if getline(lnum - 1) =~# '\\$' let lnum = prevnonblank(lnum - 1) else - call cursor(lnum, 1) - let stopline = max([1, lnum - s:maxoff_multiline_statement]) - let pos = searchpairpos('\V(', '', '\V)', 'bnW', s:skip_special_chars, stopline) - if pos[0] - return pos[0] + let [paren_lnum, _] = s:find_opening_paren(lnum) + if paren_lnum < 1 + return lnum + else + let lnum = paren_lnum endif - return lnum endif endwhile endfunction diff --git a/spec/indent/indent_spec.rb b/spec/indent/indent_spec.rb index b08203b..6e5a79f 100644 --- a/spec/indent/indent_spec.rb +++ b/spec/indent/indent_spec.rb @@ -651,3 +651,18 @@ describe "Handles far away opening curly brackets" do indent.should == shiftwidth end end + +describe "Compact multiline dict" do + before { vim.feedkeys '\ggdGid = {"one": 1,' } + + it "gets indented correctly" do + vim.feedkeys '\' + proposed_indent.should == 5 + + vim.feedkeys '"two": 2}' + proposed_indent.should == 5 + + vim.feedkeys '\' + proposed_indent.should == 0 + end +end -- 2.39.5 From 19c53ee5f8b6e9054d0ee1c295d876ccb96a21f7 Mon Sep 17 00:00:00 2001 From: Jake Harr Date: Sun, 15 Jul 2018 15:11:26 -0400 Subject: [PATCH 15/16] Add option for hanging closing brackets (#94) The main idea is discussed at length in PyCQA/pycodestyle#103. * Add tests for `python_pep8_indent_hang_closing` This might be overkill. It reruns the current "vim" set of tests once for each value of the new setting. Of course, this makes the test suite take longer to run. I couldn't think of a good way to factor out the relevant test cases without creating a mess. --- README.rst | 26 +++++++++++++++++++++++++ indent/python.vim | 9 ++++++++- spec/indent/indent_spec.rb | 39 +++++++++++++++++++++++++------------- spec/spec_helper.rb | 12 ++++++++++++ 4 files changed, 72 insertions(+), 14 deletions(-) diff --git a/README.rst b/README.rst index 92fed3b..ada507e 100644 --- a/README.rst +++ b/README.rst @@ -74,6 +74,32 @@ With content already, it will be aligned to the opening parenthesis:: Existing indentation (including ``0``) in multiline strings will be kept, so this setting only applies to the indentation of new/empty lines. +g:python_pep8_indent_hang_closing +^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + +Control closing bracket indentation with ``python_pep8_indent_hang_closing``, set globally or per buffer. + +By default (set to ``0``), closing brackets line up with the opening line:: + + my_list = [ + 1, 2, 3, + 4, 5, 6, + ] + result = some_function_that_takes_arguments( + 'a', 'b', 'c', + 'd', 'e', 'f', + ) + +With ``python_pep8_indent_hang_closing = 1``, closing brackets line up with the items:: + + my_list = [ + 1, 2, 3, + 4, 5, 6, + ] + result = some_function_that_takes_arguments( + 'a', 'b', 'c', + 'd', 'e', 'f', + ) Notes ----- diff --git a/indent/python.vim b/indent/python.vim index 86155cf..a095ca6 100644 --- a/indent/python.vim +++ b/indent/python.vim @@ -34,6 +34,10 @@ if !exists('g:python_pep8_indent_multiline_string') let g:python_pep8_indent_multiline_string = 0 endif +if !exists('g:python_pep8_indent_hang_closing') + let g:python_pep8_indent_hang_closing = 0 +endif + let s:block_rules = { \ '^\s*elif\>': ['if', 'elif'], \ '^\s*except\>': ['try', 'except'], @@ -203,8 +207,11 @@ function! s:indent_like_opening_paren(lnum) \ s:skip_after_opening_paren, paren_lnum, paren_col+1) let starts_with_closing_paren = getline(a:lnum) =~# '^\s*[])}]' + let hang_closing = get(b:, 'python_pep8_indent_hang_closing', + \ get(g:, 'python_pep8_indent_hang_closing', 0)) + if nothing_after_opening_paren - if starts_with_closing_paren + if starts_with_closing_paren && !hang_closing let res = base else let res = base + s:sw() diff --git a/spec/indent/indent_spec.rb b/spec/indent/indent_spec.rb index 6e5a79f..79d7f84 100644 --- a/spec/indent/indent_spec.rb +++ b/spec/indent/indent_spec.rb @@ -52,7 +52,7 @@ shared_examples_for "vim" do it "puts the closing parenthesis at the same level" do vim.feedkeys ')' - indent.should == 0 + indent.should == (hang_closing ? shiftwidth : 0) end end @@ -87,7 +87,7 @@ shared_examples_for "vim" do it "lines up the closing parenthesis" do vim.feedkeys '}' - indent.should == 0 + indent.should == (hang_closing ? shiftwidth : 0) end end @@ -514,18 +514,31 @@ shared_examples_for "multiline strings" do end end -describe "vim when using width of 4" do - before { - vim.command("set sw=4 ts=4 sts=4 et") - } - it_behaves_like "vim" -end +SUITE_SHIFTWIDTHS = [4, 3] +SUITE_HANG_CLOSINGS = [nil, false, true] -describe "vim when using width of 3" do - before { - vim.command("set sw=3 ts=3 sts=3 et") - } - it_behaves_like "vim" +SUITE_SHIFTWIDTHS.each do |sw| + describe "vim when using width of #{sw}" do + before { + vim.command("set sw=#{sw} ts=#{sw} sts=#{sw} et") + } + it "sets shiftwidth to #{sw}" do + shiftwidth.should == sw + end + + SUITE_HANG_CLOSINGS.each do |hc| + describe "vim when hang_closing is set to #{hc}" do + before { + set_hang_closing hc + } + it "sets hang_closing to #{hc}" do + hang_closing.should == !!hc + end + + it_behaves_like "vim" + end + end + end end describe "vim when not using python_pep8_indent_multiline_string" do diff --git a/spec/spec_helper.rb b/spec/spec_helper.rb index 8636f41..4cd2b56 100644 --- a/spec/spec_helper.rb +++ b/spec/spec_helper.rb @@ -47,6 +47,18 @@ Vimrunner::RSpec.configure do |config| i = vim.echo("get(g:, 'python_pep8_indent_multiline_string', 0)").to_i return (i == -2 ? default : i), i < 0 ? (i == -1 ? prev : default) : i end + def hang_closing + i = vim.echo("get(g:, 'python_pep8_indent_hang_closing', 0)").to_i + return (i != 0) + end + def set_hang_closing(value) + if value.nil? + vim.command("unlet! g:python_pep8_indent_hang_closing") + else + i = value ? 1 : 0 + vim.command("let g:python_pep8_indent_hang_closing=#{i}") + end + end vim end -- 2.39.5 From d735178838c7122c7540aca05bcfb94005a3abe9 Mon Sep 17 00:00:00 2001 From: Daniel Hahler Date: Sun, 15 Jul 2018 21:31:38 +0200 Subject: [PATCH 16/16] README: add Troubleshooting section Fixes https://github.com/Vimjas/vim-python-pep8-indent/issues/75. --- README.rst | 17 +++++++++++++++++ 1 file changed, 17 insertions(+) diff --git a/README.rst b/README.rst index ada507e..b8eb2ac 100644 --- a/README.rst +++ b/README.rst @@ -21,6 +21,8 @@ and:: Installation ------------ +Install the plugin using your favorite plugin manager / method, a few examples +follow: Pathogen ^^^^^^^^ @@ -101,6 +103,21 @@ With ``python_pep8_indent_hang_closing = 1``, closing brackets line up with the 'd', 'e', 'f', ) + +Troubleshooting +--------------- + +In case it is not working, please make sure your Vim is configured to load +indent files (``filetype indent on``). +This is typically the case when using a plugin manager, but check its docs. + +Check ``:verbose set indentexpr?`` in a Python file, which should show +something like the following: + + indentexpr=GetPythonPEPIndent(v:lnum) + Last set from ~/…/plugged/vim-python-pep8-indent/indent/python.vim + + Notes ----- -- 2.39.5