-
Notifications
You must be signed in to change notification settings - Fork 2
/
Copy pathvertical-selection.kak
82 lines (75 loc) · 2.61 KB
/
vertical-selection.kak
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
provide-module vertical-selection %{
# copy the current selection upwards/downwards to all lines matching the current selection
define-command vertical-selection-up -docstring "
Select matching pattern from the lines above
" %{
eval -itersel %{
try %{
# throw if we're at the top of the buffer
exec -draft "gh<a-C><a-,>"
exec "<a-:><a-;>"
vertical-selection-impl "<a-?>" "\n"
exec "<a-:>"
}
}
exec 'Zz' # needed in order not to stack up overlapping selections
}
define-command vertical-selection-down -docstring "
Select matching pattern from the lines below
" %{
eval -itersel %{
try %{
# throw if we're at the bottom of the buffer
exec -draft "ghC<a-,>"
exec "<a-:>"
vertical-selection-impl "?" "^."
}
}
exec 'Zz'
}
define-command vertical-selection-up-and-down -docstring "
Select matching pattern from the lines above and below
" %{
eval -save-regs '^' %{
eval -save-regs '' -draft %{
vertical-selection-up
exec -save-regs '' Z
}
vertical-selection-down
exec <a-z>a
# silence the register message, it's an implementation detail
echo
}
}
define-command -hidden vertical-selection-impl -params 2 %{
eval -save-regs 'sp/"' %{
# %reg{p} contains the regex to select all lines that potentially match the current
# %reg{s} contains the regex to subselect the current pattern from that selection
exec '"p<a-*>'
try %{
exec "<a-K>^<ret>"
# pattern is not at the beginning of the line
eval -draft %{
# select every character on the same line before the pattern
exec "<a-:><a-;>;hGh<ret>"
# and require N chars to precede the pattern we're searching for
# or lines that have fewer than N chars
reg s "^.{%val{selection_length}}(%reg{p})"
reg p "(?:^(?:.{%val{selection_length}}%reg{p}.*|.{,%reg{#}})\n)+"
}
} catch %{
reg s "^(%reg{p})"
# empty lines are accepted too
reg p "^(?:%reg{p}[^\n]*\n|\n)+"
}
# extend (resp. reverse extend) to all lines that match the pattern (or are short enough)
# or stop if the next (resp. previous) line is not a candidate
reg / "(?S)(?:%reg{p}|%arg{2})"
exec "%arg{1}<ret>x"
# and select the pattern back from this selection
reg / "(?S)%reg{s}"
exec '<a-s>1s<ret>'
}
}
}
require-module vertical-selection