]> git.lizzy.rs Git - micro.git/blob - runtime/plugins/autoclose/autoclose.lua
Fix minor issue with autoclose
[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(false)
24                 v:CursorRight(false)
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 preInsertNewline()
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 curRune = charAt(curLine, v.Cursor.X)
54     local nextRune = charAt(curLine, v.Cursor.X+1)
55     local ws = GetLeadingWhitespace(curLine)
56     messenger:Message(curRune, " ", nextRune)
57
58     for i = 1, #autoNewlinePairs do
59         if curRune == charAt(autoNewlinePairs[i], 1) then
60             if nextRune == charAt(autoNewlinePairs[i], 2) then
61                 v:InsertNewline(false)
62                 v:InsertTab(false)
63                 v.Buf:Insert(-v.Cursor.Loc, "\n" .. ws)
64                 return false
65             end
66         end
67     end
68
69     return true
70 end
71
72 function preBackspace()
73     if not GetOption("autoclose") then
74         return
75     end
76
77     local v = CurView()
78
79     for i = 1, #autoclosePairs do
80         local curLine = v.Buf:Line(v.Cursor.Y)
81         if charAt(curLine, v.Cursor.X+1) == charAt(autoclosePairs[i], 2) and charAt(curLine, v.Cursor.X) == charAt(autoclosePairs[i], 1) then
82             v:Delete(false)
83         end
84     end
85
86     return true
87 end