]> git.lizzy.rs Git - micro.git/blob - runtime/plugins/autoclose/autoclose.lua
Merge pull request #1412 from tommyshem/batSyntaxHighlighting
[micro.git] / runtime / plugins / autoclose / autoclose.lua
1 local uutil = import("micro/util")
2 local utf8 = import("utf8")
3 local autoclosePairs = {"\"\"", "''", "``", "()", "{}", "[]"}
4 local autoNewlinePairs = {"()", "{}", "[]"}
5
6 function charAt(str, i)
7     -- lua indexing is one off from go
8     return uutil.RuneAt(str, i-1)
9 end
10
11 function onRune(bp, r)
12     for i = 1, #autoclosePairs do
13         if r == charAt(autoclosePairs[i], 2) then
14             local curLine = bp.Buf:Line(bp.Cursor.Y)
15
16             if charAt(curLine, bp.Cursor.X+1) == charAt(autoclosePairs[i], 2) then
17                 bp:Backspace()
18                 bp:CursorRight()
19                 break
20             end
21
22             if bp.Cursor.X > 1 and (uutil.IsWordChar(charAt(curLine, bp.Cursor.X-1)) or charAt(curLine, bp.Cursor.X-1) == charAt(autoclosePairs[i], 1)) then
23                 break
24             end
25         end
26         if r == charAt(autoclosePairs[i], 1) then
27             local curLine = bp.Buf:Line(bp.Cursor.Y)
28
29             if bp.Cursor.X == utf8.RuneCountInString(curLine) or not uutil.IsWordChar(charAt(curLine, bp.Cursor.X+1)) then
30                 -- the '-' here is to derefence the pointer to bp.Cursor.Loc which is automatically made
31                 -- when converting go structs to lua
32                 -- It needs to be dereferenced because the function expects a non pointer struct
33                 bp.Buf:Insert(-bp.Cursor.Loc, charAt(autoclosePairs[i], 2))
34                 bp:CursorLeft()
35                 break
36             end
37         end
38     end
39     return true
40 end
41
42 function preInsertNewline(bp)
43     local curLine = bp.Buf:Line(bp.Cursor.Y)
44     local curRune = charAt(curLine, bp.Cursor.X)
45     local nextRune = charAt(curLine, bp.Cursor.X+1)
46     local ws = uutil.GetLeadingWhitespace(curLine)
47
48     for i = 1, #autoNewlinePairs do
49         if curRune == charAt(autoNewlinePairs[i], 1) then
50             if nextRune == charAt(autoNewlinePairs[i], 2) then
51                 bp:InsertNewline()
52                 bp:InsertTab()
53                 bp.Buf:Insert(-bp.Cursor.Loc, "\n" .. ws)
54                 bp:StartOfLine()
55                 bp:CursorLeft()
56                 return false
57             end
58         end
59     end
60
61     return true
62 end
63
64 function preBackspace(bp)
65     for i = 1, #autoclosePairs do
66         local curLine = bp.Buf:Line(bp.Cursor.Y)
67         if charAt(curLine, bp.Cursor.X+1) == charAt(autoclosePairs[i], 2) and charAt(curLine, bp.Cursor.X) == charAt(autoclosePairs[i], 1) then
68             bp:Delete()
69         end
70     end
71
72     return true
73 end