mirror of
https://github.com/zyedidia/micro.git
synced 2025-06-21 00:05:42 -04:00

Since we already have the StoreVisualX() helper, use it all over the place instead of setting LastVisualX directly. This will allow us to add more logic to StoreVisualX() add let this extra logic apply everywhere automatically.
213 lines
6.4 KiB
Lua
213 lines
6.4 KiB
Lua
VERSION = "1.0.0"
|
|
|
|
local util = import("micro/util")
|
|
local config = import("micro/config")
|
|
local buffer = import("micro/buffer")
|
|
|
|
local ft = {}
|
|
|
|
ft["apacheconf"] = "# %s"
|
|
ft["batch"] = ":: %s"
|
|
ft["c"] = "// %s"
|
|
ft["c++"] = "// %s"
|
|
ft["cmake"] = "# %s"
|
|
ft["conf"] = "# %s"
|
|
ft["crystal"] = "# %s"
|
|
ft["css"] = "/* %s */"
|
|
ft["d"] = "// %s"
|
|
ft["dart"] = "// %s"
|
|
ft["dockerfile"] = "# %s"
|
|
ft["elm"] = "-- %s"
|
|
ft["fish"] = "# %s"
|
|
ft["gdscript"] = "# %s"
|
|
ft["glsl"] = "// %s"
|
|
ft["go"] = "// %s"
|
|
ft["haskell"] = "-- %s"
|
|
ft["html"] = "<!-- %s -->"
|
|
ft["ini"] = "; %s"
|
|
ft["java"] = "// %s"
|
|
ft["javascript"] = "// %s"
|
|
ft["jinja2"] = "{# %s #}"
|
|
ft["json"] = "// %s"
|
|
ft["julia"] = "# %s"
|
|
ft["kotlin"] = "// %s"
|
|
ft["lua"] = "-- %s"
|
|
ft["markdown"] = "<!-- %s -->"
|
|
ft["nginx"] = "# %s"
|
|
ft["nim"] = "# %s"
|
|
ft["objc"] = "// %s"
|
|
ft["ocaml"] = "(* %s *)"
|
|
ft["pascal"] = "{ %s }"
|
|
ft["perl"] = "# %s"
|
|
ft["php"] = "// %s"
|
|
ft["pony"] = "// %s"
|
|
ft["powershell"] = "# %s"
|
|
ft["proto"] = "// %s"
|
|
ft["python"] = "# %s"
|
|
ft["python3"] = "# %s"
|
|
ft["ruby"] = "# %s"
|
|
ft["rust"] = "// %s"
|
|
ft["scala"] = "// %s"
|
|
ft["shell"] = "# %s"
|
|
ft["sql"] = "-- %s"
|
|
ft["swift"] = "// %s"
|
|
ft["tex"] = "% %s"
|
|
ft["toml"] = "# %s"
|
|
ft["twig"] = "{# %s #}"
|
|
ft["v"] = "// %s"
|
|
ft["xml"] = "<!-- %s -->"
|
|
ft["yaml"] = "# %s"
|
|
ft["zig"] = "// %s"
|
|
ft["zscript"] = "// %s"
|
|
ft["zsh"] = "# %s"
|
|
|
|
local last_ft
|
|
|
|
function updateCommentType(buf)
|
|
if buf.Settings["commenttype"] == nil or (last_ft ~= buf.Settings["filetype"] and last_ft ~= nil) then
|
|
if ft[buf.Settings["filetype"]] ~= nil then
|
|
buf:SetOptionNative("commenttype", ft[buf.Settings["filetype"]])
|
|
else
|
|
buf:SetOptionNative("commenttype", "# %s")
|
|
end
|
|
|
|
last_ft = buf.Settings["filetype"]
|
|
end
|
|
end
|
|
|
|
function isCommented(bp, lineN, commentRegex)
|
|
local line = bp.Buf:Line(lineN)
|
|
local regex = commentRegex:gsub("%s+", "%s*")
|
|
if string.match(line, regex) then
|
|
return true
|
|
end
|
|
return false
|
|
end
|
|
|
|
function commentLine(bp, lineN, indentLen)
|
|
updateCommentType(bp.Buf)
|
|
|
|
local line = bp.Buf:Line(lineN)
|
|
local commentType = bp.Buf.Settings["commenttype"]
|
|
local sel = -bp.Cursor.CurSelection
|
|
local curpos = -bp.Cursor.Loc
|
|
local index = string.find(commentType, "%%s") - 1
|
|
local indent = string.sub(line, 1, indentLen)
|
|
local trimmedLine = string.sub(line, indentLen + 1)
|
|
trimmedLine = trimmedLine:gsub("%%", "%%%%")
|
|
local commentedLine = commentType:gsub("%%s", trimmedLine)
|
|
bp.Buf:Replace(buffer.Loc(0, lineN), buffer.Loc(#line, lineN), indent .. commentedLine)
|
|
if bp.Cursor:HasSelection() then
|
|
bp.Cursor.CurSelection[1].Y = sel[1].Y
|
|
bp.Cursor.CurSelection[2].Y = sel[2].Y
|
|
bp.Cursor.CurSelection[1].X = sel[1].X
|
|
bp.Cursor.CurSelection[2].X = sel[2].X
|
|
else
|
|
bp.Cursor.X = curpos.X + index
|
|
bp.Cursor.Y = curpos.Y
|
|
end
|
|
bp.Cursor:Relocate()
|
|
bp.Cursor:StoreVisualX()
|
|
end
|
|
|
|
function uncommentLine(bp, lineN, commentRegex)
|
|
updateCommentType(bp.Buf)
|
|
|
|
local line = bp.Buf:Line(lineN)
|
|
local commentType = bp.Buf.Settings["commenttype"]
|
|
local sel = -bp.Cursor.CurSelection
|
|
local curpos = -bp.Cursor.Loc
|
|
local index = string.find(commentType, "%%s") - 1
|
|
if not string.match(line, commentRegex) then
|
|
commentRegex = commentRegex:gsub("%s+", "%s*")
|
|
end
|
|
if string.match(line, commentRegex) then
|
|
uncommentedLine = string.match(line, commentRegex)
|
|
bp.Buf:Replace(buffer.Loc(0, lineN), buffer.Loc(#line, lineN), util.GetLeadingWhitespace(line) .. uncommentedLine)
|
|
if bp.Cursor:HasSelection() then
|
|
bp.Cursor.CurSelection[1].Y = sel[1].Y
|
|
bp.Cursor.CurSelection[2].Y = sel[2].Y
|
|
bp.Cursor.CurSelection[1].X = sel[1].X
|
|
bp.Cursor.CurSelection[2].X = sel[2].X
|
|
else
|
|
bp.Cursor.X = curpos.X - index
|
|
bp.Cursor.Y = curpos.Y
|
|
end
|
|
end
|
|
bp.Cursor:Relocate()
|
|
bp.Cursor:StoreVisualX()
|
|
end
|
|
|
|
function toggleCommentLine(bp, lineN, commentRegex)
|
|
if isCommented(bp, lineN, commentRegex) then
|
|
uncommentLine(bp, lineN, commentRegex)
|
|
else
|
|
commentLine(bp, lineN, #util.GetLeadingWhitespace(bp.Buf:Line(lineN)))
|
|
end
|
|
end
|
|
|
|
function toggleCommentSelection(bp, startLine, endLine, commentRegex)
|
|
local allComments = true
|
|
for line = startLine, endLine do
|
|
if not isCommented(bp, line, commentRegex) then
|
|
allComments = false
|
|
break
|
|
end
|
|
end
|
|
|
|
-- NOTE: we assume that the indentation is either tabs only or spaces only
|
|
local indentMin = -1
|
|
if not allComments then
|
|
for line = startLine, endLine do
|
|
local indentLen = #util.GetLeadingWhitespace(bp.Buf:Line(line))
|
|
if indentMin == -1 or indentLen < indentMin then
|
|
indentMin = indentLen
|
|
end
|
|
end
|
|
end
|
|
|
|
for line = startLine, endLine do
|
|
if allComments then
|
|
uncommentLine(bp, line, commentRegex)
|
|
else
|
|
commentLine(bp, line, indentMin)
|
|
end
|
|
end
|
|
end
|
|
|
|
function comment(bp, args)
|
|
updateCommentType(bp.Buf)
|
|
|
|
local commentType = bp.Buf.Settings["commenttype"]
|
|
local commentRegex = "^%s*" .. commentType:gsub("%%","%%%%"):gsub("%$","%$"):gsub("%)","%)"):gsub("%(","%("):gsub("%?","%?"):gsub("%*", "%*"):gsub("%-", "%-"):gsub("%.", "%."):gsub("%+", "%+"):gsub("%]", "%]"):gsub("%[", "%["):gsub("%%%%s", "(.*)")
|
|
|
|
if bp.Cursor:HasSelection() then
|
|
if bp.Cursor.CurSelection[1]:GreaterThan(-bp.Cursor.CurSelection[2]) then
|
|
local endLine = bp.Cursor.CurSelection[1].Y
|
|
if bp.Cursor.CurSelection[1].X == 0 then
|
|
endLine = endLine - 1
|
|
end
|
|
toggleCommentSelection(bp, bp.Cursor.CurSelection[2].Y, endLine, commentRegex)
|
|
else
|
|
local endLine = bp.Cursor.CurSelection[2].Y
|
|
if bp.Cursor.CurSelection[2].X == 0 then
|
|
endLine = endLine - 1
|
|
end
|
|
toggleCommentSelection(bp, bp.Cursor.CurSelection[1].Y, endLine, commentRegex)
|
|
end
|
|
else
|
|
toggleCommentLine(bp, bp.Cursor.Y, commentRegex)
|
|
end
|
|
end
|
|
|
|
function string.starts(String,Start)
|
|
return string.sub(String,1,string.len(Start))==Start
|
|
end
|
|
|
|
function init()
|
|
config.MakeCommand("comment", comment, config.NoComplete)
|
|
config.TryBindKey("Alt-/", "lua:comment.comment", false)
|
|
config.TryBindKey("CtrlUnderscore", "lua:comment.comment", false)
|
|
config.AddRuntimeFile("comment", config.RTHelp, "help/comment.md")
|
|
end
|