-
Notifications
You must be signed in to change notification settings - Fork 2
/
Copy pathauto-pairs.kak
166 lines (140 loc) · 6.43 KB
/
auto-pairs.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
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
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
# Auto-pairing of characters
# Heavily based on Visual Studio Code.
# https://code.visualstudio.com
#
# Usage:
#
# enable-auto-pairs
#
# Configuration:
#
# set-option global auto_pairs ( ) { } [ ] '"' '"' "'" "'" ` ` “ ” ‘ ’ « » ‹ ›
#
# How does it work?
#
# The script installs insert hooks on opening pair characters, such as brackets and quotes.
# When auto-closing has been triggered, it activates the following functionalities:
#
# – {closing-pair} ⇒ Insert character or move right in pair
# – Enter ⇒ Insert a new indented line in pair (only for the next key)
#
# When moving or leaving insert mode, the functionalities deactivate.
#
# Technical details:
#
# – Insert hooks are added on opening pair characters from %opt{auto_pairs} option.
# – Evaluates %opt{auto_close_trigger} option to activate auto-pairing.
# – Provides %opt{opening_pair} expansion in expressions.
# Configuration ────────────────────────────────────────────────────────────────
# List of surrounding pairs
declare-option -docstring 'list of surrounding pairs' str-list auto_pairs ( ) { } [ ] '"' '"' "'" "'" ` ` “ ” ‘ ’ « » ‹ ›
# Auto-pairing of characters activates only when this expression does not fail.
# By default, it avoids non-nestable pairs (such as quotes), escaped pairs and word characters.
declare-option -docstring 'auto-pairing of characters activates only when this expression does not fail' str auto_close_trigger %{
execute-keys '<a-h>'
execute-keys '<a-K>(\w["''`]|""|''''|``).\z<ret>'
set-register / "[^\\]?\Q%opt{opening_pair}\E\W\z"
execute-keys '<a-k><ret>'
}
# Internal variables ┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈
declare-option -hidden str opening_pair
declare-option -hidden int inserted_pairs
# Retain inserted pairs
remove-hooks global clean-auto-pairs-state
hook -group clean-auto-pairs-state global WinSetOption 'inserted_pairs=0' %{
unmap window insert
remove-hooks window auto-pairs
}
# Commands ─────────────────────────────────────────────────────────────────────
define-command -override enable-auto-pairs -docstring 'enable auto-pairs' %{
remove-hooks global auto-pairs
evaluate-commands %sh{
set -- ${kak_opt_auto_pairs}
while [ "$2" ]
do
printf 'auto-close-pair %%<%s> %%<%s>\n' "$1" "$2"
shift 2
done
}
}
define-command -override disable-auto-pairs -docstring 'disable auto-pairs' %{
remove-hooks global auto-pairs
}
# Internal commands ┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈
define-command -override -hidden auto-close-pair -params 2 %{
hook -group auto-pairs global InsertChar "\Q%arg{1}" "handle-inserted-opening-pair %%<%arg{1}> %%<%arg{2}>"
hook -group auto-pairs global InsertDelete "\Q%arg{1}" "handle-deleted-opening-pair %%<%arg{1}> %%<%arg{2}>"
}
# Internal hooks ┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈
define-command -override -hidden handle-inserted-opening-pair -params 2 %{
try %{
# Test whether the commands contained in the option pass.
# If not, it will throw an exception and execution will jump to
# the “catch” block below.
set-option window opening_pair %arg{1}
evaluate-commands -draft -save-regs '/' %opt{auto_close_trigger}
# Action: Close pair
execute-keys %arg{2}
# Move back in pair (preserve selected text):
try %{
execute-keys -draft '<a-k>..<ret>'
execute-keys '<a-;>H'
} catch %{
execute-keys '<a-;>h'
}
# Add insert mappings
map -docstring 'insert character or move right in pair' window insert %arg{2} "<a-;>:auto-pairs-insert-character %%🐈%arg{2}🐈<ret>"
map -docstring 'insert a new indented line in pair' window insert <ret> '<a-;>:auto-pairs-insert-new-line<ret>'
# Keep the track of inserted pairs
increment-inserted-pairs-count
# Clean state when moving or leaving insert mode
# Enter is only available on next key.
hook -group auto-pairs -once window InsertMove '.*' %{
reset-inserted-pairs-count
}
hook -group auto-pairs -once window InsertChar '.*' %{
unmap window insert <ret>
}
hook -always -once window ModeChange 'pop:insert:normal' %{
reset-inserted-pairs-count
}
}
}
# Backspace ⇒ Erases the whole bracket
define-command -override -hidden handle-deleted-opening-pair -params 2 %{
try %{
execute-keys -draft "<space>;<a-k>\Q%arg{2}<ret>"
execute-keys '<del>'
decrement-inserted-pairs-count
}
}
# Internal mappings ┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈
# {closing-pair} ⇒ Insert character or move right in pair
define-command -override -hidden auto-pairs-insert-character -params 1 %{
try %{
execute-keys -draft "<space>;<a-k>\Q%arg{1}<ret>"
# Move right in pair
execute-keys '<a-;>l'
decrement-inserted-pairs-count
} catch %{
# Insert character with hooks
execute-keys -with-hooks %arg{1}
}
}
# Enter ⇒ Insert a new indented line in pair (only for the next key)
define-command -override -hidden auto-pairs-insert-new-line %{
execute-keys '<esc>;i<ret><ret><esc>KK<a-&>j<a-gt>'
execute-keys -with-hooks A
reset-inserted-pairs-count
}
# ┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈
# Increment and decrement inserted pairs count
define-command -override -hidden increment-inserted-pairs-count %{
set-option -add window inserted_pairs 1
}
define-command -override -hidden decrement-inserted-pairs-count %{
set-option -remove window inserted_pairs 1
}
define-command -override -hidden reset-inserted-pairs-count %{
set-option window inserted_pairs 0
}