diff --git a/README.md b/README.md index aa21bcb..943e72a 100644 --- a/README.md +++ b/README.md @@ -71,6 +71,36 @@ require'marks'.setup { See `:help marks-setup` for all of the keys that can be passed to the setup function. +## Telescope + +There is a [telescope](https://github.com/nvim-telescope/telescope.nvim) extension allowing to list marks through telescope. + +To activate it you need to load the extension: +```lua +local status_ok, telescope = pcall(require, "telescope") +if not status_ok then + return +end + +telescope.load_extension("marks_nvim") +``` + +You can then use the extension methods to list marks instead of using the native loclist system. +You simply need to call these methods in your mappings. + +```lua +require('telescope').extensions.marks_nvim.marks_list_buf(opts) --[[ List buffer marks ]] +require('telescope').extensions.marks_nvim.marks_list_all(opts) --[[ List all marks ]] +require('telescope').extensions.marks_nvim.bookmarks_list_group(1, opts) --[[ List a bookmark group marks (takes the group number as argument) ]] +require('telescope').extensions.marks_nvim.bookmarks_list_all(opts) --[[ List all bookmarks marks ]] +``` + +These methods will use your `path_display` telescope configuraiton to display paths. +You can also pass a specific property for one method in the `opts` table. Eg. +```lua +require('telescope').extensions.marks_nvim.marks_list_all({ path_display = 'shorten' }) +``` + ## Mappings The following default mappings are included: diff --git a/lua/marks/bookmark.lua b/lua/marks/bookmark.lua index b39a9ea..d2dfb41 100644 --- a/lua/marks/bookmark.lua +++ b/lua/marks/bookmark.lua @@ -1,4 +1,4 @@ -local utils = require'marks.utils' +local utils = require("marks.utils") local a = vim.api local Bookmarks = {} @@ -65,7 +65,7 @@ function Bookmarks:place_mark(group_nr, bufnr) return end - local data = { buf = bufnr, line = pos[1], col = pos[2], sign_id = -1} + local data = { buf = bufnr, line = pos[1], col = pos[2], sign_id = -1 } local display_signs = utils.option_nil(self.opt.buf_signs[bufnr], self.opt.signs) if display_signs and group.sign then @@ -76,11 +76,11 @@ function Bookmarks:place_mark(group_nr, bufnr) local opts = {} if group.virt_text then - opts.virt_text = {{ group.virt_text, "MarkVirtTextHL" }} + opts.virt_text = { { group.virt_text, "MarkVirtTextHL" } } opts.virt_text_pos = "eol" end - local extmark_id = a.nvim_buf_set_extmark(bufnr, group.ns, pos[1]-1, pos[2], opts) + local extmark_id = a.nvim_buf_set_extmark(bufnr, group.ns, pos[1] - 1, pos[2], opts) data.extmark_id = extmark_id @@ -192,8 +192,13 @@ function Bookmarks:next(group_nr) return false end - local next = utils.search(marks, {buf = bufnr, line=pos[1]}, - {buf=math.huge, line=math.huge}, comparator, false) + local next = utils.search( + marks, + { buf = bufnr, line = pos[1] }, + { buf = math.huge, line = math.huge }, + comparator, + false + ) if not next then next = marks[1] @@ -232,8 +237,7 @@ function Bookmarks:prev(group_nr) return false end - local prev = utils.search(marks, {buf = bufnr, line=pos[1]}, - {buf=-1, line=-1}, comparator, false) + local prev = utils.search(marks, { buf = bufnr, line = pos[1] }, { buf = -1, line = -1 }, comparator, false) if not prev then prev = marks[#marks] @@ -268,20 +272,20 @@ function Bookmarks:annotate(group_nr) local text = vim.fn.input("annotation: ") if text ~= "" then - a.nvim_buf_set_extmark(bufnr, self.groups[group_nr].ns, bookmark.line-1, bookmark.col, { - id = bookmark.extmark_id, virt_lines = {{{text, "MarkVirtTextHL"}}}, - virt_lines_above=true, + a.nvim_buf_set_extmark(bufnr, self.groups[group_nr].ns, bookmark.line - 1, bookmark.col, { + id = bookmark.extmark_id, + virt_lines = { { { text, "MarkVirtTextHL" } } }, + virt_lines_above = true, }) else a.nvim_buf_del_extmark(bufnr, self.groups[group_nr].ns, bookmark.extmark_id) local opts = {} if self.groups[group_nr].virt_text then - opts.virt_text = {{ self.groups[group_nr].virt_text, "MarkVirtTextHL" }} + opts.virt_text = { { self.groups[group_nr].virt_text, "MarkVirtTextHL" } } opts.virt_text_pos = "eol" end - bookmark.extmark_id = a.nvim_buf_set_extmark(bufnr, self.groups[group_nr].ns, bookmark.line-1, - bookmark.col, opts) + bookmark.extmark_id = a.nvim_buf_set_extmark(bufnr, self.groups[group_nr].ns, bookmark.line - 1, bookmark.col, opts) end end @@ -299,8 +303,7 @@ function Bookmarks:refresh() buf_marks = group.marks[bufnr] if buf_marks then for _, mark in pairs(vim.tbl_values(buf_marks)) do - local line = a.nvim_buf_get_extmark_by_id(bufnr, group.ns, - mark.extmark_id, {})[1] + local line = a.nvim_buf_get_extmark_by_id(bufnr, group.ns, mark.extmark_id, {})[1] if line + 1 ~= mark.line then buf_marks[line + 1] = mark @@ -316,6 +319,53 @@ function Bookmarks:refresh() end end +function Bookmarks:get_group_list(group_nr) + local items = {} + if not group_nr or not self.groups[group_nr] then + return items + end + + for bufnr, buffer_marks in pairs(self.groups[group_nr].marks) do + for line, mark in pairs(buffer_marks) do + local text = a.nvim_buf_get_lines(bufnr, line - 1, line, true)[1] + local filename = vim.api.nvim_buf_get_name(bufnr) + table.insert(items, { + bufnr = bufnr, + lnum = line, + col = mark.col + 1, + group = group_nr, + line = vim.trim(text), + path = filename, + }) + end + end + + return items +end + +function Bookmarks:get_all_list() + local items = {} + for group_nr, group in pairs(self.groups) do + for bufnr, buffer_marks in pairs(group.marks) do + for line, mark in pairs(buffer_marks) do + local text = a.nvim_buf_get_lines(bufnr, line - 1, line, true)[1] + local filename = vim.api.nvim_buf_get_name(bufnr) + + table.insert(items, { + bufnr = bufnr, + lnum = line, + col = mark.col + 1, + group = group_nr, + line = vim.trim(text), + path = filename, + }) + end + end + end + + return items +end + function Bookmarks:to_list(list_type, group_nr) if not group_nr or not self.groups[group_nr] then return @@ -327,8 +377,8 @@ function Bookmarks:to_list(list_type, group_nr) local items = {} for bufnr, buffer_marks in pairs(self.groups[group_nr].marks) do for line, mark in pairs(buffer_marks) do - local text = a.nvim_buf_get_lines(bufnr, line-1, line, true)[1] - table.insert(items, { bufnr=bufnr, lnum=line, col=mark.col + 1, text=text }) + local text = a.nvim_buf_get_lines(bufnr, line - 1, line, true)[1] + table.insert(items, { bufnr = bufnr, lnum = line, col = mark.col + 1, text = text }) end end @@ -343,9 +393,13 @@ function Bookmarks:all_to_list(list_type) for group_nr, group in pairs(self.groups) do for bufnr, buffer_marks in pairs(group.marks) do for line, mark in pairs(buffer_marks) do - local text = a.nvim_buf_get_lines(bufnr, line-1, line, true)[1] - table.insert(items, { bufnr=bufnr, lnum=line, col=mark.col + 1, - text="bookmark group "..group_nr..": "..text }) + local text = a.nvim_buf_get_lines(bufnr, line - 1, line, true)[1] + table.insert(items, { + bufnr = bufnr, + lnum = line, + col = mark.col + 1, + text = "bookmark group " .. group_nr .. ": " .. text, + }) end end end @@ -358,8 +412,13 @@ function Bookmarks:add_sign(bufnr, text, line, id) end function Bookmarks.new() - return setmetatable({signs = {"!", "@", "#", "$", "%", "^", "&", "*", "(", [0]=")"}, - virt_text = {}, groups = {}, prompt_annotate = {}, opt = {}}, {__index = Bookmarks}) + return setmetatable({ + signs = { "!", "@", "#", "$", "%", "^", "&", "*", "(", [0] = ")" }, + virt_text = {}, + groups = {}, + prompt_annotate = {}, + opt = {}, + }, { __index = Bookmarks }) end return Bookmarks diff --git a/lua/marks/mark.lua b/lua/marks/mark.lua index 4f65042..e92521c 100644 --- a/lua/marks/mark.lua +++ b/lua/marks/mark.lua @@ -262,6 +262,47 @@ function Mark.preview_mark() vim.cmd("normal! zz") end +function Mark:get_buf_list(bufnr) + bufnr = bufnr or a.nvim_get_current_buf() + if not self.buffers[bufnr] then + return + end + + local items = {} + for mark, data in pairs(self.buffers[bufnr].placed_marks) do + local text = a.nvim_buf_get_lines(bufnr, data.line-1, data.line, true)[1] + local path = vim.api.nvim_buf_get_name(bufnr) + table.insert(items, { + bufnr = bufnr, + lnum = data.line, + col = data.col + 1, + mark = mark, + line = vim.trim(text), + path = path + }) + end + return items +end + +function Mark:get_all_list() + local items = {} + for bufnr, buffer_state in pairs(self.buffers) do + for mark, data in pairs(buffer_state.placed_marks) do + local text = a.nvim_buf_get_lines(bufnr, data.line-1, data.line, true)[1] + local path = vim.api.nvim_buf_get_name(bufnr) + table.insert(items, { + bufnr = bufnr, + lnum = data.line, + col = data.col + 1, + mark = mark, + line = vim.trim(text), + path = path + }) + end + end + return items +end + function Mark:buffer_to_list(list_type, bufnr) list_type = list_type or "loclist" diff --git a/lua/telescope/_extensions/marks_nvim.lua b/lua/telescope/_extensions/marks_nvim.lua new file mode 100644 index 0000000..7165f5a --- /dev/null +++ b/lua/telescope/_extensions/marks_nvim.lua @@ -0,0 +1,182 @@ +local telescope = require("telescope") +local pickers = require("telescope.pickers") +local finders = require("telescope.finders") +local entry_display = require("telescope.pickers.entry_display") +local telescope_utils = require("telescope.utils") +local conf = require("telescope.config").values +local marks = require("marks") + +local list_marks_buf = function(opts) + opts = opts or {} + local results = marks.mark_state:get_buf_list() or {} + + local displayer = entry_display.create({ + separator = " ", + items = { + { width = 3 }, + { width = 10 }, + {}, + }, + }) + + local make_display = function(entry) + return displayer({ + { entry.mark, "TelescopeResultsIdentifier" }, + { entry.lnum }, + { entry.line, "String" }, + }) + end + + pickers + .new(opts, { + prompt_title = "Buffer Marks", + finder = finders.new_table({ + results = results, + entry_maker = function(entry) + entry.value = entry.mark + entry.ordinal = entry.line + entry.display = make_display + return entry + end, + }), + sorter = conf.generic_sorter(opts), + previewer = conf.grep_previewer(opts), + }) + :find() +end + +local list_marks_all = function(opts) + opts = opts or {} + local conf_path = { path_display = opts.path_display or conf.path_display or {} } + local results = marks.mark_state:get_all_list() or {} + + local displayer = entry_display.create({ + separator = " ", + items = { + { width = 1 }, + { width = 5 }, + { width = 20 }, + {}, + }, + }) + + local make_display = function(entry) + local file_path = telescope_utils.transform_path(conf_path, entry.path) + return displayer({ + { entry.mark, "TelescopeResultsIdentifier" }, + { entry.lnum }, + { entry.line, "String" }, + { file_path, "Comment" }, + }) + end + + pickers + .new(opts, { + prompt_title = "All Marks", + finder = finders.new_table({ + results = results, + entry_maker = function(entry) + entry.value = entry.mark + entry.ordinal = entry.line + entry.display = make_display + return entry + end, + }), + sorter = conf.generic_sorter(opts), + previewer = conf.grep_previewer(opts), + }) + :find() +end + +local list_bookmarks_group = function(group, opts) + opts = opts or {} + local conf_path = { path_display = opts.path_display or conf.path_display or {} } + local results = marks.bookmark_state:get_group_list(group) or {} + + local displayer = entry_display.create({ + separator = " ", + items = { + { width = 1 }, + { width = 5 }, + { width = 20 }, + {}, + }, + }) + + local make_display = function(entry) + return displayer({ + { entry.group, "TelescopeResultsIdentifier" }, + { entry.lnum }, + { entry.line, "String" }, + { telescope_utils.transform_path(conf_path, entry.path) }, + }) + end + + pickers + .new(opts, { + prompt_title = "Bookmark " .. group, + finder = finders.new_table({ + results = results, + entry_maker = function(entry) + entry.value = entry.group + entry.ordinal = entry.line + entry.display = make_display + return entry + end, + }), + sorter = conf.generic_sorter(opts), + previewer = conf.grep_previewer(opts), + }) + :find() +end + +local list_bookmarks_all = function(opts) + opts = opts or {} + local conf_path = { path_display = opts.path_display or conf.path_display or {} } + local results = marks.bookmark_state:get_all_list() or {} + + local displayer = entry_display.create({ + separator = " ", + items = { + { width = 1 }, + { width = 5 }, + { width = 20 }, + {}, + }, + }) + + local make_display = function(entry) + return displayer({ + { entry.group, "TelescopeResultsIdentifier" }, + { entry.lnum }, + { entry.line, "String" }, + { telescope_utils.transform_path(conf_path, entry.path) }, + }) + end + + pickers + .new(opts, { + prompt_title = "All Bookmarks", + finder = finders.new_table({ + results = results, + entry_maker = function(entry) + entry.value = entry.group + entry.ordinal = entry.line + entry.display = make_display + return entry + end, + }), + sorter = conf.generic_sorter(opts), + previewer = conf.grep_previewer(opts), + }) + :find() +end + +return telescope.register_extension({ + exports = { + marks_list_buf = list_marks_buf, + marks_list_all = list_marks_all, + bookmarks_list_group = list_bookmarks_group, + bookmarks_list_all = list_bookmarks_all, + }, +})