summaryrefslogtreecommitdiff
path: root/lua/aotrix/compile.lua
blob: e7c95562a59c452283c3a1aaa13cf6f4217d564a (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
local build_dir

---Generates a table with available targets
---
---@return table
---@nodiscard
function tableOfTargets()
    -- Ugly way to retrieve targets, but it works
    -- Do not hesitate to change the command
    local command = "cmake --build " .. build_dir ..
                        " -t help|sed 1d|grep -v -e " .. [["]] ..
                        "all\\|clean\\|depend\\|edit_cache\\|rebuild_cache" ..
                        [["]] .. " -e " .. [["]] .. "\\.\\{3\\} .*\\..*$" ..
                        [["]] .. "|sed " .. [["]] .. "s/\\.\\.\\. //" .. [["]]
    local generatorExecutable = io.popen(command):lines()
    local choiceTable = {}
    for line in generatorExecutable do table.insert(choiceTable, line) end
    return choiceTable
end

---Displays a menu to let the user choose a target to compile
---
---@return nil
function chooseTarget(pCallbackFunction)
    vim.ui.select(tableOfTargets(), {
        prompt = 'Choose target:',
        format_item = function(item) return item end
    }, pCallbackFunction)
end

---@return nil
function createFloatingWindow()
    local max_height = vim.api.nvim_win_get_height(0)
    local max_width = vim.api.nvim_win_get_width(0)
    local window_height = math.floor(max_height / 2)
    local window_width = math.floor(max_width / 2)
    local window_buffer = vim.api.nvim_create_buf(false, true)
    vim.api.nvim_open_win(window_buffer, true, {
        border = "rounded",
        style = "minimal",
        relative = "editor",
        noautocmd = true,
        height = window_height,
        width = window_width,
        col = math.floor((max_width - window_width) / 2),
        row = math.floor((max_height - window_height) / 2)
    })
    return window_buffer
end

---@return nil
function createFloatingTerminal()
    createFloatingWindow()
    vim.cmd.term()
    vim.cmd.startinsert()
end

---@param command string
---@return nil
function executeCommandInTerminal(command)
    local channel = vim.bo.channel
    -- 'clear' is used to hide the command
    local exit_message = "\nPress enter to exit..."
    vim.api.nvim_chan_send(channel,
                           "clear && " .. command .. "; echo '" .. exit_message ..
                               "' && read -s && exit" .. "\n")
end

---@return nil
function defineBuildFolderPath()
    -- TODO: One might not want a directory called "build"
    build_dir = "build"
end

---Compiles a target
---
---@return nil
function compileTarget()
    function compile(pTarget)
        if not (pTarget == nil) and string.len(pTarget) > 0 then
            createFloatingTerminal()
            local commandTable = {
                "cmake --build " .. build_dir .. " --target " .. pTarget
            }
            local commandConcatenation = ""
            for i, command in ipairs(commandTable) do
                commandConcatenation = commandConcatenation .. command
                if i < #commandTable then
                    commandConcatenation = commandConcatenation .. " && "
                end
            end
            executeCommandInTerminal(commandConcatenation)
        end
    end

    defineBuildFolderPath()
    chooseTarget(compile)
end

function compileAndExecuteTarget()
    function compileAndExecute(pTarget)
        if not (pTarget == nil) and string.len(pTarget) > 0 then
            createFloatingTerminal()
            local commandTable = {
                "cmake --build " .. build_dir .. " --target " .. pTarget,
                build_dir .. "/" .. pTarget
            }
            local commandConcatenation = ""
            for i, command in ipairs(commandTable) do
                commandConcatenation = commandConcatenation .. command
                if i < #commandTable then
                    commandConcatenation = commandConcatenation .. " && "
                end
            end
            executeCommandInTerminal(commandConcatenation)
        end
    end

    defineBuildFolderPath()
    chooseTarget(compileAndExecute)
end

vim.keymap.set("n", "mc", compileTarget)
vim.keymap.set("n", "mt", compileAndExecuteTarget)