Skip to content

Conversation

@benvansleen
Copy link

This PR introduces a new argument to the Vi::new constructor: the alternate_esc_seq. When set to (KeyCode::Null, KeyCode::Null), this does nothing.

alternate_esc_seq can be set to something like (KeyCode::Char('j'), KeyCode::Char('k')) -- allowing the user to press "jk" (without modifiers) to move from Vi insert mode to Vi normal mode.

I wrote this because I would love to be able to use "jj" to enter normal mode in Nu (like I do for all other similar vi-modes).

(I am very new to Rust, Nu, and Reedline; if something is non-idiomatic, please tell me!)

…rt mode (e.g. press "jk" to exit insert mode)
@benvansleen
Copy link
Author

Addressing: #499

@codecov
Copy link

codecov bot commented Nov 18, 2023

Codecov Report

Merging #670 (dfa469b) into main (93af55c) will decrease coverage by 0.07%.
The diff coverage is 42.85%.

Additional details and impacted files

Impacted file tree graph

@@            Coverage Diff             @@
##             main     #670      +/-   ##
==========================================
- Coverage   49.19%   49.12%   -0.07%     
==========================================
  Files          46       46              
  Lines        7930     7959      +29     
==========================================
+ Hits         3901     3910       +9     
- Misses       4029     4049      +20     
Files Coverage Δ
src/edit_mode/vi/mod.rs 61.90% <42.85%> (-4.20%) ⬇️

... and 3 files with indirect coverage changes

@kuchta
Copy link

kuchta commented Nov 18, 2023

Actually all other major vi modes (vim, bash, zsh) uses Meta (Alt) + whatever for entering normal mode. If you get used to it, it's indispensable, but reedline is the only one that doesn't support that...

@tamlok
Copy link

tamlok commented Dec 23, 2023

