commit 48b4c97e3e9738ba43bc062333cf3b9007a51180 Author: sashakoshka@tebibyte.media Date: Thu Jan 9 11:10:37 2025 -0500 Initial commit diff --git a/README.md b/README.md new file mode 100644 index 0000000..93317ec --- /dev/null +++ b/README.md @@ -0,0 +1,4 @@ +# Micro Plugins + +Plugins for the [micro](https://github.com/zyedidia/micro) text editor that +I've made. To install, just drop them in `$HOME/.config/micro/plug`. diff --git a/case/go.lua b/case/go.lua new file mode 100644 index 0000000..7027050 --- /dev/null +++ b/case/go.lua @@ -0,0 +1,177 @@ +VERSION = "0.1.0" +PLUGIN_NAME = "case" + +local micro = import("micro") +local config = import("micro/config") +local util = import("micro/util") +local buffer = import("micro/buffer") + +function init () + config.MakeCommand(PLUGIN_NAME .. ".upper", caseUpper, config.NoComplete) + config.MakeCommand(PLUGIN_NAME .. ".lower", caseLower, config.NoComplete) + config.MakeCommand(PLUGIN_NAME .. ".snake", caseSnake, config.NoComplete) + config.MakeCommand(PLUGIN_NAME .. ".kebab", caseKebab, config.NoComplete) + config.MakeCommand(PLUGIN_NAME .. ".uppersnake", caseUpperSnake, config.NoComplete) + config.MakeCommand(PLUGIN_NAME .. ".upperkebab", caseUpperKebab, config.NoComplete) + config.MakeCommand(PLUGIN_NAME .. ".camel", caseCamel, config.NoComplete) + config.MakeCommand(PLUGIN_NAME .. ".pascal", casePascal, config.NoComplete) +end + +function caseUpper (bufferPane) + case(bufferPane, "upper") +end + +function caseLower (bufferPane) + case(bufferPane, "lower") +end + +function caseSnake (bufferPane) + case(bufferPane, "snake") +end + +function caseKebab (bufferPane) + case(bufferPane, "kebab") +end + +function caseUpperSnake (bufferPane) + case(bufferPane, "uppersnake") +end + +function caseUpperKebab (bufferPane) + case(bufferPane, "upperkebab") +end + +function caseCamel (bufferPane) + case(bufferPane, "camel") +end + +function casePascal (bufferPane) + case(bufferPane, "pascal") +end + +function case (bufferPane, cas) + local cursor = bufferPane.Buf:GetActiveCursor() + if not (cursor and cursor:HasSelection()) then return end + + local sstart, send = nil, nil + if cursor.CurSelection[1]:GreaterThan(-cursor.CurSelection[2]) then + sstart, send = cursor.CurSelection[2], cursor.CurSelection[1] + else + sstart, send = cursor.CurSelection[1], cursor.CurSelection[2] + end + sstart = buffer.Loc(sstart.X, sstart.Y) + send = buffer.Loc(send.X, send.Y) + + local selection = util.String(cursor:GetSelection()) + selection = changeCase(selection, cas) + bufferPane.Buf:Replace(sstart, send, selection) +end + +function changeCase (text, cas) + if cas == "upper" then + return string.upper(text) + elseif cas == "lower" then + return string.lower(text) + elseif cas == "snake" then + return concatTokens(lowerCaseTokens(tokenize(text)), "_") + elseif cas == "kebab" then + return concatTokens(lowerCaseTokens(tokenize(text)), "-") + elseif cas == "uppersnake" then + return concatTokens(upperCaseTokens(tokenize(text)), "_") + elseif cas == "upperkebab" then + return concatTokens(upperCaseTokens(tokenize(text)), "-") + elseif cas == "camel" then + return concatTokens(camelCaseTokens(tokenize(text)), "") + elseif cas == "pascal" then + return concatTokens(pascalCaseTokens(tokenize(text)), "") + end +end + +function tokenize (text) + local tokens = { } + local wasAlphanumeric = false + + local newToken = function () + if #tokens == 0 or tokens[#tokens].text ~= "" then + table.insert(tokens, { text = "" }) + end + tokens[#tokens].word = true + end + + for index = 1, #text do + local ch = text:sub(index, index) + local alphanumeric = ch:match("%w") ~= nil + local uppercase = ch:match("%u") ~= nil + if uppercase or alphanumeric ~= wasAlphanumeric then + newToken() + end + if ch ~= " " and ch ~= "-" and ch ~= "_" then + tokens[#tokens].text = tokens[#tokens].text .. ch + end + if not alphanumeric then + tokens[#tokens].word = false + end + wasAlphanumeric = alphanumeric + end + return tokens +end + +function mapOverTokens (tokens, callback) + local result = { } + for index, token in ipairs(tokens) do + token = { + text = token.text, + word = token.word, + } + callback(index, token) + result[index] = token + end + return result +end + +function lowerCaseTokens (tokens) + return mapOverTokens(tokens, function (index, token) + if token.word then + token.text = string.lower(token.text) + end + end) +end + +function upperCaseTokens (tokens) + return mapOverTokens(tokens, function (index, token) + if token.word then + token.text = string.upper(token.text) + end + end) +end + +function camelCaseTokens (tokens) + local wasAlphanumeric = false + return mapOverTokens(tokens, function (index, token) + if token.word and wasAlphanumeric then + token.text = (token.text:gsub("^%l", string.upper)) + end + wasAlphanumeric = token.word + end) +end + +function pascalCaseTokens (tokens) + return mapOverTokens(tokens, function (index, token) + if token.word then + token.text = (token.text:gsub("^%l", string.upper)) + end + end) +end + +function concatTokens (tokens, separator) + local result = "" + local wasAlphanumeric = false + for index, token in ipairs(tokens) do + if wasAlphanumeric and token.word then + result = result .. separator + end + wasAlphanumeric = token.word + result = result .. token.text + end + return result +end diff --git a/case/repo.json b/case/repo.json new file mode 100644 index 0000000..e367562 --- /dev/null +++ b/case/repo.json @@ -0,0 +1,5 @@ +[{ + "Name": "case", + "Description": "Change the case of the selection", + "License": "GPLv3", +}]