return { -- Fuzzy Finder (files, lsp, etc) 'nvim-telescope/telescope.nvim', branch = '0.1.x', dependencies = { 'nvim-lua/plenary.nvim', -- Fuzzy Finder Algorithm which requires local dependencies to be built. -- Only load if `make` is available. Make sure you have the system -- requirements installed. { 'nvim-telescope/telescope-fzf-native.nvim', -- NOTE: If you are having trouble with this installation, -- refer to the README for telescope-fzf-native for more instructions. build = 'make', cond = function() return vim.fn.executable 'make' == 1 end, }, }, config = function() -- [[ Configure Telescope ]] -- See `:help telescope` and `:help telescope.setup()` require('telescope').setup { defaults = { mappings = { i = { [''] = false, [''] = false, }, }, }, } -- Enable telescope fzf native, if installed pcall(require('telescope').load_extension, 'fzf') -- smart_open function for Telescope to check if the current tab has an empty "No Name" buffer. If it has, it replaces the empty buffer and open a file in the same tab local actions = require 'telescope.actions' local action_state = require 'telescope.actions.state' local function smart_open(prompt_bufnr) local entry = action_state.get_selected_entry() if not entry then return end local path = entry.path or entry.filename if not path then return end if prompt_bufnr and vim.api.nvim_buf_is_valid(prompt_bufnr) then pcall(actions.close, prompt_bufnr) end -- 1. If file is already open → jump to it local tabpages = vim.api.nvim_list_tabpages() for _, tab in ipairs(tabpages) do for _, win in ipairs(vim.api.nvim_tabpage_list_wins(tab)) do local buf = vim.api.nvim_win_get_buf(win) if vim.api.nvim_buf_get_name(buf) == path then vim.api.nvim_set_current_tabpage(tab) -- jump to tab vim.api.nvim_set_current_win(win) -- jump to window return end end end -- 2. If current tab has an empty "No Name" buffer → reuse it local wins = vim.api.nvim_tabpage_list_wins(0) for _, win in ipairs(wins) do local buf = vim.api.nvim_win_get_buf(win) local name = vim.api.nvim_buf_get_name(buf) local buftype = vim.api.nvim_buf_get_option(buf, 'buftype') local modified = vim.api.nvim_buf_get_option(buf, 'modified') if name == '' and buftype == '' and not modified then vim.api.nvim_set_current_win(win) vim.cmd('edit ' .. vim.fn.fnameescape(path)) return end end -- 3. Otherwise → open in a new tab vim.cmd('tabnew ' .. vim.fn.fnameescape(path)) end -- Split option in Telescope file picker with smart_open local actions = require 'telescope.actions' local action_state = require 'telescope.actions.state' local function smart_open_split(prompt_bufnr, split_type) local entry = action_state.get_selected_entry() if not entry then return end local path = entry.path or entry.filename if not path then return end if prompt_bufnr and vim.api.nvim_buf_is_valid(prompt_bufnr) then pcall(actions.close, prompt_bufnr) end -- Check if file is already open local open_tab, open_win for _, tab in ipairs(vim.api.nvim_list_tabpages()) do for _, win in ipairs(vim.api.nvim_tabpage_list_wins(tab)) do local buf = vim.api.nvim_win_get_buf(win) if vim.api.nvim_buf_get_name(buf) == path then open_tab = tab open_win = win break end end if open_tab then break end end if open_tab then local choice = vim.fn.confirm('File is already open in a tab. Open split here anyway?', '&Yes\n&No', 2) if choice ~= 1 then -- User chose No → jump to the tab where file is open vim.api.nvim_set_current_tabpage(open_tab) vim.api.nvim_set_current_win(open_win) return end -- Else user chose Yes → continue to open split in current tab end -- Open in split if split_type == 'v' then -- horizontal → always below vim.cmd('belowright split ' .. vim.fn.fnameescape(path)) elseif split_type == 'h' then -- vertical → always right vim.cmd('vertical rightbelow split ' .. vim.fn.fnameescape(path)) end end -- Telescope keymap using Smart Open vim.keymap.set('n', 'sf', function() require('telescope.builtin').find_files { attach_mappings = function(_, map) map('i', '', function(prompt_bufnr) smart_open(prompt_bufnr) end) map('n', '', function(prompt_bufnr) smart_open(prompt_bufnr) end) -- Horizontal split with 'h' map('n', 'h', function(prompt_bufnr) smart_open_split(prompt_bufnr, 'h') end) -- Vertical split with 'v' map('n', 'v', function(prompt_bufnr) smart_open_split(prompt_bufnr, 'v') end) return true end, } end, { desc = '[S]earch [F]iles (Smart Open)' }) -- Telescope live_grep in git root -- Function to find the git root directory based on the current buffer's path local function find_git_root() -- Use the current buffer's path as the starting point for the git search local current_file = vim.api.nvim_buf_get_name(0) local current_dir local cwd = vim.fn.getcwd() -- If the buffer is not associated with a file, return nil if current_file == '' then current_dir = cwd else -- Extract the directory from the current file's path current_dir = vim.fn.fnamemodify(current_file, ':h') end -- Find the Git root directory from the current file's path local git_root = vim.fn.systemlist('git -C ' .. vim.fn.escape(current_dir, ' ') .. ' rev-parse --show-toplevel')[1] if vim.v.shell_error ~= 0 then print 'Not a git repository. Searching on current working directory' return cwd end return git_root end -- Custom live_grep function to search in git root local function live_grep_git_root() local git_root = find_git_root() if git_root then require('telescope.builtin').live_grep { search_dirs = { git_root }, } end end vim.api.nvim_create_user_command('LiveGrepGitRoot', live_grep_git_root, {}) -- See `:help telescope.builtin` vim.keymap.set('n', '?', require('telescope.builtin').oldfiles, { desc = '[?] Find recently opened files' }) vim.keymap.set('n', '', require('telescope.builtin').buffers, { desc = '[ ] Find existing buffers' }) vim.keymap.set('n', '/', function() -- You can pass additional configuration to telescope to change theme, layout, etc. require('telescope.builtin').current_buffer_fuzzy_find(require('telescope.themes').get_dropdown { winblend = 10, previewer = false, }) end, { desc = '[/] Fuzzily search in current buffer' }) local function telescope_live_grep_open_files() require('telescope.builtin').live_grep { grep_open_files = true, prompt_title = 'Live Grep in Open Files', } end vim.keymap.set('n', 's/', telescope_live_grep_open_files, { desc = '[S]earch [/] in Open Files' }) vim.keymap.set('n', 'ss', require('telescope.builtin').builtin, { desc = '[S]earch [S]elect Telescope' }) vim.keymap.set('n', 'gf', function() local is_git_dir = vim.fn.system('git rev-parse --is-inside-work-tree'):gsub('%s+', '') == 'true' if not is_git_dir then vim.notify('Not a git repository', vim.log.levels.WARN, { title = 'Telescope Git Files' }) return end require('telescope.builtin').git_files { attach_mappings = function(_, map) local actions = require 'telescope.actions' local action_state = require 'telescope.actions.state' local function open_smart(prompt_bufnr) local entry = action_state.get_selected_entry() if not entry then return end pcall(actions.close, prompt_bufnr) smart_open(prompt_bufnr) end map('i', '', open_smart) map('n', '', open_smart) return true end, } end, { desc = 'Search [G]it [F]iles (Smart Open)' }) vim.keymap.set('n', 'si', require('telescope.builtin').help_tags, { desc = '[S]earch [I]nfo' }) vim.keymap.set('n', 'sw', require('telescope.builtin').grep_string, { desc = '[S]earch current [W]ord' }) vim.keymap.set('n', 'sg', require('telescope.builtin').live_grep, { desc = '[S]earch by [G]rep' }) vim.keymap.set('n', 'sG', ':LiveGrepGitRoot', { desc = '[S]earch by [G]rep on Git Root' }) vim.keymap.set('n', 'sd', require('telescope.builtin').diagnostics, { desc = '[S]earch [D]iagnostics' }) vim.keymap.set('n', 'sr', require('telescope.builtin').resume, { desc = '[S]earch [R]esume' }) end, }