helix
helix copied to clipboard
Add vim/neovim style tabs
Describe your feature request
I would like to have something similar to :tabe on vim / neovim as it happens to be an important part of my workflow.
I should mention, I would be happy to contribute this feature if I can get some direction to get started.
I haven't found myself missing tabs as I've been using Helix. Since the buffer management (especially the picker) is so good I don't find cases where I would use it. I wonder what in your workflow makes tabs so necessary?
Tabs are useful when you want to glance at other files without changing your current layout of open splits. Atleast that's the primary use I have for them.
In Neovim we can have different working directory per tab which is excellent to working with different directory at the same time.
I think tabs would be bloat and should be the job of the terminal. In Kitty you can control them programmatically, for example, if the project has a git repo then Lazygit is opened in the next tab:
# if the dir is a git repo then open a tab and run lazygit
if [[ -d ".git" ]]; then
kitty @ launch --type=tab --tab-title="lazygit: $selected_project_name" --keep-focus --cwd="$(pwd)" lazygit
fi
# when quit close the lazygit tab if it exists
kitty @ send-text --match-tab title:"lazygit: $selected_project_name" q
@the-mikedavis, that's a fair point. I can see myself adopting a different workflow given that it's a different editor. However, I do think that there's good reasons to have tabs and some people just prefer having that workflow available.
@David-Else I disagree on tabs being a bloat. First thing is that tabs are a relatively simple concept: a container of views (splits). Tabs simply allow you to have many instead of just one. In Vim/Neovim, tabs add negligible visual clutter. Additionally, most editors and IDEs have a concept of tabs. I prefer the vim-style tabs (splits within tabs) over say the vscode-style tabs (tabs within splits), and I would imagine that if Helix were to adopt tabs, it would align with the vim way.
Tabs are indeed one of the main features I'm currently missing from Helix.
I wouldn't consider in-built tabs bloat. But I would go so far as to say that not having built-in tabs is pretty inefficient and cumbersome (if one wants to use this feature).
My usecase of tabs is that I usually work on multiple "scopes" in the same codebase at the same time. For example, if I work on an API, I have the actual endpoint logic, storage layer and related stuff on one tab in multiple v/hsplit buffers. At the same time, there's a second (sometimes even a third) tab with various buffers on tests and places where this API endpoint is used.
This allows me to quickly do changes on one end, switch to the usages, adjust them accordingly, check if everything works and repeat the whole process for the next change.
It's true that this can be achieved via multiple instances, but this has a few disadvantages:
- Changes in one Helix instance don't trigger a language server re-evaluation on the other instance.
This means, that you have to explicitly save in the other instance to get updated lint/compilation errors, which is quite annoying.
-> The more tabs you have, the more often you have to type:waENTER. - Every instance of Helix spins up it's own language server.
In the case of Rust, you would have 3
rust-analyzerinstances running at the same time when emulating 3 tabs via i3.
For example, each rust-analyzer instance on one of my medium sized projects (10k LOC) takes about ~1GB, bumping my memory usage from 1GB to 3GB. A proper project with 70k LOC is in the range of 1.7GB per instance, resulting in a whooping ~5GB of RAM usage with 3 tabs. - Rust-analyzer needs to run multiple times (once for each instance), which decreases developer speed.
- One cannot re-use buffers across multiple Helix instances, which is quite useful if you want to take a quick look at specific buffer in another tab. You can of course open up a new buffer on the second instance, but that disregards two of the main usecases for buffers, i.e. they allow you to easily sync changes and re-use cursor positions in different views!
- Unsaved changes aren't synchronized to other helix instances (as they cannot access the same buffers)
I would also be interested in checking out how to built this feature, even though I would definitely need some introduction to the codebase!
Edit: I stopped using Helix as this disrupted my workflow a bit too much. I also kind of lost the motivation to contribute, so the last section above can be disregarded ;) But I'll definitley check Helix out once more, if this i actually going to be implemented.
Isn't this supposed to be fixed with "bufferline"?
Bufferline is a distinct feature from tabs. Bufferline is more like https://github.com/akinsho/bufferline.nvim while tabs are a built-in Vim feature (:help tabpage)
I generally don't prefer tabs for my workflow. Even in vscode i disable the tabs and use the recently opened buffers. I use cmd + w to open the picker and cmd + w to go next in the picker. IMHO makes it very easy to navigate.
https://user-images.githubusercontent.com/1687946/194905419-df68c77f-5b92-4bc4-a2ed-bb63583c4f73.mov
Just my 2 cents though.
Similar workflow for hx, using space + b and down arrow
https://user-images.githubusercontent.com/1687946/194906643-2084b434-3859-45fa-a636-2d9ec56eabc2.mov
@pyrossh Some of us tend to touch 8+ different files in parallel. Especially when doing refactorings or adjustments to large existing code bases.
Se we just need a quick way of navigating 8+ buffers. Tabs allow you to create a tree-like map of your code, which can be navigated in an extremely easy and intuitive way.
main tab
|
---> API buffer
---> Schema buffer
fixtures tab
|
---> Test Fixtures
---> Test runner code
test tab
|
---> Test file 1
---> Test file 2
---> Test file 3
---> Test file 4
My workflow would be like this:
- Do a change in the schema buffer.
- Do changes in the api.
- Go to the
fixtures tab(gt) - Adjust the fixtures code.
- Switch to the
test tab(gt) - Go through the different tests files and adjust the tests.
- Go to the test runner code
(gT) - Rinse and repeat.
We know about buffer search, there's no need to post videos showing how they work in different editors.
It doesn't change the fact, that a simple gt/gT is simpler and faster than a space b + search open buffers.
I don't have to think about which file I want to go to, I thought about this once and now all I have to do is to switch to the right view.
It's just another workflow that's more intuitive for some people! No need to discourage building this functionality if you don't like ;) Just don't use it, just like you don't use it in other projects.
@Nukesor has already done a great job explaining why folks want this ("scopes" of work is a great way to think about it). I'll add two things that I didn't see mentioned above:
- After my work expands to multiple "scopes" (tabs containing one or more splits), it eventually collapses back to the original tab. In
vim, I use:tabonly. In helix, I found myself accumulating tons of buffer tabs without a good way to close them.buffer-close-otherscloses all the hidden splits, but it also closes splits I'm looking at. - It nicely parallels workspaces in a window manager like
dwm. Each workspace has a distinct configuration of windows that is "remembered" when I switch to another workspace.
Has anyone worked on this feature yet? This was important enough to me that I finally took the time to hack together a PoC in an evening and I may start using my fork just because of that but I don't want to duplicate any existing efforts.
EDIT: The aforementioned PoC in action https://asciinema.org/a/hcgiXAJlDep8bity7iXSxU3sR
@nrabulinski What an awesome prototype! I'd love to have that in helix. I'm tempted to use your fork. Have you considered opening a draft PR for feedback?
Maybe "view"?
@z0al can you expand on that? I think of these as "tabs", and they feel similar to what I'd call "tabs" in most other apps. Based on the conversation here, many others think of them as "tabs" as well.
When I wanted to look up this feature, I searched for "helix tabs". I wouldn't have thought to search for "helix window groups" or "helix layouts".
@rcorre nevermind, I did a bit more research and I think you're right. I guess I'm just a confused neovim/helix newbie :).
If I take Wezterm as an example, tabs can contain vertical or horizontal "panes" (windows/splits in vim) and each pane holds a shell session. I could have another "tab" with a different layout. In that sense, the term tab in vim/helix would make sense.
Here is another simple way to conceptualize this feature:
"Vim tabs" are basically Multiple Desktops.
They solve the same problem. With Multiple desktops, you can organize several logically distinct tasks across desktops. Same thing with "Vim tabs" (as was explained above).
The term "Vim tabs" is terrible, and I've only ever seen it cause confusion.