DEV Community

Quqin
Quqin

Posted on

Building a Custom C/C++ Development Environment in Arch Linux

Introduction

IDEs like CLion and VS Code are incredibly powerful, they often feel bloated and can drain system resources. If you are developing or working with bare-metal hardware or something that needs to watch out for resources, you might want a leaner solution. Neovim offers the exact same code intelligence, but runs instantly right in your terminal. This guide will walk you through building a blazing fast, modern development environment from scratch.

Setup

Prerequisites

Before diving into the configuration, ensure you have the following ready:
1 Basic Terminal Fluency: You should be comfortable navigating directories and editing basic text files from the command line.
2 Essential Build Tools: Ensure you have git, make, and a C/C++ compiler (like gcc or clang) installed on your system. You can grab the basics by running for Arch Linux sudo pacman -S base-devel git.

You need to install Neovim into your machine. For Arch Linux, you can run sudo pacman -S neovim

If you are building from source or need an alternative installation method, refer to the official Neovim installation guide.

Go to folder ~/.config/nvim (for linux), this directory is the root place of all things related to your Neovim configuration.

After the installation process of Neovim, you need to choose your plugin manager. A plugin manager is a tool that automates the process of installing, updating, configuring, and removing extensions for Neovim. Without this, adding a new extension to Neovim would mean manually downloading source code from GitHub, extracting it, and placing the files into specific folders within your operating system.

In this guide you will be using Lazy plugin manager. The benefit is that it only loads the required plugin at the time. This ensures your text editor starts up faster than traditional setups.

Create a file called init.lua, then add this snippet into it. The goal is to detect if Lazy is installed. If not, it will clone the repo directly from GitHub then place it on the Neovim runtime path.

vim.g.mapleader = " "
vim.g.maplocalleader = " "

local opt = vim.opt

local lazypath = vim.fn.stdpath "data" .. "/lazy/lazy.nvim"
if not vim.loop.fs_stat(lazypath) then
  vim.fn.system {
    "git",
    "clone",
    "--filter=blob:none",
    "https://github.com/folke/lazy.nvim.git",
    "--branch=stable",
    lazypath,
  }
end
opt.rtp:prepend(lazypath)

require("lazy").setup({
  { import = "packages" },
}, {
  change_detection = { notify = false },
})
Enter fullscreen mode Exit fullscreen mode

Note:

  1. The import = 'packages' line tells Lazy to look inside the lua/packages directory relative to the Neovim configuration folder.
  2. The change_detection line automatically tracks your configuration file and reloads them on the fly for you. By default change_detection is always on and always gives you notification every time something has been changed.
  3. The vim.g.mapleader = " " line sets your global leader key to the Spacebar, making all of your custom keybindings much faster to type

Configuration and Plugins

After downloading your Neovim and the plugin manager, you are ready to implement the bare minimum that can make Neovim usable like VS Code or CLion with only a total of around 30 plugins dispersed across 6 different folders.

Start by creating a parent folder called lua, and inside it, create a subfolder called packages.

Go into the packages directory.

Create a file called imports.lua inside your packages directory. This single file acts as a directory index, instructing lazy.nvim to automatically search for your subfolder for configuration

-- ~/.config/nvim/lua/packages/imports.lua

return {
  { import = "packages.coding" },
  { import = "packages.interface" },
  { import = "packages.treesitter" },
  { import = "packages.editor" },
  { import = "packages.utils" },
  { import = "packages.extras" },
}
Enter fullscreen mode Exit fullscreen mode

1. Coding

With everything setup, you can jump into configuring the coding environment. Create a subfolder called coding inside the packages directory.

Create a file called lsp.lua. This file configures the Language Server Protocol (LSP), which allows Neovim to understand your codebase, jump to definitions, and analyze syntax.

-- ~/.config/nvim/lua/packages/coding/lsp.lua

