From bef3a1df3803479355f815a97e6404b780ea899c Mon Sep 17 00:00:00 2001 From: Chris Pecunies Date: Sun, 15 Dec 2024 06:19:51 -0800 Subject: [PATCH] updating bin --- Makefile | 16 +- lua/word/mod/init.lua | 86 +++-- scripts/bin/word | 731 ++++++++++++++++++++++++++++++++++-- scripts/bin/word-lsp | 805 +++++++++++++++++++++++++++------------- scripts/bin/word-lsp.sh | 376 +++++++++++++++++++ scripts/bin/word.lua | 5 - scripts/bin/wordf | 22 -- scripts/bin/wordls | 43 --- 8 files changed, 1697 insertions(+), 387 deletions(-) create mode 100755 scripts/bin/word-lsp.sh delete mode 100644 scripts/bin/word.lua delete mode 100755 scripts/bin/wordf delete mode 100755 scripts/bin/wordls diff --git a/Makefile b/Makefile index f941ec0..4379cef 100644 --- a/Makefile +++ b/Makefile @@ -2,22 +2,30 @@ # # nvimf="--headless -u ./test/config/minit.lua --noplugin -c ''" -wf: - ./scripts/bin/wordf +export PATH=$PATH:$HOME/word/scripts/bin + w: ./scripts/bin/word -wls: +wl: ./scripts/bin/wordls +iw: + cp -r ./scripts/bin/word ${HOME}/.local/bin/ +iwl: + cp -r ./scripts/bin/word-lsp ${HOME}/.local/bin/ + +i: iw iwl clean: fd --no-ignore --glob "*-E" -x "rm" ./ v: - nvim -u ./test/config/minit.lua + nvim -u ./test/config/minit.lua # -c 'Lazy install' # books: # cd book && mdbook serve # default: clean +i: + diff --git a/lua/word/mod/init.lua b/lua/word/mod/init.lua index 64eb8bb..3116991 100644 --- a/lua/word/mod/init.lua +++ b/lua/word/mod/init.lua @@ -5,9 +5,20 @@ local log = require("word.util.log") local utils = require("word.util") -- TODO: remove global -_G.Mod = {} -Mod.__index = Mod +---@class word.Mod +Mod = setmetatable({}, { + __index = Mod, + ---@param self word.Mod + ---@param other word.Mod + __eq = function(self, other) + return self.name == other.name + end, + ---@param self word.Mod + __tostring = function(self) + return self.name + end, +}) Mod.default_mod = function(name) return { @@ -61,7 +72,7 @@ Mod.default_mod = function(name) events = { subscribed = { -- The events that the init is subscribed to }, - defined = { -- The events that the init itself has defined + defined = { -- The events that the init itself has defined }, }, required = {}, @@ -82,8 +93,8 @@ function Mod.create(name, imports) if not Mod.load_mod(fullpath) then log.error( "Unable to load import '" - .. fullpath - .. "'! An error (see traceback below):" + .. fullpath + .. "'! An error (see traceback below):" ) assert(false) end @@ -175,20 +186,20 @@ function Mod.load_mod_from_table(m) -- Invoke the setup function. This function returns whether or not the loading of the init was successful and some metadata. ---@type word.mod.Setup local mod_load = m.setup and m.setup() - or { - loaded = true, - replaces = {}, - merge = false, - requires = {}, - wants = {}, - } + or { + loaded = true, + replaces = {}, + merge = false, + requires = {}, + wants = {}, + } -- We do not expect init.setup() to ever return nil, that's why this check is in place if not mod_load then log.error( "init" - .. m.name - .. "does not handle init loading correctly; init.setup() returned nil. Omitting..." + .. m.name + .. "does not handle init loading correctly; init.setup() returned nil. Omitting..." ) return false end @@ -220,15 +231,15 @@ function Mod.load_mod_from_table(m) if config.user.mod[req_mod] then log.trace( "Wanted init" - .. req_mod - .. "isn't loaded but can be as it's defined in the user's config. Loading..." + .. req_mod + .. "isn't loaded but can be as it's defined in the user's config. Loading..." ) if not Mod.load_mod(req_mod) then require("word.util.log").error( "Unable to load wanted init for" - .. m.name - .. "- the init didn't load successfully" + .. m.name + .. "- the init didn't load successfully" ) -- Modake sure to clean up after ourselves if the init failed to load @@ -237,7 +248,8 @@ function Mod.load_mod_from_table(m) end else log.error( - ("Unable to load init %s, wanted dependency %s was not satisfied. Be sure to load the init and its appropriate config too!"):format( + ("Unable to load init %s, wanted dependency %s was not satisfied. Be sure to load the init and its appropriate config too!") + :format( m.name, req_mod ) @@ -296,7 +308,8 @@ function Mod.load_mod_from_table(m) -- If this flag has already been set before, then throw an error - there is no way for us to know which hotswapped init should take priority. if mod_to_replace.replaced then log.error( - ("Unable to replace init %s - init replacement clashing detected. This error triggers when a init tries to be replaced more than two times - word doesn't know which replacement to prioritize."):format( + ("Unable to replace init %s - init replacement clashing detected. This error triggers when a init tries to be replaced more than two times - word doesn't know which replacement to prioritize.") + :format( mod_to_replace.name ) ) @@ -375,8 +388,8 @@ function Mod.load_mod(modn, cfg) if not modl then log.error( "Unable to load init" - .. modn - .. "- loaded file returned nil. Be sure to return the table created by mod.create() at the end of your init.lua file!" + .. modn + .. "- loaded file returned nil. Be sure to return the table created by mod.create() at the end of your init.lua file!" ) return false end @@ -384,8 +397,9 @@ function Mod.load_mod(modn, cfg) if modl == true then log.error( "An error has occurred when loading" - .. modn - .. "- loaded file didn't return anything meaningful. Be sure to return the table created by mod.create() at the end of your init.lua file!" + .. modn + .. + "- loaded file didn't return anything meaningful. Be sure to return the table created by mod.create() at the end of your init.lua file!" ) return false end @@ -398,8 +412,8 @@ function Mod.load_mod(modn, cfg) -- print(modl.config.custom, modl.config.public, config.mod[modn]) modl.config.custom = config.mod[modn] modl.config.public = - -- vim.tbl_extend("force", modl.config.public, modl.config.custom or {}) - utils.extend(modl.config.public, modl.config.custom or {}) + -- vim.tbl_extend("force", modl.config.public, modl.config.custom or {}) + utils.extend(modl.config.public, modl.config.custom or {}) end -- Pass execution onto load_mod_from_table() and let it handle the rest @@ -451,8 +465,8 @@ function Mod.get_mod_config(modn) if not Mod.is_mod_loaded(modn) then log.trace( "Attempt to get init config with name" - .. modn - .. "failed - init is not loaded." + .. modn + .. "failed - init is not loaded." ) return end @@ -475,8 +489,8 @@ function Mod.get_mod_version(modn) if not Mod.is_mod_loaded(modn) then log.trace( "Attempt to get init version with name" - .. modn - .. "failed - init is not loaded." + .. modn + .. "failed - init is not loaded." ) return end @@ -488,8 +502,8 @@ function Mod.get_mod_version(modn) if not version then log.trace( "Attempt to get init version with name" - .. modn - .. "failed - version variable not present." + .. modn + .. "failed - version variable not present." ) return end @@ -598,7 +612,7 @@ function Mod.create_event(m, type, content, ev) -- Retrieve the template from init.events.defined local event_template = - Mod.get_event_template(Mod.loaded_mod[modn] or { name = "" }, type) + Mod.get_event_template(Mod.loaded_mod[modn] or { name = "" }, type) if not event_template then log.warn("Unable to create event of type" .. type .. ". Returning nil...") @@ -624,7 +638,7 @@ function Mod.create_event(m, type, content, ev) new_event.cursor_position = vim.api.nvim_win_get_cursor(winid) local row_1b = new_event.cursor_position[1] new_event.line_content = - vim.api.nvim_buf_get_lines(bufid, row_1b - 1, row_1b, true)[1] + vim.api.nvim_buf_get_lines(bufid, row_1b - 1, row_1b, true)[1] new_event.referrer = m.name new_event.broadcast = true new_event.buffer = bufid @@ -642,8 +656,8 @@ function Mod.broadcast_event(event, callback) if not event.split_type then log.error( "Unable to broadcast event of type" - .. event.type - .. "- invalid event name" + .. event.type + .. "- invalid event name" ) return end diff --git a/scripts/bin/word b/scripts/bin/word index 12ed51c..255ac4f 100755 --- a/scripts/bin/word +++ b/scripts/bin/word @@ -1,37 +1,714 @@ #!/usr/bin/env lua -local ffi, jit = require("ffi"), require("jit") -local e = require("vim.lpeg") -local lp = require("lpeg") -local cr = coroutine -local io, i, o, e = io, io.stdin, io.stdout, io.stderr - ----@param arg string -local function handle_arg(arg) - if arg == "-h" or arg == "--help" then - print("Help") - elseif arg == "-v" or arg == "--version" then - print("Version") - elseif arg == "-i" or arg == "--interactive" then - print("Interactive") - elseif arg == "-e" or arg == "--execute" then - print("Execute") +--+ +----------------------+ word +----------------------+ +-- +--+ | | +-- +--+ | word v0.1.0-alpha | +-- +--+ | | +-- +--+ | ABOUT | +-- +--+ | word (word.lua) is a dev-focused note-taking | +-- +--+ | environment for markdown, in development. | +-- +--+ | | +-- +--+ | USAGE | +-- +--+ | word [options] [file] | +-- +--+ | | +-- +--+ | OPTIONS | +-- +--+ | -h, --help Show help and exit | +-- +--+ | -v, --version Show version and exit | +-- +--+ | -i, --interactive Run in interactive mode | +-- +--+ | -e, --execute Run in execute mode | +-- +--+ | -c, --config Specify a config file | +-- +--+ | | +-- +--+ | ARGS | +-- +--+ | serve Run the server | +-- +--+ | init Initialize the server | +-- +--+ | shell Run the shell | +-- +--+ | update Update the server | +-- +--+ | install Install the server | +-- +--+ | uninstall Uninstall the server | +-- +--+ | config Configure the server | +-- +--+ | status Show the server status | +-- +--+ | start Start the server | +-- +--+ | stop Stop the server | +-- +--+ | restart Restart the server | +-- +--+ | | +-- +--+ +----------------------------------------------------+ +-- + +local w_ok, word = pcall(require, "word") +local u_ok, util = pcall(require, "word.util") +local m_ok, mod = pcall(require, "word.mod") +local c_ok, conf = pcall(require, "word.config") +local l_ok, lsp = pcall(require, "word.mod.lsp") +local ws_ok, ws = pcall(require, "word.mod.workspace") +local wts_ok, wts = pcall(require, "word.mod.integration.treesitter") + +--+ +---------------------+ extern +---------------------+ +-- +--+ | | +-- +--+ | import the word lua dependencies. | +-- +--+ | | +-- +--+ +----------------------------------------------------+ +-- + +local lp_ok, lp = pcall(require, "lpeg") +local vt_ok, vts = pcall(require, "vim.treesitter") +local ts_ok, nts = pcall(require, "nvim-treesitter") +local tsu_ok, tsu = pcall(require, "nvim-treesitter.ts_utils") + +--+ +----------------------+ util +----------------------+ +-- +--+ | | +-- +--+ | define utility functions. | +-- +--+ | | +-- +--+ +----------------------------------------------------+ +-- + +-- local lb, rb, gb, yb, s, mb, cb, wb = "\x1b[40m", "\x1b[41m", "\x1b[42m", "\x1b[43m", "\x1b[44m", "\x1b[45m", +-- "\x1b[46m", +-- "\x1b[47m" +local x, i, s, e, u, cr = + "\x1b[0m", "\x1b[7m", "\x1b[1m", "\x1b[3m", "\x1b[4m", "\x1b[9m" +local ll, lr, lg, ly, lb, lm, lc, lw = + "\x1b[90m", + "\x1b[91m", + "\x1b[92m", + "\x1b[93m", + "\x1b[94m", + "\x1b[95m", + "\x1b[96m", + "\x1b[97m" +local l, r, g, y, b, m, c, w = + "\x1b[30m", + "\x1b[31m", + "\x1b[32m", + "\x1b[33m", + "\x1b[34m", + "\x1b[35m", + "\x1b[36m", + "\x1b[37m" +local bi = function(inp) + return inp .. i +end +local si = function(inp) + return inp .. s .. i +end +local br, bg, by, bb, bm, bc, bw = + bi(r), bi(g), bi(y), bi(b), bi(m), bi(c), bi(w) +local sr, sg, sy, sb, sm, sc, sw = + si(r), si(g), si(y), si(b), si(m), si(c), si(w) + +--+ +----------------------+ vars +----------------------+ +-- +--+ | | +-- +--+ | define necessary variables. | +-- +--+ | | +-- +--+ +----------------------------------------------------+ +-- + +local Word = { + pre = { + i = function(c, a) + return c .. "" .. a + end, + y = function(a) + return sy .. "" .. a + end, + c = function(a) + return sc .. "" .. a + end, + m = function(a) + return sm .. "" .. a + end, + r = function(a) + return sr .. "" .. a + end, + w = function(a) + return sw .. "" .. a + end, + g = function(a) + return sg .. "" .. a + end, + b = function(a) + return sb .. "" .. a + end, + }, + colors = { + word = y, + info = c, + cmd = m, + arg = w, + flag = g, + }, + style = function(pre, h) + return pre .. " " .. h .. " " + end, + version = "v0.1.0-alpha.2", + repo = "github.com/clpi/word.lua", + home = "word.cli.st", + updated = "2024-12-15", + color = true, + debug = false, +} +Word.styles = {} +Word.bits = { + vers = ll .. "v" .. x .. w .. "0.1.1" .. ll .. "-" .. x .. w .. "alpha", + lambda = ll .. s .. "󰘧 " .. x, + wordi = ll .. s .. "󰘧 " .. x .. y .. "word" .. x, + brk = { + l = ll .. "[" .. x, + r = ll .. "]" .. x, + }, + brc = { + l = ll .. "{" .. x, + r = ll .. "}" .. x, + }, + par = { + l = ll .. "(" .. x, + r = ll .. ")" .. x, + }, + icon = { + block = ll .. "󰆧 " .. x, + info = ll .. "󰆨 " .. x, + }, + arrow = { + l = ll .. "←" .. x, + r = ll .. "→" .. x, + }, + arr = { + l = ll .. "<" .. x, + r = ll .. ">" .. x, + }, + ellipses = ll .. "…" .. x, + pipe = ll .. "|" .. x, + comma = ll .. "," .. x, + colon = ll .. ":" .. x, + period = ll .. "." .. x, + asterisk = ll .. "*" .. x, + plus = ll .. "+" .. x, + hy = ll .. "-" .. x, + hy2 = ll .. "--" .. x, + eq = ll .. "=" .. x, + word = y .. "word" .. x, + markdown = lg .. " 󰍔 " .. g .. " Mark" .. x .. g .. "down" .. x, + wordluai = x .. y .. ll .. "󰘧" .. y .. " word" .. "." .. "lua", + wordlua = x .. ly .. "word" .. ll .. "." .. y .. "lua", + command = ll .. "[" .. g .. "󰆧 " .. g .. "command" .. ll .. "]" .. x, + opts = ll .. "[" .. b .. "󰆧 " .. ll .. "" .. b .. "opts" .. ll .. "]" .. x, + flags = ll .. "[" .. m .. "󰆧 " .. m .. "flags" .. ll .. "]" .. x, + args = ll .. "[" .. r .. "󰆧 " .. ll .. "" .. r .. "args" .. ll .. "]" .. x, + author = "Chris Pecunies " .. g .. "", +} +Word.bits.version = Word.bits.vers + .. ll + .. " (" + .. ll + .. "updated " + .. g + .. Word.updated + .. ll + .. ")" +Word.bits.usage = "" + .. Word.bits.wordi + .. " " + .. Word.bits.command + .. Word.bits.opts + .. Word.bits.flags + .. Word.bits.args + .. Word.bits.brk.l + .. Word.bits.ellipses + .. Word.bits.brk.r +Word.bits.desc = Word.bits.wordlua + .. x + .. w + .. " is a dev-focused, familiar" + .. Word.bits.markdown + .. "\n " + .. w + .. "environment, focused on providing familiarity \n " + .. w + .. "and extensibility for developers, in development." + +--+ +----------------------+ kind +----------------------+ +-- +--+ | | +-- +--+ | define kind type. | +-- +--+ | | +-- +--+ +----------------------------------------------------+ +-- + +local Kind = { + opt = { + param = "param", + flag = "flag", + }, + arg = "arg", + cmd = "cmd", +} + +--+ +----------------------+ args +----------------------+ +-- +--+ | | +-- +--+ | define arg type. | +-- +--+ | | +-- +--+ +----------------------------------------------------+ +-- + +local Arg = { + long = nil, + index = -1, + pos = 1, + kind = nil, + short = nil, + value = nil, + handler = nil, + desc = "", + help = "", +} + +Arg.Kind = { + -- like --... or -... or --...=... or -...=... + opt = { + -- like --...=... or -...=... + param = { + short = { + -- like -a=... + short = "opt_param_short_letter", + -- like -abc=... NOTE: bad + long = "opt_param_short_short", + }, + long = { + -- like --a=... NOTE: bad + short = "opt_param_long_short", + -- like --abc=... + long = "opt_param_long_long", + }, + }, + flag = { + -- like -... + short = { + -- like -a + short = "opt_flag_short_short", + -- like -abc NOTE: bad + long = "opt_flag_short_long", + }, + -- like --... + long = { + -- like --a NOTE: bad + short = "opt_flag_long_short", + -- like --abc + long = "opt_flag_long_long", + }, + }, + }, + arg = "arg", + cmd = { + -- like abc + long = "cmd_long", + -- like a + short = "cmd_short", + }, +} + +---@return string, string +function Arg.Kind.check(a) + if a:sub(1, 1) == "-" then + if a:sub(2, 2) == "-" then + a = a:sub(3) + if #a == 1 then + return a, Arg.Kind.opt.flag.long.short + end + return a, Arg.Kind.opt.flag.long.long + else + a = a:sub(2) + if #a == 1 then + return a, Arg.Kind.opt.flag.short.short + end + return a, Arg.Kind.opt.flag.short.long + end + else + if #a == 1 then + return a, Arg.Kind.cmd.short + else + return a, Arg.Kind.cmd.long + end + end +end + +Arg.Kind.opt.param.is = function(k) + if k:sub(1, 9) == "opt_param" then + return true + end + return false +end +Arg.Kind.opt.flag.is = function(k) + if k:sub(1, 8) == "opt_flag" then + return true + end + return false +end + +Arg.Kind.opt.is = function(k) + if k:sub(1, 3) == "opt" then + return true + end + return false +end + +Arg.Kind.cmd.is = function(k) + if k:sub(1, 3) == "cmd" then + return true + end + return false +end + +function Arg.Kind.unknown(a, k) + if k == Arg.Kind.opt.flag.long.long then + print( + r + .. "unknown" + .. x + .. b + .. " long " + .. l + .. "(long)" + .. x + .. " flag: " + .. Word.bits.hy2 + .. a + ) + elseif k == Arg.Kind.opt.flag.long.short then + print( + r + .. "unknown" + .. x + .. b + .. " long " + .. l + .. "(short)" + .. x + .. " flag: " + .. Word.bits.hy2 + .. a + ) + elseif k == Arg.Kind.opt.flag.short.long then + print( + r + .. "unknown" + .. x + .. g + .. " short " + .. l + .. "(long)" + .. x + .. " flag: " + .. Word.bits.hy + .. a + ) + elseif k == Arg.Kind.opt.flag.short.short then + print( + r + .. "unknown" + .. x + .. g + .. " short " + .. l + .. "(short)" + .. x + .. " flag: " + .. Word.bits.hy + .. a + ) + elseif k == Arg.Kind.cmd.short then + print( + r + .. "unknown" + .. x + .. g + .. " short " + .. y + .. "cmd" + .. ll + .. ": " + .. x + .. a + ) + elseif k == Arg.Kind.cmd.long then + print( + r .. "unknown" .. x .. b .. " long " .. y .. "cmd" .. ll .. ": " .. x .. a + ) + else + print(r .. "unknown" .. x .. " arg" .. ll .. ": " .. x .. a) + end +end + +function Arg.flag(lng, desc, h, sh) + return Arg.init(lng, sh or lng:sub(1, 1), Kind.opt.flag, desc, h) +end + +function Arg.cmd(pos, lng, desc, h, sh) + ---TODO: add subcommands + return Arg.init(lng, sh or lng:sub(1, 1), Kind.cmd, desc, h, pos) +end + +function Arg.init(lng, sh, k, d, h, v, pos) + local self = {} + self.__index = self + self.pos = pos or nil + self.__tostring = function(t) + return t.long + end + self.desc = d or "" + self.long = lng or "" + self.short = sh or l[1] + self.kind = k or Kind.arg + self.handler = h or function() + print(lng, sh) + end + self.value = v or nil + self.help = Arg.help(self) + return self +end + +function Arg:help(h) + if self.kind == Kind.cmd then + return "" + .. g + .. self.short + .. "" + .. x + .. " " + .. Word.bits.pipe + .. " " + .. g + .. self.long:sub(1, 1) + .. x + .. self.long:sub(2) + .. "\t " + .. self.desc + elseif self.kind == Kind.opt.flag then + return "" + .. Word.bits.hy + .. b + .. self.short + .. x + .. " " + .. Word.bits.pipe + .. " " + .. Word.bits.hy2 + .. b + .. self.long:sub(1, 1) + .. x + .. self.long:sub(2) + .. "\t " + .. self.desc else - print("Unknown arg: ", arg) + print(self.long, self.short) + end +end + +function Arg:isopt() + return self.kind == Kind.opt.param or self.kind == Kind.opt.flag +end + +function Arg:check(a, k) + if a == self.long and k == Arg.Kind.opt.flag.long.long then + return true + elseif a == self.short and k == Arg.Kind.opt.flag.short.short then + return true + elseif a == self.short and k == Arg.Kind.cmd.short then + return true + elseif a == self.long and k == Arg.Kind.cmd.long then + return true + end + return false +end + +function Arg:handle(a, k) + if Arg.check(self, a, k) then + return self.handler() + end +end + +--+ +--------------------+ handlers +--------------------+ +-- +--+ | | +-- +--+ | define handler functions. | +-- +--+ | | +-- +--+ +----------------------------------------------------+ +-- + +local function test(...) + print("test") +end + +local function conf(...) + print("conf") +end + +--+ +----------------------+ func +----------------------+ +-- +--+ | | +-- +--+ | define core functions. | +-- +--+ | | +-- +--+ +----------------------------------------------------+ +-- + +Word.opts = {} +Word.args = {} + +Word.help = { + header = { + print = function(pre, h) + print("\n" .. pre .. " " .. h .. " ") + end, + info = "󰯂 INFO ", + cmds = " CMDS ", + args = "󰆧 ARGS ", + flag = "󰷐 FLAGS", + opts = "󰆧 OPTS ", + usage = "󰒓 USAGE", + }, + word = function() + print("\n" .. Word.bits.wordi .. " " .. x .. Word.bits.version) + -- print(b .. " author " .. x .. " " .. Word.bits.author) + -- print(b .. " repo " .. x .. " " .. Word.repo) + -- print(b .. " home " .. x .. " " .. Word.home) + end, + info = function() + Word.help.header.print(sy, Word.help.header.info) + print(bg .. "" .. x .. " " .. w .. Word.bits.desc) + end, + usage = function() + Word.help.header.print(sg, Word.help.header.usage) + print(bg .. "" .. x .. " " .. w .. Word.bits.usage) + end, + cmds = function() + Word.help.header.print(sg, Word.help.header.cmds) + for _, v in pairs(Word.cmds) do + print(bg .. "" .. x .. " " .. w .. Arg.help(v)) + end + end, + flags = function() + Word.help.header.print(sb, Word.help.header.flag) + for _, v in pairs(Word.flags) do + print(bg .. "" .. x .. " " .. w .. Arg.help(v)) + end + end, + opts = function() + Word.help.header.print(sm, Word.help.header.opts) + print(br .. "" .. x .. " " .. x .. r .. Word.bits.ellipses) + end, + args = function() + Word.help.header.print(sr, Word.help.header.args) + print(bm .. "" .. x .. " " .. x .. m .. Word.bits.ellipses) + end, +} +Word.help.print = function() + Word.help.word() + Word.help.info() + -- Word.help.usage() + Word.help.cmds() + Word.help.flags() + -- Word.help.opts() + -- Word.help.args() +end +Word.flags = { + version = Arg.flag("version", "Print version", function() + print(Word.version) + end), + debug = Arg.flag("debug", "Set debug", function() + print("debug") + end), + config = Arg.flag("config", "Specify config file", function(...) + print("config") + end), + stdout = Arg.flag("stdout", "Set stdout output", function() + print("stdout") + end), + profile = Arg.flag("color", "Set color output", function() + print("color") + end), + help = Arg.flag("help", "Print help", Word.help.print), +} + +Word.cmds = { + init = Arg.cmd(1, "init", "Initialize workspace", function() + print("init") + end), + upgrade = Arg.cmd(1, "upgrade", "Upgrade binary", function() + print("upgrade") + end), + log = Arg.cmd(1, "log", "Log functionality", function(...) + print("log") + end), + note = Arg.cmd(1, "note", "Note functionality", function(...) + print("note") + end), + workspace = Arg.cmd(1, "workspace", "List workspaces", function(...) + print("work") + end), + run = Arg.cmd(1, "run", "Run the lsp", function(...) + print("run") + end), + serve = Arg.cmd(1, "serve", "Serve the lsp", function(...) + print("serve") + end), + -- version = Arg.cmd("version", "Print version", Word.flags.version.desc, Word.flags.version.handler), + config = Arg.cmd(1, "config", "Set config values", Word.flags.config.handler), + help = Arg.cmd(1, "help", "Print help", Word.flags.help.handler), +} +--- @param a string arg +function Word:pflag(a, k) + local ok = false + for _, v in pairs(self.flags) do + if Arg.check(v, a, k) then + ok = true + return Arg.handle(v, a, k) + end + end + if ok == false then + return Arg.Kind.unknown(a, k) end end -local function parse() - local i, a, ac = 1, arg, #arg - while i <= ac do - local arg = a[i] - print(i, arg, "\n") - handle_arg(arg) - i = i + 1 +--- @param a string arg +function Word:pcmd(ix, a, k) + local ok = false + for _, v in pairs(self.cmds) do + local pos = v.pos or 1 + if Arg.check(v, a, k, ix) and ix == pos then + ok = true + return Arg.handle(v, a, k, ix) + end + end + if ok == false then + return Arg.Kind.unknown(a, k) + end +end + +--- @return nil +function Word:parse() + local a, ac = arg, #arg + if ac == 0 then + self.flags.help.handler() + end + local ci = 1 + for _ix, str in ipairs(a) do + local st, k = Arg.Kind.check(str) + if Arg.Kind.opt.flag.is(k) then + self:pflag(st, k) + elseif Arg.Kind.cmd.is(k) then + self:pcmd(ci, st, k) + ci = ci + 1 + else + Arg.Kind.unknown(st, k) + end end end -print("HI") +--+ +----------------------+ main +----------------------+ +-- +--+ | | +-- +--+ | define and call main function. | +-- +--+ | | +-- +--+ +----------------------------------------------------+ +-- + +function Word:main() + self:parse() +end + +Word:main() + +--+ +----------------------+ word +----------------------+ +-- +--+ | | +-- +--+ | version 0.1.0-alpha. | +-- +--+ | | +-- +--+ | author: Chris Pecunies | +-- +--+ | | +-- +--+ +----------------------------------------------------+ +-- -parse() ---vim:ft=lua +--vim:ft=lua,ts=2,sw=2,sts=2,et diff --git a/scripts/bin/word-lsp b/scripts/bin/word-lsp index bc8cebe..c66eab0 100755 --- a/scripts/bin/word-lsp +++ b/scripts/bin/word-lsp @@ -1,277 +1,582 @@ -#!/usr/bin/env bash - -# ======================= word-lsp ======================= - -# ----------------------- exports ----------------------- - -export WORD_LSP_BIN="word-lsp" -export WORD_LSP_COMPLETIONS=$(head [file] | +-- +--+ | | +-- +--+ | OPTIONS | +-- +--+ | -h, --help Show help and exit | +-- +--+ | -v, --version Show version and exit | +-- +--+ | -i, --interactive Run in interactive mode | +-- +--+ | -e, --execute Run in execute mode | +-- +--+ | -c, --config Specify a config file | +-- +--+ | | +-- +--+ | ARGS | +-- +--+ | serve Run the server | +-- +--+ | init Initialize the server | +-- +--+ | shell Run the shell | +-- +--+ | update Update the server | +-- +--+ | install Install the server | +-- +--+ | uninstall Uninstall the server | +-- +--+ | config Configure the server | +-- +--+ | status Show the server status | +-- +--+ | start Start the server | +-- +--+ | stop Stop the server | +-- +--+ | restart Restart the server | +-- +--+ | | +-- +--+ +----------------------------------------------------+ +-- -WORD_LSP_DEBUG=false -WORD_LSP_STDIO=false -WORD_LSP_PORT=2088 -WORD_LSP_HOST=localhost +local w_ok, word = pcall(require, "word") +local u_ok, util = pcall(require, "word.util") +local m_ok, mod = pcall(require, "word.mod") +local c_ok, conf = pcall(require, "word.config") +local l_ok, lsp = pcall(require, "word.mod.lsp") +local ws_ok, ws = pcall(require, "word.mod.workspace") +local wts_ok, wts = pcall(require, "word.mod.integration.treesitter") -# ----------------------- methods ----------------------- +--+ +---------------------+ extern +---------------------+ +-- +--+ | | +-- +--+ | import the word lua dependencies. | +-- +--+ | | +-- +--+ +----------------------------------------------------+ +-- -# param 1: id -# param 2: result -function lsp-reply() { - reply '{ - "jsonrpc": "2.0", - "id": '"$1"', - "result": '"$2"' - }' -} +local lp_ok, lp = pcall(require, "lpeg") +local vt_ok, vts = pcall(require, "vim.treesitter") +local ts_ok, nts = pcall(require, "nvim-treesitter") +local tsu_ok, tsu = pcall(require, "nvim-treesitter.ts_utils") -function reply() { - local b="$1" - local len=${#b} - local r="Content-Length: $len\r\n\r\n$b" - echo "$r" >>/tmp/out.log - echo -e "$r" -} +--+ +----------------------+ util +----------------------+ +-- +--+ | | +-- +--+ | define utility functions. | +-- +--+ | | +-- +--+ +----------------------------------------------------+ +-- -# param 1: id -# param 2: method -function lsp-handle() { - ID="$1" - METHOD="$2" - case $2 in - 'initialize') lsp-reply $ID '{ - "clientInfo": '"$WORD_LSP_CLIENTINFO"', - "capabilities": '"$WORD_LSP_CAPABILITIES"' - }' ;; - 'textDocument/moniker') lsp-reply "$ID" '[]' ;; - 'textDocument/codeLens') lsp-reply "$ID" '[]' ;; - 'textDocument/definition') lsp-reply "$ID" '[]' ;; - 'textDocument/documentHighlight') lsp-reply "$ID" '[]' ;; - 'textDocument/documentLink') lsp-reply "$ID" '[]' ;; - 'textDocument/publishDiagnostics') lsp-reply $ID '[]' ;; - 'textDocument/signatureHelp') lsp-reply $ID '{ - "signatures": [], - "activeSignature": 0, - "activeParameter": 0 - }' ;; - 'textDocument/completion') lsp-reply "$ID" '{ - "isIncomplete": false, - "items": '"$WORD_LSP_COMPLETIONS"' - }' ;; - 'textDocument/rename') lsp-reply "$ID" 'null' ;; - 'textDocument/formatting') lsp-reply "$ID" '[]' ;; - 'textDocument/rangeFormatting') lsp-reply "$ID" '[]' ;; - 'textDocument/onTypeFormatting') lsp-reply "$ID" '[]' ;; - 'textDocument/prepareRename') lsp-reply "$ID" 'null' ;; - 'textDocument/hover') lsp-reply "$ID" '{ - "contents": { - "kind": "markdown", - "value": "```python\nhello world\n```" - } - }' ;; - esac +local x, i, s, e, u, cr = "\x1b[0m", "\x1b[7m", "\x1b[1m", "\x1b[3m", "\x1b[4m", "\x1b[9m" +local lb, rb, gb, yb, bb, mb, cb, wb = "\x1b[40m", "\x1b[41m", "\x1b[42m", "\x1b[43m", "\x1b[44m", "\x1b[45m", + "\x1b[46m", + "\x1b[47m" +local l, r, g, y, b, m, c, w = "\x1b[90m", "\x1b[31m", "\x1b[32m", "\x1b[33m", "\x1b[34m", "\x1b[35m", + "\x1b[36m", + "\x1b[37m" +local bi = function(inp) return inp .. i end +local si = function(inp) return inp .. s .. i end +local br, bg, by, bb, bm, bc, bw = bi(r), bi(g), bi(y), bi(b), bi(m), bi(c), bi(w) +local bbr, bbg, bby, bbb, bbm, bbc, bbw = si(r), si(g), si(y), si(b), si(m), si(c), si(w) -} -function lsp-format() { - echo "" -} - -function lsp-serve() { - echo "Serving at " $WORD_LSP_PORT - while IFS= read -r LN; do - [[ "$LN" =~ ^Content-Length:\ ([0-9]+) ]] - LEN="${BASH_REMATCH[1]}" - LEN=$((len + 2)) - PAYLOAD=$(head -c "$LEN") - ID=$(echo -E "$PAYLOAD" | jq --raw-output '.id') - METHOD=$(echo -E "$PAYLOAD" | jq --raw-output '.method') - log $ID $METHOD - lsp-handle $ID $METHOD - done +--+ +----------------------+ vars +----------------------+ +-- +--+ | | +-- +--+ | define necessary variables. | +-- +--+ | | +-- +--+ +----------------------------------------------------+ +-- +local Word = { + pre = { + i = function(c, a) return c .. "" .. a end, + y = function(a) return bby .. "" .. a end, + c = function(a) return bbc .. "" .. a end, + m = function(a) return bbm .. "" .. a end, + r = function(a) return bbr .. "" .. a end, + w = function(a) return bbw .. "" .. a end, + g = function(a) return bbg .. "" .. a end, + b = function(a) return bbb .. "" .. a end, + }, + colors = { + word = y, + info = c, + cmd = m, + arg = w, + flag = g, + }, + style = function(pre, h) return pre .. " " .. h .. " " end, + version = "v0.1.0-alpha.2", + repo = "github.com/clpi/word.lua", + home = "word.cli.st", + updated = "2024-12-15", + color = true, + debug = false, } +Word.styles = { -# ======================= format ======================= - -# ----------------------- styling ----------------------- - -X="\x1b[0m" # RESET -B="\x1b[1m" # BOLD -D="\x1b[2m" # DIM -I="\x1b[3m" # ITALIC -U="\x1b[4m" # UNDERLINE -L="\x1b[5m" # BLINK -R="\x1b[7m" # REVERSE -H="\x1b[8m" # HIDDEN -F="\x1b[9m" # STRIKE - -# ----------------------- colors ----------------------- - -FL="\x1b[30m" # FG BLACK -FR="\x1b[31m" # FG RED -FG="\x1b[32m" # FG GREEN -FY="\x1b[33m" # FG YELLOW -FB="\x1b[34m" # FG BLUE -FM="\x1b[35m" # FG MAGENTA -FM="\x1b[36m" # FG CYAN -FW="\x1b[37m" # FG WHITE - -BL="\x1b[40m" # BG BLACK -BR="\x1b[41m" # BG RED -BG="\x1b[42m" # BG GREEN -BY="\x1b[43m" # BG YELLOW -BB="\x1b[44m" # BG BLUE -BM="\x1b[45m" # BG MAGENTA -BC="\x1b[46m" # BG CYAN -BW="\x1b[47m" # BG WHITE - -# ----------------------- helpers ----------------------- - -bold() { - echo -e "$B$1$X" -} -italic() { - echo -e "$I$1$X" } -underline() { - echo -e "$U$1$X" +Word.bits = { + vers = l .. "v" .. x .. w .. "0.1.1" .. l .. "-" .. x .. w .. "alpha", + lambda = l .. s .. "󰘧 " .. x, + wordi = l .. s .. "󰘧 " .. x .. y .. "word" .. x, + brk = { + l = l .. "[" .. x, + r = l .. "]" .. x, + }, + brc = { + l = l .. "{" .. x, + r = l .. "}" .. x, + }, + par = { + l = l .. "(" .. x, + r = l .. ")" .. x, + }, + icon = { + block = l .. "󰆧 " .. x, + info = l .. "󰆨 " .. x, + }, + arrow = { + l = l .. "←" .. x, + r = l .. "→" .. x, + }, + arr = { + l = l .. "<" .. x, + r = l .. ">" .. x, + }, + ellipses = l .. "…" .. x, + pipe = l .. "|" .. x, + comma = l .. "," .. x, + colon = l .. ":" .. x, + period = l .. "." .. x, + asterisk = l .. "*" .. x, + plus = l .. "+" .. x, + hy = l .. "-" .. x, + hy2 = l .. "--" .. x, + eq = l .. "=" .. x, + word = y .. "word" .. x, + markdown = g .. " 󰍔 Markdown" .. x, + wordluai = x .. y .. lb .. l .. "󰘧" .. y .. " word" .. "." .. "lua", + wordlua = x .. y .. lb .. "word.lua", + command = l .. "[" .. g .. "󰆧 " .. l .. "" .. g .. "command" .. l .. "]" .. x, + opts = l .. "[" .. b .. "󰆧 " .. l .. "" .. b .. "opts" .. l .. "]" .. x, + flags = l .. "[" .. m .. "󰆧 " .. l .. "" .. m .. "flags" .. l .. "]" .. x, + args = l .. "[" .. r .. "󰆧 " .. l .. "" .. r .. "args" .. l .. "]" .. x, + author = "Chris Pecunies " .. g .. "", } -strike() { - echo -e "$F$1$X" -} -reverse() { - echo -e "$R$1$X" -} -blink() { - echo -e "$L$1$X" -} -dim() { - echo -e "$D$1$X" -} -color() { - echo -e "$2$1$X" -} -# 1: log -# 2: message -# 3: context -# 4: location -# 5: color -logs() { - DIV="$FW$R$D$L $X" - LOC="" - CTX="" - MSG="" - LOG="" - [[ -n "$1" ]] && LOG="$B$5$R $1 $X" || LOG="" - [[ -n "$2" ]] && MSG="$FW$D$2$X" || MSG="" - [[ -n "$3" ]] && CTX="$5$B$3$X" || CTX="" - [[ -n "$4" ]] && LOC="$FL$B($4)$X" || LOC="" - echo -e "$LOG $CTX $MSG $LOC" -} -LOC="" +Word.bits.version = Word.bits.vers .. + l .. " (" .. l .. "updated" .. g .. " " .. Word.updated .. l .. ")" +Word.bits.usage = "" + .. Word.bits.wordi .. " " + .. Word.bits.command .. "" + .. Word.bits.opts .. "" + .. Word.bits.flags .. "" .. "" + .. Word.bits.args .. "" + .. Word.bits.brk.l .. "" .. Word.bits.ellipses .. "" .. Word.bits.brk.r +Word.bits.desc = Word.bits.wordlua .. x .. + " is a dev-focused, familiar" .. Word.bits.markdown .. "\n " + .. "environment, focused on providing familiarity \n " + .. "and extensibility for developers, in development." -# 1: context -# 2: message -# 3: location -info() { - logs "󰍡 INF" $2 $1 "" "$FB" -} -log() { - logs "󰗚 LOG" $2 $1 "" $FW -} -# 󰙅 󰍔 󱡠 󰆼  󰘧 󰷐 -dbg() { - logs "󰯂 DBG" $2 $1 "" $FM -} -hint() { - logs " HNT" $2 $1 "" $FG -} -warn() { - logs " WRN" $2 $1 "" $FY -} -err() { - logs "󰟢 ERR" $2 $1 "" $FR +--+ +----------------------+ kind +----------------------+ +-- +--+ | | +-- +--+ | define kind type. | +-- +--+ | | +-- +--+ +----------------------------------------------------+ +-- + +local Kind = { + opt = { + param = "param", + flag = "flag", + }, + arg = "arg", + cmd = "cmd", } -lsp() { - logs "󰘧 LSP" $2 $1 "" $FM + +--+ +----------------------+ args +----------------------+ +-- +--+ | | +-- +--+ | define arg type. | +-- +--+ | | +-- +--+ +----------------------------------------------------+ +-- + +local Arg = { + long = nil, + kind = nil, + short = nil, + value = nil, + handler = nil, + desc = "", + help = "", } -word() { - logs "󰒓 word" $2 $1 "" $FB + +Arg.Kind = { + -- like --... or -... or --...=... or -...=... + opt = { + -- like --...=... or -...=... + param = { + short = { + -- like -a=... + short = "opt_param_short_letter", + -- like -abc=... NOTE: bad + long = "opt_param_short_short", + }, + long = { + -- like --a=... NOTE: bad + short = "opt_param_long_short", + -- like --abc=... + long = "opt_param_long_long", + } + }, + flag = { + -- like -... + short = { + -- like -a + short = "opt_flag_short_short", + -- like -abc NOTE: bad + long = "opt_flag_short_long", + }, + -- like --... + long = { + -- like --a NOTE: bad + short = "opt_flag_long_short", + -- like --abc + long = "opt_flag_long_long", + } + }, + }, + arg = "arg", + cmd = { + -- like abc + long = "cmd_long", + -- like a + short = "cmd_short", + + } } -trace() { - logs "󰆧 TRC" $2 $1 "" $FM + +---@return string, string +function Arg.Kind.check(a) + if a:sub(1, 1) == "-" then + if a:sub(2, 2) == "-" then + a = a:sub(3) + if #a == 1 then + return a, Arg.Kind.opt.flag.long.short + end + return a, Arg.Kind.opt.flag.long.long + else + a = a:sub(2) + if #a == 1 then + return a, Arg.Kind.opt.flag.short.short + end + return a, Arg.Kind.opt.flag.short.long + end + else + if #a == 1 then + return a, Arg.Kind.cmd.short + else + return a, Arg.Kind.cmd.long + end + end +end + +Arg.Kind.opt.param.is = function(k) + if k:sub(1, 9) == "opt_param" then + return true + end + return false +end +Arg.Kind.opt.flag.is = function(k) + if k:sub(1, 8) == "opt_flag" then + return true + end + return false +end + +Arg.Kind.opt.isopt = function(k) + if k:sub(1, 3) == "opt" then + return true + end + return false +end + +Arg.Kind.cmd.iscmd = function(k) + if k:sub(1, 3) == "cmd" then + return true + end + return false +end + + +function Arg.Kind.unknown(a, k) + if k == Arg.Kind.opt.flag.long.long then + print(r .. "unknown" .. x .. b .. " long " .. l .. "(long)" .. x .. " flag: " .. Word.bits.hy2 .. a) + elseif k == Arg.Kind.opt.flag.long.short then + print(r .. "unknown" .. x .. b .. " long " .. l .. "(short)" .. x .. " flag: " .. Word.bits.hy2 .. a) + elseif k == Arg.Kind.opt.flag.short.long then + print(r .. "unknown" .. x .. g .. " short " .. l .. "(long)" .. x .. " flag: " .. Word.bits.hy .. a) + elseif k == Arg.Kind.opt.flag.short.short then + print(r .. "unknown" .. x .. g .. " short " .. l .. "(short)" .. x .. " flag: " .. Word.bits.hy .. a) + elseif k == Arg.Kind.cmd.short then + print(r .. "unknown" .. x .. g .. " short " .. y .. "cmd" .. l .. ": " .. x .. a) + elseif k == Arg.Kind.cmd.long then + print(r .. "unknown" .. x .. b .. " long " .. y .. "cmd" .. l .. ": " .. x .. a) + else + print(r .. "unknown" .. x .. " arg" .. l .. ": " .. x .. a) + end +end + +function Arg.flag(lng, desc, h, sh) + return Arg.init(lng, sh or lng:sub(1, 1), Kind.opt.flag, desc, h) +end + +function Arg.cmd(lng, desc, h, sh) + return Arg.init(lng, sh or lng:sub(1, 1), Kind.cmd, desc, h) +end + +function Arg.init(lng, sh, k, d, h, v) + local self = {} + self.__index = self + self.__tostring = function(t) + return t.long + end + self.desc = d or "" + self.long = lng or "" + self.short = sh or l[1] + self.kind = k or Kind.arg + self.handler = h or function() print(l, s) end + self.value = v or nil + self.help = Arg.help(self) + return self +end + +function Arg:help(h) + if self.kind == Kind.cmd then + return "" + .. g .. self.short .. "" .. x .. " " + .. Word.bits.pipe .. " " + .. g .. self.long:sub(1, 1) + .. x .. self.long:sub(2) + .. "\t " + .. self.desc + elseif self.kind == Kind.opt.flag then + return "" + .. Word.bits.hy + .. b .. self.short .. x .. " " + .. Word.bits.pipe .. " " + .. Word.bits.hy2 + .. b .. self.long:sub(1, 1) + .. x .. self.long:sub(2) + .. "\t " + .. self.desc + else + print(self.long, self.short) + end +end + +function Arg:isopt() + return self.kind == Kind.opt.param or self.kind == Kind.opt.flag +end + +function Arg:check(a, k) + if a == self.long and k == Arg.Kind.opt.flag.long.long then + return true + elseif a == self.short and k == Arg.Kind.opt.flag.short.short then + return true + elseif a == self.short and k == Arg.Kind.cmd.short then + return true + elseif a == self.long and k == Arg.Kind.cmd.long then + return true + end + return false +end + +function Arg:handle(a, k) + if Arg.check(self, a, k) then + return self.handler() + end +end + +--+ +--------------------+ handlers +--------------------+ +-- +--+ | | +-- +--+ | define handler functions. | +-- +--+ | | +-- +--+ +----------------------------------------------------+ +-- + +local function test(...) + print "test" +end + +local function conf(...) + print "conf" +end + +--+ +----------------------+ func +----------------------+ +-- +--+ | | +-- +--+ | define core functions. | +-- +--+ | | +-- +--+ +----------------------------------------------------+ +-- + + +Word.opts = { + } +Word.args = { -# ======================= argparse ======================= -# ----------------------- subcmds ----------------------- - -function show-help() { - echo "Usage: $WORD_LSP_BIN [-h] [-v] [-f filename]" - echo "" - echo "COMMANDS" - echo "" - echo " serve" - echo " run" - echo "" - echo "OPTIONS" - echo "" - echo " --help | -h Show help" - echo " --version | -v Show version" - echo " -c CONFIG-FILE Specify a file" - echo "" } -function show-version() { - word "version" "0.0.1-alpha.1" + +Word.help = { + header = { + print = function(pre, h) print("\n" .. pre .. " " .. h .. " ") end, + info = "󰯂 INFO ", + cmds = " CMDS ", + args = "󰆧 ARGS ", + flag = "󰷐 FLAGS", + opts = "󰆧 OPTS ", + usage = "󰒓 USAGE", + + + }, + word = function() + print("\n" .. Word.bits.wordi .. " " .. x .. Word.bits.version) + -- print(b .. " author " .. x .. " " .. Word.bits.author) + -- print(b .. " repo " .. x .. " " .. Word.repo) + -- print(b .. " home " .. x .. " " .. Word.home) + end, + info = function() + Word.help.header.print(bby, Word.help.header.info) + print(bg .. "" .. x .. " " .. Word.bits.desc) + end, + usage = function() + Word.help.header.print(bbg, Word.help.header.usage) + print(bg .. "" .. x .. " " .. Word.bits.usage) + end, + cmds = function() + Word.help.header.print(bbg, Word.help.header.cmds) + for _, v in pairs(Word.cmds) do + print(bg .. "" .. x .. " " .. Arg.help(v)) + end + end, + flags = function() + Word.help.header.print(bbb, Word.help.header.flag) + for _, v in pairs(Word.flags) do + print(bg .. "" .. x .. " " .. Arg.help(v)) + end + end, + opts = function() + Word.help.header.print(bbm, Word.help.header.opts) + print(br .. "" .. x .. " " .. x .. r .. Word.bits.ellipses) + end, + args = function() + Word.help.header.print(bbr, Word.help.header.args) + print(bm .. "" .. x .. " " .. x .. m .. Word.bits.ellipses) + end, } -function shell() { - lsp "shell" "sh" +Word.help.print = function() + Word.help.word() + Word.help.info() + -- Word.help.usage() + Word.help.cmds() + Word.help.flags() + -- Word.help.opts() + -- Word.help.args() +end +Word.flags = { + version = Arg.flag("version", "Print version", function() + print(Word.version) + end), + debug = Arg.flag("debug", "Set debug", function() + print("debug") + end), + config = Arg.flag("config", "Specify config file", function(...) + print "config" + end), + stdout = Arg.flag("stdout", "Set stdout output", function() + print("stdout") + end), + profile = Arg.flag("color", "Set color output", function() + print("color") + end), + help = Arg.flag("help", "Print help", Word.help.print), } -function update() { - word "update" "..." +Word.cmds = { + init = Arg.cmd("init", "Initialize workspace", function() + print('init') + end), + upgrade = Arg.cmd("upgrade", "Upgrade binary", function() + print('upgrade') + end), + run = Arg.cmd("run", "Run the lsp", function(...) + print "run" + end), + lsp = Arg.cmd("lsp", "Serve the lsp", function(...) + print "serve" + end), + -- version = Arg.cmd("version", "Print version", Word.flags.version.desc, Word.flags.version.handler), + config = Arg.cmd("config", "Set config values", Word.flags.config.handler), + help = Arg.cmd("help", "Print help", Word.flags.help.handler), } -# ----------------------- main fn ----------------------- -function main() { - # if no subcommand, serve - - [[ $# -eq 0 ]] && lsp-serve - - case "$1" in - serve | s | run | r) lsp-serve ;; - shell | sh) shell ;; - --config | -c) WORD_LSP_CONFIG=$2 ;; - --stdio | -s) WORD_LSP_STDIO=true ;; - --debug | -d) WORD_LSP_DEBUG=true ;; - --port | -p) WORD_LSP_PORT=$2 ;; - --host) WORD_LSP_HOST=$2 ;; - help | h | -h | --help) show-help ;; - format | f) lsp-format ;; - version | v | --version | -v) show-version ;; - update | up | u) update ;; - esac -} +--+ +---------------------+ parse +---------------------+ +-- +--+ | | +-- +--+ | define parse functions. | +-- +--+ | | +-- +--+ +----------------------------------------------------+ +-- + +--- @param a string arg +function Word:pflag(a, k) + local ok = false + for _, v in pairs(self.flags) do + if Arg.check(v, a, k) then + ok = true + return Arg.handle(v, a, k) + end + end + if ok == false then Arg.Kind.unknown(a, k) end +end + +--- @param a string arg +function Word:pcmd(a, k) + local ok = false + for _, v in pairs(self.cmds) do + if Arg.check(v, a, k) then + ok = true + return Arg.handle(v, a, k) + end + end + if ok == false then return Arg.Kind.unknown(a, k) end +end + +--- @param a string +function Word:pstr(a) + local st, k = Arg.Kind.check(a) + if Arg.Kind.opt.isopt(k) then + return self:pflag(st, k) + elseif Arg.Kind.cmd.iscmd(k) then + return self:pcmd(st, k) + else + Arg.Kind.unknown(st, k) + end +end + +--- @return nil +function Word:parse() + local i, a, ac = 1, arg, #arg + if ac == 0 then + return self.flags.help.handler() + end + for ai, a in ipairs(a) do + return self:pstr(a) + end +end + +--+ +----------------------+ main +----------------------+ +-- +--+ | | +-- +--+ | define and call main function. | +-- +--+ | | +-- +--+ +----------------------------------------------------+ +-- + +function Word:main() + self:parse() +end -main "$@" +Word:main() -# echo "Running wordsh..." -# serve +--+ +----------------------+ word +----------------------+ +-- +--+ | | +-- +--+ | version 0.1.0-alpha. | +-- +--+ | | +-- +--+ | author: Chris Pecunies | +-- +--+ | | +-- +--+ +----------------------------------------------------+ +-- -# vim:ft=bash +--vim:ft=lua,ts=2,sw=2,sts=2,et diff --git a/scripts/bin/word-lsp.sh b/scripts/bin/word-lsp.sh new file mode 100755 index 0000000..a33945d --- /dev/null +++ b/scripts/bin/word-lsp.sh @@ -0,0 +1,376 @@ +#!/usr/bin/env bash + +# +--------------------+ word-lsp +--------------------+ # +# | | # +# | word-lsp v0.1.0-alpha | # +# | | # +# | ABOUT | # +# | word-lsp is a dev-focused note-taking | # +# | environment for markdown, in development. | # +# | | # +# | USAGE | # +# | word-lsp [options] [file] | # +# | | # +# | OPTIONS | # +# | -h, --help Show help and exit | # +# | -v, --version Show version and exit | # +# | -i, --interactive Run in interactive mode | # +# | -e, --execute Run in execute mode | # +# | -c, --config Specify a config file | # +# | | # +# | ARGS | # +# | serve Run the server | # +# | init Initialize the server | # +# | shell Run the shell | # +# | update Update the server | # +# | install Install the server | # +# | uninstall Uninstall the server | # +# | config Configure the server | # +# | status Show the server status | # +# | start Start the server | # +# | stop Stop the server | # +# | restart Restart the server | # +# | | # +# | EXAMPLES | # +# | word-lsp serve | # +# | word-lsp shell | # +# | | # +# +----------------------------------------------------+ # +# +# +--------------------+ export +--------------------+ # +# | | # +# | define exports. | # +# | | # +# +----------------------------------------------------+ # + +export WORD_LSP_BIN="word-lsp" +export WORD_LSP_COMPLETIONS=$(head >/tmp/out.log + echo -e "$r" +} + +# param 1: id +# param 2: method +function lsp-handle() { + ID="$1" + METHOD="$2" + case $2 in + 'initialize') lsp-reply $ID '{ + "clientInfo": '"$WORD_LSP_CLIENTINFO"', + "capabilities": '"$WORD_LSP_CAPABILITIES"' + }' ;; + 'textDocument/moniker') lsp-reply "$ID" '[]' ;; + 'textDocument/codeLens') lsp-reply "$ID" '[]' ;; + 'textDocument/definition') lsp-reply "$ID" '[]' ;; + 'textDocument/documentHighlight') lsp-reply "$ID" '[]' ;; + 'textDocument/documentLink') lsp-reply "$ID" '[]' ;; + 'textDocument/publishDiagnostics') lsp-reply $ID '[]' ;; + 'textDocument/signatureHelp') lsp-reply $ID '{ + "signatures": [], + "activeSignature": 0, + "activeParameter": 0 + }' ;; + 'textDocument/completion') lsp-reply "$ID" '{ + "isIncomplete": false, + "items": '"$WORD_LSP_COMPLETIONS"' + }' ;; + 'textDocument/rename') lsp-reply "$ID" 'null' ;; + 'textDocument/formatting') lsp-reply "$ID" '[]' ;; + 'textDocument/rangeFormatting') lsp-reply "$ID" '[]' ;; + 'textDocument/onTypeFormatting') lsp-reply "$ID" '[]' ;; + 'textDocument/prepareRename') lsp-reply "$ID" 'null' ;; + 'textDocument/hover') lsp-reply "$ID" '{ + "contents": { + "kind": "markdown", + "value": "```python\nhello world\n```" + } + }' ;; + esac + +} +function lsp-format() { + echo -e "" +} + +function lsp-serve() { + echo -e "Serving at " $WORD_LSP_PORT + while IFS= read -r LN; do + [[ "$LN" =~ ^Content-Length:\ ([0-9]+) ]] + LEN="${BASH_REMATCH[1]}" + LEN=$((len + 2)) + PAYLOAD=$(head -c "$LEN") + ID=$(echo -E "$PAYLOAD" | jq --raw-output '.id') + METHOD=$(echo -E "$PAYLOAD" | jq --raw-output '.method') + log $ID $METHOD + lsp-handle $ID $METHOD + done + +} + +# +--------------------+ style +----------------------+ # +# | | # +# | define style utilities. | # +# | | # +# +-----------------------------------------------------+ # + +X="\x1b[0m" # RESET +B="\x1b[1m" # BOLD +D="\x1b[2m" # DIM +I="\x1b[3m" # ITALIC +U="\x1b[4m" # UNDERLINE +L="\x1b[5m" # BLINK +R="\x1b[7m" # REVERSE +H="\x1b[8m" # HIDDEN +F="\x1b[9m" # STRIKE + +FL="\x1b[30m" # FG BLACK +FR="\x1b[31m" # FG RED +FG="\x1b[32m" # FG GREEN +FY="\x1b[33m" # FG YELLOW +FB="\x1b[34m" # FG BLUE +FM="\x1b[35m" # FG MAGENTA +FC="\x1b[36m" # FG CYAN +FW="\x1b[37m" # FG WHITE + +BL="\x1b[40m" # BG BLACK +BR="\x1b[41m" # BG RED +BG="\x1b[42m" # BG GREEN +BY="\x1b[43m" # BG YELLOW +BB="\x1b[44m" # BG BLUE +BM="\x1b[45m" # BG MAGENTA +BC="\x1b[46m" # BG CYAN +BW="\x1b[47m" # BG WHITE + +# +---------------------+ util +----------------------+ # +# | | # +# | define utility functions. | # +# | | # +# +-----------------------------------------------------+ # + +bold() { + echo -e "$B$1$X" +} +italic() { + echo -e "$I$1$X" +} +underline() { + echo -e "$U$1$X" +} +strike() { + echo -e "$F$1$X" +} +reverse() { + echo -e "$R$1$X" +} +blink() { + echo -e "$L$1$X" +} +dim() { + echo -e "$D$1$X" +} +color() { + echo -e "$2$1$X" +} +# 1: log +# 2: message +# 3: context +# 4: location +# 5: color +logs() { + DIV="$FW$R$D$L $X" + LOC="" + CTX="" + MSG="" + LOG="" + [[ -n "$1" ]] && LOG="$B$5$R $1 $X" || LOG="" + [[ -n "$2" ]] && MSG="$FW$D$2$X" || MSG="" + [[ -n "$3" ]] && CTX="$5$B$3$X" || CTX="" + [[ -n "$4" ]] && LOC="$FL$B($4)$X" || LOC="" + echo -e "$LOG $CTX $MSG $LOC" +} +LOC="" + +# 1: context +# 2: message +# 3: location +# 󰙅 󰍔 󱡠 󰆼  󰘧󰷐 +info() { + logs "󰍡 INF" $2 $1 "" "$FB" +} +log() { + logs "󰗚 LOG" $2 $1 "" $FW +} +dbg() { + logs "󰯂 DBG" $2 $1 "" $FM +} +hint() { + logs " HNT" $2 $1 "" $FG +} +warn() { + logs " WRN" $2 $1 "" $FY +} +err() { + logs "󰟢 ERR" $2 $1 "" $FR +} +lsp() { + logs "󰘧 LSP" $2 $1 "" $FM +} +word() { + logs "�������������������������������� word" $2 $1 "" $FB +} +trace() { + logs "󰆧 TRC" $2 $1 "" $FM +} + +# +---------------------+ cmds +- --------------------+ # +# | | # +# | define command functions. | # +# | | # +# +-----------------------------------------------------+ # + +function word-help() { + echo -e "\x1b[1m\x1b[33m\x1b[7m 󰘧 WORD \x1b[0m" + echo -e "\x1b[1m\x1b[33m\x1b[7m \x1b[0m v0.1.0-alpha.2\n" + echo -e "\x1b[1m\x1b[32m\x1b[7m 󰯂 INFO \x1b[0m " + echo -e "\x1b[1m\x1b[32m\x1b[7m \x1b[0m word\x1b[0m is a dev-focused, familiar note-taking" + echo -e "\x1b[1m\x1b[32m\x1b[7m \x1b[0m environment for\x1b[32m 󰍔\x1b[0m\x1b[32m Markdown\x1b[0m, in development.\n" + echo -e "\x1b[1m\x1b[36m\x1b[7m 󰒓 USAGE \x1b[0m " + echo -e "\x1b[1m\x1b[36m\x1b[7m \x1b[0m word [options]\x1b[0m [file]\x1b[0m\n" + echo -e "\x1b[1m\x1b[34m\x1b[7m 󰆧 OPTS \x1b[0m " + echo -e "\x1b[1m\x1b[34m\x1b[7m \x1b[0m -h\x1b[0m, --help\x1b[0m Show help and exit" + echo -e "\x1b[1m\x1b[34m\x1b[7m \x1b[0m -v\x1b[0m, --version\x1b[0m Show version and exit " + echo -e "\x1b[1m\x1b[34m\x1b[7m \x1b[0m -d\x1b[0m, --debug \x1b[0m Run in debug mode " + echo -e "\x1b[1m\x1b[34m\x1b[7m \x1b[0m -c\x1b[0m, --config\x1b[0m Specify a config file\n" + echo -e "\x1b[1m\x1b[35m\x1b[7m 󰷐 CMDS \x1b[0m " + echo -e "\x1b[1m\x1b[35m\x1b[7m \x1b[0m serve | s Run the server " + echo -e "\x1b[1m\x1b[35m\x1b[7m \x1b[0m update | u Update the server " + echo -e "\x1b[1m\x1b[35m\x1b[7m \x1b[0m config | c Configure the server " + echo -e "\x1b[1m\x1b[35m\x1b[7m \x1b[0m help | h Show this help \n" + echo -e "\x1b[1m\x1b[31m\x1b[7m  ARGS \x1b[0m " + echo -e "\x1b[1m\x1b[31m\x1b[7m \x1b[0m [file] The file to open \n" +} +function show-help() { + echo -e " " + echo -e " $B$FY$R$D$L 󰘧 word-lsp $X v0.1.0-alpha.2 $X " + echo -e " " + echo -e " $B$FG$R$D$L 󰯂 ABOUT $X " + echo -e " word-lsp$X is a dev-focused note-taking " + echo -e " environment for$FG 󰍔$X$FG Markdown$X, in development. " + echo -e " " + echo -e " $B$FC$R$D$L 󰒓 USAGE $X " + echo -e " word-lsp$X [options]$X [file]$X " + echo -e " " + echo -e " $B$FB$R$D$L 󰆧 FLAGS $X " + echo -e " -h$X, $D--help$X Show help and exit " + echo -e " -v$X, $D--version$X Show version and exit " + echo -e " -i$X, $D--interactive$X Run in interactive mode " + echo -e " -e$X, $D--execute$X Run in execute mode " + echo -e " -c$X, $D--config$X Specify a config file " + echo -e " " + echo -e " $B$FM$R$D$L 󰷐 COMMAND $X " + echo -e " serve | s Run the server " + echo -e " update | u Update the server " + echo -e " config | c Configure the server " + echo -e " help | h Show this help " + echo -e " " + echo -e " $B$FR$R$D$L  ARG $X " + echo -e " [file] The file to open " + echo -e " " +} +function show-version() { + word "version" "0.0.1-alpha.1" +} +function shell() { + lsp "shell" "sh" +} + +function update() { + word "update" "..." +} + +# +---------------------+ main +----------------------+ # +# | | # +# | define and call main function. | # +# | | # +# +-----------------------------------------------------+ # + +function main() { + # if no subcommand, serve + + [[ $# -eq 0 ]] && lsp-serve + + case "$1" in + serve | s | run | r) lsp-serve ;; + shell | sh) shell ;; + --config | -c) WORD_LSP_CONFIG=$2 ;; + --stdio | -s) WORD_LSP_STDIO=true ;; + --debug | -d) WORD_LSP_DEBUG=true ;; + --port | -p) WORD_LSP_PORT=$2 ;; + --host) WORD_LSP_HOST=$2 ;; + halp | --halp) show-help ;; + help | h | -h | --help) word-help ;; + format | f) lsp-format ;; + version | v | --version | -v) show-version ;; + update | up | u) update ;; + esac +} + +main "$@" + +# +------------------+ word-lsp +---------------------+ # +# | | # +# | word-lsp v0.1.0-alpha.2 | # +# | | # +# | Chris Pecunies | # +# | | # +# +-----------------------------------------------------+ # + +#vim:ft=bash,ts=2,sw=2,sts=2,et diff --git a/scripts/bin/word.lua b/scripts/bin/word.lua deleted file mode 100644 index e847d47..0000000 --- a/scripts/bin/word.lua +++ /dev/null @@ -1,5 +0,0 @@ -#!/usr/bin/env lua - --- load - -local m = require("lpeg") diff --git a/scripts/bin/wordf b/scripts/bin/wordf deleted file mode 100755 index 3c5dc13..0000000 --- a/scripts/bin/wordf +++ /dev/null @@ -1,22 +0,0 @@ -#!/usr/bin/env fennel - -(local cr coroutine) -(local fnl (require :fennel)) - -(print "hi") -(lambda eq? [x y] - "equals?" - (if (= x y) - (print "eq") - ) - (if (~= x y) - (print "neq"))) - -(eq? 3 3) -(eq? 3 4) - -(fn hithere [] - (fnl)) - - -;vim:ft=fennel diff --git a/scripts/bin/wordls b/scripts/bin/wordls deleted file mode 100755 index e38e860..0000000 --- a/scripts/bin/wordls +++ /dev/null @@ -1,43 +0,0 @@ -#!/usr/bin/env lua - --- local e = require("cmp_avante") -local c = require("coroutine") - -S = {} - -S.server = function(disp) - local q = false - local msg = {} - local srv = {} - - ---@return boolean, integer - function srv.request(meth, params, cb) - table.insert(msg, { methd = meth, params = params }) - if meth == "initialize" then - cb(nil, { capabilities = {} }) - elseif meth == "shutdown" then - cb(nil, nil) - end - return true, 1 - end - - function srv.notify(meth, param) - if meth == "exit" then - disp.on_exit(0, 15) - end - end - - function srv.closing() - return q - end - - function srv.terminate() - q = true - end - - return srv -end - -return S - ---vim:ft=lua,ts=2,et,sw=2