Skip to content

Commit

Permalink
feat: ws relative file/header backlink pickers (#50)
Browse files Browse the repository at this point in the history
  • Loading branch information
benlubas authored Feb 10, 2024
1 parent 6a7a677 commit 418f8fd
Show file tree
Hide file tree
Showing 9 changed files with 127 additions and 16 deletions.
3 changes: 3 additions & 0 deletions .editorconfig
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
[*]
indent_style = space
indent_size = 4
15 changes: 15 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -41,6 +41,21 @@ With `Telescope neorg search_headings` you can search through all the headings i
<img alt="search_headings" src="https://user-images.githubusercontent.com/81827001/153647155-80f5579f-acc9-489e-9e05-acf31a646bba.png">
</details>

### Search File and Heading Backlinks
- `Telescope neorg find_backlinks` - find every line in your workspace that links^* to the current file
- `Telescope neorg find_header_backlinks` - same but with links to the current file _and_ heading

These are limited to workspace relative links (ie.
`{:$/worspace/relative/path:}`) for the sake of simplicity. Both exact
(`{:$/path:** lvl 2 heading}`) and fuzzy (`{:$/path:# heading}`) links are
found.

<details>
<summary>Demo</summary>

![search backlink](https://github.com/nvim-neorg/neorg-telescope/assets/56943754/37a5b68f-29b3-43ae-a679-9656cfa646db)
</details>

## Gtd Pickers
### Those pickers are all broken since gtd was removed in core
<details>
Expand Down
10 changes: 10 additions & 0 deletions lua/neorg/modules/core/integrations/telescope/module.lua
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,8 @@ module.load = function()
"find_aof_tasks",
"find_context_tasks",
"switch_workspace",
"find_backlinks",
"find_header_backlinks",
})
end

Expand All @@ -42,6 +44,8 @@ module.public = {
find_aof_tasks = require("telescope._extensions.neorg.find_aof_tasks"),
find_aof_project_tasks = require("telescope._extensions.neorg.find_aof_project_tasks"),
switch_workspace = require("telescope._extensions.neorg.switch_workspace"),
find_backlinks = require("telescope._extensions.neorg.backlinks.file_backlinks"),
find_header_backlinks = require("telescope._extensions.neorg.backlinks.header_backlinks"),
}

module.on_event = function(event)
Expand All @@ -65,6 +69,10 @@ module.on_event = function(event)
module.public.find_context_tasks()
elseif event.split_type[2] == "core.integrations.telescope.switch_workspace" then
module.public.switch_workspace()
elseif event.split_type[2] == "core.integrations.telescope.find_backlinks" then
module.public.find_backlinks()
elseif event.split_type[2] == "core.integrations.telescope.find_header_backlinks" then
module.public.find_header_backlinks()
end
end

Expand All @@ -80,6 +88,8 @@ module.events.subscribed = {
["core.integrations.telescope.find_aof_tasks"] = true,
["core.integrations.telescope.find_aof_project_tasks"] = true,
["core.integrations.telescope.switch_workspace"] = true,
["core.integrations.telescope.find_backlinks"] = true,
["core.integrations.telescope.find_header_backlinks"] = true,
},
}

Expand Down
11 changes: 11 additions & 0 deletions lua/neorg/telescope_utils.lua
Original file line number Diff line number Diff line change
Expand Up @@ -152,4 +152,15 @@ utils.get_project_tasks = function()
return projects_tasks
end

---Gets the full path to the current workspace
---@return string?
utils.get_current_workspace = function()
local dirman = neorg.modules.get_module("core.dirman")
if dirman then
local current_workspace = dirman.get_current_workspace()[2]
return current_workspace
end
return nil
end

return utils
2 changes: 2 additions & 0 deletions lua/telescope/_extensions/neorg.lua
Original file line number Diff line number Diff line change
Expand Up @@ -10,5 +10,7 @@ return require("telescope").register_extension({
find_aof_tasks = require("neorg.modules.core.integrations.telescope.module").public.find_aof_tasks,
find_aof_project_tasks = require("neorg.modules.core.integrations.telescope.module").public.find_aof_project_tasks,
switch_workspace = require("neorg.modules.core.integrations.telescope.module").public.switch_workspace,
find_backlinks = require("neorg.modules.core.integrations.telescope.module").public.find_backlinks,
find_header_backlinks = require("neorg.modules.core.integrations.telescope.module").public.find_header_backlinks,
},
})
27 changes: 27 additions & 0 deletions lua/telescope/_extensions/neorg/backlinks/common.lua
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
local M = {}

