2
2
3
3
# Show where the matching open paren is when inserting a closing one. Disabling
4
4
# as it hijacks the `)`, `]` and `}` characters to enable blinking.
5
- bind " set blink-matching-paren on "
5
+ bind " set blink-matching-paren off "
6
6
7
7
function __autopair() {
8
8
local typed_char=" $1 "
@@ -11,33 +11,41 @@ function __autopair() {
11
11
local cursor_char=" ${READLINE_LINE: READLINE_POINT: 1} "
12
12
local previous_char=" ${READLINE_LINE: READLINE_POINT-1: 1} "
13
13
local next_char=" ${READLINE_LINE: READLINE_POINT+1: 1} "
14
- local num_of_char
15
14
16
- local s
17
- s=" ${READLINE_LINE:: READLINE_POINT} "
15
+ local s=" ${READLINE_LINE:: READLINE_POINT} "
18
16
17
+ # escaped character
19
18
if [[ " $previous_char " == " \\ " ]]; then
20
19
s+=" $typed_char "
20
+
21
+ # ''""``
21
22
elif [[ " $opening_char " == " $closing_char " ]]; then
22
- num_of_char=" ${READLINE_LINE// \\ $typed_char / } "
23
+ local num_of_char=" ${READLINE_LINE// \\ $typed_char / } "
23
24
num_of_char=" ${num_of_char// [^$typed_char]/ } "
24
25
num_of_char=" ${# num_of_char} "
25
26
26
27
if [[ " $(( num_of_char % 2 )) " -eq 1 ]]; then
27
28
s+=" $typed_char "
28
- elif [[ " $cursor_char " == " $closing_char " ]]; then
29
- :
30
- elif [[ " $(( num_of_char % 2 )) " -eq 0 ]]; then
29
+ else
31
30
s+=" $typed_char$typed_char "
32
31
fi
32
+
33
+ # [{(
33
34
elif [[ " $typed_char " == " $opening_char " ]]; then
35
+ # TODO check right part string for balance
34
36
s+=" $opening_char$closing_char "
37
+
38
+ # [ | ]{ | }( | ) and pressing ]})
35
39
elif [[ " $typed_char " == " $closing_char " && " $cursor_char " == " " &&
36
40
" $next_char " == " $closing_char " ]]; then
37
41
s+=' '
38
42
(( READLINE_POINT++ ))
43
+
44
+ # ]}): cursor is already on closing char
39
45
elif [[ " $cursor_char " == " $closing_char " ]]; then
46
+ # TODO check left and right string parts for balance
40
47
:
48
+ # ]})
41
49
else
42
50
s+=" $typed_char "
43
51
fi
@@ -56,28 +64,25 @@ function __autopair_space() {
56
64
local next_char=" ${READLINE_LINE: READLINE_POINT+1: 1} "
57
65
local num_of_char
58
66
59
- local s
60
- s=" ${READLINE_LINE:: READLINE_POINT} "
67
+ local s=" ${READLINE_LINE:: READLINE_POINT} "
61
68
62
- # https://unix.stackexchange.com/questions/213799#answer-213821
63
69
# The user pressed space, so we want to print at least one space no matter
64
70
# what. If magic-space is enabled on the space bar, send a magic space. If
65
71
# not, send a regular space.
66
72
if [[ " $magic_space_enabled_on_space " -eq 1 ]]; then
73
+ # https://unix.stackexchange.com/questions/213799#answer-213821
67
74
bind ' "\e[0n": magic-space' && printf ' \e[5n'
68
75
else
69
76
s+=' '
70
77
(( READLINE_POINT++ ))
71
78
fi
72
79
73
- local autopair_operated=false
74
- for pair in " ${__pairs[@]: 2} " ; do
80
+ for pair in " ${__pairs[@]: 3} " ; do
75
81
local opening_char=" ${pair: 0: 1} "
76
82
local closing_char=" ${pair: 1: 1} "
77
83
78
84
if [[ " $previous_char " == " $opening_char " && " $cursor_char " == " $closing_char " ]]; then
79
85
s+=" "
80
- autopair_operated=true
81
86
break
82
87
fi
83
88
done
@@ -88,64 +93,54 @@ function __autopair_space() {
88
93
}
89
94
90
95
function __autopair_remove() {
91
- local previous_char=" ${READLINE_LINE: READLINE_POINT-1: 1} "
92
- local cursor_char=" ${READLINE_LINE: READLINE_POINT: 1} "
93
-
96
+ # empty line or backspace at the start of line
94
97
if [[ " ${# READLINE_LINE} " -eq 0 || " $READLINE_POINT " -eq 0 ]]; then
95
98
return
96
99
fi
97
100
98
- local s
99
- s=" ${READLINE_LINE:: READLINE_POINT-1} "
100
-
101
- local autopair_operated=false
101
+ local s=" ${READLINE_LINE:: READLINE_POINT-1} "
102
+ local previous_char=" ${READLINE_LINE: READLINE_POINT-1: 1} "
103
+ local cursor_char=" ${READLINE_LINE: READLINE_POINT: 1} "
102
104
local pair
105
+ local offset=0
106
+ local loop_index=0
107
+ local num_of_char
103
108
104
- # double space in ()[]{}
105
- for pair in " ${__pairs[@]: 2} " ; do
109
+ for pair in " ${__pairs[@]} " ; do
106
110
local minus_2_char=" ${READLINE_LINE: READLINE_POINT-2: 1} "
107
111
local next_char=" ${READLINE_LINE: READLINE_POINT+1: 1} "
108
112
113
+ # ()[]{}: delete first space in double space (e.g. {A|B}, delete space "A")
109
114
if [[ " $previous_char " == ' ' ]] \
110
115
&& [[ " $cursor_char " == ' ' ]] \
111
116
&& [[ " $minus_2_char " == " ${pair: 0: 1} " ]] \
112
117
&& [[ " $next_char " == " ${pair: 1: 1} " ]]; then
113
- s+=" ${READLINE_LINE: READLINE_POINT+1} "
114
- autopair_operated=true
115
- fi
116
- done
117
-
118
- # ()[]{}
119
- for pair in " ${__pairs[@]: 2} " ; do
120
- if [[ " $previous_char " == " ${pair: 0: 1} " ]] \
121
- && [[ " $cursor_char " == " ${pair: 1: 1} " ]]; then
122
-
123
- s+=" ${READLINE_LINE: READLINE_POINT+1} "
124
- autopair_operated=true
118
+ offset=1
125
119
break
126
- fi
127
- done
128
120
129
- # ""''
130
- for pair in " ${__pairs[@]: 0: 2} " ; do
131
- if [[ " $previous_char " == " ${pair: 0: 1} " ]] \
121
+ # all pairs: delete the opening
122
+ elif [[ " $previous_char " == " ${pair: 0: 1} " ]] \
132
123
&& [[ " $cursor_char " == " ${pair: 1: 1} " ]]; then
133
124
134
- num_of_char=" ${READLINE_LINE// [^${pair:0:1}]/ } "
135
- num_of_char=" ${# num_of_char} "
125
+ # ''""``: delete results in balanced pairs on line
126
+ if [[ " $loop_index " -lt 3 ]]; then
127
+ num_of_char=" ${READLINE_LINE// [^${pair:0:1}]/ } "
128
+ num_of_char=" ${# num_of_char} "
136
129
137
- if [[ " $(( num_of_char % 2 )) " -eq 1 ]]; then
138
- break
130
+ if [[ " $(( num_of_char % 2 )) " -eq 1 ]]; then
131
+ break
132
+ fi
139
133
fi
140
134
141
- s+=" ${READLINE_LINE: READLINE_POINT+1} "
142
- autopair_operated=true
135
+ # all pairs: delete whole pair
136
+ offset=1
137
+ break
143
138
fi
139
+
140
+ (( index++ ))
144
141
done
145
142
146
- if [[ " $autopair_operated " == ' false' ]]; then
147
- s+=" ${READLINE_LINE: READLINE_POINT} "
148
- fi
143
+ s+=" ${READLINE_LINE: READLINE_POINT+$offset } "
149
144
150
145
READLINE_LINE=" $s "
151
146
@@ -161,7 +156,10 @@ __pairs=(
161
156
' {}'
162
157
)
163
158
164
- for pair in " ${__pairs[@]} " ; do
159
+ for pair in " ${__pairs[@]: 1: 3} " ; do
160
+ bind -x " \" ${pair: 0: 1} \" : __autopair \\ ${pair: 0: 1} \\ ${pair: 0: 1} \\ ${pair: 1: 1} "
161
+ done
162
+ for pair in " ${__pairs[@]: 3} " ; do
165
163
bind -x " \" ${pair: 0: 1} \" : __autopair \\ ${pair: 0: 1} \\ ${pair: 0: 1} \\ ${pair: 1: 1} "
166
164
bind -x " \" ${pair: 1: 1} \" : __autopair \\ ${pair: 1: 1} \\ ${pair: 0: 1} \\ ${pair: 1: 1} "
167
165
done
0 commit comments