Skip to content

Commit

Permalink
support arguments
Browse files Browse the repository at this point in the history
  • Loading branch information
jonathf committed Aug 2, 2023
1 parent f579679 commit 0c151a6
Showing 1 changed file with 66 additions and 37 deletions.
103 changes: 66 additions & 37 deletions lua/neorg/modules/core/tangle/module.lua
Original file line number Diff line number Diff line change
Expand Up @@ -68,11 +68,20 @@ tangle: {
lua: ./output.lua
haskell: my-haskell-file
}
delimiter: heading
scope: all
}
@end
```
The `delimiter` option determines how to delimit codeblocks that exports to the same file.
The following alternatives are allowed:
* `heading` -- Try to determine the filetype of the code block and insert the current heading as a comment as a delimiter.
If filetype determination fails, `newline` will be used instead.
* `newline` -- Use an extra newline between blocks.
* `none` --Do not add delimiter. This implies that the code blocks are inserted into the the tangle target as-is.
The `scope` option is discussed in a [later section](#tangling-scopes), what we want to focus on is the `languages` object.
It's a simple language-filepath mapping, but it's especially useful when the output file's language type cannot be inferred from the name.
So far we've been using `init.lua`, `output.hs` - but what if we wanted to export all `haskell` code blocks into `my-file-without-an-extension`?
Expand Down Expand Up @@ -181,16 +190,45 @@ module.load = function()
end


local function clean_norg_content(content)
for i, line in ipairs(content) do
-- remove escape char
local new_line, _ = line:gsub("\\(.?)", "%1")
content[i] = new_line or ""
end
return content
end

local function get_comment_string(language)
local cur_buf = vim.api.nvim_get_current_buf()
local tmp_buf = vim.api.nvim_create_buf(false, true)
vim.api.nvim_set_current_buf(tmp_buf)
vim.bo.filetype = language
local commentstring = vim.bo.commentstring
vim.api.nvim_set_current_buf(cur_buf)
vim.api.nvim_buf_delete(tmp_buf, { force = true })
return commentstring
end


module.public = {
tangle = function(buffer)
local parsed_document_metadata = module.required["core.integrations.treesitter"].get_document_metadata(buffer) or {}
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 {}
local scope = tangle_settings.scope or "all" -- "all" | "tagged" | "main"
local delimiter = tangle_settings.delimiter or "newline" -- "newline" | "heading" | "none"
local filetype_to_filenames = tangle_settings.languages or tangle_settings
local filenames_only
if vim.tbl_islist(filetype_to_filenames) then
filenames_only = filetype_to_filenames
filetype_to_filenames = {}
elseif type(filetype_to_filenames) == string then
filetype_to_filenames = {_ = filetype_to_filenames}
end

local treesitter = module.required["core.integrations.treesitter"]
local document_root = treesitter.get_document_root(buffer)

local filetype_to_filenames = {}
local filename_to_languages = {}

local tangles = {
Expand Down Expand Up @@ -240,11 +278,7 @@ module.public = {
local content = parsed_tag.content

if parsed_tag.parameters[1] == "norg" then
for i, line in ipairs(content) do
-- remove escape char
local new_line, _ = line:gsub("\\(.?)", "%1")
content[i] = new_line or ""
end
content = clean_norg_content(content)
end

for _, attribute in ipairs(parsed_tag.attributes) do
Expand All @@ -258,39 +292,41 @@ module.public = {
end
end

-- determine tangle file target
if not file_to_tangle_to then
if declared_filetype and filetype_to_filenames[declared_filetype] then
file_to_tangle_to = filetype_to_filenames[declared_filetype]
elseif type(tangle_settings) == "string" then
file_to_tangle_to = tangle_settings
elseif type(tangle_settings) == "table" then
if not declared_filetype then
goto skip_tag
end
if vim.tbl_islist(tangle_settings) then
for idx, filename in ipairs(tangle_settings) do
else
if filenames_only then
for _, filename in ipairs(filenames_only) do
if declared_filetype == vim.filetype.match({ filename=filename, contents=content }) then
tangle_settings[idx] = nil
file_to_tangle_to = filename
break
end
end
else
file_to_tangle_to = tangle_settings[declared_filetype]
tangle_settings[declared_filetype] = nil
if not declared_filetype then
goto skip_tag
end
file_to_tangle_to = filetype_to_filenames[declared_filetype]
end
if file_to_tangle_to then
filetype_to_filenames[declared_filetype] = file_to_tangle_to
else
file_to_tangle_to = filetype_to_filenames["_"]
end
end
end
if not file_to_tangle_to then
goto skip_tag
end

if file_to_tangle_to then

if delimiter == "heading" then
local language
if filename_to_languages[file_to_tangle_to] then
language = filename_to_languages[file_to_tangle_to]
else
language = vim.filetype.match({ filename=file_to_tangle_to, contents=content })
language = vim.filetype.match({filename = file_to_tangle_to, contents = content})
if not language and declared_filetype then
language = vim.filetype.match({ filename="___." .. declared_filetype, contents=content })
end
Expand All @@ -310,30 +346,24 @@ module.public = {

-- Get commentstring from vim scratch buffer
if not commentstrings[language] then
local cur_buf = vim.api.nvim_get_current_buf()
local tmp_buf = vim.api.nvim_create_buf(false, true)
vim.api.nvim_set_current_buf(tmp_buf)
vim.bo.filetype = language
commentstrings[language] = vim.bo.commentstring
vim.api.nvim_set_current_buf(cur_buf)
vim.api.nvim_buf_delete(tmp_buf, { force = true })
commentstrings[language] = get_comment_string(language)
end
if commentstrings[language] ~= "" then
table.insert(content, 1, "")
table.insert(content, 1, commentstrings[language]:format(heading_string))
previous_headings[language] = heading
end
end
end

if not tangles[file_to_tangle_to] then
tangles[file_to_tangle_to] = {}
else
table.insert(content, 1, "")
end

vim.list_extend(tangles[file_to_tangle_to], content)
if not tangles[file_to_tangle_to] then
tangles[file_to_tangle_to] = {}
elseif delimiter ~= "none" then
table.insert(content, 1, "")
end

vim.list_extend(tangles[file_to_tangle_to], content)

::skip_tag::
end
end
Expand All @@ -346,7 +376,6 @@ module.public = {
module.on_event = function(event)
if event.type == "core.neorgcmd.events.core.tangle.current-file" then
local tangles = module.public.tangle(event.buffer)
assert(0, vim.inspect(tangles))

if not tangles or vim.tbl_isempty(tangles) then
neorg.utils.notify("Nothing to tangle!", vim.log.levels.WARN)
Expand Down

0 comments on commit 0c151a6

Please sign in to comment.