1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
|
" Falling motions for Vim. "Falling" means moving the cursor down until it hits
" text that doesn't match a pattern.
" Returns an expression to be used in normal mode that results in the falling
" motion. The semantics are as follows:
"
" The motion moves in the direction given by a:dir (which must be 'j' or 'k').
" The motion moves while the character under the cursor does not match the
" pattern, then it moves while the character under the cursor matches the
" pattern stopping when the character under the cursor does not match the
" pattern once again.
"
" ex.
"
" fall#fall('j', '^\s*$')
"
" for
"
" | t⌷is is some text
" | this is some other text
" |
" |
" | this is some bottom text
" | this is some other bottom text
"
" will return an expression to update the cursor position to:
"
" | this is some text
" | this is some other text
" |
" |
" | t⌷is is some bottom text
" | this is some other bottom text
"
" This works pretty well for navigating around languages that use indentation
" and lack braces for bodies, i.e. vimscript, ruby. Less well for python, but
" still okay.
function! fall#fall(dir, pattern) abort
let i = 0
let n = 0
if a:dir == 'j'
let delta = 1
else
let delta = -1
endif
let line = line('.')
let column = col('.')
let c = v:count
if c == 0
let c = 1
endif
while i < c
let match = matchstr(getline(line), '\%' . column . 'c.')
while ! (match =~ a:pattern)
let n += 1
let line += delta
if line <= 0 || line >= line('$')
return "m'" . n . a:dir
endif
let match = matchstr(getline(line), '\%' . column . 'c.')
endwhile
while (match =~ a:pattern)
let n += 1
let line += delta
if line <= 0 || line >= line('$')
return "m'" . n . a:dir
endif
let match = matchstr(getline(line), '\%' . column . 'c.')
endwhile
let i += 1
endwhile
return "m'" . n . a:dir
endfunction
function! fall#visual_same_character(dir)
let start_line = line(".")
let line = start_line
let column = col(".")
let char_to_match = matchstr(getline(line), '\%' . column . 'c.')
let expr = ""
if a:dir =~ 'k'
while line > 1
let line -= 1
if matchstr(getline(line), '\%' . column . 'c.') != char_to_match
break
endif
let expr .= 'k'
endwhile
endif
if a:dir == 'jk'
let expr .= 'o'
let line = start_line
endif
if a:dir =~ 'j'
while line <= line("$")
let line += 1
if matchstr(getline(line), '\%' . column . 'c.') != char_to_match
break
endif
let expr .= 'j'
endwhile
endif
return expr
endfunction
|