Skip to content

Commit 0f24e4a

Browse files
authored
feat: auto tangle (#1413)
1 parent 3c3b977 commit 0f24e4a

File tree

2 files changed

+47
-14
lines changed

2 files changed

+47
-14
lines changed

lua/neorg/modules/core/integrations/treesitter/module.lua

+15-10
Original file line numberDiff line numberDiff line change
@@ -534,8 +534,9 @@ module.public = {
534534
return result
535535
end,
536536
--- Given a node this function will break down the AST elements and return the corresponding text for certain nodes
537-
-- @Param tag_node (userdata/treesitter node) - a node of type tag/carryover_tag
538-
get_tag_info = function(tag_node)
537+
--- @param tag_node TSNode - a node of type tag/carryover_tag
538+
--- @param throw boolean - when true, throw an error instead of logging and returning on failure
539+
get_tag_info = function(tag_node, throw)
539540
if
540541
not tag_node
541542
or not vim.tbl_contains(
@@ -558,7 +559,7 @@ module.public = {
558559
if vim.endswith(child:type(), "_carryover_set") then
559560
for subchild in child:iter_children() do
560561
if vim.endswith(subchild:type(), "_carryover") then
561-
local meta = module.public.get_tag_info(subchild)
562+
local meta = module.public.get_tag_info(subchild, throw)
562563

563564
table.insert(attributes, meta)
564565
end
@@ -578,13 +579,17 @@ module.public = {
578579
for i, line in ipairs(content) do
579580
if i == 1 then
580581
if content_start_column < start_column then
581-
log.error(
582-
string.format(
583-
"Unable to query information about tag on line %d: content is indented less than tag start!",
584-
start_row + 1
585-
)
582+
local error_msg = string.format(
583+
"Unable to query information about tag on line %d: content is indented less than tag start!",
584+
start_row + 1
586585
)
587-
return nil
586+
587+
if throw then
588+
error(error_msg)
589+
else
590+
log.error(error_msg)
591+
return nil
592+
end
588593
end
589594
content[i] = string.rep(" ", content_start_column - start_column) .. line
590595
else
@@ -718,7 +723,7 @@ module.public = {
718723

719724
---get document's metadata
720725
---@param source number | string | PathlibPath
721-
---@param no_trim boolean
726+
---@param no_trim boolean?
722727
---@return table?
723728
get_document_metadata = function(source, no_trim)
724729
source = source or 0

lua/neorg/modules/core/tangle/module.lua

+32-4
Original file line numberDiff line numberDiff line change
@@ -162,7 +162,7 @@ The first code block will be tangled to `./output.lua`, the second code block wi
162162
--]]
163163

164164
local neorg = require("neorg.core")
165-
local lib, modules, utils = neorg.lib, neorg.modules, neorg.utils
165+
local lib, modules, utils, log = neorg.lib, neorg.modules, neorg.utils, neorg.log
166166

167167
local module = modules.create("core.tangle")
168168
local Path = require("pathlib")
@@ -196,6 +196,16 @@ module.load = function()
196196
},
197197
})
198198
end)
199+
200+
if module.config.public.tangle_on_write then
201+
local augroup = vim.api.nvim_create_augroup("norg_auto_tangle", { clear = true })
202+
vim.api.nvim_create_autocmd("BufWritePost", {
203+
desc = "Tangle the current file on write",
204+
pattern = "*.norg",
205+
group = augroup,
206+
command = "Neorg tangle current-file",
207+
})
208+
end
199209
end
200210

201211
local function get_comment_string(language)
@@ -211,6 +221,7 @@ end
211221

212222
module.public = {
213223
tangle = function(buffer)
224+
---@type core.integrations.treesitter
214225
local treesitter = module.required["core.integrations.treesitter"]
215226
local parsed_document_metadata = treesitter.get_document_metadata(buffer) or {}
216227
local tangle_settings = parsed_document_metadata.tangle or {}
@@ -271,7 +282,15 @@ module.public = {
271282
local capture = query.captures[id]
272283

273284
if capture == "tag" then
274-
local parsed_tag = treesitter.get_tag_info(node)
285+
local ok, parsed_tag = pcall(treesitter.get_tag_info, node, true)
286+
if not ok then
287+
if module.config.public.indent_errors == "print" then
288+
print(parsed_tag)
289+
else
290+
log.error(parsed_tag)
291+
end
292+
goto skip_tag
293+
end
275294

276295
if parsed_tag then
277296
local declared_filetype = parsed_tag.parameters[1]
@@ -405,10 +424,9 @@ module.public = {
405424
vim.list_extend(tangles[file_to_tangle_to], delimiter_content)
406425
end
407426
vim.list_extend(tangles[file_to_tangle_to], block_content)
408-
409-
::skip_tag::
410427
end
411428
end
429+
::skip_tag::
412430
end
413431

414432
if options.delimiter == "file-content" then
@@ -431,6 +449,16 @@ module.public = {
431449
module.config.public = {
432450
-- Notify when there is nothing to tangle (INFO) or when the content is empty (WARN).
433451
report_on_empty = true,
452+
453+
-- Tangle all code blocks in the current norg file on file write.
454+
tangle_on_write = false,
455+
456+
-- When text in a code block is less indented than the block itself, Neorg will not tangle that
457+
-- block to a file. Instead it can either print or vim.notify error. By default, vim.notify is
458+
-- loud and is more likely to create a press enter message.
459+
-- - "notify" - Throw a normal looking error
460+
-- - "print" - print the error
461+
indent_errors = "notify",
434462
}
435463

436464
module.on_event = function(event)

0 commit comments

Comments
 (0)