]> git.lizzy.rs Git - micro.git/blob - runtime/plugins/autoclose/autoclose.lua
Fix issue with autoclose plugin
[micro.git] / runtime / plugins / autoclose / autoclose.lua
1 function charAt(str, i)
2     return string.sub(str, i, i)
3 end
4
5 if GetOption("autoclose") == nil then
6     AddOption("autoclose", true)
7 end
8
9 local autoclosePairs = {"\"\"", "''", "()", "{}", "[]"}
10 local autoNewlinePairs = {"()", "{}", "[]"}
11
12 function onRune(r)
13     if not GetOption("autoclose") then
14         return
15     end
16
17     local v = CurView()
18     for i = 1, #autoclosePairs do
19         if r == charAt(autoclosePairs[i], 2) then
20             local curLine = v.Buf:Line(v.Cursor.Y)
21
22             if charAt(curLine, v.Cursor.X+1) == charAt(autoclosePairs[i], 2) then
23                 v:Backspace()
24                 v:CursorRight()
25                 break
26             end
27
28             if v.Cursor.X > 1 and (IsWordChar(charAt(curLine, v.Cursor.X-1)) or charAt(curLine, v.Cursor.X-1) == charAt(autoclosePairs[i], 1)) then
29                 break
30             end
31         end
32         if r == charAt(autoclosePairs[i], 1) then
33             local curLine = v.Buf:Line(v.Cursor.Y)
34
35             if v.Cursor.X == #curLine or not IsWordChar(charAt(curLine, v.Cursor.X+1)) then
36                 -- the '-' here is to derefence the pointer to v.Cursor.Loc which is automatically made
37                 -- when converting go structs to lua
38                 -- It needs to be dereferenced because the function expects a non pointer struct
39                 v.Buf:Insert(-v.Cursor.Loc, charAt(autoclosePairs[i], 2))
40                 break
41             end
42         end
43     end
44 end
45
46 function onInsertEnter()
47     if not GetOption("autoclose") then
48         return
49     end
50
51     local v = CurView()
52     local curLine = v.Buf:Line(v.Cursor.Y)
53     local lastLine = v.Buf:Line(v.Cursor.Y-1)
54     local curRune = charAt(lastLine, #lastLine)
55     local nextRune = charAt(curLine, 1)
56
57     for i = 1, #autoNewlinePairs do
58         if curRune == charAt(autoNewlinePairs[i], 1) then
59             if nextRune == charAt(autoNewlinePairs[i], 2) then
60                 v:InsertTab()
61                 v.Buf:Insert(-v.Cursor.Loc, "\n")
62             end
63         end
64     end
65 end
66
67 function onBackspace()
68     if not GetOption("autoclose") then
69         return
70     end
71
72     local v = CurView()
73
74     for i = 1, #autoclosePairs do
75         local curLine = v.Buf:Line(v.Cursor.Y)
76         if charAt(curLine, v.Cursor.X+1) == charAt(autoclosePairs[i], 2) then
77             v:Delete()
78         end
79     end
80 end