-
Notifications
You must be signed in to change notification settings - Fork 10
/
autoclose.lua
177 lines (151 loc) · 4.7 KB
/
autoclose.lua
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
167
168
169
170
171
172
173
174
175
176
177
local autoclose = {}
local config = {
keys = {
["("] = { escape = false, close = true, pair = "()" },
["["] = { escape = false, close = true, pair = "[]" },
["{"] = { escape = false, close = true, pair = "{}" },
[">"] = { escape = true, close = false, pair = "<>" },
[")"] = { escape = true, close = false, pair = "()" },
["]"] = { escape = true, close = false, pair = "[]" },
["}"] = { escape = true, close = false, pair = "{}" },
['"'] = { escape = true, close = true, pair = '""' },
["'"] = { escape = true, close = true, pair = "''" },
["`"] = { escape = true, close = true, pair = "``" },
[" "] = { escape = false, close = true, pair = " " },
["<BS>"] = {},
["<C-H>"] = {},
["<C-W>"] = {},
["<CR>"] = { disable_command_mode = true },
["<S-CR>"] = { disable_command_mode = true },
},
options = {
disabled_filetypes = { "text" },
disable_when_touch = false,
touch_regex = "[%w(%[{]",
pair_spaces = false,
auto_indent = true,
disable_command_mode = false,
},
disabled = false,
}
local function insert_get_pair()
-- add "_" to let close function work in the first col
local line = "_" .. vim.api.nvim_get_current_line()
local col = vim.api.nvim_win_get_cursor(0)[2] + 1
return line:sub(col, col + 1)
end
local function command_get_pair()
-- add "_" to let close function work in the first col
local line = "_" .. vim.fn.getcmdline()
local col = vim.fn.getcmdpos()
return line:sub(col, col + 1)
end
local function is_pair(pair)
if pair == " " then
return false
end
for _, info in pairs(config.keys) do
if pair == info.pair then
return true
end
end
return false
end
local function is_disabled(info)
if config.disabled then
return true
end
local current_filetype = vim.api.nvim_buf_get_option(0, "filetype")
for _, filetype in pairs(config.options.disabled_filetypes) do
if filetype == current_filetype then
return true
end
end
if info["enabled_filetypes"] ~= nil then
for _, filetype in pairs(info.enabled_filetypes) do
if filetype == current_filetype then
return false
end
end
return true
end
-- Let's check if the disabled_filetypes key is in the info table
if info["disabled_filetypes"] ~= nil then
for _, filetype in pairs(info.disabled_filetypes) do
if filetype == current_filetype then
return true
end
end
end
return false
end
local function handler(key, info, mode)
if is_disabled(info) then
return key
end
local pair = mode == "insert" and insert_get_pair() or command_get_pair()
if (key == "<BS>" or key == "<C-H>" or key == "<C-W>") and is_pair(pair) then
return "<BS><Del>"
elseif
mode == "insert"
and (key == "<CR>" or key == "<S-CR>")
and is_pair(pair)
then
return "<CR><ESC>O" .. (config.options.auto_indent and "" or "<C-D>")
elseif info.escape and pair:sub(2, 2) == key then
return mode == "insert" and "<C-G>U<Right>" or "<Right>"
elseif info.close then
-- disable if the cursor touches alphanumeric character
if
config.options.disable_when_touch
and (pair .. "_"):sub(2, 2):match(config.options.touch_regex)
then
return key
end
-- don't pair spaces
if
key == " "
and (
not config.options.pair_spaces
or (config.options.pair_spaces and not is_pair(pair))
or pair:sub(1, 1) == pair:sub(2, 2)
)
then
return key
end
return info.pair .. (mode == "insert" and "<C-G>U<Left>" or "<Left>")
else
return key
end
end
function autoclose.setup(user_config)
user_config = user_config or {}
if user_config.keys ~= nil then
for key, info in pairs(user_config.keys) do
config.keys[key] = info
end
end
if user_config.options ~= nil then
for key, info in pairs(user_config.options) do
config.options[key] = info
end
end
for key, info in pairs(config.keys) do
vim.keymap.set("i", key, function()
return (key == " " and "<C-]>" or "") .. handler(key, info, "insert")
end, { noremap = true, expr = true })
if
not config.options.disable_command_mode
and not info.disable_command_mode
then
vim.keymap.set("c", key, function()
return (key == " " and "<C-]>" or "")
.. handler(key, info, "command")
end, { noremap = true, expr = true })
end
end
end
function autoclose.toggle()
config.disabled = not config.disabled
end
return autoclose