]> git.lizzy.rs Git - micro.git/blob - runtime/plugins/comment/comment.lua
Improve comment plugin
[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         end
138     end
139
140     for line = startLine, endLine do
141         if allComments then
142             uncommentLine(bp, line, commentRegex)
143         else
144             commentLine(bp, line)
145         end
146     end
147 end
148
149 function comment(bp, args)
150     local commentType = bp.Buf.Settings["commenttype"]
151     local commentRegex = "^%s*" .. commentType:gsub("%%","%%%%"):gsub("%$","%$"):gsub("%)","%)"):gsub("%(","%("):gsub("%?","%?"):gsub("%*", "%*"):gsub("%-", "%-"):gsub("%.", "%."):gsub("%+", "%+"):gsub("%]", "%]"):gsub("%[", "%["):gsub("%%%%s", "(.*)"):gsub("%s+", "%s*")
152
153     if bp.Cursor:HasSelection() then
154         if bp.Cursor.CurSelection[1]:GreaterThan(-bp.Cursor.CurSelection[2]) then
155             local endLine = bp.Cursor.CurSelection[1].Y
156             if bp.Cursor.CurSelection[1].X == 0 then
157                 endLine = endLine - 1
158             end
159             toggleCommentSelection(bp, bp.Cursor.CurSelection[2].Y, endLine, commentRegex)
160         else
161             local endLine = bp.Cursor.CurSelection[2].Y
162             if bp.Cursor.CurSelection[2].X == 0 then
163                 endLine = endLine - 1
164             end
165             toggleCommentSelection(bp, bp.Cursor.CurSelection[1].Y, endLine, commentRegex)
166         end
167     else
168         toggleCommentLine(bp, bp.Cursor.Y, commentRegex)
169     end
170 end
171
172 function trim(s)
173     local trimmed = s:gsub("^%s*(.-)%s*$", "%1"):gsub("%%","%%%%")
174     return trimmed
175 end
176
177 function string.starts(String,Start)
178     return string.sub(String,1,string.len(Start))==Start
179 end
180
181 function init()
182     config.MakeCommand("comment", comment, config.NoComplete)
183     config.TryBindKey("Alt-/", "lua:comment.comment", false)
184     config.TryBindKey("CtrlUnderscore", "lua:comment.comment", false)
185     config.AddRuntimeFile("comment", config.RTHelp, "help/comment.md")
186 end