]> git.lizzy.rs Git - micro.git/blob - runtime/plugins/comment/comment.lua
Slight performance improvement
[micro.git] / runtime / plugins / comment / comment.lua
1 VERSION = "1.0.0"
2
3 local util = import("micro/util")
4 local config = import("micro/config")
5 local buffer = import("micro/buffer")
6
7 local ft = {}
8
9 ft["apacheconf"] = "# %s"
10 ft["bat"] = ":: %s"
11 ft["c"] = "// %s"
12 ft["c++"] = "// %s"
13 ft["cmake"] = "# %s"
14 ft["conf"] = "# %s"
15 ft["crystal"] = "# %s"
16 ft["css"] = "/* %s */"
17 ft["d"] = "// %s"
18 ft["dart"] = "// %s"
19 ft["dockerfile"] = "# %s"
20 ft["elm"] = "-- %s"
21 ft["fish"] = "# %s"
22 ft["gdscript"] = "# %s"
23 ft["glsl"] = "// %s"
24 ft["go"] = "// %s"
25 ft["haskell"] = "-- %s"
26 ft["html"] = "<!-- %s -->"
27 ft["ini"] = "; %s"
28 ft["java"] = "// %s"
29 ft["javascript"] = "// %s"
30 ft["jinja2"] = "{# %s #}"
31 ft["julia"] = "# %s"
32 ft["kotlin"] = "// %s"
33 ft["lua"] = "-- %s"
34 ft["markdown"] = "<!-- %s -->"
35 ft["nginx"] = "# %s"
36 ft["nim"] = "# %s"
37 ft["objc"] = "// %s"
38 ft["pascal"] = "{ %s }"
39 ft["perl"] = "# %s"
40 ft["php"] = "// %s"
41 ft["pony"] = "// %s"
42 ft["powershell"] = "# %s"
43 ft["proto"] = "// %s"
44 ft["python"] = "# %s"
45 ft["python3"] = "# %s"
46 ft["ruby"] = "# %s"
47 ft["rust"] = "// %s"
48 ft["scala"] = "// %s"
49 ft["shell"] = "# %s"
50 ft["sql"] = "-- %s"
51 ft["swift"] = "// %s"
52 ft["tex"] = "% %s"
53 ft["toml"] = "# %s"
54 ft["twig"] = "{# %s #}"
55 ft["v"] = "// %s"
56 ft["xml"] = "<!-- %s -->"
57 ft["yaml"] = "# %s"
58 ft["zig"] = "// %s"
59 ft["zscript"] = "// %s"
60 ft["zsh"] = "# %s"
61
62 function onBufferOpen(buf)
63     if buf.Settings["commenttype"] == nil then
64         if ft[buf.Settings["filetype"]] ~= nil then
65             buf.Settings["commenttype"] = ft[buf.Settings["filetype"]]
66         else
67             buf.Settings["commenttype"] = "# %s"
68         end
69     end
70 end
71
72 function isCommented(bp, lineN, commentRegex)
73     local line = bp.Buf:Line(lineN)
74     if string.match(line, commentRegex) then
75         return true
76     end
77     return false
78 end
79
80 function commentLine(bp, lineN)
81     local line = bp.Buf:Line(lineN)
82     local commentType = bp.Buf.Settings["commenttype"]
83     local sel = -bp.Cursor.CurSelection
84     local curpos = -bp.Cursor.Loc
85     local index = string.find(commentType, "%%s") - 1
86     local commentedLine = commentType:gsub("%%s", trim(line))
87     bp.Buf:Replace(buffer.Loc(0, lineN), buffer.Loc(#line, lineN), util.GetLeadingWhitespace(line) .. commentedLine)
88     if bp.Cursor:HasSelection() then
89         bp.Cursor.CurSelection[1].Y = sel[1].Y
90         bp.Cursor.CurSelection[2].Y = sel[2].Y
91         bp.Cursor.CurSelection[1].X = sel[1].X
92         bp.Cursor.CurSelection[2].X = sel[2].X
93     else
94         bp.Cursor.X = curpos.X + index
95         bp.Cursor.Y = curpos.Y
96     end
97     bp.Cursor:Relocate()
98     bp.Cursor.LastVisualX = bp.Cursor:GetVisualX()
99 end
100
101 function uncommentLine(bp, lineN, commentRegex)
102     local line = bp.Buf:Line(lineN)
103     local commentType = bp.Buf.Settings["commenttype"]
104     local sel = -bp.Cursor.CurSelection
105     local curpos = -bp.Cursor.Loc
106     local index = string.find(commentType, "%%s") - 1
107     if string.match(line, commentRegex) then
108         uncommentedLine = string.match(line, commentRegex)
109         bp.Buf:Replace(buffer.Loc(0, lineN), buffer.Loc(#line, lineN), util.GetLeadingWhitespace(line) .. uncommentedLine)
110         if bp.Cursor:HasSelection() then
111             bp.Cursor.CurSelection[1].Y = sel[1].Y
112             bp.Cursor.CurSelection[2].Y = sel[2].Y
113             bp.Cursor.CurSelection[1].X = sel[1].X
114             bp.Cursor.CurSelection[2].X = sel[2].X
115         else
116             bp.Cursor.X = curpos.X - index
117             bp.Cursor.Y = curpos.Y
118         end
119     end
120     bp.Cursor:Relocate()
121     bp.Cursor.LastVisualX = bp.Cursor:GetVisualX()
122 end
123
124 function toggleCommentLine(bp, lineN, commentRegex)
125     if isCommented(bp, lineN, commentRegex) then
126         uncommentLine(bp, lineN, commentRegex)
127     else
128         commentLine(bp, lineN)
129     end
130 end
131
132 function toggleCommentSelection(bp, startLine, endLine, commentRegex)
133     local allComments = true
134     for line = startLine, endLine do
135         if not isCommented(bp, line, commentRegex) then
136             allComments = false
137             break
138         end
139     end
140
141     for line = startLine, endLine do
142         if allComments then
143             uncommentLine(bp, line, commentRegex)
144         else
145             commentLine(bp, line)
146         end
147     end
148 end
149
150 function comment(bp, args)
151     local commentType = bp.Buf.Settings["commenttype"]
152     local commentRegex = "^%s*" .. commentType:gsub("%%","%%%%"):gsub("%$","%$"):gsub("%)","%)"):gsub("%(","%("):gsub("%?","%?"):gsub("%*", "%*"):gsub("%-", "%-"):gsub("%.", "%."):gsub("%+", "%+"):gsub("%]", "%]"):gsub("%[", "%["):gsub("%%%%s", "(.*)"):gsub("%s+", "%s*")
153
154     if bp.Cursor:HasSelection() then
155         if bp.Cursor.CurSelection[1]:GreaterThan(-bp.Cursor.CurSelection[2]) then
156             local endLine = bp.Cursor.CurSelection[1].Y
157             if bp.Cursor.CurSelection[1].X == 0 then
158                 endLine = endLine - 1
159             end
160             toggleCommentSelection(bp, bp.Cursor.CurSelection[2].Y, endLine, commentRegex)
161         else
162             local endLine = bp.Cursor.CurSelection[2].Y
163             if bp.Cursor.CurSelection[2].X == 0 then
164                 endLine = endLine - 1
165             end
166             toggleCommentSelection(bp, bp.Cursor.CurSelection[1].Y, endLine, commentRegex)
167         end
168     else
169         toggleCommentLine(bp, bp.Cursor.Y, commentRegex)
170     end
171 end
172
173 function trim(s)
174     local trimmed = s:gsub("^%s*(.-)%s*$", "%1"):gsub("%%","%%%%")
175     return trimmed
176 end
177
178 function string.starts(String,Start)
179     return string.sub(String,1,string.len(Start))==Start
180 end
181
182 function init()
183     config.MakeCommand("comment", comment, config.NoComplete)
184     config.TryBindKey("Alt-/", "lua:comment.comment", false)
185     config.TryBindKey("CtrlUnderscore", "lua:comment.comment", false)
186     config.AddRuntimeFile("comment", config.RTHelp, "help/comment.md")
187 end