feat: first attempt at compile-commands-picker
This commit is contained in:
parent
8802b654c9
commit
fef576fbde
|
@ -0,0 +1,137 @@
|
|||
-- Telescope picker for selecting compile_commands.json
|
||||
local M = {}
|
||||
|
||||
local function find_compile_commands()
|
||||
local root = vim.fn.getcwd()
|
||||
local cmd = string.format('find "%s" -name compile_commands.json -type f 2>/dev/null', root)
|
||||
local handle = io.popen(cmd)
|
||||
if not handle then
|
||||
return {}
|
||||
end
|
||||
|
||||
local result = handle:read('*a')
|
||||
handle:close()
|
||||
|
||||
local files = {}
|
||||
for line in result:gmatch('[^\n]+') do
|
||||
-- Get relative path for display
|
||||
local relative = line:gsub('^' .. vim.pesc(root) .. '/', '')
|
||||
table.insert(files, {
|
||||
path = line,
|
||||
display = relative,
|
||||
dir = vim.fn.fnamemodify(line, ':h'),
|
||||
relative_dir = vim.fn.fnamemodify(relative, ':h'),
|
||||
})
|
||||
end
|
||||
|
||||
return files
|
||||
end
|
||||
|
||||
function M.pick_compile_commands()
|
||||
local files = find_compile_commands()
|
||||
|
||||
if #files == 0 then
|
||||
vim.notify('No compile_commands.json files found', vim.log.levels.WARN)
|
||||
return
|
||||
elseif #files == 1 then
|
||||
vim.notify('Using: ' .. files[1].display, vim.log.levels.INFO)
|
||||
M.set_compile_commands(files[1])
|
||||
return
|
||||
end
|
||||
|
||||
-- Multiple files found, show picker
|
||||
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')
|
||||
|
||||
pickers.new({}, {
|
||||
prompt_title = 'Select compile_commands.json',
|
||||
finder = finders.new_table {
|
||||
results = files,
|
||||
entry_maker = function(entry)
|
||||
return {
|
||||
value = entry,
|
||||
display = entry.display,
|
||||
ordinal = entry.display,
|
||||
}
|
||||
end,
|
||||
},
|
||||
sorter = conf.generic_sorter{},
|
||||
attach_mappings = function(prompt_bufnr, map)
|
||||
actions.select_default:replace(function()
|
||||
actions.close(prompt_bufnr)
|
||||
local selection = action_state.get_selected_entry()
|
||||
if selection then
|
||||
M.set_compile_commands(selection.value)
|
||||
end
|
||||
end)
|
||||
return true
|
||||
end,
|
||||
}):find()
|
||||
end
|
||||
|
||||
function M.set_compile_commands(file_info)
|
||||
local clangd_config = string.format([[
|
||||
CompileFlags:
|
||||
CompilationDatabase: %s
|
||||
]], file_info.relative_dir)
|
||||
|
||||
-- Write .clangd file
|
||||
local clangd_file = vim.fn.getcwd() .. '/.clangd'
|
||||
local file = io.open(clangd_file, 'w')
|
||||
if file then
|
||||
file:write(clangd_config)
|
||||
file:close()
|
||||
vim.notify('Created .clangd pointing to: ' .. file_info.relative_dir, vim.log.levels.INFO)
|
||||
|
||||
-- Restart LSP if clangd is running
|
||||
local clients = vim.lsp.get_active_clients({ name = 'clangd' })
|
||||
if #clients > 0 then
|
||||
vim.notify('Restarting clangd...', vim.log.levels.INFO)
|
||||
vim.cmd('LspRestart clangd')
|
||||
end
|
||||
else
|
||||
vim.notify('Failed to create .clangd file', vim.log.levels.ERROR)
|
||||
end
|
||||
end
|
||||
|
||||
-- Auto-detect multiple compile_commands.json on startup
|
||||
function M.auto_detect()
|
||||
local files = find_compile_commands()
|
||||
|
||||
if #files > 1 then
|
||||
-- Check if .clangd already exists
|
||||
local clangd_file = vim.fn.getcwd() .. '/.clangd'
|
||||
if vim.fn.filereadable(clangd_file) == 0 then
|
||||
vim.notify(
|
||||
string.format('Found %d compile_commands.json files. Use :CompileCommandsPicker to select one.', #files),
|
||||
vim.log.levels.INFO
|
||||
)
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
-- Setup function to create command
|
||||
function M.setup()
|
||||
vim.api.nvim_create_user_command('CompileCommandsPicker', function()
|
||||
M.pick_compile_commands()
|
||||
end, { desc = 'Select compile_commands.json for clangd' })
|
||||
|
||||
-- Auto-detect on entering a C/C++ file
|
||||
vim.api.nvim_create_autocmd('FileType', {
|
||||
pattern = { 'c', 'cpp', 'objc', 'objcpp' },
|
||||
callback = function()
|
||||
-- Only run once per session
|
||||
if not vim.g.compile_commands_detected then
|
||||
vim.g.compile_commands_detected = true
|
||||
vim.defer_fn(function()
|
||||
M.auto_detect()
|
||||
end, 100)
|
||||
end
|
||||
end,
|
||||
})
|
||||
end
|
||||
|
||||
return M
|
|
@ -21,6 +21,9 @@ function M.setup()
|
|||
|
||||
-- Setup LSP keymaps
|
||||
require('plugins.config.lsp.keymaps').setup()
|
||||
|
||||
-- Setup compile_commands.json picker for C/C++ projects
|
||||
require('plugins.config.compile-commands-picker').setup()
|
||||
end
|
||||
|
||||
return M
|
|
@ -9,7 +9,7 @@ local function get_clangd_query_driver()
|
|||
'/nix/store/*/bin/clang*',
|
||||
'/opt/homebrew/opt/llvm/bin/clang*',
|
||||
'/usr/bin/clang*',
|
||||
}, ';')
|
||||
}, ':')
|
||||
end
|
||||
|
||||
-- Get clang resource directory
|
||||
|
|
|
@ -79,6 +79,10 @@ function M.setup()
|
|||
vim.keymap.set('n', '<leader>sn', function()
|
||||
builtin.find_files { cwd = vim.fn.stdpath 'config' }
|
||||
end, { desc = '[S]earch [N]eovim files' })
|
||||
|
||||
-- C/C++ compile_commands.json picker
|
||||
vim.keymap.set('n', '<leader>sc', '<cmd>CompileCommandsPicker<cr>',
|
||||
{ desc = '[S]earch [C]ompile commands.json' })
|
||||
end
|
||||
|
||||
return M
|
Loading…
Reference in New Issue