From fc4811c1ab9467d4a690852cea227a1e44601192 Mon Sep 17 00:00:00 2001 From: Zachary Yedidia Date: Sat, 3 Aug 2019 15:49:05 -0700 Subject: [PATCH] Add comment plugin support --- cmd/micro/initlua.go | 3 + internal/action/bufpane.go | 22 ++++++ internal/config/runtime.go | 25 +++++++ runtime/plugins/comment/comment.lua | 106 ++++++++++++++++++++++++++++ 4 files changed, 156 insertions(+) create mode 100644 runtime/plugins/comment/comment.lua diff --git a/cmd/micro/initlua.go b/cmd/micro/initlua.go index 665ed37e..9220f139 100644 --- a/cmd/micro/initlua.go +++ b/cmd/micro/initlua.go @@ -86,6 +86,9 @@ func luaImportMicroBuffer() *lua.LTable { ulua.L.SetField(pkg, "MTInfo", luar.New(ulua.L, buffer.MTInfo)) ulua.L.SetField(pkg, "MTWarning", luar.New(ulua.L, buffer.MTWarning)) ulua.L.SetField(pkg, "MTError", luar.New(ulua.L, buffer.MTError)) + ulua.L.SetField(pkg, "Loc", luar.New(ulua.L, func(x, y int) buffer.Loc { + return buffer.Loc{x, y} + })) return pkg } diff --git a/internal/action/bufpane.go b/internal/action/bufpane.go index edf81ebe..6796b78e 100644 --- a/internal/action/bufpane.go +++ b/internal/action/bufpane.go @@ -7,6 +7,7 @@ import ( luar "layeh.com/gopher-luar" + lua "github.com/yuin/gopher-lua" "github.com/zyedidia/micro/internal/buffer" "github.com/zyedidia/micro/internal/config" "github.com/zyedidia/micro/internal/display" @@ -28,6 +29,23 @@ func init() { BufMouseBindings = make(map[MouseEvent]BufMouseAction) } +func LuaAction(fn string) func(*BufPane) bool { + luaFn := strings.Split(fn, ".") + plName, plFn := luaFn[0], luaFn[1] + pl := config.FindPlugin(plName) + return func(h *BufPane) bool { + val, err := pl.Call(plFn, luar.New(ulua.L, h)) + if err != nil { + screen.TermMessage(err) + } + if v, ok := val.(lua.LBool); !ok { + return false + } else { + return bool(v) + } + } +} + // BufMapKey maps a key event to an action func BufMapKey(k Event, action string) { if strings.HasPrefix(action, "command:") { @@ -38,6 +56,10 @@ func BufMapKey(k Event, action string) { action = strings.SplitN(action, ":", 2)[1] BufKeyStrings[k] = action BufKeyBindings[k] = CommandEditAction(action) + } else if strings.HasPrefix(action, "lua:") { + action = strings.SplitN(action, ":", 2)[1] + BufKeyStrings[k] = action + BufKeyBindings[k] = LuaAction(action) } else if f, ok := BufKeyActions[action]; ok { BufKeyStrings[k] = action BufKeyBindings[k] = f diff --git a/internal/config/runtime.go b/internal/config/runtime.go index baa0e43f..4e267ef6 100644 --- a/internal/config/runtime.go +++ b/internal/config/runtime.go @@ -41,6 +41,7 @@ // runtime/help/plugins.md // runtime/help/tutorial.md // runtime/plugins/autoclose/autoclose.lua +// runtime/plugins/comment/comment.lua // runtime/plugins/ftoptions/ftoptions.lua // runtime/plugins/linter/linter.lua // runtime/plugins/literate/README.md @@ -1051,6 +1052,26 @@ func runtimePluginsAutocloseAutocloseLua() (*asset, error) { return a, nil } +var _runtimePluginsCommentCommentLua = "\x1f\x8b\x08\x00\x00\x00\x00\x00\x00\xff\xec\x57\x5b\x6f\x2b\x35\x10\x7e\xcf\xaf\x30\x7b\x88\x64\xb7\xd9\xed\x49\x79\x8b\x08\x12\xed\x43\x91\x08\x07\xa9\xad\x20\x55\x14\xa4\xbd\xcc\x26\x3e\x78\xbd\x2b\xdb\x0b\x44\x08\x7e\x3b\xf2\x65\xaf\xde\x84\x1c\x21\xc1\x0b\x95\xda\x6c\x3e\xcf\x37\x63\xcf\x7c\xe3\xd9\xb2\x32\x8d\x19\xaa\x15\x65\x68\x8d\x68\x51\x95\x42\xe1\xa0\xa0\xa9\x28\xef\x34\x18\x90\x99\xb5\x48\x4b\x9e\xd3\x83\x67\x63\xe1\xd6\x2a\xa9\xf3\x1c\x84\x67\x65\xe1\x80\xcc\x9c\x59\xae\xd0\x1a\xfd\xfe\xc7\x6c\x96\xab\x5d\x90\x06\x7b\xb4\x46\xc1\xdd\x1d\x9a\xcb\xc0\x22\xb7\xb7\x1e\x76\x28\x3d\xa8\x3a\xa9\x63\xc9\x2d\xfc\x6e\x84\x7e\x31\x86\x8f\xaa\x60\x16\xfb\xf2\xb3\x30\x44\x73\x89\xc2\xf0\x2b\xbb\xf4\x31\xfe\x25\xf6\x9c\x7f\xac\x19\x8d\x3d\xdf\x20\x98\x87\x1d\x2b\x8f\x2c\x6a\xa9\x3c\x50\x1e\x81\x79\x6c\x56\xbb\x20\x66\x4f\xdd\x7e\x64\x2a\x68\xe5\xfb\x10\x75\x72\x1a\xbb\xc8\xfc\x48\xbf\xd2\x7c\xc8\x9d\xe5\x35\x4f\x15\x2d\x39\x2a\xf9\x83\x29\xc6\xf7\x15\x70\x9c\xd4\x39\x99\x21\x84\x10\xcd\x75\xe9\xa2\x17\x50\x8a\xf2\x83\xdc\x05\x69\x59\x14\xc0\x95\x3a\x55\xa0\x1d\xad\x11\xa7\x0c\xa9\x23\x70\x63\xee\x28\xb9\xda\x0d\x59\x39\x65\x60\x29\x7b\xf4\xe7\x04\x47\xff\x5c\x8c\x73\xd1\x65\xeb\x06\x98\x84\x4f\xf0\xe9\x72\xd5\xb2\x79\x36\x6b\x3e\xf5\x6f\x97\x1b\x47\xdc\x50\x0e\x38\xa9\x16\x88\x51\x0e\x1f\x6c\x82\xac\x6e\x35\x80\xd6\x28\xa9\xa2\x87\x3a\x5f\x19\x3b\xcf\xc6\x39\x79\x3d\x55\x9d\xe9\xb9\xcd\xf9\xb4\x67\x38\xc0\x6f\x7a\xcf\x3f\xcd\xe5\x4d\x80\xa2\xa8\xef\x6f\x75\x90\x75\x82\x83\xf9\x4d\xb0\x40\xfa\x2f\x69\x80\xd0\x00\x61\x07\x44\x06\x88\x3a\xe0\xd6\x00\xb7\x1d\xb0\x37\xc0\xbe\x03\x76\x06\xd8\x75\xc0\x5c\x6a\x04\x47\x37\x24\xe8\x9f\x4f\x82\xbe\x29\xc2\xa4\x8a\x1e\x6b\x21\x4b\xa1\x3f\x5e\x80\x81\x49\x61\xff\x40\xb5\xa8\x4a\x39\x34\xdd\x94\x69\xcf\x82\xf2\xcc\x9c\x55\x2a\x41\xf9\x21\xca\x29\xcf\x70\xef\xb4\x7a\x3b\x73\x19\x10\x14\xa2\x65\x23\x52\x67\x5a\xc4\x2a\x3d\x9a\xd4\x2f\x06\x89\x23\x43\xb9\xd5\xdc\x2d\x42\xb6\xb1\x95\xfb\x3b\x7e\x4b\x75\x25\x7e\x86\x8a\xc5\x29\x60\x7b\x81\xe9\xfd\xe3\xf7\x8d\x2e\x16\xa8\x87\xbe\xb3\xce\x9a\x15\x7d\x75\x46\x4f\xa0\x36\x10\x67\x94\x1f\x7e\x3c\x52\x05\xb2\xd2\x9e\xb4\x05\xd1\x75\x1d\x6d\x8e\xf4\x1b\xab\xcd\xd8\xea\x9b\x58\xb6\xc9\xc5\x64\xa2\x9b\x26\xcb\xb0\x5b\xee\xa3\x37\x7d\x5c\x60\xe6\xf1\x1a\xca\x7d\x47\xb9\xbf\x92\xb2\xdc\x47\xdb\x2e\xca\xf6\xca\x28\xdb\x2e\xca\xf6\x42\x4b\xb7\x7c\x6d\x6f\xc5\x14\x6d\x51\x68\x55\x73\xc6\xf4\xad\x33\x7d\xf3\xfb\xbd\x1f\x62\xd0\x74\xad\x3c\x26\x7a\xcd\x74\x81\x12\xb4\xb0\x95\xfb\x37\x15\xf2\xbf\x3e\x3e\x5d\x1f\xb7\xff\x40\x1f\xee\xb3\x4b\xee\x33\x68\x99\x28\xc0\x64\xb8\x10\x6d\x62\xa9\x7e\xa0\xb2\x8e\xd9\xd6\xde\xf1\x8e\xf0\x04\x0d\x8c\xc9\xf4\x6c\xe9\x8a\xa5\x07\x8c\x54\xb1\x30\xe3\x66\xa1\xa3\x77\x65\xce\x4b\xd1\xcc\x1a\xdf\x04\x65\x65\xbb\xf7\xa9\x89\x45\x2e\x4f\x37\x9c\x54\xdd\xcc\xbf\x4a\x47\x7d\xc3\x71\x81\x57\x4f\x02\x62\x05\xe2\xf5\x18\x73\x7c\x66\x28\xec\xee\xf7\x13\xca\xb4\x1d\xd8\x9c\x69\x7d\x49\xa9\x03\xde\xa5\xdd\x68\x2d\xac\xd1\x7b\x3f\x98\xcb\x88\x0b\xd5\x3c\x35\x83\x65\xac\x84\x51\x76\x87\x35\xbb\xd0\x1e\xa3\x2a\x4e\xea\xf6\xca\x63\x7b\x2d\x76\xfe\xd8\xf7\xff\xe5\xb1\x97\x67\x8e\x3d\x75\xe7\x8e\xc5\xda\xeb\xcb\x73\x9a\x35\x17\xaf\xb4\xab\x02\x54\x2d\x38\xc2\xd2\x5d\xcd\xfa\x0d\x09\x47\x21\x99\xcb\x9b\xcf\xcd\xbb\xcb\x32\x20\xe3\xae\x73\xf3\xde\x34\x91\xc4\x2f\xe6\xdb\xe2\x45\x7f\x1b\xf8\x6c\xcc\xea\xa4\xb1\x59\x2e\x1c\xc6\x80\x63\x4b\x20\xeb\xb5\x79\xb0\x21\xec\x3f\x3e\xd1\x77\xf1\xcf\xf0\x58\x16\x45\xcc\x33\xdc\xbc\xdb\xe9\xcd\xb8\xc7\xa8\x83\x1c\xe1\x43\xf9\x58\x16\x15\x03\x05\xa4\xf1\xf1\x2a\x4e\x0f\x94\x67\xdf\xc2\x09\x07\x5f\x33\x15\xde\x69\x07\xac\x8e\x57\xbe\x93\x3c\x66\x12\xc8\xec\xaf\x00\x00\x00\xff\xff\x93\xd1\x8d\x0e\xb5\x0d\x00\x00" + +func runtimePluginsCommentCommentLuaBytes() ([]byte, error) { + return bindataRead( + _runtimePluginsCommentCommentLua, + "runtime/plugins/comment/comment.lua", + ) +} + +func runtimePluginsCommentCommentLua() (*asset, error) { + bytes, err := runtimePluginsCommentCommentLuaBytes() + if err != nil { + return nil, err + } + + info := bindataFileInfo{name: "runtime/plugins/comment/comment.lua", size: 0, mode: os.FileMode(0), modTime: time.Unix(0, 0)} + a := &asset{bytes: bytes, info: info} + return a, nil +} + var _runtimePluginsFtoptionsFtoptionsLua = "\x1f\x8b\x08\x00\x00\x00\x00\x00\x00\xff\x94\xcf\xb1\x0e\x82\x40\x0c\x06\xe0\x9d\xa7\x68\x6e\x82\xc4\x49\x37\x12\x16\x07\x57\x06\x7d\x81\x3b\x6c\xe5\xe2\xd1\x5e\xb8\x32\xf0\xf6\x86\x13\x75\x82\xc4\x26\x5d\xfa\x25\xfd\xf3\xd3\xc4\x9d\x7a\x61\x10\x3e\x4f\x44\x38\xb6\x11\xb9\x74\x55\x01\x00\x10\xa4\xb3\x01\x48\xa1\x01\x57\x5f\x7c\xc0\xdb\x1c\xb1\xac\x8a\x8c\x9e\xb2\x34\x60\x1e\x62\x40\xc6\x7c\x5c\x2f\x83\x7d\x22\xf9\x80\x06\xb4\x47\xce\xb2\x8c\xab\xaf\xa8\x6d\x5c\xf2\x4a\xa3\xd6\x25\x95\x14\x6d\x87\xc9\x1c\xc0\x08\x91\x79\xc7\x62\x48\xf8\xfb\x4e\x3e\xf5\xdf\xff\xeb\xac\x14\x67\xed\x85\x77\xf1\xb8\xab\xa7\x0d\x9d\xed\x10\x36\x88\xfd\xf0\x57\x2b\xfe\x94\xe2\x7b\xb1\xec\x2b\x00\x00\xff\xff\x55\x1f\xb6\x5b\x71\x01\x00\x00" func runtimePluginsFtoptionsFtoptionsLuaBytes() ([]byte, error) { @@ -3604,6 +3625,7 @@ var _bindata = map[string]func() (*asset, error){ "runtime/help/plugins.md": runtimeHelpPluginsMd, "runtime/help/tutorial.md": runtimeHelpTutorialMd, "runtime/plugins/autoclose/autoclose.lua": runtimePluginsAutocloseAutocloseLua, + "runtime/plugins/comment/comment.lua": runtimePluginsCommentCommentLua, "runtime/plugins/ftoptions/ftoptions.lua": runtimePluginsFtoptionsFtoptionsLua, "runtime/plugins/linter/linter.lua": runtimePluginsLinterLinterLua, "runtime/plugins/literate/README.md": runtimePluginsLiterateReadmeMd, @@ -3821,6 +3843,9 @@ var _bintree = &bintree{nil, map[string]*bintree{ "autoclose": &bintree{nil, map[string]*bintree{ "autoclose.lua": &bintree{runtimePluginsAutocloseAutocloseLua, map[string]*bintree{}}, }}, + "comment": &bintree{nil, map[string]*bintree{ + "comment.lua": &bintree{runtimePluginsCommentCommentLua, map[string]*bintree{}}, + }}, "ftoptions": &bintree{nil, map[string]*bintree{ "ftoptions.lua": &bintree{runtimePluginsFtoptionsFtoptionsLua, map[string]*bintree{}}, }}, diff --git a/runtime/plugins/comment/comment.lua b/runtime/plugins/comment/comment.lua new file mode 100644 index 00000000..0b34a4dc --- /dev/null +++ b/runtime/plugins/comment/comment.lua @@ -0,0 +1,106 @@ +local util = import("micro/util") +local config = import("micro/config") +local buffer = import("micro/buffer") + +local ft = {} + +ft["c"] = "// %s" +ft["c++"] = "// %s" +ft["go"] = "// %s" +ft["python"] = "# %s" +ft["python3"] = "# %s" +ft["html"] = "" +ft["java"] = "// %s" +ft["julia"] = "# %s" +ft["perl"] = "# %s" +ft["php"] = "// %s" +ft["rust"] = "// %s" +ft["shell"] = "# %s" +ft["lua"] = "-- %s" +ft["javascript"] = "// %s" +ft["ruby"] = "# %s" +ft["d"] = "// %s" +ft["swift"] = "// %s" + +function onBufferOpen(buf) + if buf.Settings["commenttype"] == nil then + if ft[buf.Settings["filetype"]] ~= nil then + buf.Settings["commenttype"] = ft[buf.Settings["filetype"]] + else + buf.Settings["commenttype"] = "# %s" + end + end +end + +function commentLine(bp, lineN) + local line = bp.Buf:Line(lineN) + local commentType = bp.Buf.Settings["commenttype"] + local commentRegex = "^%s*" .. commentType:gsub("%*", "%*"):gsub("%-", "%-"):gsub("%.", "%."):gsub("%+", "%+"):gsub("%]", "%]"):gsub("%[", "%["):gsub("%%s", "(.*)") + local sel = -bp.Cursor.CurSelection + local curpos = -bp.Cursor.Loc + local index = string.find(commentType, "%%s") - 1 + 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 + else + local commentedLine = commentType:gsub("%%s", trim(line)) + bp.Buf:Replace(buffer.Loc(0, lineN), buffer.Loc(#line, lineN), util.GetLeadingWhitespace(line) .. 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 + end + bp.Cursor:Relocate() + bp.Cursor.LastVisualX = bp.Cursor:GetVisualX() +end + +function commentSelection(bp, startLine, endLine) + for line = startLine, endLine do + commentLine(bp, line) + end +end + +function comment(bp) + 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 + commentSelection(bp, bp.Cursor.CurSelection[2].Y, endLine) + else + local endLine = bp.Cursor.CurSelection[2].Y + if bp.Cursor.CurSelection[2].X == 0 then + endLine = endLine - 1 + end + commentSelection(bp, bp.Cursor.CurSelection[1].Y, endLine) + end + else + commentLine(bp, bp.Cursor.Y) + end +end + +function trim(s) + return (s:gsub("^%s*(.-)%s*$", "%1")) +end + +function string.starts(String,Start) + return string.sub(String,1,string.len(Start))==Start +end + +config.MakeCommand("comment", "comment.comment", config.NoComplete) +config.TryBindKey("Alt-/", "lua:comment.comment", false)