Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion lua/compiler/init.lua
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@ local M = {}

M.setup = function(opts)
cmd("CompilerOpen", function()
require("compiler.telescope").show()
require("compiler.picker").show()
end, { desc = "Open the compiler" })

cmd("CompilerToggleResults", function()
Expand Down
131 changes: 131 additions & 0 deletions lua/compiler/picker-util.lua
Original file line number Diff line number Diff line change
@@ -0,0 +1,131 @@
--- ### Shared utilities for compiler.nvim pickers

local M = {}

--- Validates that the current working directory is not the home directory
--- @return boolean true if valid, false if invalid (also shows notification)
function M.validate_working_directory()
if vim.loop.os_homedir() == vim.loop.cwd() then
vim.notify(
"You must :cd your project dir first.\nHome is not allowed as working dir.",
vim.log.levels.WARN,
{
title = "Compiler.nvim",
}
)
return false
end
return true
end

--- Prepares compiler options by gathering language and BAU options
--- @return table { language, options, filetype }
function M.prepare_compiler_options()
local utils = require("compiler.utils")
local utils_bau = require("compiler.utils-bau")

local buffer = vim.api.nvim_get_current_buf()
local filetype = vim.api.nvim_get_option_value("filetype", { buf = buffer })

-- Programatically require the backend for the current language.
local language = utils.require_language(filetype)

-- On unsupported languages, default to make.
if not language then language = utils.require_language("make") or {} end

-- Also show options discovered on Makefile, Cmake... and other bau.
if not language.bau_added then
language.bau_added = true
local bau_opts = utils_bau.get_bau_opts()

-- Insert a separator for every bau.
local last_bau_value = nil
for _, item in ipairs(bau_opts) do
if last_bau_value ~= item.bau then
table.insert(language.options, { text = "", value = "separator" })
last_bau_value = item.bau
end
table.insert(language.options, item)
end
end

-- Add numbers in front of the options to display.
local index_counter = 0
for _, option in ipairs(language.options) do
if option.value ~= "separator" then
index_counter = index_counter + 1
option.text = index_counter .. " - " .. option.text
end
end

return {
language = language,
options = language.options,
filetype = filetype,
}
end

--- Executes the selected compiler option
--- @param selected_value string The value of the selected option
--- @param selected_text string The display text of the selected option
--- @param language_options table The full options table
--- @param filetype string The current filetype
function M.execute_selection(
selected_value,
selected_text,
language_options,
language,
filetype
)
if selected_value == "" or selected_value == "separator" then return end

local utils_bau = require("compiler.utils-bau")

-- Do the selected option belong to a build automation utility?
local bau = nil
for _, value in ipairs(language_options) do
if value.text == selected_text or value.value == selected_value then
bau = value.bau
break
end
end

if bau then -- call the bau backend.
bau = utils_bau.require_bau(bau)
if bau then bau.action(selected_value) end
-- then
-- clean redo (language)
_G.compiler_redo_selection = nil
-- save redo (bau)
_G.compiler_redo_bau_selection = selected_value
_G.compiler_redo_bau = bau
else -- call the language backend.
language.action(selected_value)
-- then
-- save redo (language)
_G.compiler_redo_selection = selected_value
_G.compiler_redo_filetype = filetype
-- clean redo (bau)
_G.compiler_redo_bau_selection = nil
_G.compiler_redo_bau = nil
end
end

--- Creates items and mapping for vim.ui.select (filters out separators)
--- @param language_options table The full options table
--- @return table { items, item_map }
function M.create_select_items(language_options)
local items = {}
local item_map = {}

for _, option in ipairs(language_options) do
if option.value ~= "separator" then
table.insert(items, option.text)
item_map[option.text] = { value = option.value, bau = option.bau }
end
end

return { items = items, item_map = item_map }
end

return M
48 changes: 48 additions & 0 deletions lua/compiler/picker.lua
Original file line number Diff line number Diff line change
@@ -0,0 +1,48 @@
--- ### Picker frontend for compiler.nvim
-- Automatically detects and uses telescope.nvim or falls back to vim.ui.select

local M = {}

function M.show()
local telescope_ok = pcall(require, "telescope")

if telescope_ok then
require("compiler.telescope").show()
else
-- Fallback to vim.ui.select implementation
local picker_util = require("compiler.picker-util")

-- Validate working directory
if not picker_util.validate_working_directory() then return end

-- Prepare compiler options
local compiler_data = picker_util.prepare_compiler_options()
local language = compiler_data.language
local options = compiler_data.options
local filetype = compiler_data.filetype

-- Create items for vim.ui.select
local select_data = picker_util.create_select_items(options)
local items = select_data.items
local item_map = select_data.item_map

-- Show vim.ui.select
vim.ui.select(items, {
prompt = "Compiler: ",
}, function(choice)
if not choice then return end
local selected = item_map[choice]
if not selected then return end

picker_util.execute_selection(
selected.value,
choice,
options,
language,
filetype
)
end)
end
end

return M
107 changes: 23 additions & 84 deletions lua/compiler/telescope.lua
Original file line number Diff line number Diff line change
Expand Up @@ -3,61 +3,23 @@
local M = {}

function M.show()
-- If working directory is home, don't open telescope.
if vim.loop.os_homedir() == vim.loop.cwd() then
vim.notify("You must :cd your project dir first.\nHome is not allowed as working dir.", vim.log.levels.WARN, {
title = "Compiler.nvim"
})
return
end
local picker_util = require("compiler.picker-util")

-- Validate working directory
if not picker_util.validate_working_directory() then return end

-- Dependencies
local conf = require("telescope.config").values
local actions = require "telescope.actions"
local state = require "telescope.actions.state"
local pickers = require "telescope.pickers"
local finders = require "telescope.finders"
local utils = require("compiler.utils")
local utils_bau = require("compiler.utils-bau")

local buffer = vim.api.nvim_get_current_buf()
local filetype = vim.api.nvim_get_option_value("filetype", { buf = buffer })


-- POPULATE
-- ========================================================================

-- Programatically require the backend for the current language.
local language = utils.require_language(filetype)

-- On unsupported languages, default to make.
if not language then language = utils.require_language("make") or {} end

-- Also show options discovered on Makefile, Cmake... and other bau.
if not language.bau_added then
language.bau_added = true
local bau_opts = utils_bau.get_bau_opts()

-- Insert a separator on telescope for every bau.
local last_bau_value = nil
for _, item in ipairs(bau_opts) do
if last_bau_value ~= item.bau then
table.insert(language.options, { text = "", value = "separator" })
last_bau_value = item.bau
end
table.insert(language.options, item)
end
end

-- Add numbers in front of the options to display.
local index_counter = 0
for _, option in ipairs(language.options) do
if option.value ~= "separator" then
index_counter = index_counter + 1
option.text = index_counter .. " - " .. option.text
end
end
local actions = require("telescope.actions")
local state = require("telescope.actions.state")
local pickers = require("telescope.pickers")
local finders = require("telescope.finders")

-- Prepare compiler options
local compiler_data = picker_util.prepare_compiler_options()
local language = compiler_data.language
local language_options = compiler_data.options
local filetype = compiler_data.filetype

-- RUN ACTION ON SELECTED
-- ========================================================================
Expand All @@ -66,58 +28,35 @@ function M.show()
local function on_option_selected(prompt_bufnr)
actions.close(prompt_bufnr) -- Close Telescope on selection
local selection = state.get_selected_entry()
if selection.value == "" then return end -- Ignore separators

if selection then
-- Do the selected option belong to a build automation utility?
local bau = nil
for _, value in ipairs(language.options) do
if value.text == selection.display then
bau = value.bau
end
end

if bau then -- call the bau backend.
bau = utils_bau.require_bau(bau)
if bau then bau.action(selection.value) end
-- then
-- clean redo (language)
_G.compiler_redo_selection = nil
-- save redo (bau)
_G.compiler_redo_bau_selection = selection.value
_G.compiler_redo_bau = bau
else -- call the language backend.
language.action(selection.value)
-- then
-- save redo (language)
_G.compiler_redo_selection = selection.value
_G.compiler_redo_filetype = filetype
-- clean redo (bau)
_G.compiler_redo_bau_selection = nil
_G.compiler_redo_bau = nil
end

picker_util.execute_selection(
selection.value,
selection.display,
language_options,
language,
filetype
)
end
end


-- SHOW TELESCOPE
-- ========================================================================
local function open_telescope()
pickers
.new({}, {
prompt_title = "Compiler",
results_title = "Options",
finder = finders.new_table {
results = language.options,
finder = finders.new_table({
results = language_options,
entry_maker = function(entry)
return {
display = entry.text,
value = entry.value,
ordinal = entry.text,
}
end,
},
}),
sorter = conf.generic_sorter(),
attach_mappings = function(_, map)
map(
Expand Down