diff --git a/helix-view/src/input.rs b/helix-view/src/input.rs index 5f5067eac..bd737f231 100644 --- a/helix-view/src/input.rs +++ b/helix-view/src/input.rs @@ -387,6 +387,23 @@ fn from_str(s: &str) -> Result { .then_some(KeyCode::F(function)) .ok_or_else(|| anyhow!("Invalid function key '{}'", function))? } + // Checking that the last token is empty ensures that this branch is only taken if + // `-` is used as a code. For example this branch will not be taken for `S-` (which is + // missing a code). + _ if s.ends_with('-') && tokens.last().is_some_and(|t| t.is_empty()) => { + if s == "-" { + return Ok(KeyEvent { + code: KeyCode::Char('-'), + modifiers: KeyModifiers::empty(), + }); + } else { + let suggestion = format!("{}-{}", s.trim_end_matches('-'), keys::MINUS); + return Err(anyhow!( + "Key '-' cannot be used with modifiers, use '{}' instead", + suggestion + )); + } + } invalid => return Err(anyhow!("Invalid key code '{}'", invalid)), }; @@ -661,6 +678,13 @@ fn parsing_unmodified_keys() { modifiers: KeyModifiers::NONE } ); + assert_eq!( + str::parse::("-").unwrap(), + KeyEvent { + code: KeyCode::Char('-'), + modifiers: KeyModifiers::NONE, + } + ); } #[test] @@ -721,6 +745,7 @@ fn parsing_nonsensical_keys_fails() { assert!(str::parse::("FU").is_err()); assert!(str::parse::("123").is_err()); assert!(str::parse::("S--").is_err()); + assert!(str::parse::("S-").is_err()); assert!(str::parse::("S-percent").is_err()); }