From: Tucker Johnson Date: Wed, 18 Jun 2025 20:32:18 +0000 (-0400) Subject: init X-Git-Url: https://git.newer.systems/?a=commitdiff_plain;h=706129d35eb3839a11eee2b2894609bd14be769c;p=setclass.git init --- 706129d35eb3839a11eee2b2894609bd14be769c diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..afed073 --- /dev/null +++ b/.gitignore @@ -0,0 +1 @@ +*.csv diff --git a/core.lua b/core.lua new file mode 100644 index 0000000..5a7ba3b --- /dev/null +++ b/core.lua @@ -0,0 +1,100 @@ +local ok, bit = pcall(require, "bit32") +if not ok then + bit = require("bit") -- LuaJIT fallback +end + +local M = {} + +local pluginDir = debug.getinfo(1, "S").source:sub(2):match("(.*/)") +local csvPath = pluginDir .. "set-classes.csv" +local csvLoaded = false +local lookup = {} + +local function load_csv() + local f = io.open(csvPath, "r") + if not f then error("Could not open setclasses.csv at " .. csvPath) end + for line in f:lines() do + local dec, setClass = line:match("^(%d+),%[?([0-9AB ]+)%]?") + if dec and setClass then + lookup[tonumber(dec)] = "[" .. setClass .. "]" + end + end + f:close() +end + +function M.get_visual_selection() + local start_pos = vim.fn.getpos("'<") + local end_pos = vim.fn.getpos("'>") + local lines = vim.fn.getline(start_pos[2], end_pos[2]) + if #lines == 0 then return "" end + if #lines == 1 then + return string.sub(lines[1], start_pos[3], end_pos[3]) + end + lines[1] = string.sub(lines[1], start_pos[3]) + lines[#lines] = string.sub(lines[#lines], 1, end_pos[3]) + return table.concat(lines, "\n") +end + +function M.analyze_set(inputStr) + if not csvLoaded then + load_csv() + csvLoaded = true + end + + local function parse_set(input) + local pcs = {} + for i = 1, #input do + local char = input:sub(i, i):upper() + local pc = tonumber(char) + if char == 'A' then pc = 10 + elseif char == 'B' then pc = 11 end + if pc and pc >= 0 and pc < 12 then + table.insert(pcs, pc) + else + error("Invalid pc: " .. char) + end + end + return pcs + end + + local function compute_bitmask(pcs) + local mask = 0 + for _, pc in ipairs(pcs) do + mask = bit.bor(mask, bit.lshift(1, pc)) + end + return mask + end + + local function complement(mask) + return bit.band(bit.bnot(mask), 0xFFF) + end + + local function multiply_set(pcs, factor) + local result = {} + for _, pc in ipairs(pcs) do + table.insert(result, (pc * factor) % 12) + end + return result + end + + local pcs = parse_set(inputStr) + local mask = compute_bitmask(pcs) + local decimal = mask + local setClass = lookup[decimal] or "[Unknown]" + local complementMask = complement(mask) + local complementClass = lookup[complementMask] or "[Unknown]" + local m5Set = multiply_set(pcs, 5) + local m5Mask = compute_bitmask(m5Set) + local m5Decimal = m5Mask + local m5Class = lookup[m5Decimal] or "[Unknown]" + + return { + input = inputStr, + decimal = decimal, + set_class = setClass, + complement_class = complementClass, + m5_class = m5Class + } +end + +return M diff --git a/init.lua b/init.lua new file mode 100644 index 0000000..5028733 --- /dev/null +++ b/init.lua @@ -0,0 +1,17 @@ +local M = {} +local core = require("setclass.core") + +function M.analyze_selection() + local input = core.get_visual_selection() + local result = core.analyze_set(input) + if result then + vim.notify("input: " .. result.input .. " (" .. result.decimal .. ")") + vim.notify("set class: " .. result.set_class) + vim.notify("abs. complement: " .. result.complement_class) + vim.notify("M5: " .. result.m5_class) + else + vim.notify("Invalid set") + end +end + +return M