From 34a41e809c427d2d27724358ce40c3a413b99e34 Mon Sep 17 00:00:00 2001 From: Daniel Mathiot <d.danymat@gmail.com> Date: Sat, 18 Sep 2021 13:24:03 +0200 Subject: [PATCH] feat: retrieve/generate links for files in the current workspace (#2) --- .../core/integrations/telescope/module.lua | 12 +- lua/telescope/_extensions/neorg.lua | 10 +- .../_extensions/neorg/find_linkable.lua | 19 ++- .../_extensions/neorg/insert_link.lua | 146 ++++++++++++++---- 4 files changed, 142 insertions(+), 45 deletions(-) diff --git a/lua/neorg/modules/core/integrations/telescope/module.lua b/lua/neorg/modules/core/integrations/telescope/module.lua index c847aff..26a47e5 100644 --- a/lua/neorg/modules/core/integrations/telescope/module.lua +++ b/lua/neorg/modules/core/integrations/telescope/module.lua @@ -2,7 +2,7 @@ A Neorg module designed to integrate telescope.nvim --]] -require('neorg.modules.base') +require("neorg.modules.base") local module = neorg.modules.create("core.integrations.telescope") @@ -11,18 +11,18 @@ module.setup = function() end module.load = function() - local telescope_loaded, telescope = pcall(require, 'telescope') + local telescope_loaded, telescope = pcall(require, "telescope") assert(telescope_loaded, telescope) - telescope.load_extension('neorg') + telescope.load_extension("neorg") module.required["core.keybinds"].register_keybinds(module.name, { "find_linkable", "insert_link" }) end module.public = { - find_linkable = require('telescope._extensions.neorg.find_linkable'), - insert_link = require('telescope._extensions.neorg.insert_link') + find_linkable = require("telescope._extensions.neorg.find_linkable"), + insert_link = require("telescope._extensions.neorg.insert_link"), } module.on_event = function(event) @@ -37,7 +37,7 @@ module.events.subscribed = { ["core.keybinds"] = { ["core.integrations.telescope.find_linkable"] = true, ["core.integrations.telescope.insert_link"] = true, - } + }, } return module diff --git a/lua/telescope/_extensions/neorg.lua b/lua/telescope/_extensions/neorg.lua index c427aaf..82bac92 100644 --- a/lua/telescope/_extensions/neorg.lua +++ b/lua/telescope/_extensions/neorg.lua @@ -1,6 +1,6 @@ -return require('telescope').register_extension { +return require("telescope").register_extension({ exports = { - find_linkable = require('neorg.modules.core.integrations.telescope.module').public.find_linkable, - insert_link = require('neorg.modules.core.integrations.telescope.module').public.insert_link, - } -} + find_linkable = require("neorg.modules.core.integrations.telescope.module").public.find_linkable, + insert_link = require("neorg.modules.core.integrations.telescope.module").public.insert_link, + }, +}) diff --git a/lua/telescope/_extensions/neorg/find_linkable.lua b/lua/telescope/_extensions/neorg/find_linkable.lua index 6b186d8..0e9033b 100644 --- a/lua/telescope/_extensions/neorg/find_linkable.lua +++ b/lua/telescope/_extensions/neorg/find_linkable.lua @@ -1,4 +1,4 @@ -local neorg_loaded, _ = pcall(require, 'neorg.modules') +local neorg_loaded, _ = pcall(require, "neorg.modules") assert(neorg_loaded, "Neorg is not loaded - please make sure to load Neorg first") @@ -15,15 +15,18 @@ local function get_current_workspace() end return function(opts) - opts = opts or {} + opts = opts or {} local current_workspace = get_current_workspace() - if current_workspace then - require('telescope.builtin').grep_string({ - search = "^\\s*(\\*+|\\|{1,2})\\s+", - use_regex = true, - search_dirs = { current_workspace } - }) + if not current_workspace then + return end + + require("telescope.builtin").grep_string({ + search = "^\\s*(\\*+|\\|{1,2})\\s+", + use_regex = true, + search_dirs = { current_workspace }, + prompt_title = "Find in Norg files", + }) end diff --git a/lua/telescope/_extensions/neorg/insert_link.lua b/lua/telescope/_extensions/neorg/insert_link.lua index 9790965..0796b98 100644 --- a/lua/telescope/_extensions/neorg/insert_link.lua +++ b/lua/telescope/_extensions/neorg/insert_link.lua @@ -1,47 +1,118 @@ -local actions = require('telescope.actions') -local actions_set = require('telescope.actions.set') -local finders = require('telescope.finders') -local pickers = require('telescope.pickers') -local conf = require('telescope.config').values +local actions = require("telescope.actions") +local actions_set = require("telescope.actions.set") +local finders = require("telescope.finders") +local pickers = require("telescope.pickers") +local conf = require("telescope.config").values -local neorg_loaded, _ = pcall(require, 'neorg.modules') +local neorg_loaded, _ = pcall(require, "neorg.modules") assert(neorg_loaded, "Neorg is not loaded - please make sure to load Neorg first") -local function get_linkables() - local ret = {} +--- Get a list of all norg files in current workspace. Returns { workspace_path, norg_files } +--- @return table +local function get_norg_files() + local dirman = neorg.modules.get_module("core.norg.dirman") - local lines = vim.api.nvim_buf_get_lines(0, 0, -1, true) + if not dirman then + return nil + end - for i, line in ipairs(lines) do - local heading = { line:match("^%s*(%*+%s+(.+))$") } - if not vim.tbl_isempty(heading) then - table.insert(ret, { line = i, linkable = heading[2], display = heading[1] }) - end + local current_workspace = dirman.get_current_workspace() - local marker_or_drawer = { line:match("^%s*(%|%|?%s+(.+))$") } - if not vim.tbl_isempty(marker_or_drawer) then - table.insert(ret, { line = i, linkable = marker_or_drawer[2], display = marker_or_drawer[1] }) - end - end + local norg_files = dirman.get_norg_files(current_workspace[1]) - return ret + return { current_workspace[2], norg_files } +end + +--- Creates links for a `file` specified by `bufnr` +--- @param bufnr number +--- @param file string +--- @return table +local function get_linkables(bufnr, file) + local ret = {} + + if file then + file = file:gsub(".norg", "") + end + + local lines = vim.api.nvim_buf_get_lines(bufnr, 0, -1, true) + + for i, line in ipairs(lines) do + local heading = { line:match("^%s*(%*+%s+(.+))$") } + if not vim.tbl_isempty(heading) then + table.insert(ret, { line = i, linkable = heading[2], display = heading[1], file = file }) + end + + local marker_or_drawer = { line:match("^%s*(%|%|?%s+(.+))$") } + if not vim.tbl_isempty(marker_or_drawer) then + table.insert(ret, { line = i, linkable = marker_or_drawer[2], display = marker_or_drawer[1], file = file }) + end + end + + return ret +end + +--- Generate links for telescope +--- @return table +local function generate_links() + local res = {} + local dirman = neorg.modules.get_module("core.norg.dirman") + + if not dirman then + return nil + end + + local files = get_norg_files() + + if not files[2] then + return + end + + for _, file in pairs(files[2]) do + local full_path_file = files[1] .. "/" .. file + local bufnr = dirman.get_file_bufnr(full_path_file) + if not bufnr then + return + end + + vim.fn.bufload(full_path_file) + + -- Because we do not want file name to appear in a link to the same file + local file_inserted = (function () + if vim.api.nvim_get_current_buf() == bufnr then + return nil + else + return file + end + end)() + + local links = get_linkables(bufnr, file_inserted) + + if vim.api.nvim_get_current_buf() ~= bufnr then + vim.cmd('bunload! ' .. bufnr) + end + + vim.list_extend(res, links) + end + + return res end return function(opts) opts = opts or {} - pickers.new(opts, { - prompt_title = "Insert Link", + pickers.new(opts, { + prompt_title = "Insert Link", results_title = "Linkables", finder = finders.new_table({ - results = get_linkables(), + results = generate_links(), entry_maker = function(entry) return { value = entry.line, display = entry.display, ordinal = entry.linkable, lnum = entry.line, + file = entry.file } end, }), @@ -51,11 +122,34 @@ return function(opts) attach_mappings = function(prompt_bufnr) actions_set.select:replace(function() local entry = actions.get_selected_entry() - actions.close(prompt_bufnr) - vim.api.nvim_put({ "[" .. entry.ordinal:gsub(":$", "") .. "]" .. "(" .. entry.display:gsub("^(%W+)%s+.+", "%1") .. entry.ordinal:gsub("[%*#%|_]", "\\%1") .. ")" }, "c", false, true) + actions.close(prompt_bufnr) + + local inserted_file = (function () + if entry.file then + return ":" .. entry.file .. ":" + else + return "" + end + end)() + + vim.api.nvim_put( + { + "[" + .. entry.ordinal:gsub(":$", "") + .. "]" + .. "(" + .. inserted_file + .. entry.display:gsub("^(%W+)%s+.+", "%1") + .. entry.ordinal:gsub("[%*#%|_]", "\\%1") + .. ")", + }, + "c", + false, + true + ) vim.api.nvim_feedkeys("f)a", "t", false) end) return true end, - }):find() + }):find() end