How I Setup Neovim For Competitive Programming In C++
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.