# Objective Closes #41743 When selecting text on the last line, excluding the trailing newline, Vim and Helix modes behave differently from native Vim and Helix when the file has a trailing newline: 1. We cannot use `l` (move right) to include the final `\n` in the selection, while native Vim and Helix allow this. 2. By default, the rendered cursor should appear on the selected character. When that character is the final `\n`, however, Zed renders the cursor on the synthetic empty line after it rather than at the end of the preceding line. This differs from native Vim and Helix, as well as from Zed's behavior for newlines elsewhere in the file. 3. When the final `\n` is selected, it affects subsequent selection motions, as reported in #41743. The cause is several special-case guards for trailing newlines in Visual and Select modes. These guards exist in the cursor rendering logic: https://github.com/zed-industries/zed/blob/c9e8e611dbc279afa0914d28c4d37ad07f38c03b/crates/editor/src/element.rs#L201-L213 They also exist in the Visual motion logic for Vim mode and the Select motion logic for Helix mode (the Helix implementation was adopted directly from Vim in #43234): https://github.com/zed-industries/zed/blob/c9e8e611dbc279afa0914d28c4d37ad07f38c03b/crates/vim/src/visual.rs#L254-L259 Finally, they exist in the selection extension logic for Vim and Helix (the Helix logic was also adopted from Vim): https://github.com/zed-industries/zed/blob/c9e8e611dbc279afa0914d28c4d37ad07f38c03b/crates/vim/src/visual.rs#L273-L284 These guards cause trailing-newline selections to behave inconsistently with selections containing newlines elsewhere in the file. ## Solution Remove all the guards mentioned above, including those in cursor rendering, Visual and Select motions, and selection extension. And due to the cursor rendering logic is also changed, an exsisting test is updated. After removing these guards, I could not reproduce the unexpected behavior described in the existing comments: https://github.com/zed-industries/zed/blob/c9e8e611dbc279afa0914d28c4d37ad07f38c03b/crates/vim/src/visual.rs#L247-L253 The only remaining difference is that, when the cursor is on the last line in Visual mode, pressing `j` moves it to the final `\n` rather than to the synthetic empty line after it. In comparison, native Vim and Helix do nothing in this case. ## Testing - Built and tested locally. - Added new GPUI tests. ## Self-Review Checklist: - [x] I've reviewed my own diff for quality, security, and reliability - [x] Unsafe blocks (if any) have justifying comments - [x] The content adheres to Zed's UI standards ([UX/UI](https://github.com/zed-industries/zed/blob/main/CONTRIBUTING.md#uiux-checklist) and [icon](https://github.com/zed-industries/zed/blob/main/crates/icons/README.md) guidelines) - [x] Tests cover the new/changed behavior - [x] Performance impact has been considered and is acceptable Release Notes: - Improved Vim Visual and Helix Select modes when selections include a trailing newline.
3 files changedLine totals unavailable