return {
  "neovim/nvim-lspconfig",
  dependencies = { "hrsh7th/cmp-nvim-lsp" },

  config = function()
    -- Setup Lua Language Server
    vim.lsp.config("lua_ls", {
      cmd = { "lua-language-server" },
      root_markers = { ".git", ".luarc.json", "init.lua" },
      capabilities = require("cmp_nvim_lsp").default_capabilities(),
      settings = {
        Lua = {
          runtime = { version = "LuaJIT" },
          diagnostics = { globals = { "vim" } },
        },
        workspace = {
          library = vim.api.nvim_get_runtime_file("", true),
          checkThirdParty = false,
        },
        telemetry = {
          enable = false,
        },
      },
    })
    vim.lsp.enable "lua_ls"

    -- Setup Clangd (C/C++)
    vim.lsp.config("clangd", {
      cmd = { "clangd", "--background-index", "--clang-tidy" },
      root_markers = { ".git", "compile_commands.json" },
      capabilities = require("cmp_nvim_lsp").default_capabilities(),
    })
    vim.lsp.enable "clangd"

    -- Setup Arduino (Requires arduino-cli and arduino-language-server)
    vim.lsp.config("arduino_language_server", {
      cmd = {
        "arduino-language-server",
        "-cli-config",
        vim.fn.expand "~/.arduino15/arduino-cli.yaml",
        "-cli",
        "/usr/bin/arduino-cli",
        "-clangd",
        "/usr/bin/clangd",
      },
      root_markers = { "sketch.yaml", "arduino.json", ".git" },
      capabilities = require("cmp_nvim_lsp").default_capabilities(),
    })
    vim.lsp.enable "arduino_language_server"

    -- Global Keybindings (LspAttach)
    vim.api.nvim_create_autocmd("LspAttach", {
      callback = function(args)
        local opts = { buffer = args.buf }
        vim.keymap.set("n", "gd", vim.lsp.buf.definition, opts)
        vim.keymap.set("n", "K", vim.lsp.buf.hover, opts)
        vim.keymap.set("n", "<leader>rn", vim.lsp.buf.rename, opts)
        vim.keymap.set({ "n", "v" }, "<leader>ca", vim.lsp.buf.code_action, opts)
      end,
    })

    -- Force filetype detection
    vim.api.nvim_create_autocmd({ "BufRead", "BufNewFile" }, {
      pattern = { "*.ino", "*.pde" },
      command = "set filetype=arduino",
    })
  end,
}
Enter fullscreen mode Exit fullscreen mode

Note:

  1. The lua_ls and clangd blocks tell Neovim how to talk to the language servers, but they do not install the tools. You must install the compilers and servers on your system (for example, on Arch Linux, run sudo pacman -S lua-language-server clang).
  2. The root_markers listed for both servers (like .git or compile_commands.json) are crucial. They tell Neovim exactly where the project starts, allowing cross-file features to trace symbols across your entire codebase automatically.
  3. The shortcut defined at the bottom uses an LspAttach event hook, meaning these keybinds only become active when a language server is successfully running in your current buffer.
  4. For the Arduino setup to work, you must generate a configuration file first by running arduino-cli config init in your terminal. Otherwise, Neovim will fail to find the arduino-cli.yaml file.

How to use Language Server Protocol:

  • g + d: Go to code definition
  • Shift + k: Hover the current word
  • Space + c + a: Run code action

Next, create a file called autocomplete.lua. You need an engine to display the code suggestion as you type. This configuration sets up nvim-cmp and ties it directly to your LSP.

-- ~/.config/nvim/lua/packages/coding/autocomplete.lua

return {
  "hrsh7th/nvim-cmp",
  event = "InsertEnter",
  dependencies = {
    "hrsh7th/cmp-buffer",
    "hrsh7th/cmp-path",
    "L3MON4D3/LuaSnip",
    "saadparwaiz1/cmp_luasnip",
    "rafamadriz/friendly-snippets",
  },
  config = function()
    local cmp = require "cmp"
    local luasnip = require "luasnip"
    require("luasnip.loaders.from_vscode").lazy_load()

    cmp.setup {
      snippet = { expand = function(args) luasnip.lsp_expand(args.body) end },
      mapping = cmp.mapping.preset.insert {
        ["<C-b>"] = cmp.mapping.scroll_docs(-4),
        ["<C-f>"] = cmp.mapping.scroll_docs(4),
        ["<C-Space>"] = cmp.mapping.complete(),
        ["<CR>"] = cmp.mapping.confirm { select = true },
        ["<Tab>"] = cmp.mapping(function(fallback)
          if cmp.visible() then
            cmp.select_next_item()
          elseif luasnip.expand_or_jumpable() then
            luasnip.expand_or_jump()
          else
            fallback()
          end
        end, { "i", "s" }),
        ["<S-Tab>"] = cmp.mapping(function(fallback)
          if cmp.visible() then
            cmp.select_prev_item()
          elseif luasnip.jumpable(-1) then
            luasnip.jump(-1)
          else
            fallback()
          end
        end, { "i", "s" }),
      },
      sources = cmp.config.sources({
        { name = "nvim_lsp" },
        { name = "luasnip" },
      }, {
        { name = "buffer" },
      }),
    }
  end,
}
Enter fullscreen mode Exit fullscreen mode

Finally, create a file called format.lua. Formatting your code manually is a waste of development time. This file configures conform.nvim to automatically format your files every time you save.

-- ~/.config/nvim/lua/packages/coding/format.lua

return {
  "stevearc/conform.nvim",
  event = { "BufWritePre" },
  keys = {
    {
      "<leader>fm",
      function() require("conform").format { lsp_fallback = true } end,
      desc = "Format File",
    },
  },
  opts = {
    formatters_by_ft = {
      lua = { "stylua" },
      c = { "clang-format" },
      cpp = { "clang-format" },
    },
    format_on_save = { timeout_ms = 500, lsp_fallback = true },
  },
}
Enter fullscreen mode Exit fullscreen mode

How to use Conform:

  • Space + f + m: Format your current file

2. Editor

Create a subfolder called editor inside the packages directory.

Create a file called telescope.lua. When your project grows, manually navigating directories become a massive bottleneck. This file adds an extensible fuzzy finder to Neovim. It allows you to instantly search through your project files, grep specific text, and navigate active buffers without leaving your keyboard.

-- ~/.config/nvim/lua/packages/editor/telescope.lua

return {
  "nvim-telescope/telescope.nvim",
  dependencies = {
    "nvim-lua/plenary.nvim",
    {
      "nvim-telescope/telescope-fzf-native.nvim",
      build = "make",
      config = function() require("telescope").load_extension "fzf" end,
    },
  },

  keys = {
    { "<leader>ff", "<cmd>Telescope find_files<cr>", desc = "Find Files" },
    { "<leader>fg", "<cmd>Telescope live_grep<cr>", desc = "Live Grep (Search Text)" },
    { "<leader>fb", "<cmd>Telescope buffers<cr>", desc = "Find Buffers" },
    { "<leader>fh", "<cmd>Telescope help_tags<cr>", desc = "Find Help" },
  },

  config = function()
    local telescope = require "telescope"

    telescope.setup {
      defaults = {
        layout_strategy = "horizontal",
        layout_config = {
          horizontal = { prompt_position = "top", preview_width = 0.55 },
          vertical = { mirror = false },
          width = 0.87,
          height = 0.80,
          preview_cutoff = 120,
        },
        sorting_strategy = "ascending",
        winblend = 0,
        mappings = {
          i = {
            ["<C-k>"] = "move_selection_previous",
            ["<C-j>"] = "move_selection_next",
            ["<C-q>"] = "send_to_qflist",
          },
        },
      },
    }
  end,
}
Enter fullscreen mode Exit fullscreen mode

How to use Telescope:

  • Space + f + f: Open the file finder
  • Space + f + g: Search for specific text across entire project
  • Space + f + b: Find active buffers
  • Space + f + h: Open the help finder with a tag

Next, create a file called overseer.lua. Switching between your editor and a separate terminal to run make breaks your focus. This plugin acts as a task runner, allowing you to compile your code directly within Neovim and parsing the output for errors.

-- ~/.config/nvim/lua/packages/editor/overseer.lua

return {
  "stevearc/overseer.nvim",

  -- Global Keybindings for Task Management
  keys = {
    { "<leader>or", "<cmd>OverseerRun<CR>", desc = "Run Task" },
    { "<leader>ot", "<cmd>OverseerToggle<CR>", desc = "Toggle Overseer UI" },
    { "<leader>oi", "<cmd>OverseerInfo<CR>", desc = "Overseer Info" },
  },

  config = function()
    local overseer = require "overseer"

    overseer.setup {
      dap = false,
      strategy = "terminal",
      templates = { "builtin" },
      form = { border = "rounded" },
      task_list = {
        direction = "bottom",
        min_height = 10,
        max_height = 15,
      },
    }

    -- Bear + Makefile (For C/C++ projects)
    overseer.register_template {
      name = "Build with Bear (Make)",

      builder = function()
        local makefile_match = vim.fs.find("Makefile", { upward = true, path = vim.fn.expand "%:p:h" })
        local target_dir = #makefile_match > 0 and vim.fs.dirname(makefile_match[1]) or vim.fn.getcwd()

        return {
          cmd = { "bear" },
          args = { "--", "make" },
          cwd = target_dir,
          components = { { "on_output_quickfix", open = true }, "default" },
        }
      end,
      condition = {
        filetype = { "c", "cpp" },
        callback = function() return vim.fn.filereadable(vim.fn.getcwd() .. "/Makefile") == 1 end,
      },
    }
  end,
}
Enter fullscreen mode Exit fullscreen mode

Note:

  1. Bear is a command-line tool that generate json compilation database (compile_commands.json) when you run make. Without this database, clangd will not be able to analyze your project's cross-file dependencies.

How to use Overseer:

  • Space + o + r: Open the run task menu
  • Space + o + t: Toggle the overseer ui menu
  • Space + o + i: Get the info of run task

Next, create a file called mini.lua. Neovim's default file explorer can be clunky and unpredictable. This plugin replaces it with highly intuitive, buffer-based file navigator and manipulator, giving you the visual tree.

-- ~/.config/nvim/lua/packages/editor/mini.lua

return {
  {
    "echasnovski/mini.files",
    dependencies = {
      "echasnovski/mini.bufremove",
    },
    keys = {
      {
        "<leader>e",
        function() require("mini.files").open(vim.api.nvim_buf_get_name(0), true) end,
        desc = "Open Current File",
      },
      {
        "<leader>d",
        function()
          local bd = require("mini.bufremove").delete
          if vim.bo.modified then
            local choice = vim.fn.confirm(("Save changes to %q?"):format(vim.fn.bufname()), "&Yes\n&No\n&Cancel")
            if choice == 1 then -- Yes
              vim.cmd.write()
              bd(0)
            elseif choice == 2 then -- No
              bd(0, true)
            end
          else
            bd(0)
          end
        end,
        desc = "Close current buffer",
      },
    },

    config = function()
      require("mini.files").setup {
        windows = {
          preview = true,
          width_focus = 30,
          width_nofocus = 15,
          width_preview = 40,
        },
        options = {
          use_as_default_explorer = true,
        },
        mappings = {
          close = "q",
          go_in = "l",
          go_in_plus = "L",
          go_out = "h",
          go_out_plus = "H",
          reset = "<BS>",
          reveal_cwd = "@",
          show_help = "g?",
          synchronize = "=",
          trim_left = "<",
          trim_right = ">",
        },
      }
    end,
  },
}
Enter fullscreen mode Exit fullscreen mode

How to use Mini:

  • Space + e: Open the current project file navigation
  • Space + d: Close the current open file

In these two next files, you can combine them if you don't like too much files.

Create a file called autopairs.lua. Manually closing braces, brackets, and quotes is tedious and frequently causes compilation errors. This plugin automatically pairs them for you.

-- ~/.config/nvim/lua/packages/editor/autopairs.lua

return {
  "windwp/nvim-autopairs",
  event = "InsertEnter",
  config = true,
}
Enter fullscreen mode Exit fullscreen mode

Create a file called comment.lua. When debugging logic, you often need to quickly disable chunks of code. This plugin helps you instantly toggle comments on single lines or visual blocks by pressing gcc, gbc, and friends.

-- ~/.config/nvim/lua/packages/editor/comment.lua

return {
  "numToStr/Comment.nvim",
  config = function() require("Comment").setup() end,
}
Enter fullscreen mode Exit fullscreen mode

3. Interface

Create a subfolder called interface inside the packages directory.

Create a file called theme.lua. This file handles your color scheme, as the default Neovim theme lacks the modern polish.

-- ~/.config/nvim/lua/packages/interface/theme.lua

return {
  "catppuccin/nvim",
  name = "catppuccin",
  priority = 1000,
  config = function()
    require("catppuccin").setup {
      flavour = "mocha",
      transparent_background = true,
    }
    vim.cmd.colorscheme "catppuccin"
    vim.cmd "hi statusline guibg=NONE"
  end,
}
Enter fullscreen mode Exit fullscreen mode

Note:

  1. The vim.cmd "hi statusline guibg=NONE" and transparent_background = true line make it so that your neovim background is transparent
  2. The vim.cmd.colorscheme "catppuccin" line tells Neovim to use the Catppuccin color scheme.

Create a file dress.lua. This plugin acts as a UI wrapper that intercepts native Neovim input prompts and selection menus, routing them through Telescope instead.

-- ~/.config/nvim/lua/packages/interface/dress.lua

return {
  "stevearc/dressing.nvim",
  event = "VeryLazy",
  opts = {
    input = {
      enabled = true,
    },
    select = {
      enabled = true,
      backend = { "telescope" },
    },
  },
}
Enter fullscreen mode Exit fullscreen mode

Create a file noice.lua. This plugin completely replaces the default UI for messages, cmdline, and the popupmenu, giving it a modern, floating interface.

-- ~/.config/nvim/lua/packages/interface/noice.lua

return {
  "folke/noice.nvim",
  event = "VeryLazy",
  dependencies = {
    "MunifTanjim/nui.nvim",
    "rcarriga/nvim-notify",
  },
  opts = {
    lsp = {
      override = {
        ["vim.lsp.util.convert_input_to_markdown_lines"] = true,
        ["vim.lsp.util.stylize_markdown"] = true,
        ["cmp.entry.get_documentation"] = true,
      },
    },
    presets = {
      bottom_search = true,
      command_palette = true,
      long_message_to_split = true,
    },
  },
}
Enter fullscreen mode Exit fullscreen mode

When testing your configuration, you might encounter a floating error message. This happens because your terminal is fully transparent, breaking the plugin's shadow calculations. You can permanently fix this just by creating a file called bug.lua to set a fallback background color.

-- ~/.config/nvim/lua/packages/interface/bug.lua

return {
  "rcarriga/nvim-notify",
  opts = {
    background_colour = "#000000",
  },
}
Enter fullscreen mode Exit fullscreen mode

4. Extras

Create a subfolder called extras inside the packages directory.

Create a file called trouble.lua. While the LSP shows you errors inline, reading long compiler diagnostics at the bottom of the screen is difficult. This plugin gives you a dedicated, easily readable list of all your code problems, warnings, and references without hard navigation.

-- ~/.config/nvim/lua/packages/extras/trouble.lua

return {
  "folke/trouble.nvim",
  dependencies = { "nvim-tree/nvim-web-devicons" },
  opts = {
    focus = true,
  },
  cmd = "Trouble",
  keys = {
    {
      "<leader>xx",
      "<cmd>Trouble diagnostics toggle<cr>",
      desc = "Diagnostics (Trouble)",
    },
    {
      "<leader>xX",
      "<cmd>Trouble diagnostics toggle filter.buf=0<cr>",
      desc = "Buffer Diagnostics (Trouble)",
    },
    {
      "<leader>cs",
      "<cmd>Trouble symbols toggle focus=false<cr>",
      desc = "Symbols (Trouble)",
    },
    {
      "<leader>cl",
      "<cmd>Trouble lsp toggle focus=false win.position=right<cr>",
      desc = "LSP Definitions / references / ... (Trouble)",
    },
    {
      "<leader>xL",
      "<cmd>Trouble loclist toggle<cr>",
      desc = "Location List (Trouble)",
    },
    {
      "<leader>xQ",
      "<cmd>Trouble qflist toggle<cr>",
      desc = "Quickfix List (Trouble)",
    },
  },
}
Enter fullscreen mode Exit fullscreen mode

How to use trouble:

  • Space + x + x: Get all problem at project
  • Space + x + X: Get problem at current open file
  • Space + x + L: Get the location problem as list
  • Space + x + Q: Do a quickfix if possible
  • Space + c + s: Toggle problem symbols
  • Space + c + l: Toggle lsp problem

Create a file called todo.lua. This plugin highlights comments like // TODO or // FIXME in your codebase. This keeps you highly organized and ensures you never forget to implement pending logic.

-- ~/.config/nvim/lua/packages/extras/todo.lua

return {
  "folke/todo-comments.nvim",
  dependencies = { "nvim-lua/plenary.nvim" },
  opts = { signs = false }, -- set to true if you want icons in the sidebar
}

Enter fullscreen mode Exit fullscreen mode

Create a file called indent_backline.lua. When dealing with deeply nested statements in your code, tracing the scope visually can be painful. This plugin adds vertical lines to ensure you are never confused about your current indentation level.

