Skip to content

Commit 357ec1c

Browse files
committed
Fix motion.
1 parent 9590fa6 commit 357ec1c

3 files changed

Lines changed: 118 additions & 61 deletions

File tree

after/ftplugin/python.vim

Lines changed: 18 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -7,24 +7,24 @@ endif
77

88
if !pymode#Default('g:pymode_motion', 1) || g:pymode_motion
99

10-
nnoremap <buffer> ]] :<C-U>call pymode#motion#move2('^\(class\\|def\)\s', '')<CR>
11-
nnoremap <buffer> [[ :<C-U>call pymode#motion#move2('^\(class\\|def\)\s', 'b')<CR>
12-
nnoremap <buffer> ]C :<C-U>call pymode#motion#move2('^\(class\\|def\)\s', '')<CR>
13-
nnoremap <buffer> [C :<C-U>call pymode#motion#move2('^\(class\\|def\)\s', 'b')<CR>
14-
nnoremap <buffer> ]M :<C-U>call pymode#motion#move2('^\s*def\s', '')<CR>
15-
nnoremap <buffer> [M :<C-U>call pymode#motion#move2('^\s*def\s', 'b')<CR>
16-
17-
onoremap <buffer> ]] :<C-U>call pymode#motion#move2('^\(class\\|def\)\s', '')<CR>
18-
onoremap <buffer> [[ :<C-U>call pymode#motion#move2('^\(class\\|def\)\s', 'b')<CR>
19-
onoremap <buffer> ]C :<C-U>call pymode#motion#move2('^\(class\\|def\)\s', '')<CR>
20-
onoremap <buffer> [C :<C-U>call pymode#motion#move2('^\(class\\|def\)\s', 'b')<CR>
21-
onoremap <buffer> ]M :<C-U>call pymode#motion#move2('^\s*def\s', '')<CR>
22-
onoremap <buffer> [M :<C-U>call pymode#motion#move2('^\s*def\s', 'b')<CR>
23-
24-
vnoremap <buffer> ]] :<C-U>call pymode#motion#vmove('^\(class\\|def\)\s', '')<CR>
25-
vnoremap <buffer> [[ :<C-U>call pymode#motion#vmove('^\(class\\|def\)\s', 'b')<CR>
26-
vnoremap <buffer> ]M :<C-U>call pymode#motion#vmove('^\s*def\s', '')<CR>
27-
vnoremap <buffer> [M :<C-U>call pymode#motion#vmove('^\s*def\s', 'b')<CR>
10+
nnoremap <buffer> ]] :<C-U>call pymode#motion#move('^\(class\\|def\)\s', '')<CR>
11+
nnoremap <buffer> [[ :<C-U>call pymode#motion#move('^\(class\\|def\)\s', 'b')<CR>
12+
nnoremap <buffer> ]C :<C-U>call pymode#motion#move('^\(class\\|def\)\s', '')<CR>
13+
nnoremap <buffer> [C :<C-U>call pymode#motion#move('^\(class\\|def\)\s', 'b')<CR>
14+
nnoremap <buffer> ]M :<C-U>call pymode#motion#move('^\s*def\s', '')<CR>
15+
nnoremap <buffer> [M :<C-U>call pymode#motion#move('^\s*def\s', 'b')<CR>
16+
17+
onoremap <buffer> ]] :<C-U>call pymode#motion#move('^\(class\\|def\)\s', '')<CR>
18+
onoremap <buffer> [[ :<C-U>call pymode#motion#move('^\(class\\|def\)\s', 'b')<CR>
19+
onoremap <buffer> ]C :<C-U>call pymode#motion#move('^\(class\\|def\)\s', '')<CR>
20+
onoremap <buffer> [C :<C-U>call pymode#motion#move('^\(class\\|def\)\s', 'b')<CR>
21+
onoremap <buffer> ]M :<C-U>call pymode#motion#move('^\s*def\s', '')<CR>
22+
onoremap <buffer> [M :<C-U>call pymode#motion#move('^\s*def\s', 'b')<CR>
23+
24+
vnoremap <buffer> ]] :call pymode#motion#vmove('^\(class\\|def\)\s', '')<CR>
25+
vnoremap <buffer> [[ :call pymode#motion#vmove('^\(class\\|def\)\s', 'b')<CR>
26+
vnoremap <buffer> ]M :call pymode#motion#vmove('^\s*def\s', '')<CR>
27+
vnoremap <buffer> [M :call pymode#motion#vmove('^\s*def\s', 'b')<CR>
2828
2929
onoremap <buffer> C :<C-U>call pymode#motion#select('^\s*class\s', 0)<CR>
3030
onoremap <buffer> aC :<C-U>call pymode#motion#select('^\s*class\s', 0)<CR>

autoload/pymode.vim

Lines changed: 66 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1,12 +1,20 @@
1+
" Python-mode base functions
2+
3+
14
fun! pymode#Default(name, default) "{{{
5+
" DESC: Set default value if it not exists
6+
"
27
if !exists(a:name)
38
let {a:name} = a:default
49
return 0
510
endif
611
return 1
712
endfunction "}}}
813

14+
915
fun! pymode#QuickfixOpen(onlyRecognized, holdCursor, maxHeight, minHeight, jumpError) "{{{
16+
" DESC: Open quickfix window
17+
"
1018
let numErrors = len(filter(getqflist(), 'v:val.valid'))
1119
let numOthers = len(getqflist()) - numErrors
1220
if numErrors > 0 || (!a:onlyRecognized && numOthers > 0)
@@ -30,6 +38,8 @@ endfunction "}}}
3038

3139

3240
fun! pymode#PlaceSigns() "{{{
41+
" DESC: Place error signs
42+
"
3343
sign unplace *
3444
for item in filter(getqflist(), 'v:val.bufnr != ""')
3545
execute printf('silent! sign place 1 line=%d name=%s buffer=%d', item.lnum, item.type, item.bufnr)
@@ -38,6 +48,8 @@ endfunction "}}}
3848

3949

4050
fun! pymode#CheckProgram(name, append) "{{{
51+
" DESC: Check program is executable or redifined by user.
52+
"
4153
let name = 'g:' . a:name
4254
if pymode#Default(name, a:name)
4355
return 1
@@ -49,21 +61,29 @@ fun! pymode#CheckProgram(name, append) "{{{
4961
return 1
5062
endfunction "}}}
5163

64+
5265
fun! pymode#TempBuffer() "{{{
66+
" DESC: Open temp buffer.
67+
"
5368
pclose | botright 8new
5469
setlocal buftype=nofile bufhidden=delete noswapfile nowrap previewwindow
5570
redraw
5671
endfunction "}}}
5772

73+
5874
fun! pymode#ShowStr(str) "{{{
75+
" DESC: Open temp buffer with `str`.
76+
"
5977
call pymode#TempBuffer()
6078
put! =a:str
6179
redraw
62-
normal gg
63-
wincmd p
80+
normal gg | wincmd p
6481
endfunction "}}}
6582

83+
6684
fun! pymode#ShowCommand(cmd) "{{{
85+
" DESC: Run command and open temp buffer with result
86+
"
6787
call pymode#TempBuffer()
6888
try
6989
silent exec 'r!' . a:cmd
@@ -72,16 +92,57 @@ fun! pymode#ShowCommand(cmd) "{{{
7292
echoerr 'Command fail: '.a:cmd
7393
endtry
7494
redraw
75-
normal gg
76-
wincmd p
95+
normal gg | wincmd p
7796
endfunction "}}}
7897

7998

80-
" DESC: Show wide message
8199
fun! pymode#WideMessage(msg) "{{{
100+
" DESC: Show wide message
101+
82102
let x=&ruler | let y=&showcmd
83103
set noruler noshowcmd
84104
redraw
85105
echo strpart(a:msg, 0, &columns-1)
86106
let &ruler=x | let &showcmd=y
87107
endfunction "}}}
108+
109+
110+
fun! pymode#BlockStart(lnum, ...) "{{{
111+
let pattern = a:0 ? a:1 : '^\s*\(@\|class\s.*:\|def\s\)'
112+
let lnum = a:lnum + 1
113+
let indent = 100
114+
while lnum
115+
let lnum = prevnonblank(lnum - 1)
116+
let test = indent(lnum)
117+
let line = getline(lnum)
118+
if line =~ '^\s*#' " Skip comments
119+
continue
120+
elseif !test " Zero-level regular line
121+
return lnum
122+
elseif test >= indent " Skip deeper or equal lines
123+
continue
124+
" Indent is strictly less at this point: check for def/class
125+
elseif line =~ pattern && line !~ '^\s*@'
126+
return lnum
127+
endif
128+
let indent = indent(lnum)
129+
endwhile
130+
return 0
131+
endfunction "}}}
132+
133+
134+
fun! pymode#BlockEnd(lnum, ...) "{{{
135+
let indent = a:0 ? a:1 : indent(a:lnum)
136+
let lnum = a:lnum
137+
while lnum
138+
let lnum = nextnonblank(lnum + 1)
139+
if getline(lnum) =~ '^\s*#' | continue
140+
elseif lnum && indent(lnum) <= indent
141+
return lnum - 1
142+
endif
143+
endwhile
144+
return line('$')
145+
endfunction "}}}
146+
147+
148+
" vim: fdm=marker:fdl=0

autoload/pymode/motion.vim

Lines changed: 34 additions & 38 deletions
Original file line numberDiff line numberDiff line change
@@ -1,40 +1,25 @@
1-
" Check indentation level on motion
2-
" dC dM
3-
4-
fun! pymode#motion#block(lnum) "{{{
5-
let start = indent(a:lnum)
6-
let num = a:lnum
7-
while num
8-
let num = nextnonblank(num + 1)
9-
if num && indent(num) <= start
10-
return num - 1
11-
endif
12-
endwhile
13-
return line('$')
14-
endfunction "}}}
1+
" Python-mode motion functions
152

163

17-
fun! pymode#motion#move2(pattern, flags, ...) "{{{
18-
normal! m'
4+
fun! pymode#motion#move(pattern, flags, ...) "{{{
195
let cnt = v:count1 - 1
20-
let [line, column] = searchpos(a:pattern, a:flags . 'W')
6+
let [line, column] = searchpos(a:pattern, a:flags . 'sW')
217
let indent = indent(line)
22-
23-
while l:cnt && l:line
8+
while cnt && line
249
let [line, column] = searchpos(a:pattern, a:flags . 'W')
25-
if indent(line) == l:indent
26-
let cnt = l:cnt - 1
10+
if indent(line) == indent
11+
let cnt = cnt - 1
2712
endif
2813
endwhile
29-
3014
return [line, column]
31-
3215
endfunction "}}}
3316

3417

35-
fun! pymode#motion#vmove(pattern, flags) "{{{
36-
let end = pymode#motion#move2(a:pattern, a:flags)
37-
normal! gv
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
3823
call cursor(end)
3924
endfunction "}}}
4025

@@ -45,21 +30,32 @@ endfunction "}}}
4530

4631

4732
fun! pymode#motion#select(pattern, inner) "{{{
33+
let cnt = v:count1 - 1
4834
let orig = getpos('.')[1:2]
49-
let start = pymode#motion#move2(a:pattern, 'cb')
50-
let eline = pymode#motion#block(start[0])
51-
let end = [eline, len(getline(eline))]
52-
call cursor(orig)
53-
54-
if pymode#motion#pos_le(start, orig) && pymode#motion#pos_le(orig, end)
35+
let snum = pymode#BlockStart(orig[0], a:pattern)
36+
if getline(snum) !~ a:pattern
37+
return 0
38+
endif
39+
let enum = pymode#BlockEnd(snum, indent(snum))
40+
while cnt
41+
let lnum = search(a:pattern, 'nW')
42+
if lnum
43+
let enum = pymode#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])
5549
if a:inner
56-
let start = [start[0] + 1, start[1]]
57-
let eline = prevnonblank(end[0])
58-
let end = [eline, len(getline(eline))]
50+
let snum = snum + 1
51+
let enum = prevnonblank(enum)
5952
endif
53+
54+
call cursor(snum, 1)
6055
normal! v
61-
call cursor(start)
62-
normal! o
63-
call cursor(end)
56+
call cursor(enum, len(getline(enum)))
6457
endif
6558
endfunction "}}}
59+
60+
61+
" vim: fdm=marker:fdl=0

0 commit comments

Comments
 (0)