lua_formatter = lua_formatter or { initDone = false }
-- Not using @johnnymorganz/[email protected]/stylua.web/stylua_lib.js
-- because of https://github.com/JohnnyMorganz/StyLua/issues/999
local stylua = js.import(
"https://cdn.jsdelivr.net/npm/@isentinel/[email protected]/stylua.web/stylua_lib.min.js"
)
local getChild = function(node, type)
for _, child in ipairs(node.children) do
if child.type == type then return child end
end
end
local getText = function(node)
if not node then return nil end
if node.text then
return node.text
else
for _, child in ipairs(node.children) do
local text = getText(child)
if text then return text end
end
end
end
-- Note: the return value of this can only be used once.
-- You cannot store and reuse the config object, because
-- it is automatically freed after its use.
local getConfig = function()
-- Workaround to call a static method on the Config class.
local newConfig = js.window.eval("(x) => x.Config.new()")
local cfg = newConfig(stylua)
lua_formatter.config = cfg
cfg.column_width = 80
cfg.indent_type = stylua.IndentType.Spaces
cfg.indent_width = 2
cfg.collapse_simple_statement = stylua.CollapseSimpleStatement.Always
return cfg
end
local maybeInit = function()
if not lua_formatter.initDone then
-- This loads the WASM module
lua_formatter.module = stylua.default()
lua_formatter.initDone = true
end
end
local getCodeBlock = function()
local text = editor.getText()
local tree = markdown.parseMarkdown(text)
local cursorPos = editor.getCursor()
-- find the FencedCode node with lua code that the cursor is currently in
local findMyFence = function()
local node = tree
if not node.children then return nil end
while node.to >= cursorPos do
for _, child in ipairs(node.children) do
if child.from <= cursorPos and child.to >= cursorPos then
if node.type == "FencedCode" then
local info = getText(getChild(node, "CodeInfo"))
if info and info:find("lua") then
return getChild(node, "CodeText")
end
editor.flashNotification(
"[Lua Format] Code has wrong type: " .. info,
"warning"
)
return nil
end
node = child -- traverse into node
break -- for loop
end
end --for
end -- while
end
local fence = findMyFence()
if fence then return fence.children[1] end
editor.flashNotification(
"[Lua Format] Doing nothing. Not in a space-lua fence.",
"warning"
)
return nil
end
function lua_formatter.format()
local line = editor.getCursor()
local block = getCodeBlock()
if not block then return end
maybeInit()
local formatted = stylua.formatCode(block.text, getConfig())
editor.replaceRange(block.from, block.to, formatted)
editor.flashNotification("Lua code block formatted", "info")
editor.moveCursor(line)
end
command.define({
name = "Editor: Lua Format",
run = lua_formatter.format,
})
Last active
October 18, 2025 17:29
-
-
Save felixr/9e713d96c5165bc2f32ea6a0fa9786da to your computer and use it in GitHub Desktop.
Lua formatter for silverbullet
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment