How I Setup Neovim For Competitive Programming In C++

Michael Bao
Unixification
Published in
3 min readAug 20, 2023
Screenshot by author

I have been using Neovim for a few years, and the experience is revolutionary. For competitive programming, I have gone through many different text editors and IDEs, but in the end, landed on Neovim.

When I use Neovim for competitive programming, I use clangd for LSP and clang-format for formatting.

Prerequisites

There are a few packages that we must install before we can start configuring. To do this run the following commands.

brew install neovim --HEAD
brew install llvm gcc@12
brew install clang-format

Since we are using clangd for LSP, we need to configure GCC headers. I have already written an article on this which will mainly cover how to integrate GCC headers to be accessible by clangd. This also goes over the process of using it with Neovim LSP, so I will not be going over that in this article.

Neovim

Clang Format

I love clang-format. The reason for this is when I write code, the formatting like the spacing isn’t correct, but the code will still run. Therefore, I like to have auto-formatting on save so it can be corrected to something that is consistent and readable.

To configure clang-format, I use guard.nvim. Before I switched to guard.nvim, I used null-ls, which has unfortunately been archived. Adding guard.nvim to Neovim is seamless, just add the following.

 {
"nvimdev/guard.nvim",
event = "BufReadPre",
config = function()
local ft = require("guard.filetype")

ft("c,cpp,json"):fmt("clang-format")

require("guard").setup({
-- the only options for the setup function
fmt_on_save = true,
-- Use lsp if no formatter was defined for this filetype
lsp_as_default_formatter = false,
})
end,
},

We can also add other formatters and linters for other file types. The ones I have installed can be found here.

I also have a clang-format config, which was copied from usaco.guide.

TabWidth: 4
IndentWidth: 4
UseTab: ForIndentation
AllowShortIfStatementsOnASingleLine: AllIfsAndElse
AllowShortBlocksOnASingleLine: Always
AllowShortFunctionsOnASingleLine: All
AllowShortLambdasOnASingleLine: All
AllowShortLoopsOnASingleLine: true
SpacesBeforeTrailingComments: 2

Now that we have formatting out of the way we can move on to keybinds.

Keybinds

I won’t be going over all my keybinds, but rather the keybinds I use specifically for C++. I use which-key for my keybinds, so that is what I will be showing here. There are only 2 keybinds: one for running the code and one for debugging (which is used much less). To do this, add the following to cpp.lua in the ftplugin directory.

local wk = require("which-key")

local leader = {
["r"] = {
name = "+run",
["r"] = {
":w | :TermExec cmd='cr \"%\"' size=50 direction=tab go_back=0<CR>",
"Run",
},
["d"] = {
":w | :TermExec cmd='cr \"%\" -d' size=50 direction=tab go_back=0<CR>",
"Debug",
},
},
}

wk.register(leader, { prefix = "<leader>" })

Note: cr is a script that I created to run and debug my code — see here.

These commands require toggleterm.nvim to be installed. For this, my config can be referenced here.

Specifically for competitive programming, there isn’t much, but I do think this is a good baseline that can be added onto. There are other plugins and features that one might want, like snippets and debuggers, but for competitive programming, I don’t use either.

Hopefully, this article was helpful, and have a great rest of your day.

--

--

Unixification
Unixification

Published in Unixification

We write about ricing different Unix systems such as macOS, and Linux. Other than Unix systems we write on various tools, like Neovim and Obsidian.

Michael Bao
Michael Bao

Written by Michael Bao

Neovim | Arch Linux | macOS | I love to write about random tech stuff. Tinkering around with Linux, Neovim, and computers.

No responses yet