Skip to content
Max Del Canto edited this page Oct 23, 2024 · 1 revision

Welcome to the terminal.nvim wiki!

Language-Specific Build and Execution Commands

---@param path string
local function mkdir(path)
  local stat = vim.uv.fs_statfs(path)
  if stat == nil then
    local ok, err = vim.uv.fs_mkdir(path, 493)
    if not ok then
      return err
    end
  end
  return true, nil
end

local runners = {
  c = function(dir)
    local root_dir = vim.fs.root(dir, {
      'makefile',
      'MakeFile',
      '.clangd',
      '.clang-tidy',
      '.clang-format',
      'compile_commands.json',
      'compile_flags.txt',
      'configure.ac',
      'main.c',
    })
    if not root_dir then
      return
    end
    local ok, err = mkdir(root_dir .. '/bin')
    if not ok then
      vim.notify(string.format('Err: %s', err), vim.log.levels.ERROR)
      return
    end
    local file = vim.fn.expand '%:t'
    local program = string.format('%s/%s', root_dir, file)
    return string.format('gcc %s -o ./bin/program && ./bin/program', program)
  end,
  cpp = function(dir)
    local root_dir = vim.fs.root(dir, {
      'makefile',
      'MakeFile',
      '.clangd',
      '.clang-tidy',
      '.clang-format',
      'compile_commands.json',
      'compile_flags.txt',
      'configure.ac',
      'main.c',
    })
    if not root_dir then
      return
    end
    local ok, err = mkdir(root_dir .. '/bin')
    if not ok then
      vim.notify(string.format('Err: %s', err), vim.log.levels.ERROR)
      return
    end
    local file = vim.fn.expand '%:t'
    local program = string.format('%s/%s', root_dir, file)
    return string.format('g++ %s -o ./bin/program && ./bin/program', program)
  end,
  lua = function(dir)
    local root_dir = vim.fs.root(dir, { 'init.lua', 'stylua.toml', '.stylua.toml' })
    if not root_dir then
      return
    end
    local ok, err = mkdir(root_dir .. '/bin')
    if not ok then
      vim.notify(string.format('Err: %s', err), vim.log.levels.ERROR)
      return
    end
    local file = vim.fn.expand '%:t'
    local program = string.format('%s/%s', root_dir, file)
    return string.format('luajit -b %s -X ./bin/program && luajit ./bin/program', program)
  end,
  python = function(dir)
    local root_dir = vim.fs.root(dir, { 'main.py' })
    local file = vim.fn.expand '%:t'
    local program = string.format('%s/%s', root_dir, file)
    return string.format('python %s', program)
  end,
}
local command = vim.api.nvim_create_user_command
command('Runner', function()
  local dir, err, err_name = vim.uv.cwd()
  if err ~= nil or dir == nil or string.len(dir) == 0 then
    if err_name then
      return
    end
    return
  end

  local dirs = vim.fs.find({ 'makefile', 'MakeFile' }, { path = dir })
  local default = function()
    local runner = runners[vim.bo.filetype]
    local arg = runner(dir)
    vim.cmd.TermOpen(arg)
  end

  if vim.tbl_isempty(dirs) then
    default()
  else
    vim.ui.select({ 'yes', 'no' }, {
      prompt = 'Makefile detected. Would you like to run it?',
    }, function(choice)
      if choice == 'yes' then
        vim.cmd.TermOpen 'make'
      else
        default()
      end
    end)
  end
end, { nargs = 0, bang = false })
Clone this wiki locally