Skip to content

Commit 6fb5e39

Browse files
authored
Merge branch 'nvim-neorg:main' into main
2 parents 332a8ed + bdb29ea commit 6fb5e39

File tree

9 files changed

+161
-41
lines changed

9 files changed

+161
-41
lines changed

Diff for: CHANGELOG.md

+27
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,32 @@
11
# Changelog
22

3+
## [9.2.0](https://github.com/nvim-neorg/neorg/compare/v9.1.1...v9.2.0) (2025-01-22)
4+
5+
6+
### Features
7+
8+
* automatically typed `module.required` dependencies ([#1537](https://github.com/nvim-neorg/neorg/issues/1537)) ([1985f2d](https://github.com/nvim-neorg/neorg/commit/1985f2d6f152622b0066f48ba8e39d157635dd38))
9+
* **dirman:** dynamically set default workspace ([#1623](https://github.com/nvim-neorg/neorg/issues/1623)) ([29993a7](https://github.com/nvim-neorg/neorg/commit/29993a7bb8279ffa0ba473a3f393daa28c645825))
10+
* **dirman:** in_workspace function ([#1615](https://github.com/nvim-neorg/neorg/issues/1615)) ([62671a7](https://github.com/nvim-neorg/neorg/commit/62671a7b03a1f38a6e5e03b006a9b6f8d804be0e))
11+
* **esupports.hop:** Add tab drop as option for open_mode ([#1580](https://github.com/nvim-neorg/neorg/issues/1580)) ([c7ada78](https://github.com/nvim-neorg/neorg/commit/c7ada7881d7076a235b6323edcd81ae260affb41))
12+
* **export:** copy to clipboard ([#1627](https://github.com/nvim-neorg/neorg/issues/1627)) ([1783928](https://github.com/nvim-neorg/neorg/commit/178392822c8c2ef0911458b7f43c980667784011))
13+
* **introspector:** implement introspector customizability and improvements ([#1539](https://github.com/nvim-neorg/neorg/issues/1539)) ([fd11950](https://github.com/nvim-neorg/neorg/commit/fd11950048d111b837b9f615c5d023e79bd1af9a))
14+
* **keybinds:** add back keybind "gO" for ToC ([#1633](https://github.com/nvim-neorg/neorg/issues/1633)) ([bed58f8](https://github.com/nvim-neorg/neorg/commit/bed58f884ecf9b0b5e855cebe26760bfadbc8f38))
15+
* make journal methods public ([8b59db7](https://github.com/nvim-neorg/neorg/commit/8b59db79307037032c5f83fc79dff5741d6da869))
16+
* support ranges in Neorg command, ([c04bd96](https://github.com/nvim-neorg/neorg/commit/c04bd96eeb3bed19f23d394bebb6193bcd5271da))
17+
18+
19+
### Bug Fixes
20+
21+
* coq_nvim completion integration ([#1597](https://github.com/nvim-neorg/neorg/issues/1597)) ([488507b](https://github.com/nvim-neorg/neorg/commit/488507bb996f75ee29073f50dec32fa220867ca5))
22+
* don't suggest leading chars for file completions ([ba35900](https://github.com/nvim-neorg/neorg/commit/ba35900b21921c439e676b063a79c8fad914eac9))
23+
* intuitive default undone icon ([#1578](https://github.com/nvim-neorg/neorg/issues/1578)) ([13d1d54](https://github.com/nvim-neorg/neorg/commit/13d1d546684c83ba464adbf463a8a272c884e1e8))
24+
* Neorg return to most recent file ([e5e797e](https://github.com/nvim-neorg/neorg/commit/e5e797e6eddcb6efb1d2c3fc2612b31ad9a76cef))
25+
* **summary:** unpack summary category list ([#1637](https://github.com/nvim-neorg/neorg/issues/1637)) ([41aa380](https://github.com/nvim-neorg/neorg/commit/41aa3800cf5d30a5f90520c2a31b34727b443219))
26+
* **toc:** only capture first detached modifier ([#1631](https://github.com/nvim-neorg/neorg/issues/1631)) ([399832e](https://github.com/nvim-neorg/neorg/commit/399832e5437de0cea5efb1d5428de03adc42cc79))
27+
* **ToC:** only try to open when still in norg buffer ([#1549](https://github.com/nvim-neorg/neorg/issues/1549)) ([88dbab5](https://github.com/nvim-neorg/neorg/commit/88dbab5325ce07092ab7a38b160bc8e988830524))
28+
* weird tangle file path logic ([#1604](https://github.com/nvim-neorg/neorg/issues/1604)) ([993f077](https://github.com/nvim-neorg/neorg/commit/993f077f0bff8faa68dbdb89ad95f67116b8007a))
29+
330
## [9.1.1](https://github.com/nvim-neorg/neorg/compare/v9.1.0...v9.1.1) (2024-07-24)
431

532

Diff for: README.md

+1-1
Original file line numberDiff line numberDiff line change
@@ -188,6 +188,6 @@ Immense thank you to all of the sponsors of my work!
188188

189189
<div align="center">
190190

191-
<!-- sponsors --><a href="https://github.com/vsedov"><img src="https://github.com/vsedov.png" width="60px" alt="vsedov" /></a>&nbsp;&nbsp;&nbsp;<a href="https://github.com/skbolton"><img src="https://github.com/skbolton.png" width="60px" alt="skbolton" /></a>&nbsp;&nbsp;&nbsp;<a href="https://github.com/molleweide"><img src="https://github.com/molleweide.png" width="60px" alt="molleweide" /></a>&nbsp;&nbsp;&nbsp;<a href="https://github.com/danymat"><img src="https://github.com/danymat.png" width="60px" alt="danymat" /></a>&nbsp;&nbsp;&nbsp;<a href="https://github.com/theherk"><img src="https://github.com/theherk.png" width="60px" alt="theherk" /></a>&nbsp;&nbsp;&nbsp;<a href="https://github.com/purepani"><img src="https://github.com/purepani.png" width="60px" alt="purepani" /></a>&nbsp;&nbsp;&nbsp;<a href="https://github.com/tromars"><img src="https://github.com/tromars.png" width="60px" alt="tromars" /></a>&nbsp;&nbsp;&nbsp;<a href="https://github.com/jgregoire"><img src="https://github.com/jgregoire.png" width="60px" alt="jgregoire" /></a>&nbsp;&nbsp;&nbsp;<a href="https://github.com/bottd"><img src="https://github.com/bottd.png" width="60px" alt="bottd" /></a>&nbsp;&nbsp;&nbsp;<a href="https://github.com/DingDean"><img src="https://github.com/DingDean.png" width="60px" alt="DingDean" /></a>&nbsp;&nbsp;&nbsp;<a href="https://github.com/petermoser"><img src="https://github.com/petermoser.png" width="60px" alt="petermoser" /></a>&nbsp;&nbsp;&nbsp;<!-- sponsors -->
191+
<!-- sponsors --><a href="https://github.com/vsedov"><img src="https://github.com/vsedov.png" width="60px" alt="vsedov" /></a>&nbsp;&nbsp;&nbsp;<a href="https://github.com/skbolton"><img src="https://github.com/skbolton.png" width="60px" alt="skbolton" /></a>&nbsp;&nbsp;&nbsp;<a href="https://github.com/molleweide"><img src="https://github.com/molleweide.png" width="60px" alt="molleweide" /></a>&nbsp;&nbsp;&nbsp;<a href="https://github.com/danymat"><img src="https://github.com/danymat.png" width="60px" alt="danymat" /></a>&nbsp;&nbsp;&nbsp;<a href="https://github.com/purepani"><img src="https://github.com/purepani.png" width="60px" alt="purepani" /></a>&nbsp;&nbsp;&nbsp;<a href="https://github.com/jgregoire"><img src="https://github.com/jgregoire.png" width="60px" alt="jgregoire" /></a>&nbsp;&nbsp;&nbsp;<a href="https://github.com/bottd"><img src="https://github.com/bottd.png" width="60px" alt="bottd" /></a>&nbsp;&nbsp;&nbsp;<a href="https://github.com/DingDean"><img src="https://github.com/DingDean.png" width="60px" alt="DingDean" /></a>&nbsp;&nbsp;&nbsp;<a href="https://github.com/petermoser"><img src="https://github.com/petermoser.png" width="60px" alt="petermoser" /></a>&nbsp;&nbsp;&nbsp;<a href="https://github.com/kvodenicharov"><img src="https://github.com/kvodenicharov.png" width="60px" alt="kvodenicharov" /></a>&nbsp;&nbsp;&nbsp;<!-- sponsors -->
192192

193193
</div>

Diff for: lua/neorg/core/config.lua

+1-1
Original file line numberDiff line numberDiff line change
@@ -82,7 +82,7 @@ local config = {
8282
arguments = {},
8383

8484
norg_version = "1.1.1",
85-
version = "9.1.1",
85+
version = "9.2.0",
8686

8787
os_info = os_info,
8888
pathsep = os_info == "windows" and "\\" or "/",

Diff for: lua/neorg/modules/core/dirman/module.lua

+15-5
Original file line numberDiff line numberDiff line change
@@ -100,20 +100,20 @@ module.load = function()
100100

101101
if module.config.public.open_last_workspace and vim.fn.argc(-1) == 0 then
102102
if module.config.public.open_last_workspace == "default" then
103-
if not module.config.public.default_workspace then
103+
if not module.public.get_default_workspace() then
104104
log.warn(
105105
'Configuration error in `core.dirman`: the `open_last_workspace` option is set to "default", but no default workspace is provided in the `default_workspace` configuration variable. Defaulting to opening the last known workspace.'
106106
)
107107
module.public.set_last_workspace()
108108
return
109109
end
110110

111-
module.public.open_workspace(module.config.public.default_workspace)
111+
module.public.open_workspace(module.public.get_default_workspace())
112112
else
113113
module.public.set_last_workspace()
114114
end
115-
elseif module.config.public.default_workspace then
116-
module.public.set_workspace(module.config.public.default_workspace)
115+
elseif module.public.get_default_workspace() then
116+
module.public.set_workspace(module.public.get_default_workspace())
117117
end
118118
end
119119

@@ -131,6 +131,7 @@ module.config.public = {
131131
-- The index file is the "entry point" for all of your notes.
132132
index = "index.norg",
133133
-- The default workspace to set whenever Neovim starts.
134+
-- If a function, will be called with the current workspace and should resolve to a valid workspace name
134135
default_workspace = nil,
135136
-- Whether to open the last workspace's index file when `nvim` is executed
136137
-- without arguments.
@@ -166,6 +167,15 @@ module.public = {
166167
get_current_workspace = function()
167168
return module.private.current_workspace
168169
end,
170+
--- The default workspace, may be set dynamically based on cwd
171+
---@return string? # Should evaluate to a valid workspace name
172+
get_default_workspace = function()
173+
if type(module.config.public.default_workspace) == "function" then
174+
return module.config.public.default_workspace()
175+
end
176+
177+
return module.config.public.default_workspace
178+
end,
169179
--- Sets the workspace to the one specified (if it exists) and broadcasts the workspace_changed event
170180
---@param ws_name string #The name of a valid namespace we want to switch to
171181
---@return boolean #True if the workspace is set correctly, false otherwise
@@ -361,7 +371,7 @@ module.public = {
361371

362372
local last_workspace = storage.retrieve("last_workspace")
363373
last_workspace = type(last_workspace) == "string" and last_workspace
364-
or module.config.public.default_workspace
374+
or module.public.get_default_workspace()
365375
or ""
366376

367377
local workspace_path = module.public.get_workspace(last_workspace)

Diff for: lua/neorg/modules/core/export/module.lua

+92-25
Original file line numberDiff line numberDiff line change
@@ -24,6 +24,10 @@ It takes 3 arguments:
2424
- `filetype` - the filetype to export to
2525
- `output-dir` (optional) - a custom output directory to use. If not provided will fall back to `config.public.export_dir`
2626
(see [configuration](#configuration)).
27+
28+
And if you just want to export a snippet from a single document, you can use `:Neorg export
29+
to-clipboard <filetype>`. Filetype is required, at the time of writing the only option is "markdown".
30+
This copies the range given to the command to the `+` register.
2731
--]]
2832

2933
local neorg = require("neorg.core")
@@ -39,7 +43,12 @@ module.setup = function()
3943
}
4044
end
4145

46+
---@type core.integrations.treesitter
47+
local ts
48+
4249
module.load = function()
50+
ts = module.required["core.integrations.treesitter"]
51+
4352
modules.await("core.neorgcmd", function(neorgcmd)
4453
neorgcmd.add_commands_from_table({
4554
export = {
@@ -57,6 +66,10 @@ module.load = function()
5766
max_args = 3,
5867
name = "export.directory",
5968
},
69+
["to-clipboard"] = {
70+
args = 1,
71+
name = "export.to-clipboard",
72+
},
6073
},
6174
},
6275
})
@@ -84,39 +97,58 @@ module.public = {
8497
return modules.get_module("core.export." .. ftype), modules.get_module_config("core.export." .. ftype)
8598
end,
8699

100+
---export part of a buffer
101+
---@param buffer number
102+
---@param start_row number 1 indexed
103+
---@param end_row number 1 indexed, inclusive
104+
---@param filetype string
105+
---@return string? content, string? extension exported content as a string, and the extension
106+
---used for the export
107+
export_range = function(buffer, start_row, end_row, filetype)
108+
local converter = module.private.get_converter_checked(filetype)
109+
if not converter then
110+
return
111+
end
112+
local content = vim.iter(vim.api.nvim_buf_get_lines(buffer, start_row - 1, end_row, false)):join("\n")
113+
local root = ts.get_document_root(content)
114+
if not root then
115+
return
116+
end
117+
118+
return module.public.export_from_root(root, converter, content)
119+
end,
120+
87121
--- Takes a buffer and exports it to a specific file
88122
---@param buffer number #The buffer ID to read the contents from
89123
---@param filetype string #A Neovim filetype to specify which language to export to
90124
---@return string?, string? #The entire buffer parsed, converted and returned as a string, as well as the extension used for the export.
91125
export = function(buffer, filetype)
92-
local converter, converter_config = module.public.get_converter(filetype)
93-
126+
local converter, converter_config = module.private.get_converter_checked(filetype)
94127
if not converter or not converter_config then
95-
log.error("Unable to export file - did not find exporter for filetype '" .. filetype .. "'.")
96128
return
97129
end
98130

99-
-- Each converter must have a `extension` field in its public config
100-
-- This is done to do a backwards lookup, e.g. `markdown` uses the `.md` file extension.
101-
if not converter_config.extension then
102-
log.error(
103-
"Unable to export file - exporter for filetype '"
104-
.. filetype
105-
.. "' did not return a preferred extension. The exporter is unable to infer extensions."
106-
)
107-
return
108-
end
109-
110-
local document_root = module.required["core.integrations.treesitter"].get_document_root(buffer)
131+
local document_root = ts.get_document_root(buffer)
111132

112133
if not document_root then
113134
return
114135
end
115136

137+
local content = module.public.export_from_root(document_root, converter, buffer)
138+
139+
return content, converter_config.extension
140+
end,
141+
142+
---Do the work of exporting the given TS node via the given converter
143+
---@param root TSNode
144+
---@param converter table
145+
---@param source number | string
146+
---@return string
147+
export_from_root = function(root, converter, source)
116148
-- Initialize the state. The state is a table that exists throughout the entire duration
117149
-- of the export, and can be used to e.g. retain indent levels and/or keep references.
118150
local state = converter.export.init_state and converter.export.init_state() or {}
119-
local ts_utils = module.required["core.integrations.treesitter"].get_ts_utils()
151+
local ts_utils = ts.get_ts_utils()
120152

121153
--- Descends down a node and its children
122154
---@param start table #The TS node to begin at
@@ -144,7 +176,7 @@ module.public = {
144176
-- `keep_descending` - if true will continue to recurse down the current node's children despite the current
145177
-- node already being parsed
146178
-- `state` - a modified version of the state that then gets merged into the main state table
147-
local result = exporter(vim.treesitter.get_node_text(node, buffer), node, state, ts_utils)
179+
local result = exporter(vim.treesitter.get_node_text(node, source), node, state, ts_utils)
148180

149181
if type(result) == "table" then
150182
state = result.state and vim.tbl_extend("force", state, result.state) or state
@@ -155,8 +187,8 @@ module.public = {
155187

156188
if result.keep_descending then
157189
if state.parse_as then
158-
node = module.required["core.integrations.treesitter"].get_document_root(
159-
"\n" .. vim.treesitter.get_node_text(node, buffer),
190+
node = ts.get_document_root(
191+
"\n" .. vim.treesitter.get_node_text(node, source),
160192
state.parse_as
161193
)
162194
state.parse_as = nil
@@ -172,10 +204,7 @@ module.public = {
172204
table.insert(output, result)
173205
end
174206
elseif exporter == true then
175-
table.insert(
176-
output,
177-
module.required["core.integrations.treesitter"].get_node_text(node, buffer)
178-
)
207+
table.insert(output, ts.get_node_text(node, source))
179208
else
180209
table.insert(output, exporter)
181210
end
@@ -208,13 +237,41 @@ module.public = {
208237
or (not vim.tbl_isempty(output) and table.concat(output))
209238
end
210239

211-
local output = descend(document_root)
240+
local output = descend(root)
212241

213242
-- Every converter can also come with a `cleanup` function that performs some final tweaks to the output string
214-
return converter.export.cleanup and converter.export.cleanup(output) or output, converter_config.extension
243+
return converter.export.cleanup and converter.export.cleanup(output) or output
215244
end,
216245
}
217246

247+
module.private = {
248+
---get the converter for the given filetype
249+
---@param filetype string
250+
---@return table?, table?
251+
get_converter_checked = function(filetype)
252+
local converter, converter_config = module.public.get_converter(filetype)
253+
254+
if not converter or not converter_config then
255+
log.error("Unable to export file - did not find exporter for filetype '" .. filetype .. "'.")
256+
return
257+
end
258+
259+
-- Each converter must have a `extension` field in its public config
260+
-- This is done to do a backwards lookup, e.g. `markdown` uses the `.md` file extension.
261+
if not converter_config.extension then
262+
log.error(
263+
"Unable to export file - exporter for filetype '"
264+
.. filetype
265+
.. "' did not return a preferred extension. The exporter is unable to infer extensions."
266+
)
267+
return
268+
end
269+
270+
return converter, converter_config
271+
end,
272+
}
273+
274+
---@param event neorg.event
218275
module.on_event = function(event)
219276
if event.type == "core.neorgcmd.events.export.to-file" then
220277
-- Syntax: Neorg export to-file file.extension forced-filetype?
@@ -234,6 +291,15 @@ module.on_event = function(event)
234291

235292
vim.schedule(lib.wrap(utils.notify, "Successfully exported 1 file!"))
236293
end)
294+
elseif event.type == "core.neorgcmd.events.export.to-clipboard" then
295+
-- Syntax: Neorg export to-clipboard filetype
296+
-- Example: Neorg export to-clipboard markdown
297+
298+
local filetype = event.content[1]
299+
local data = event.content.data
300+
local exported = module.public.export_range(event.buffer, data.line1, data.line2, filetype)
301+
302+
vim.fn.setreg("+", exported, "l")
237303
elseif event.type == "core.neorgcmd.events.export.directory" then
238304
local path = event.content[3] and vim.fn.expand(event.content[3])
239305
or module.config.public.export_dir
@@ -328,6 +394,7 @@ end
328394
module.events.subscribed = {
329395
["core.neorgcmd"] = {
330396
["export.to-file"] = true,
397+
["export.to-clipboard"] = true,
331398
["export.directory"] = true,
332399
},
333400
}

Diff for: lua/neorg/modules/core/keybinds/module.lua

+8
Original file line numberDiff line numberDiff line change
@@ -213,6 +213,14 @@ module.private = {
213213
"<Plug>(neorg.dirman.new-note)",
214214
opts = { desc = "[neorg] Create New Note" },
215215
},
216+
217+
-- Create a Table of Contents
218+
-- ^Table of Contents
219+
{
220+
"gO",
221+
"<cmd>Neorg toc<CR>",
222+
opts = { desc = "[neorg] Create Table of Contents" },
223+
},
216224
},
217225
},
218226
norg = {

0 commit comments

Comments
 (0)