micro-plugins/case/go.lua

178 lines
4.6 KiB
Lua

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