-- ~/.config/nvim/lua/packages/extras/indent_backline.lua

return {
  "lukas-reineke/indent-blankline.nvim",
  main = "ibl",
  opts = {
    indent = {
      char = "│",
      tab_char = "│",
    },
    scope = { enabled = false }, -- turn on if you want the current scope highlighted
    exclude = {
      filetypes = {
        "help",
        "alpha",
        "dashboard",
        "neo-tree",
        "Trouble",
        "trouble",
        "lazy",
        "mason",
        "notify",
      },
    },
  },
}
Enter fullscreen mode Exit fullscreen mode

5. Treesitter

Create a subfolder called treesitter inside the packages directory.

Create a file called treesitter.lua. The default syntax highlighting in Neovim is basic and often fails on complex logic. Treesitter parses your code into an actual syntax tree, providing you with the most accurate and responsive syntax highlighting possible.

-- ~/.config/nvim/lua/packages/treesitter/treesitter.lua

return {
  {
    "nvim-treesitter/nvim-treesitter",
    build = ":TSUpdate",
    dependencies = {
      "nvim-tree/nvim-web-devicons",
      "nvim-treesitter/nvim-treesitter-textobjects",
    },
    config = function()
      require("nvim-treesitter.config").setup {
        ensure_installed = { "lua", "c", "cpp", "vim", "vimdoc", "markdown", "asm" },
        sync_install = false,
        auto_install = true,
        highlight = { enable = true },
        indent = { enable = true },

        -- Smart Selection (Text Objects)
        textobjects = {
          select = {
            enable = true,
            lookahead = true,
            keymaps = {
              -- Function selection
              ["af"] = "@function.outer", -- Select around function
              ["if"] = "@function.inner", -- Select inside function

              -- Class selection
              ["ac"] = "@class.outer", -- Select around class
              ["ic"] = "@class.inner", -- Select inside class

              -- Loop selection
              ["al"] = "@loop.outer",
              ["il"] = "@loop.inner",
            },
          },
        },
      }
    end,
  },
}
Enter fullscreen mode Exit fullscreen mode

6. Utilities

Create a subfolder called utils inside the packages directory.

Create a file called which_keys.lua. A heavily customized Neovim relies on dozens of custom keybinds. This plugin ensures you do not forget them by automatically showcasing a menu of available options at the bottom of the screen whenever you press your key in mode other than typing.

-- ~/.config/nvim/lua/packages/utils/which_keys.lua

return {
  {
    "folke/which-key.nvim",
    event = "VeryLazy",
    init = function()
      vim.o.timeout = true
      vim.o.timeoutlen = 300
    end,
    opts = {
      win = {
        border = "rounded", -- none, single, double, shadow
      },
    },
    config = function(_, opts)
      local wk = require "which-key"
      wk.setup(opts)

      wk.add {
        { "<leader>f", group = "Find" }, -- Group name
        { "<leader>c", group = "Code" },
      }
    end,
  },
}
Enter fullscreen mode Exit fullscreen mode

First Run

With all of your configuration files in place, it is time to build the environment. Open your terminal and simply type nvim. If you have never opened Neovim, just wait a few seconds for Lazy.nvim to install.

Tips and Tricks

Now that Neovim is fully configured and good to be used, here are a few advanced tips to keep it running smoothly:

  • Always Check Your Health: If your language servers or formatters ever act up, type :checkhealth in normal mode. Neovim will run a comprehensive diagnostic check across all your plugins and tell you exactly what system dependency is missing.
  • Manage Your Compilation Database: Because you are using bear with Overseer, you will constantly be generating compile_commands.json files in your project directories. Be sure to add compile_commands.json to your global .gitignore file when using GitHub so you don't accidentally commit it to your repositories.
  • Keep Your Plugins Updated: One of the best features of lazy.nvim is its built-in UI. You can type :Lazy to open the control panel, then press U to automatically update all of your plugins to their latest stable versions.

Conclusion

By structuring your environment with tools like LSP, Telescope, and Overseer, you have successfully replaced the heavy overhead of a traditional IDE with a modular, terminal-based architecture. You now have a blazing fast, highly intelligent workspace built specifically for your development. Good luck with your compilations, and enjoy the speed of your new workflow.

Top comments (0)