A Love Letter to Neovim
After several failed attempts at learning Vim over the years, I've finally found my way into the Neovim ecosystem. This is a reflection on my learning journey.
Background
In the past I have made several attempts to learn Vim, but somehow it never stuck. To be fair I was fairly capable of doing Vim-style line editing on servers or casually editing a few lines, but it was never appealing to an extent that I was persistent enough to truly learn it. Retrospectively I think this was due to the fact that there were never enough incentives to do so, as I was very comfortable with VSCode, and later Cursor, which are both IDE-style text editors.
Over the past 2 years, I've been largely coding in a remote Linux VM, using macOS devices (an M3 MacBook Air and a 2019 Intel iMac with 5K Retina display) as thin clients. I really like developing in a remote Linux VM, as it provides a fairly consistent dev environment that is server-like. Besides, I can always easily leave the work behind on the iMac and pick it up on the MacBook Air when I'm out and about.
I use VSCode's remote-ssh plugin to do work. It works reasonably well. I'm particularly fond of the automatic port forwarding feature, which allows me to view web services running on the remote machine without extra port-forwarding SSH gymnastics.
That said things changed quickly over this year, particularly due to the rise of agentic AI-assisted coding. Frankly there is less need for a full-blown IDE/text editor, as I lean towards giving instructions from the terminal. Therefore the text editor has largely become merely a tool for viewing code. A lot of folks share the same sentiment. This has led me to think - perhaps a terminal is all I need?
Besides that, the aesthetics of Vim started to grow on me. I like the idea of a minimalistic, distraction-free coding environment, which also gives the ability to achieve maximum efficiency once mastered.
Learning Journey
As I had some spare time this week (precisely Wednesday to Friday), I decided to give Vim a serious try. I chose Neovim as it appears to be the de facto Vim that people use these days. Since I'm not particularly eager to learn the mechanism behind the scenes for now, I decided to go for an "Omakase" convention-over-configuration distribution, and I picked LazyVim. Frankly because it just seems to be one of the most popular distributions.
These subtle choices (largely due to time constraints) set me up for success this time. The baked-in convenient configurations maximised my satisfaction and minimised frustration, which is crucial for a beginner like me to keep momentum going.
Still even with LazyVim, I found the learning curve fairly steep at the beginning. In hindsight I think the presence of coding agents also made a massive difference. During learning whenever I got stuck or confused, I would fire off the coding agent (I use kodelet, a home-grown one) to help me understand concepts, or sometimes just churn out some Lua code that I could read and reason about, even if I had no idea how to write it myself. This was incredible, as I could always get unstuck quickly and keep the momentum going. The presence of the AI agent has definitely made the journey less lonely and more cheerful.
My Setup
So far my setup is pretty vanilla, as I'm very much still a beginner trying to learn the ropes. You can check my configuration at https://github.com/LazyVim/starter/compare/main...jingkaihe:starter:main?expand=1.
As you can see, I'm using the LazyVim starter template with a few minor tweaks, all done by the coding agent under my supervision.
Here's my end-to-end setup:
I use mise to install the dependencies:
mise use -g neovim fd ripgrep lazygit tree-sitter fzf
Clone my config:
git clone git@github.com:jingkaihe/starter.git ~/.config/nvim
You might need to install gcc if the machine doesn't have a compiler. This is for compiling tree-sitter parsers.
Run :checkhealth to make sure that Neovim is largely functioning.
Essential Commands I've Learned
Here are the commands I find myself using most frequently:
Word Manipulations
bto move back a wordwto move forward a wordeto move forward to the end of the worddiwto delete the whole word I'm currently on- To delete words repetitively:
diwfollowed by. dwto delete the next word
Code Manipulations
gccto comment/uncomment code. You can also do this in visual mode.
Scrolling
ctrl-dto scroll down half a pagectrl-uto scroll up half a pagectrl-fto scroll down a full pagectrl-bto scroll up a full page}to scroll to the next paragraph{to scroll to the previous paragraph
Code Navigation
gdto go to the definition of a function or variable under the cursorctrl-oto go back to the previous location in the jump listctrl-ito go forward to the next location in the jump list:vsplitto open a vertical split windowspace+wmto toggle zoom in and out of the current windowctrl-[hjkl]to switch between split windowsctrl-eto toggle the Explorer panel, and/to focus on the explorer for searching filesctrl-f-fto find file
Terminal Management
space-f-tto open a floating terminalctrl-\ctrl-nto exit terminal mode and go back to normal modevsplit | terminalto open a terminal in a vertical split window
LazyVim Code Search
space-s-gto search for a string in the current projectspace-s-rto search and replace a string in the current project/\vfor regular expression search in the current file
Visual Mode Operations
vto enter visual modeVto enter visual line mode- Use
worbor{to select text to be yanked yto yank the selected text+yto yank the selected text to system clipboardpto paste the yanked text after the cursorPto paste the yanked text before the cursorxordto delete the selected text
Reflections
I've joked that learning Neovim is perhaps my way of coping with a mid-life crisis, but in reality, I think it's more of a genuine interest in exploring a different way of coding and developing a new skill based on aesthetics at this stage of my life.
I'm pleased that after several past attempts and give-ups, I'm able to stick with it this time, within just 2 days! In hindsight, I think this is thanks to a mixture of real time constraints (being a dad of a 5-year-old with limited time), picking a beaten track (LazyVim), and the presence of coding agents that make the learning journey less lonely and more fun.
It's not without frustration and sweating, but the satisfaction of keyboard shortcuts, combo dances, lovely terminal UX, and low-latency typing makes everything worthwhile.
And most of all, I love the fact that I am writing this post in Neovim.