> git clone https://git.barrettruth.com/cp.nvim.git Things have changed since I last documented my competitive programming setup here.
my goals
After many months of using the aforementioned make based setup, I had a few qualms:
- I’m lazy: I grew tired of copying (and mis-copying) inputs, outputs, etc from online judges.
- I’m lazy: I frequently submitted incorrect solutions after erroneously asserting that my outputs matched those of the sample test cases
- External dependencies: it unsettles me that my bare-bones setup required copy-pasting an entire suite of scripts
- Non-native NeoVim experience: while composition and the UNIX philosophy are great, there’s only so much you can do with pipes and files. - Raw I/O files meant I couldn’t see colored stdin/stdout - Fine-grained per-testcase I/O was suspect—isolating and running a subset of test cases required manual intervention
The solution was to leverage Neovim’s great APIs to give me granular control over every aspect of my problem-solving experience.
the solution: cp.nvim
The GitHub page documents the plugin well enough so I’ll avoid re-hashing it here. Instead, what’s more interesting to document is why I thought this was a worthwhile experience.
- Making Something Useful for Others: cp.nvim is an opportunity for me to make my first open-source project “right”—not some side project or demo, but a real, usable tool that I’ll be rolling out to the public soon. I consider the following in my active development of the plugin:
- Comprehensive continuous integration (real testing, linting, and more)
- LuaRocks integration (the future of NeoVim package management)
- Concise and thorough Vimdoc documentation that communicates effectively
- Modern lua tooling: use of busted, selene and more integrated with the NeoVim lua interpreter
- Sensible user defaults & extreme customization
- Proper versioning, tagging, and releases
- The Neovim Community: I’m elated to finally give back to the community (even if no one uses this plugin). folke, bfredl, and echasnovski are my greatest inspirations as an open-source developer and I’ve had enough of taking without giving back.
- In the coming months I plan to contribute to NeoVim core, including making
:checkhealthasynchronous and integrating an mdx parser.
- Learning Random things: I think this plugin is really cool by virtue of its efficacy and the miscellany of knowledge I accrued in the 15k+ LOC as of version v0.3.0. Some things I learned include:
- ANSI terminal colors and escape codes: I wrote my own stateful ANSI escape sequence parser to map raw bytes to native NeoVim highlighted text
- Extmarks: NeoVim extmarks (
:h extmarks) are extremely powerful. Here, I used them to apply dynamic highlighting across various components of the plugin but I also plan to leverage virtual text to catch compile errors in real-time - VIM filetypes and diffing: Vim is strange and the event-based system is
fragile. I faced filetype detection race conditions and odd side effects of
functions (such as
:diffthisresettingfoldcolumn). - LuaCATS: apparently writing comments is the best way to typecheck in lua…
- The (Neo)Vim event loop: Scraper subprocesses spawned with
vim.system. Though a powerful API, I often had to obey the event loop and wrap side effects withvim.scheduleto ensure they ran after jobs finished. This was useful to defer UI updates.