diff --git a/config/linux-dev/nvim/lua/config/options.lua b/config/linux-dev/nvim/lua/config/options.lua index 7dfa038..c23f734 100644 --- a/config/linux-dev/nvim/lua/config/options.lua +++ b/config/linux-dev/nvim/lua/config/options.lua @@ -25,22 +25,16 @@ vim.g.have_nerd_font = true vim.opt.termguicolors = false vim.opt.textwidth = 100 --- vim.opt.colorcolumn = '+0' +vim.opt.colorcolumn = '+0' vim.opt.signcolumn = 'no' vim.opt.number = true vim.opt.relativenumber = true - vim.opt.cursorline = true vim.opt.guicursor = 'n-v-i-c:block' --- vim.opt.statusline = ' %f %h%w%m%r%= ' -vim.opt.statusline = '> %f %h%w%m%r %= %l,%c - %L ' -vim.opt.fillchars:append({ stl = '─', stlnc = '─' }) - +vim.opt.statusline = '> %f %h%w%m%r %= [%l,%c-%L]' vim.opt.winborder = 'rounded' -vim.opt.laststatus = 3 -vim.opt.showcmd = false --- vim.opt.cmdheight = 0 +vim.opt.fillchars:append({ vert = '┃' }) -- Wrap vim.opt.wrap = false diff --git a/config/linux-dev/nvim/lua/custom/navigation.lua b/config/linux-dev/nvim/lua/custom/navigation.lua index a77d310..1c12870 100644 --- a/config/linux-dev/nvim/lua/custom/navigation.lua +++ b/config/linux-dev/nvim/lua/custom/navigation.lua @@ -1,5 +1,5 @@ -- Minimal fuzzy finder + content search for Neovim 0.11+ --- Optional: `fdfind` or `fd` for file listing, `rg` for text search +-- Optional: `fdfind` or `fd` for file listing, and `rg` (ripgrep) for text search. local Fuzzy = {} @@ -20,7 +20,7 @@ local function get_file_list() return vim.fn.globpath('.', '**/*', false, true) end --- Create the input/results floating windows +-- Create floating input + result windows local function open_float(prompt) local input_buf = vim.api.nvim_create_buf(false, true) local result_buf = vim.api.nvim_create_buf(false, true) @@ -64,7 +64,7 @@ local function open_float(prompt) end -------------------------------------------------------------------- --- 🔵 Highlight current selection (using extmark, not deprecated API) +-- 🔵 Highlight current selection -------------------------------------------------------------------- function Fuzzy:highlight_selection() if not self.result_buf then @@ -75,11 +75,14 @@ function Fuzzy:highlight_selection() end vim.api.nvim_buf_clear_namespace(self.result_buf, self.ns_id, 0, -1) if self.matches and self.matches[self.cursor] then - vim.api.nvim_buf_set_extmark(self.result_buf, self.ns_id, self.cursor - 1, 0, { - end_line = self.cursor, - hl_group = 'Visual', - hl_eol = true, - }) + local rel_cursor = self.cursor - (self.scroll or 0) + if rel_cursor >= 1 and rel_cursor <= self.page_size then + vim.api.nvim_buf_set_extmark(self.result_buf, self.ns_id, rel_cursor - 1, 0, { + end_line = rel_cursor, + hl_group = 'Visual', + hl_eol = true, + }) + end end end @@ -97,7 +100,7 @@ function Fuzzy.close() end -------------------------------------------------------------------- --- 🟢 Fuzzy file finder (using fd or globpath) +-- 🟢 File finder -------------------------------------------------------------------- function Fuzzy.open() if Fuzzy.active then @@ -108,27 +111,35 @@ function Fuzzy.open() Fuzzy.files = get_file_list() Fuzzy.matches = Fuzzy.files Fuzzy.cursor = 1 + Fuzzy.scroll = 0 + Fuzzy.page_size = 50 Fuzzy.input_buf, Fuzzy.result_buf, Fuzzy.input_win, Fuzzy.result_win = open_float('Search: ') + local function render_results() + local total = #Fuzzy.matches + if total == 0 then + vim.api.nvim_buf_set_lines(Fuzzy.result_buf, 0, -1, false, { '-- no matches --' }) + return + end + local start_idx = Fuzzy.scroll + 1 + local end_idx = math.min(start_idx + Fuzzy.page_size - 1, total) + local display = {} + for i = start_idx, end_idx do + display[#display + 1] = Fuzzy.matches[i] + end + vim.api.nvim_buf_set_lines(Fuzzy.result_buf, 0, -1, false, display) + Fuzzy:highlight_selection() + end + local function update_results(text) if text == '' then Fuzzy.matches = Fuzzy.files else Fuzzy.matches = vim.fn.matchfuzzy(Fuzzy.files, text) end - if #Fuzzy.matches == 0 then - vim.api.nvim_buf_set_lines(Fuzzy.result_buf, 0, -1, false, { '-- no matches --' }) - Fuzzy.cursor = 1 - return - end - local display = {} - for i = 1, math.min(#Fuzzy.matches, 50) do - display[#display + 1] = Fuzzy.matches[i] - end - vim.api.nvim_buf_set_lines(Fuzzy.result_buf, 0, -1, false, display) - Fuzzy.cursor = 1 - Fuzzy:highlight_selection() + Fuzzy.cursor, Fuzzy.scroll = 1, 0 + render_results() end vim.api.nvim_create_autocmd({ 'TextChangedI', 'TextChangedP' }, { @@ -140,13 +151,23 @@ function Fuzzy.open() }) vim.keymap.set('i', '', function() - Fuzzy.cursor = math.min(Fuzzy.cursor + 1, #Fuzzy.matches) - Fuzzy:highlight_selection() + if Fuzzy.cursor < #Fuzzy.matches then + Fuzzy.cursor = Fuzzy.cursor + 1 + if Fuzzy.cursor > Fuzzy.scroll + Fuzzy.page_size then + Fuzzy.scroll = Fuzzy.scroll + 1 + end + render_results() + end end, { buffer = Fuzzy.input_buf }) vim.keymap.set('i', '', function() - Fuzzy.cursor = math.max(Fuzzy.cursor - 1, 1) - Fuzzy:highlight_selection() + if Fuzzy.cursor > 1 then + Fuzzy.cursor = Fuzzy.cursor - 1 + if Fuzzy.cursor <= Fuzzy.scroll then + Fuzzy.scroll = math.max(Fuzzy.scroll - 1, 0) + end + render_results() + end end, { buffer = Fuzzy.input_buf }) vim.keymap.set('i', '', function() @@ -157,15 +178,16 @@ function Fuzzy.open() end end, { buffer = Fuzzy.input_buf }) - vim.keymap.set('i', '', function() - Fuzzy.close() - end, { buffer = Fuzzy.input_buf }) + vim.keymap.set('i', '', Fuzzy.close, { buffer = Fuzzy.input_buf }) + vim.keymap.set('i', '', Fuzzy.close, { buffer = Fuzzy.input_buf }) + vim.keymap.set('n', '', Fuzzy.close, { buffer = Fuzzy.input_buf }) + vim.keymap.set('n', 'q', Fuzzy.close, { buffer = Fuzzy.input_buf }) vim.cmd.startinsert() end -------------------------------------------------------------------- --- 🟣 Ripgrep-based content search +-- 🟣 Ripgrep-based content search (scrolling + match highlighting) -------------------------------------------------------------------- function Fuzzy.open_grep() if Fuzzy.active then @@ -174,8 +196,48 @@ function Fuzzy.open_grep() Fuzzy.active = true Fuzzy.input_buf, Fuzzy.result_buf, Fuzzy.input_win, Fuzzy.result_win = open_float('Grep: ') - Fuzzy.matches = {} - Fuzzy.cursor = 1 + Fuzzy.matches, Fuzzy.cursor, Fuzzy.scroll = {}, 1, 0 + Fuzzy.page_size = 50 + Fuzzy.ns_id = vim.api.nvim_create_namespace('FuzzyHighlight') + + local function render_results(query) + local total = #Fuzzy.matches + if total == 0 then + vim.api.nvim_buf_set_lines(Fuzzy.result_buf, 0, -1, false, { '-- no matches --' }) + return + end + + local start_idx = Fuzzy.scroll + 1 + local end_idx = math.min(start_idx + Fuzzy.page_size - 1, total) + local display = {} + for i = start_idx, end_idx do + display[#display + 1] = Fuzzy.matches[i] + end + + vim.api.nvim_buf_set_lines(Fuzzy.result_buf, 0, -1, false, display) + vim.api.nvim_buf_clear_namespace(Fuzzy.result_buf, Fuzzy.ns_id, 0, -1) + + -- highlight selection + local rel_cursor = math.min(Fuzzy.cursor - Fuzzy.scroll, #display) + vim.api.nvim_buf_set_extmark(Fuzzy.result_buf, Fuzzy.ns_id, rel_cursor - 1, 0, { + end_line = rel_cursor, + hl_group = 'Visual', + hl_eol = true, + }) + + -- highlight query matches + if query and query ~= '' then + local pattern = vim.pesc(query) + for i, line in ipairs(display) do + for s, e in line:gmatch('()' .. pattern .. '()') do + vim.api.nvim_buf_set_extmark(Fuzzy.result_buf, Fuzzy.ns_id, i - 1, s - 1, { + end_col = e - 1, + hl_group = 'Search', + }) + end + end + end + end local function run_grep(query) if query == '' then @@ -189,17 +251,8 @@ function Fuzzy.open_grep() local result = handle:read('*a') handle:close() Fuzzy.matches = vim.split(result, '\n', { trimempty = true }) - if #Fuzzy.matches == 0 then - vim.api.nvim_buf_set_lines(Fuzzy.result_buf, 0, -1, false, { '-- no matches --' }) - return - end - local display = {} - for i = 1, math.min(#Fuzzy.matches, 50) do - display[#display + 1] = Fuzzy.matches[i] - end - vim.api.nvim_buf_set_lines(Fuzzy.result_buf, 0, -1, false, display) - Fuzzy.cursor = 1 - Fuzzy:highlight_selection() + Fuzzy.cursor, Fuzzy.scroll = 1, 0 + render_results(query) end vim.api.nvim_create_autocmd({ 'TextChangedI', 'TextChangedP' }, { @@ -211,13 +264,25 @@ function Fuzzy.open_grep() }) vim.keymap.set('i', '', function() - Fuzzy.cursor = math.min(Fuzzy.cursor + 1, #Fuzzy.matches) - Fuzzy:highlight_selection() + if Fuzzy.cursor < #Fuzzy.matches then + Fuzzy.cursor = Fuzzy.cursor + 1 + if Fuzzy.cursor > Fuzzy.scroll + Fuzzy.page_size then + Fuzzy.scroll = Fuzzy.scroll + 1 + end + local query = vim.fn.getline('.'):gsub('^Grep:%s*', '') + render_results(query) + end end, { buffer = Fuzzy.input_buf }) vim.keymap.set('i', '', function() - Fuzzy.cursor = math.max(Fuzzy.cursor - 1, 1) - Fuzzy:highlight_selection() + if Fuzzy.cursor > 1 then + Fuzzy.cursor = Fuzzy.cursor - 1 + if Fuzzy.cursor <= Fuzzy.scroll then + Fuzzy.scroll = math.max(Fuzzy.scroll - 1, 0) + end + local query = vim.fn.getline('.'):gsub('^Grep:%s*', '') + render_results(query) + end end, { buffer = Fuzzy.input_buf }) vim.keymap.set('i', '', function() diff --git a/config/linux-dev/nvim/lua/plugins/filetree.lua b/config/linux-dev/nvim/lua/plugins/filetree.lua index a8113fd..0242c62 100644 --- a/config/linux-dev/nvim/lua/plugins/filetree.lua +++ b/config/linux-dev/nvim/lua/plugins/filetree.lua @@ -49,12 +49,15 @@ end return { 'nvim-tree/nvim-tree.lua', version = '*', + dev = true, opts = { on_attach = my_on_attach, view = { signcolumn = 'no' }, actions = { file_popup = { open_win_config = { border = 'rounded' } } }, renderer = { - root_folder_label = false, + root_folder_label = function(path) + return '-- ' .. vim.fn.fnamemodify(path, ':t') .. ' --' + end, special_files = {}, highlight_hidden = 'all', @@ -67,6 +70,7 @@ return { }, icons = { bookmarks_placement = 'after', + git_placement = 'after', show = { file = false, folder = false, @@ -77,16 +81,32 @@ return { diagnostics = false, bookmarks = true, }, - git_placement = 'after', glyphs = { + -- default = '•', + default = ' ', + symlink = '', + bookmark = '󰆤', + modified = '●', + hidden = '󰜌', + folder = { + arrow_closed = '', + arrow_open = '', + default = '▸', + open = '▾', + empty = '', + empty_open = '', + symlink = '', + symlink_open = '', + }, + git = { - unstaged = '✗', - staged = '✓', - unmerged = '', - renamed = '➜', - untracked = '★', + unstaged = '◇', -- '✗', + staged = '', + unmerged = '', + renamed = '', + untracked = '', deleted = '', -- '󰧧', - ignored = '◌', + ignored = '', }, }, },