Neovim Parity Discussion Implementing :sterminal And Termwinkey
Hey guys! Let's dive into a discussion about bringing some cool features from Vim over to Neovim. Specifically, we're talking about the :sterminal
command and mimicking Vim's 'termwinkey'
functionality. This is something that's been on my mind for a while, and I think it could really enhance the Neovim experience, especially for those of us who love using terminals in split windows. So, let's get into the nitty-gritty of what we're trying to achieve and how we might get there. This is going to be a fun journey, and I'm excited to explore these ideas with you all!
The Problem: Bridging the Gap Between Vim and Neovim
Okay, so first things first, I've been nudged by bfredl to bring this up as a bug report, even though it might feel more like a feature request. So, if things go sideways, you know who to blame! Just kidding, of course. But in all seriousness, I've been a bit hesitant to post this because I know this might not be a top priority for the maintainers, and it's something they might have intentionally avoided in the past. However, I truly believe that adding these features could make Neovim even more awesome, so here we are.
I don't think Neovim needs to copy Vim exactly, but having similar functionality would be a huge win. There are two main things I'm hoping to achieve here:
- A
:sterminal
command that splits the window, similar to:new
,:split
,:sbuffer
, etc., instead of the current behavior of:edit
or:buffer
. I've got somecabbrev
hacks to replace:term
and:vterm
at the beginning of the command-line, but having a first-class citizen like:sterm
and:vert sterm
would be super slick. - The big one: something that mimics
'termwinkey'
. For those who use terminals in splits, this would be a game-changer. We have<C-\><C-o>
, but it doesn't play nicely with<C-w>
because it:startinsert
s in the next window if you switch windows. Plus,wincmd
-ing back to the terminal window doesn't automatically:startinsert
to get you back into terminal mode. This is a major pain point for productivity.
Diving Deep into the Core Issues
Let's really break down why these features matter and the challenges they present. When you're working in a terminal within a split window, you often need to switch between the terminal and other buffers. The current workflow can be clunky. Imagine you're running a build process in a terminal window and you need to quickly edit a file. You switch to the file, make your changes, and then want to jump back to the terminal. Without termwinkey
, this simple task becomes a series of manual commands, breaking your flow and slowing you down.
Now, <C-\><C-o>
is a decent attempt, but it falls short in a few key areas. First, it doesn't seamlessly integrate with window navigation commands like <C-w>
. This means you can't quickly move around your splits without potentially messing up your terminal mode. Second, and perhaps more importantly, it doesn't automatically re-enter terminal mode when you switch back to the terminal window. This means you have to manually type :startinsert
every time, which is a real buzzkill.
To illustrate the problem, think about a typical workflow: you're in your terminal, running a command, and you need to quickly jump to another buffer. You use <C-w>
to move to the next window, do your thing, and then want to return to the terminal. With a proper termwinkey
implementation, you'd seamlessly switch back to the terminal and be right back where you left off. But without it, you're stuck manually re-entering terminal mode, which is not only annoying but also disrupts your concentration.
So, what's the solution? Well, that's what we're here to figure out! The goal is to create a system that intelligently manages terminal mode across window switches, so you can focus on your work without constantly battling the editor. This isn't just about convenience; it's about creating a smoother, more efficient workflow that allows you to stay in the zone and get things done.
My Adventures (and Misadventures) in Plugin Development
I actually tried to solve this problem myself a few years ago. I even made a plugin called vimterm.nvim
(you can check it out here: https://github.com/VioletJewel/vimterm.nvim/tree/main) that implements a 'termwinkey' for Neovim. But, and this is a big but, it's a huge hack. It's convoluted, fragile, and tweaking the source code even a little can completely lock up Neovim. It was a wild ride, let me tell you!
I had some bug fixes in there that I lost along the way, and honestly, I lost the motivation to figure it all out again. It was just too much of a headache. I discussed this with Justin (I think) on Matrix a while back, and he seemed open to the idea. I know there are tons of other important things on the Neovim team's plate, but I still think this is worth considering.
The Perils of Hacking: A Cautionary Tale
Let me tell you, diving into the internals of Neovim to hack together a solution like this is not for the faint of heart. It's like trying to perform surgery with a rusty spoon – you might get the job done, but you're probably going to cause some serious damage along the way. My vimterm.nvim
plugin was a testament to this. It worked, sort of, but it was held together with duct tape and prayers. Any minor change could send the whole thing crashing down, taking Neovim with it.
The core issue is that Neovim's terminal handling is complex and deeply intertwined with its core functionality. Trying to intercept and modify this behavior from the outside is like trying to rewire a computer while it's running – you're almost guaranteed to cause a short circuit. This is why a proper, built-in solution is so important. It needs to be implemented at a level where it can seamlessly integrate with Neovim's internal workings without causing chaos.
But hey, I learned a lot in the process! I got a much deeper understanding of how Neovim works, and I gained a newfound appreciation for the challenges the core developers face. It also solidified my belief that this functionality is important enough to warrant a proper implementation. So, even though my plugin was a bit of a Frankenstein's monster, it served its purpose in highlighting the need for a better solution.
A Better Approach: Improving <C-\><C-o>
or a Dedicated 'termwinkey'?
Bfredl suggested that we might be able to improve <C-\><C-o>
so it