---produce the regular expression used to find workspace relative paths to the given file.
---Optionally takes a header that should exist in the current file
---@param workspace_path string "/abs/path/to/workspace"
---@param current_file string "test.norg"
---@param heading string? "** heading"
---@return string
M.build_backlink_regex = function(workspace_path, current_file, heading)
current_file = vim.api.nvim_buf_get_name(0)
current_file = current_file:gsub("%.norg$", "")
current_file = current_file:gsub("^" .. workspace_path .. "/", "")

if not heading then
return ([[\{:\$/%s:.*\}]]):format(current_file) -- {:$/workspace_path:}
end

local heading_prefix = heading:match("^%**")
if heading_prefix then
heading_prefix = heading_prefix:gsub("%*", "\\*")
end
local heading_text = heading:gsub("^%** ", "")
heading_text = heading_text:gsub("^%(.%)%s?", "")
return ([[\{:\$/%s:(#|%s) %s\}]]):format(current_file, heading_prefix, heading_text) -- {:$/workspace_path:(# heading or ** heading)}
end

return M
19 changes: 19 additions & 0 deletions lua/telescope/_extensions/neorg/backlinks/file_backlinks.lua
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
local common = require("telescope._extensions.neorg.backlinks.common")
local utils = require("neorg.telescope_utils")

return function()
local current_workspace = utils.get_current_workspace()

if not current_workspace then
return
end

local current_file = vim.api.nvim_buf_get_name(0)

require("telescope.builtin").grep_string({
search = common.build_backlink_regex(current_workspace, current_file),
use_regex = true,
search_dirs = { current_workspace },
prompt_title = "File Backlinks",
})
end
38 changes: 38 additions & 0 deletions lua/telescope/_extensions/neorg/backlinks/header_backlinks.lua
Original file line number Diff line number Diff line change
@@ -0,0 +1,38 @@
local common = require("telescope._extensions.neorg.backlinks.common")
local utils = require("neorg.telescope_utils")

return function()
local current_workspace = utils.get_current_workspace()

if not current_workspace then
return
end

local current_file = vim.api.nvim_buf_get_name(0)
local linenr = vim.api.nvim_win_get_cursor(0)[1]
local lines = vim.api.nvim_buf_get_lines(0, 0, linenr, false)
local heading = nil

-- HACK: iterate backward (up) over lines, and use the first heading we find. We should be using
-- TS instead, but I'm not super familiar with how to do things like that.
for i = #lines, 1, -1 do
local line = lines[i]
local potential_heading = line:match("^%s*%*+ .*$")
if potential_heading then
heading = potential_heading
break
end
end

if not heading then
vim.notify("[Neorg Telescope] Couldn't find current heading", vim.log.levels.ERROR)
return
end

require("telescope.builtin").grep_string({
search = common.build_backlink_regex(current_workspace, current_file, heading),
use_regex = true,
search_dirs = { current_workspace },
prompt_title = "Header Backlinks (" .. heading .. ")",
})
end
18 changes: 2 additions & 16 deletions lua/telescope/_extensions/neorg/find_linkable.lua
Original file line number Diff line number Diff line change
@@ -1,23 +1,9 @@
local neorg_loaded, neorg = pcall(require, "neorg.core")

assert(neorg_loaded, "Neorg is not loaded - please make sure to load Neorg first")

local function get_current_workspace()
local dirman = neorg.modules.get_module("core.dirman")

if dirman then
local current_workspace = dirman.get_current_workspace()[2]

return current_workspace
end

return nil
end
local utils = require("neorg.telescope_utils")

return function(opts)
opts = opts or {}

local current_workspace = get_current_workspace()
local current_workspace = utils.get_current_workspace()

if not current_workspace then
return
Expand Down

0 comments on commit 418f8fd

Please sign in to comment.