From 04febcfcb512a7fae20bf132abc0e5aa6544650d Mon Sep 17 00:00:00 2001 From: LordMZTE Date: Fri, 16 Jun 2023 19:16:17 +0200 Subject: [PATCH] mzte-nv: add fennel and lua eval functionality --- mzte-nv/conf/init.fnl | 1 + mzte-nv/conf/lua/eval.fnl | 23 +++++++++++ mzte-nv/conf/lua/pluginconf/p-noice.fnl | 6 ++- mzte-nv/src/main.zig | 2 + mzte-nv/src/modules/fennel.zig | 54 +++++++++++++++++++++++++ 5 files changed, 85 insertions(+), 1 deletion(-) create mode 100644 mzte-nv/conf/lua/eval.fnl create mode 100644 mzte-nv/src/modules/fennel.zig diff --git a/mzte-nv/conf/init.fnl b/mzte-nv/conf/init.fnl index 5f7f4f9..cbd563f 100644 --- a/mzte-nv/conf/init.fnl +++ b/mzte-nv/conf/init.fnl @@ -5,3 +5,4 @@ (require :maps) (require :lsp) (require :pipe) +(require :eval) diff --git a/mzte-nv/conf/lua/eval.fnl b/mzte-nv/conf/lua/eval.fnl new file mode 100644 index 0000000..22cc0b7 --- /dev/null +++ b/mzte-nv/conf/lua/eval.fnl @@ -0,0 +1,23 @@ +(local fnl-eval (. (require :mzte_nv) :fennel :eval)) +(vim.api.nvim_create_user_command :Fnl (fn [args] (fnl-eval args.args)) + {:nargs "+"}) + +(fn insert-at-cursor [txt] + (let [[_ row col _ _] (vim.fn.getcurpos) + rpos {:line (- row 1) :character (- col 1)} + range {:start rpos :end rpos}] + (vim.lsp.util.apply_text_edits [{: range :newText (tostring txt)}] 0 :utf-8))) + +;; Fennel Eval +(vim.keymap.set :i : + (fn [] + (vim.ui.input {:prompt "fnleval> "} + (fn [inp] + (insert-at-cursor (fnl-eval inp)))))) + +;; Lua Eval +(vim.keymap.set :i : + (fn [] + (vim.ui.input {:prompt "luaeval> "} + (fn [inp] + (insert-at-cursor (vim.fn.luaeval inp)))))) diff --git a/mzte-nv/conf/lua/pluginconf/p-noice.fnl b/mzte-nv/conf/lua/pluginconf/p-noice.fnl index faef9d4..cf6586f 100644 --- a/mzte-nv/conf/lua/pluginconf/p-noice.fnl +++ b/mzte-nv/conf/lua/pluginconf/p-noice.fnl @@ -8,7 +8,11 @@ (or ;; INFO level (= notif.level :info) (and notif.opts notif.opts.mzte_nv_mini))) -(noice.setup {:messages {:view :mini} +(noice.setup {:cmdline {:format {:fnl {:pattern "^:%s*Fnl%s+" + :icon "🌜" + :lang :fennel + :title :Fennel}}} + :messages {:view :mini} :lsp {:override (collect [_ o (ipairs overrides)] (values o true))} :routes [;; Redirect DAP messages to mini view {:filter {:event :notify :cond show-mini?} :view :mini}] diff --git a/mzte-nv/src/main.zig b/mzte-nv/src/main.zig index 7190c28..5c17cfb 100644 --- a/mzte-nv/src/main.zig +++ b/mzte-nv/src/main.zig @@ -11,6 +11,7 @@ const modules = struct { const cmp = @import("modules/cmp.zig"); const compile = @import("modules/compile.zig"); const cpbuf = @import("modules/cpbuf.zig"); + const fennel = @import("modules/fennel.zig"); const jdtls = @import("modules/jdtls.zig"); const tsn_actions = @import("modules/tsn_actions.zig"); const utils = @import("modules/utils.zig"); @@ -66,6 +67,7 @@ export fn luaopen_mzte_nv(l_: ?*c.lua_State) c_int { .cmp = modules.cmp, .compile = modules.compile, .cpbuf = modules.cpbuf, + .fennel = modules.fennel, .jdtls = modules.jdtls, .tsn_actions = modules.tsn_actions, .utils = modules.utils, diff --git a/mzte-nv/src/modules/fennel.zig b/mzte-nv/src/modules/fennel.zig new file mode 100644 index 0000000..edaf1d9 --- /dev/null +++ b/mzte-nv/src/modules/fennel.zig @@ -0,0 +1,54 @@ +const std = @import("std"); +const ffi = @import("../ffi.zig"); +const ser = @import("../ser.zig"); +const c = ffi.c; + +const fnl_regkey = "mzte-nv-fnl"; + +pub fn luaPush(l: *c.lua_State) void { + ser.luaPushAny(l, .{ + .eval = ffi.luaFunc(lEval), + .fnlMod = ffi.luaFunc(lFnlMod), + }); +} + +fn loadFennel(l: *c.lua_State) !void { + c.lua_getfield(l, c.LUA_REGISTRYINDEX, fnl_regkey); + if (!c.lua_isnil(l, -1)) { + return; + } + c.lua_pop(l, 1); + + std.log.debug("loading fennel", .{}); + + if (c.luaL_loadfile(l, "/usr/share/lua/5.4/fennel.lua") != 0) { + return error.FennelLoad; + } + + if (c.lua_pcall(l, 0, 1, 0) != 0) { + std.log.err("Failed to load fennel compiler: {s}", .{ffi.luaToString(l, -1)}); + return error.FennelLoad; + } + + c.lua_pushvalue(l, -1); + c.lua_setfield(l, c.LUA_REGISTRYINDEX, fnl_regkey); +} + +fn lFnlMod(l: *c.lua_State) !c_int { + try loadFennel(l); + return 1; +} + +fn lEval(l: *c.lua_State) !c_int { + const argc = c.lua_gettop(l); + try loadFennel(l); + c.lua_getfield(l, -1, "eval"); + + var i: c_int = 1; + while (i <= argc) : (i += 1) { + c.lua_pushvalue(l, i); + } + + c.lua_call(l, argc, c.LUA_MULTRET); + return c.lua_gettop(l) - (argc + 1); +}