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