From 818850fd22f80138c2f4751874394ae3197e960d Mon Sep 17 00:00:00 2001 From: hollorol Date: Sun, 9 Mar 2025 21:11:25 +0100 Subject: [PATCH] new telescope functionality and using fzf --- lua/config/keymaps.lua | 9 ++- lua/config/plugins/telescope.lua | 42 ++++++++----- lua/custom/line_telescope.lua | 105 +++++++++++++++++++++++++++++++ 3 files changed, 141 insertions(+), 15 deletions(-) create mode 100644 lua/custom/line_telescope.lua diff --git a/lua/config/keymaps.lua b/lua/config/keymaps.lua index 013b0f5..a3b620e 100644 --- a/lua/config/keymaps.lua +++ b/lua/config/keymaps.lua @@ -6,7 +6,7 @@ vim.keymap.set('n','',':b#', {noremap=true, silent=true}) vim.keymap.set('n', 'cd', ':cd %:p:h', {noremap=true, silent=true}) vim.api.nvim_set_keymap('n', 'ff', 'Telescope find_files', {noremap = true, silent = true}) -vim.api.nvim_set_keymap('n', 'rg', 'Telescope live_grep', {noremap = true, silent = true}) +vim.api.nvim_set_keymap('n', 'rg', 'Telescope grep_string search="" only_sort_text=true', {noremap = true, silent = true}) vim.api.nvim_set_keymap('n', 'bb', 'Telescope buffers', {noremap = true, silent = true}) vim.api.nvim_set_keymap('n', 'fh', 'Telescope help_tags', {noremap = true, silent = true}) @@ -26,3 +26,10 @@ vim.api.nvim_set_keymap( "lua require('custom.fold_telescope').jump_to_fold_starts()", { noremap = true, silent = true } ) + +vim.api.nvim_set_keymap( + "n", + "ll", + "lua require('custom.line_telescope').jump_to_line()", + { noremap = true, silent = true } +) diff --git a/lua/config/plugins/telescope.lua b/lua/config/plugins/telescope.lua index 07c56a6..297f65d 100644 --- a/lua/config/plugins/telescope.lua +++ b/lua/config/plugins/telescope.lua @@ -1,19 +1,33 @@ return { - 'nvim-telescope/telescope.nvim', tag = '0.1.8', --- or , branch = '0.1.x', - dependencies = { 'nvim-lua/plenary.nvim' }, - - config = function() - require('telescope').setup{ + { + -- Main Telescope plugin + "nvim-telescope/telescope.nvim", + version = "0.1.8", -- or branch = '0.1.x' + dependencies = { + "nvim-lua/plenary.nvim", + { + -- FZF native plugin for better fuzzy matching + "nvim-telescope/telescope-fzf-native.nvim", + build = "make", -- Lazy will run `make` when installing/updating + -- If you want to ensure 'make' is available, you can do: + -- cond = function() + -- return vim.fn.executable("make") == 1 + -- end, + }, + }, + cmd = "Telescope", -- load only when calling Telescope + config = function() + require("telescope").setup({ defaults = { mappings = { i = { - [""] = require('telescope.actions').close - } - } - } - } + [""] = require("telescope.actions").close, + }, + }, + }, + }) + -- After setup, load the FZF extension (it must be built successfully first) + require("telescope").load_extension("fzf") end, - cmd = 'Telescope' - - } + }, +} diff --git a/lua/custom/line_telescope.lua b/lua/custom/line_telescope.lua new file mode 100644 index 0000000..046b94c --- /dev/null +++ b/lua/custom/line_telescope.lua @@ -0,0 +1,105 @@ +local pickers = require("telescope.pickers") +local finders = require("telescope.finders") +local conf = require("telescope.config").values +local actions = require("telescope.actions") +local action_state = require("telescope.actions.state") +local previewers = require("telescope.previewers") + +-- Custom previewer that dynamically calculates how many lines +-- can fit in the preview window, then shows a centered slice. +local dynamic_previewer = previewers.new_buffer_previewer({ + define_preview = function(self, entry, status) + -- 'entry.lnum' is the *actual file line number*. + local filepath = entry.path + local target = entry.lnum or 1 + + -- Get the preview buffer & window + local pbufnr = self.state.bufnr + local pwinid = status.preview_win + if not pbufnr or not vim.api.nvim_buf_is_valid(pbufnr) then + return + end + if not pwinid or not vim.api.nvim_win_is_valid(pwinid) then + return + end + + -- How many lines can we show in the preview window? + -- Subtract a bit (e.g., 1 or 2) if you use borders or want extra margin. + local lines_in_window = vim.api.nvim_win_get_height(pwinid) - 1 + if lines_in_window < 1 then + lines_in_window = 1 + end + + -- Read the entire file, figure out the slice to show + local all_lines = vim.fn.readfile(filepath) + local total = #all_lines + + -- We'll center on the target line, if possible + local half_context = math.floor(lines_in_window / 2) + local start_line = math.max(target - half_context, 1) + local end_line = math.min(start_line + lines_in_window - 1, total) + + -- Collect that slice of lines + local preview_lines = {} + for i = start_line, end_line do + table.insert(preview_lines, all_lines[i]) + end + + -- Write the slice to the preview buffer + vim.api.nvim_buf_set_lines(pbufnr, 0, -1, false, preview_lines) + vim.api.nvim_buf_clear_namespace(pbufnr, -1, 0, -1) + + -- Highlight the target line within the slice + local relative_line = target - start_line + 1 + if relative_line >= 1 and relative_line <= #preview_lines then + vim.api.nvim_buf_add_highlight( + pbufnr, -1, "Search", relative_line - 1, 0, -1 + ) + end + end, +}) + +local function jump_to_line() + local lines = vim.api.nvim_buf_get_lines(0, 0, -1, false) + local current_file = vim.api.nvim_buf_get_name(0) + local entries = {} + + for i, text in ipairs(lines) do + table.insert(entries, { + value = text, + display = string.format("%d: %s", i, text), + ordinal = text, + path = current_file, -- needed by the previewer + lnum = i, -- actual file line number + }) + end + + pickers.new({}, { + prompt_title = "Jump to Line", + finder = finders.new_table({ + results = entries, + entry_maker = function(e) return e end, + }), + sorter = conf.generic_sorter({}), + previewer = dynamic_previewer, + attach_mappings = function(prompt_bufnr, _) + actions.select_default:replace(function() + actions.close(prompt_bufnr) + local selection = action_state.get_selected_entry() + if selection then + local target_line = selection.lnum + local closed_line = vim.fn.foldclosed(target_line) + if closed_line ~= -1 then + target_line = closed_line + end + -- Jump and open the fold + vim.cmd(string.format("normal! %dG", target_line)) + vim.cmd("normal! zv") + end + end) + return true + end, + }):find() +end + +return { jump_to_line = jump_to_line }