3 local util = import("micro/util")
4 local config = import("micro/config")
5 local buffer = import("micro/buffer")
9 ft["apacheconf"] = "# %s"
15 ft["crystal"] = "# %s"
16 ft["css"] = "/* %s */"
19 ft["dockerfile"] = "# %s"
22 ft["gdscript"] = "# %s"
25 ft["haskell"] = "-- %s"
26 ft["html"] = "<!-- %s -->"
29 ft["javascript"] = "// %s"
30 ft["jinja2"] = "{# %s #}"
32 ft["kotlin"] = "// %s"
34 ft["markdown"] = "<!-- %s -->"
38 ft["ocaml"] = "(* %s *)"
39 ft["pascal"] = "{ %s }"
43 ft["powershell"] = "# %s"
46 ft["python3"] = "# %s"
55 ft["twig"] = "{# %s #}"
57 ft["xml"] = "<!-- %s -->"
60 ft["zscript"] = "// %s"
63 function updateCommentType(buf)
64 if ft[buf.Settings["filetype"]] ~= nil and ft[buf.Settings["filetype"]] ~= nil then
65 buf.Settings["commenttype"] = ft[buf.Settings["filetype"]]
66 elseif buf.Settings["commenttype"] == nil then
67 buf.Settings["commenttype"] = "# %s"
71 function isCommented(bp, lineN, commentRegex)
72 local line = bp.Buf:Line(lineN)
73 if string.match(line, commentRegex) then
79 function commentLine(bp, lineN)
80 updateCommentType(bp.Buf)
82 local line = bp.Buf:Line(lineN)
83 local commentType = bp.Buf.Settings["commenttype"]
84 local sel = -bp.Cursor.CurSelection
85 local curpos = -bp.Cursor.Loc
86 local index = string.find(commentType, "%%s") - 1
87 local commentedLine = commentType:gsub("%%s", trim(line))
88 bp.Buf:Replace(buffer.Loc(0, lineN), buffer.Loc(#line, lineN), util.GetLeadingWhitespace(line) .. commentedLine)
89 if bp.Cursor:HasSelection() then
90 bp.Cursor.CurSelection[1].Y = sel[1].Y
91 bp.Cursor.CurSelection[2].Y = sel[2].Y
92 bp.Cursor.CurSelection[1].X = sel[1].X
93 bp.Cursor.CurSelection[2].X = sel[2].X
95 bp.Cursor.X = curpos.X + index
96 bp.Cursor.Y = curpos.Y
99 bp.Cursor.LastVisualX = bp.Cursor:GetVisualX()
102 function uncommentLine(bp, lineN, commentRegex)
103 updateCommentType(bp.Buf)
105 local line = bp.Buf:Line(lineN)
106 local commentType = bp.Buf.Settings["commenttype"]
107 local sel = -bp.Cursor.CurSelection
108 local curpos = -bp.Cursor.Loc
109 local index = string.find(commentType, "%%s") - 1
110 if string.match(line, commentRegex) then
111 uncommentedLine = string.match(line, commentRegex)
112 bp.Buf:Replace(buffer.Loc(0, lineN), buffer.Loc(#line, lineN), util.GetLeadingWhitespace(line) .. uncommentedLine)
113 if bp.Cursor:HasSelection() then
114 bp.Cursor.CurSelection[1].Y = sel[1].Y
115 bp.Cursor.CurSelection[2].Y = sel[2].Y
116 bp.Cursor.CurSelection[1].X = sel[1].X
117 bp.Cursor.CurSelection[2].X = sel[2].X
119 bp.Cursor.X = curpos.X - index
120 bp.Cursor.Y = curpos.Y
124 bp.Cursor.LastVisualX = bp.Cursor:GetVisualX()
127 function toggleCommentLine(bp, lineN, commentRegex)
128 if isCommented(bp, lineN, commentRegex) then
129 uncommentLine(bp, lineN, commentRegex)
131 commentLine(bp, lineN)
135 function toggleCommentSelection(bp, startLine, endLine, commentRegex)
136 local allComments = true
137 for line = startLine, endLine do
138 if not isCommented(bp, line, commentRegex) then
144 for line = startLine, endLine do
146 uncommentLine(bp, line, commentRegex)
148 commentLine(bp, line)
153 function comment(bp, args)
154 updateCommentType(bp.Buf)
156 local commentType = bp.Buf.Settings["commenttype"]
157 local commentRegex = "^%s*" .. commentType:gsub("%%","%%%%"):gsub("%$","%$"):gsub("%)","%)"):gsub("%(","%("):gsub("%?","%?"):gsub("%*", "%*"):gsub("%-", "%-"):gsub("%.", "%."):gsub("%+", "%+"):gsub("%]", "%]"):gsub("%[", "%["):gsub("%%%%s", "(.*)"):gsub("%s+", "%s*")
159 if bp.Cursor:HasSelection() then
160 if bp.Cursor.CurSelection[1]:GreaterThan(-bp.Cursor.CurSelection[2]) then
161 local endLine = bp.Cursor.CurSelection[1].Y
162 if bp.Cursor.CurSelection[1].X == 0 then
163 endLine = endLine - 1
165 toggleCommentSelection(bp, bp.Cursor.CurSelection[2].Y, endLine, commentRegex)
167 local endLine = bp.Cursor.CurSelection[2].Y
168 if bp.Cursor.CurSelection[2].X == 0 then
169 endLine = endLine - 1
171 toggleCommentSelection(bp, bp.Cursor.CurSelection[1].Y, endLine, commentRegex)
174 toggleCommentLine(bp, bp.Cursor.Y, commentRegex)
179 local trimmed = s:gsub("^%s*(.-)%s*$", "%1"):gsub("%%","%%%%")
183 function string.starts(String,Start)
184 return string.sub(String,1,string.len(Start))==Start
188 config.MakeCommand("comment", comment, config.NoComplete)
189 config.TryBindKey("Alt-/", "lua:comment.comment", false)
190 config.TryBindKey("CtrlUnderscore", "lua:comment.comment", false)
191 config.AddRuntimeFile("comment", config.RTHelp, "help/comment.md")