Skip to content

Add Helix jump list navigation#44661

Open
ShaiKKO wants to merge 2 commits intozed-industries:mainfrom
ShaiKKO:helix/jump-list
Open

Add Helix jump list navigation#44661
ShaiKKO wants to merge 2 commits intozed-industries:mainfrom
ShaiKKO:helix/jump-list

Conversation

@ShaiKKO
Copy link

@ShaiKKO ShaiKKO commented Dec 11, 2025

This PR implements Helix's jump list feature, addressing issue #41580 and continuing the work discussed in #33580.

The jump list is one of Helix's core navigation features that lets users save cursor positions and quickly jump between them. I've implemented the three commands that make up this feature: Ctrl-s to save the current selection, Ctrl-o to jump backward through saved positions, and Ctrl-i to jump forward.

I followed the existing patterns in the vim crate pretty closely here. The JumpList struct lives in a new jump_list.rs module under helix/, and the global state is stored in VimGlobals alongside marks and registers. This felt like the natural home for it since the jump list persists across buffer switches, similar to how marks work.

The data structure mirrors Helix's implementation - a VecDeque with a capacity of 30 entries and a cursor tracking where we are in the history. Each entry stores a buffer ID and the selection anchors, which means positions stay valid even as the document is edited.

When you save a position that's identical to the last one, we skip it to avoid cluttering the list with duplicates. If you're in the middle of the history and save a new position, everything "ahead" of you gets truncated - this matches how most undo systems work and feels intuitive in practice.

The trickiest bit was handling the "jump from present" case. When you're at the end of the list (haven't jumped yet) and hit Ctrl-o, Helix automatically saves your current position before jumping. This way you can always get back to where you started. I've replicated this behavior.

Cross-buffer jumps work by looking up the target buffer in the workspace and activating it before restoring the selection. The anchors handle position validity automatically since they're tied to the buffer's edit history.

I've added unit tests for the JumpList data structure covering the basic operations, capacity limits, duplicate prevention, and the forward-history truncation behavior. There are also integration tests that exercise the actual keybindings in a VimTestContext with Helix mode enabled.

Release Notes

  • Added Helix jump list navigation: Ctrl-s to save position, Ctrl-o to jump backward, Ctrl-i to jump forward (vim mode with Helix keybindings enabled)

Related: #41580, #33580

Implement Helix-style jump list for position history navigation with
Ctrl-s (save), Ctrl-o (backward), and Ctrl-i (forward) keybindings.

The jump list maintains up to 30 entries matching Helix's behavior:
- Prevents consecutive duplicate entries
- Truncates forward history when pushing from middle of list
- Auto-saves current position when jumping backward from present
- Supports cross-buffer navigation

Closes zed-industries#41580
@cla-bot
Copy link

cla-bot bot commented Dec 11, 2025

We require contributors to sign our Contributor License Agreement, and we don't have @ShaiKKO on file. You can sign our CLA at https://zed.dev/cla. Once you've signed, post a comment here that says '@cla-bot check'.

@zed-industries-bot
Copy link

zed-industries-bot commented Dec 11, 2025

Warnings
⚠️

This PR is missing release notes.

Please add a "Release Notes" section that describes the change:

Release Notes:

- Added/Fixed/Improved ...

If your change is not user-facing, you can use "N/A" for the entry:

Release Notes:

- N/A

Generated by 🚫 dangerJS against 41170c1

@maxdeviant maxdeviant changed the title feat(vim): add Helix jump list navigation vim: Add Helix jump list navigation Dec 11, 2025
@ShaiKKO ShaiKKO changed the title vim: Add Helix jump list navigation Add Helix jump list navigation Dec 11, 2025
@ShaiKKO
Copy link
Author

ShaiKKO commented Dec 11, 2025

@cla-bot check

@cla-bot cla-bot bot added the cla-signed The user has signed the Contributor License Agreement label Dec 11, 2025
@cla-bot
Copy link

cla-bot bot commented Dec 11, 2025

The cla-bot has been summoned, and re-checked this pull request!

…mp list

- Store full selection ranges (start+end anchors) instead of just cursor heads
- Add JumpLocation enum: Buffer(EntityId) for open files, Path(Arc<Path>) for closed
- Add JumpSelections enum: Anchors for open buffers, Points for closed files
- Hook buffer release via cx.observe_release() to convert entries when files close
- Add helix_jump_to_path() to reopen closed files and restore selections
- Track watched buffers in VimGlobals to manage lifecycle subscriptions

This enables jumping back to positions in files that have been closed - the
jump list preserves the file path and selection points, reopening the file
when navigating to that entry.
@ShaiKKO
Copy link
Author

ShaiKKO commented Dec 14, 2025

After further review I identified 3 areas that I address in the PR below (should have caught these before submission, so apologies for that, hope this saves you some time on the backend).

  • Store full selection ranges (start+end anchors) instead of just cursor heads

  • Add JumpLocation enum: Buffer(EntityId) for open files, Path(Arc<Path>) for closed

  • Add JumpSelections enum: Anchors for open buffers, Points for closed files

  • Hook buffer release via cx.observe_release() to convert entries when files close

  • Add helix_jump_to_path() to reopen closed files and restore selections

( This enables jumping back to positions in files that have been closed and is NOT a default helix feature, and is noted as an issue in helix itself, I opted to implement it here and see what people thought on the matter) - the jump list preserves the file path and selection points and reopens the file. )

  • Track watched buffers in VimGlobals to manage lifecycle subscriptions

@kubkon
Copy link
Member

kubkon commented Jan 5, 2026

Can you fix the clippy errors? I won't be able to review the changes until the CI is green.

@jasonwilliams
Copy link

jasonwilliams commented Jan 30, 2026

@ShaiKKO are you still working on this? What's the difference between your PR and this? #46467

@ShaiKKO
Copy link
Author

ShaiKKO commented Jan 30, 2026

@jasonwilliams got busy with some other areas and this got lost in my lists.

  • The point was to make a jump list operate 1:1 for helix, not use zeds jump list.

IE ->

saves and restores full multi selections (not just cursor positions), manual + automatic save, reopening of closed files in multi-buffer, duplicate skipping, forward truncation, capacity limits, etc.

reusing zeds jump list effectively removes all of the functionality that matters/has anything to do with Helix.

@kubkon I will fix these CI issues by tomorrow so you can review, I also think the PR linked to this regarding #44530 is non related.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

cla-signed The user has signed the Contributor License Agreement

Projects

Status: Community PRs

Development

Successfully merging this pull request may close these issues.

4 participants