Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat: auto tangle #1413

Merged
merged 2 commits into from
Jul 15, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
25 changes: 15 additions & 10 deletions lua/neorg/modules/core/integrations/treesitter/module.lua
Original file line number Diff line number Diff line change
Expand Up @@ -519,8 +519,9 @@ module.public = {
return result
end,
--- Given a node this function will break down the AST elements and return the corresponding text for certain nodes
-- @Param tag_node (userdata/treesitter node) - a node of type tag/carryover_tag
get_tag_info = function(tag_node)
--- @param tag_node TSNode - a node of type tag/carryover_tag
--- @param throw boolean - when true, throw an error instead of logging and returning on failure
get_tag_info = function(tag_node, throw)
if
not tag_node
or not vim.tbl_contains(
Expand All @@ -543,7 +544,7 @@ module.public = {
if vim.endswith(child:type(), "_carryover_set") then
for subchild in child:iter_children() do
if vim.endswith(subchild:type(), "_carryover") then
local meta = module.public.get_tag_info(subchild)
local meta = module.public.get_tag_info(subchild, throw)

table.insert(attributes, meta)
end
Expand All @@ -563,13 +564,17 @@ module.public = {
for i, line in ipairs(content) do
if i == 1 then
if content_start_column < start_column then
log.error(
string.format(
"Unable to query information about tag on line %d: content is indented less than tag start!",
start_row + 1
)
local error_msg = string.format(
"Unable to query information about tag on line %d: content is indented less than tag start!",
start_row + 1
)
return nil

if throw then
error(error_msg)
else
log.error(error_msg)
return nil
end
end
content[i] = string.rep(" ", content_start_column - start_column) .. line
else
Expand Down Expand Up @@ -703,7 +708,7 @@ module.public = {

---get document's metadata
---@param source number | string | PathlibPath
---@param no_trim boolean
---@param no_trim boolean?
---@return table?
get_document_metadata = function(source, no_trim)
source = source or 0
Expand Down
36 changes: 32 additions & 4 deletions lua/neorg/modules/core/tangle/module.lua
Original file line number Diff line number Diff line change
Expand Up @@ -160,7 +160,7 @@ The first code block will be tangled to `./output.lua`, the second code block wi
--]]

local neorg = require("neorg.core")
local lib, modules, utils = neorg.lib, neorg.modules, neorg.utils
local lib, modules, utils, log = neorg.lib, neorg.modules, neorg.utils, neorg.log

local module = modules.create("core.tangle")

Expand Down Expand Up @@ -193,6 +193,16 @@ module.load = function()
},
})
end)

if module.config.public.tangle_on_write then
local augroup = vim.api.nvim_create_augroup("norg_auto_tangle", { clear = true })
vim.api.nvim_create_autocmd("BufWritePost", {
desc = "Tangle the current file on write",
pattern = "*.norg",
group = augroup,
command = "Neorg tangle current-file",
})
end
end

local function get_comment_string(language)
Expand All @@ -208,6 +218,7 @@ end

module.public = {
tangle = function(buffer)
---@type core.integrations.treesitter
local treesitter = module.required["core.integrations.treesitter"]
local parsed_document_metadata = treesitter.get_document_metadata(buffer) or {}
local tangle_settings = parsed_document_metadata.tangle or {}
Expand Down Expand Up @@ -267,7 +278,15 @@ module.public = {
local capture = query.captures[id]

if capture == "tag" then
local parsed_tag = treesitter.get_tag_info(node)
local ok, parsed_tag = pcall(treesitter.get_tag_info, node, true)
if not ok then
if module.config.public.indent_errors == "print" then
print(parsed_tag)
else
log.error(parsed_tag)
end
goto skip_tag
end

if parsed_tag then
local declared_filetype = parsed_tag.parameters[1]
Expand Down Expand Up @@ -395,10 +414,9 @@ module.public = {
vim.list_extend(tangles[file_to_tangle_to], delimiter_content)
end
vim.list_extend(tangles[file_to_tangle_to], block_content)

::skip_tag::
end
end
::skip_tag::
end

if options.delimiter == "file-content" then
Expand All @@ -421,6 +439,16 @@ module.public = {
module.config.public = {
-- Notify when there is nothing to tangle (INFO) or when the content is empty (WARN).
report_on_empty = true,

-- Tangle all code blocks in the current norg file on file write.
tangle_on_write = false,

-- When text in a code block is less indented than the block itself, Neorg will not tangle that
-- block to a file. Instead it can either print or vim.notify error. By default, vim.notify is
-- loud and is more likely to create a press enter message.
-- - "notify" - Throw a normal looking error
-- - "print" - print the error
indent_errors = "notify",
}

module.on_event = function(event)
Expand Down
Loading