Intro
Being abble to change the scope of a srarch, grep or other commands gives us more control.
Finding the root dir
--- Returns project_root
--- @param bufnr number|nil Buffer
--- @return string root dir
M.root = function(bufnr)
bufnr = bufnr or 0
local markers = {
'.git',
'.hg',
'.svn',
'pyproject.toml',
'setup.py',
'requirements.txt',
'package.json',
'tsconfig.json',
'Makefile',
'CMakeLists.txt',
'.nvim-root',
}
return vim.fs.root(bufnr, markers) or vim.fn.getcwd()
end
Custom telescope find_files
This module will be called via keymap
-- File: ~/.config/nvim/lua/core/utils/telescope.lua
-- Last Change: 2025-06-23
-- Author: Sergio Araujo
local M = {}
local actions = require('telescope.actions')
local pickers = require('telescope.pickers')
local finders = require('telescope.finders')
local conf = require('telescope.config').values
local ts_utils = require('telescope.utils')
local builtin = require('telescope.builtin')
local utils = require('telescope.utils')
local get_root = require('core.utils.file_system').root
-- Função para path_display que remove prefixo Termux e mantém estilo tail+path
local function oldfiles_path_display(_, path)
local termux_prefix = '/data/data/com.termux/files/home/'
if path:sub(1, #termux_prefix) == termux_prefix then path = path:sub(#termux_prefix + 1) end
local tail = utils.path_tail(path)
local display = string.format('%s %s', tail, path)
local hl_start = #tail + 1
local hl_end = #display
return display, { { { hl_start, hl_end }, 'Comment' } }
end
-- Garante um diretório válido mesmo que buffer esteja vazio
local function get_valid_buf_dir()
local dir = ts_utils.buffer_dir()
return (dir and dir ~= '') and dir or vim.loop.cwd()
end
-- Find files com toggle de cwd
M.find_files_with_toggle = function()
local root = get_root()
if not root or root == '' then
vim.notify('Root dir não encontrado. Você está fora de um projeto?', vim.log.levels.WARN, {
title = 'Find Files',
})
return
end
local buf_dir = get_valid_buf_dir()
local current_cwd = root
local function picker()
builtin.find_files({
cwd = current_cwd,
attach_mappings = function(prompt_bufnr, map)
map('i', '<a-d>', function()
actions.close(prompt_bufnr)
local new_cwd = (current_cwd == root) and buf_dir or root
local title = 'Find Files'
if new_cwd ~= current_cwd then
current_cwd = new_cwd
vim.notify('cwd switched to: ' .. current_cwd, vim.log.levels.INFO, { title = title })
else
vim.notify('cwd não foi alterado (já em ' .. current_cwd .. ')', vim.log.levels.WARN, { title = title })
end
picker()
end)
return true
end,
})
end
picker()
end
-- Grep customizado com toggle de cwd e preservação do prompt
M.custom_grep_with_toggle = function()
local root = get_root()
if not root or root == '' then
vim.notify('Root dir não encontrado. Você está fora de um projeto?', vim.log.levels.WARN, {
title = 'Custom Grep',
})
return
end
local buf_dir = get_valid_buf_dir()
local current_cwd = root
local current_prompt = ''
local function picker()
pickers
.new({}, {
prompt_title = 'Custom Grep',
finder = finders.new_job(function(prompt)
if prompt == '' then return nil end
current_prompt = prompt
return { 'rg', '--vimgrep', '--no-heading', prompt }
end, nil, { cwd = current_cwd }),
previewer = conf.grep_previewer({}),
sorter = conf.generic_sorter({}),
default_text = current_prompt,
attach_mappings = function(prompt_bufnr, map)
map('i', '<a-d>', function()
actions.close(prompt_bufnr)
local new_cwd = (current_cwd == root) and buf_dir or root
local title = 'Custom Grep'
if new_cwd ~= current_cwd then
current_cwd = new_cwd
vim.notify('cwd switched to: ' .. current_cwd, vim.log.levels.INFO, { title = title })
else
vim.notify('cwd não foi alterado (já em ' .. current_cwd .. ')', vim.log.levels.WARN, { title = title })
end
picker()
end)
return true
end,
})
:find()
end
picker()
end
-- Oldfiles com path_display customizado para Termux
M.oldfiles_clean = function()
builtin.oldfiles({
path_display = oldfiles_path_display,
layout_strategy = 'vertical', -- ou "horizontal", conforme preferir
layout_config = {
height = 0.5, -- aqui você diminui a altura (0.3 = 30% da tela)
width = 0.7, -- opcional: ajustar largura também
prompt_position = 'top',
preview_cutoff = 1, -- para esconder preview em telas pequenas
},
})
end
return M
The keymaps
In your telescope keys table place
-- Adjust the module path to reflect you realitty
{
'<leader>ff',
function() require('core.utils.telescope').find_files_with_toggle() end,
desc = 'Find Files (toggle raiz/buffer com Alt+D)',
},
{
'<leader>fg',
function() require('core.utils.telescope').custom_grep_with_toggle() end,
desc = 'Custom Grep (rg) toggle root/buffer com <A-d>',
},
First of all, thank you for sharing your code and your ideas. Since there are different levels of users on this platform, from basic to senior, if you briefly state in the title of the article who the article is written for and how they will use it, you can help people get an idea about the article before moving on.
My second suggestion is that if you do not want to write a long article but want to explain your code; After pasting your script via ChatGPT, you can make your code more understandable for those who are not Lua literate with the help of the "Break apart the code and add line by line comments" prompt. In this way, it will be a clearer sharing and will be open to development.