Can we use ctrl+[ to exit insert mode?

@benvansleen
Copy link
Author

@tamlok
Yes, the keycode C-[ is equivalent to ESC.

@fdncred
Copy link
Contributor

fdncred commented Jan 11, 2024

Is this exposed so that one can define what they like in the nushell config.nu keybindings section?

@benvansleen
Copy link
Author

@fdncred

I believe the config.nu configuration is defined within the nushell crate. In reedline, this configuration is exposed by the Vi constructor.

If this PR is approved, I will write an accompanying nushell PR.

@fdncred
Copy link
Contributor

fdncred commented Jan 11, 2024

I believe the config.nu configuration is defined within the nushell crate.

yes, of course. What I'm saying is will there be some way to define it in the keybinings section like this below but changed somehow to allow for other key combinations to be used for alternate_esc_seq instead of just j/k.

  {
    name: abbr
    modifier: control
    keycode: space
    mode: [emacs, vi_normal, vi_insert]
    event: [
    { send: menu name: alias_menu }
    { edit: insertchar, value: ' '}
    ]
  }

@benvansleen
Copy link
Author

Ah, I see what you mean. Currently, on the reedline side of things, the keys composing the sequence are configured by the (new) 3rd argument to Vi::new:

Vi::new(insert_mode_keybinds, normal_mode_keybinds, (KeyCode::x, KeyCode::y))

This means the user can press "x" then "y" to exit insert-mode. (Passing (KeyCode::Null, KeyCode::Null) instead recovers the current behavior where only ESC exits insert-mode.)

I was thinking of implementing the nushell PR such that config.nu would look something like this:

...
bracketed_paste: true # enable bracketed paste, currently useless on windows
edit_mode: vi # emacs, vi
vi_alternate_esc_seq: { first: x, second: y }
shell_integration: true # enables terminal shell integration. Off by default, as some terminals have issues with this.
...

Achieving this with the existing keybindings section would require implementing something akin to emacs key-chords (since you press one key, release, then press the next). That would be a much, much wider-reaching change.

@eggcaker
Copy link

eggcaker commented Sep 6, 2024

any news?

@ck3mp3r
Copy link

ck3mp3r commented Nov 7, 2024

this is one of the first settings I tweak in neovim and also zsh vim mode...

@omerxx
Copy link

omerxx commented Nov 16, 2024

Hi any news on this?
Hitting esc breaks my fingers 😅

@Jasha10
Copy link

Jasha10 commented Nov 16, 2024

It seems that this PR may be blocked pending some design decisions.

I've opened issue #853 in an attempt to move discussion forward.

benvansleen and others added 2 commits June 29, 2025 12:59
* move visual mode activation to top of match-case

* fixup: missed a call of `exit_insert_mode`

* allow `normal_keybindings` in `ViMode::Visual`
benvansleen and others added 5 commits October 26, 2025 13:41
* fix: prompt glitch when resizing with cursor in a multiline command (nushell#898)

* fix: prompt glitch when resizing with cursor in a multiline command

* fix: considering line wraps

* fix: clippy

* Bump version to `0.41.0` (nushell#936)

* Protect against invalid suggestion spans (nushell#915)

* Protect against invalid suggestion spans

* Protect against start > end

* feat: Builder option to immediately accept input (nushell#933)

* feat: Option to immediately accept input

* chore: PR feedback

* feat: add `ViChangeMode` event (nushell#932)

* feat: add `ViChangeMode` event

* fix: use `FromStr` trait

* fix: undo unused change

* fix: clippy

* Fix `mismatched_lifetime_syntaxes` (nushell#947)

From Rust 1.89.0 on this lints.
https://blog.rust-lang.org/2025/08/07/Rust-1.89.0/#mismatched-lifetime-syntaxes-lint

* Fix missing import in README.md (nushell#942)

Co-authored-by: sholderbach <[email protected]>

* fix: dislocation of cursor after previous_history navigation to a multiline entry (nushell#899)

* bumping version to 42 (nushell#949)

Co-authored-by: Jack Wright <[email protected]>

* Bump `rusqlite` to 0.37 (nushell#950)

* feat: make columnar menu traversal direction configurable (nushell#951)

* Make columnar menu traversal direction configurable

* Add tests for columnar menu selection position updates

* Apply changes based on review

* Upgrade GitHub Actions and Rust toolchain versions (nushell#954)

* Upgrade GitHub Actions and Rust toolchain versions

* Update .github/workflows/ci.yml

* Vi mode text objects for word, WORD, brackets and quotes (nushell#939)

* Addd initial change inner and around word text objects and handle whitespace

Note a buffer full of whitespace is not properly considered and still
causing incorrect behaviour. TODO fix this.

* Renaming functions and fix default value of current_whitespace_range_start

* Rename cut/yank inside enums and methods to cut/yank inside pair and add general yank/cut range methods

* Use TextObject enum instead of passing through the character

* WIP: Add quote and bracket text objects and add jumping if not inside objects

* Add my own methods for finding matching pair and jumping

* Fix bugs in new function to get matching pair range and it's finish features

- Now handles jumps to next open/close or equal symbol pairs if not in a
pair already
- Searching only on current line for equal symbol pairs e.g. quotes
- Correctly handles graphemes

* Simplify heirarchy of pair range finding functions

- Refactor the structure of the methods to get ranges, don't need to
pass in depth unecessarily, high level functions don't require cursor
passed in.
- Now two seperate functions for ranges, one "next" and one "current"
range that gets you either the range inside next text object or inside
current one depending on position of cursor.
- Finilise logic to correctly handle graphemes (not byte sized chars)

TODO Update unit tests

* Refactoring range functions and tidy up/extend unit test cases and coverage

* More refactoring

- Improve some text object ranges to use iterators rather than complex
logic
- Clean up documentation, add consts etc
- Look through and refactor some editor functions

* Move text object range methods into line_buffer from editor

* Combine line_buffer quote and pair text object functions into generic and rewrite a lot of doc strings

* Testing for quote and bracket text object functions in editor.rs

* Whitespace

* Rework unit tests for new function structure

* Remove angle brackets from b text object

* Rename yank text object functions to copy

* Add bracket test cases to range_inside_next_pair_in_group unit tests

* Add more detailed unicode safety tests

* Fix display enum string for renamed enums

* Unicode and overflow/underflow safety when expanding text object ranges

* Pass through matching pair group const for quote and bracket text object functions

* Rename yank_range -> copy_range for consistency with other methods

* Remove unecessary guard clause from expand_range_to_include_pair

* Correct display string for CutInsidePair

* Make text object types public (nushell#957)

* Make TextObject, TextObjectScope and TextObjectType public

* Correct CopyInsidePair and CopyAroundPair EditType to NoOp

* fix: dislocation of cursor during history navigation (nushell#959)

* fix: dislocation of cursor during history navigation

* test: new test case by Claude Sonnet

* simplify

* Fix typos (nushell#962)

* Bump version for `0.43.0` release (nushell#961)

* Fix shift selection in vi (insert) & emacs mode (nushell#927)

* Add match_indices field to Suggestion (nushell#798)

* Add match_indices field to Suggestion

Make columnar_menu use match indices

Make ide menu use match indices

Add fuzzy completions example

Test style_suggestion

Make doctests in default.rs pass

Highlight entire graphemes

Extract ANSI escapes from strings to apply match highlighting

Fix clippy lint for fuzzy completion example

Shut the typo checker up

Use existing variable `escape`

Copy regex from parse-ansi crate

* replace LazyLock with lazy_static that works with Rust 1.63.0 (#2)

* Homegrown ANSI parser

Fix padding for columnar menu

Highlight substring matches too by default

Simplify (?) columnar menu

* Fix clippy lints after rebase

* Use get_match_indices helper

* Stop using 'fo' because it's a typo? Fo shizzle.

* Use to_string() instead of as_str()

* Style entire suggestion same color

* RESET after suggestion

---------

Co-authored-by: Divanshu Grover <[email protected]>

* fix bashism parsing (nushell#958)

* refactor: use crossterm `supports_keyboard_enhancement` once when KittyProtocolGuard is initialized (nushell#920)

Co-authored-by: Pierre POLLET <[email protected]>

---------

Co-authored-by: zc he <[email protected]>
Co-authored-by: Stefan Holderbach <[email protected]>
Co-authored-by: Yash Thakur <[email protected]>
Co-authored-by: Stuart Carnie <[email protected]>
Co-authored-by: Daniel Bonofiglio <[email protected]>
Co-authored-by: Daniel del Castillo <[email protected]>
Co-authored-by: Jack Wright <[email protected]>
Co-authored-by: Jack Wright <[email protected]>
Co-authored-by: Piepmatz <[email protected]>
Co-authored-by: simonborje <[email protected]>
Co-authored-by: Darren Schroeder <[email protected]>
Co-authored-by: JonLD <[email protected]>
Co-authored-by: Collin Murch <[email protected]>
Co-authored-by: Divanshu Grover <[email protected]>
Co-authored-by: migraine-user <[email protected]>
Co-authored-by: PtiBouchon <[email protected]>
Co-authored-by: Pierre POLLET <[email protected]>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

8 participants