From 5eca3a51c5847e2d0c64273d1c2dbd8d2ff1fdab Mon Sep 17 00:00:00 2001 From: pBouillon Date: Thu, 23 Apr 2026 10:33:49 +0200 Subject: [PATCH] Automatically convert spaces to dashes in branch names --- src/popups/create_branch.rs | 47 ++++++++++++++++++++++++++++++++++--- src/popups/rename_branch.rs | 47 ++++++++++++++++++++++++++++++++++--- 2 files changed, 88 insertions(+), 6 deletions(-) diff --git a/src/popups/create_branch.rs b/src/popups/create_branch.rs index 9c03970aa6..4a6dd0f82d 100644 --- a/src/popups/create_branch.rs +++ b/src/popups/create_branch.rs @@ -11,9 +11,10 @@ use crate::{ }; use anyhow::Result; use asyncgit::sync::{self, RepoPathRef}; -use crossterm::event::Event; +use crossterm::event::{Event, KeyCode, KeyEvent}; use easy_cast::Cast; use ratatui::{layout::Rect, widgets::Paragraph, Frame}; +use std::borrow::Cow; pub struct CreateBranchPopup { repo: RepoPathRef, @@ -34,6 +35,13 @@ impl DrawableComponent for CreateBranchPopup { } } +const fn normalize_branch_name_char(c: char) -> char { + match c { + ' ' => '-', + c => c, + } +} + impl Component for CreateBranchPopup { fn commands( &self, @@ -57,11 +65,28 @@ impl Component for CreateBranchPopup { fn event(&mut self, ev: &Event) -> Result { if self.is_visible() { - if self.input.event(ev)?.is_consumed() { + let ev = match ev { + Event::Key(KeyEvent { + code: KeyCode::Char(c), + modifiers, + kind, + state, + }) => Cow::Owned(Event::Key(KeyEvent { + code: KeyCode::Char(normalize_branch_name_char( + *c, + )), + modifiers: *modifiers, + kind: *kind, + state: *state, + })), + _ => Cow::Borrowed(ev), + }; + + if self.input.event(&ev)?.is_consumed() { return Ok(EventState::Consumed); } - if let Event::Key(e) = ev { + if let Event::Key(e) = ev.as_ref() { if key_match(e, self.key_config.keys.enter) { self.create_branch(); } @@ -168,3 +193,19 @@ impl CreateBranchPopup { } } } + +#[cfg(test)] +mod tests { + use super::*; + + #[test] + fn test_spaces_are_replaced_by_dashes_in_branch_name() { + let input = "feature/auto replace spaces in branch name"; + let output: String = + input.chars().map(normalize_branch_name_char).collect(); + assert_eq!( + output, + "feature/auto-replace-spaces-in-branch-name" + ); + } +} diff --git a/src/popups/rename_branch.rs b/src/popups/rename_branch.rs index 85190673b0..cce76857a0 100644 --- a/src/popups/rename_branch.rs +++ b/src/popups/rename_branch.rs @@ -11,9 +11,10 @@ use crate::{ }; use anyhow::Result; use asyncgit::sync::{self, RepoPathRef}; -use crossterm::event::Event; +use crossterm::event::{Event, KeyCode, KeyEvent}; use easy_cast::Cast; use ratatui::{layout::Rect, widgets::Paragraph, Frame}; +use std::borrow::Cow; pub struct RenameBranchPopup { repo: RepoPathRef, @@ -34,6 +35,13 @@ impl DrawableComponent for RenameBranchPopup { } } +const fn normalize_branch_name_char(c: char) -> char { + match c { + ' ' => '-', + c => c, + } +} + impl Component for RenameBranchPopup { fn commands( &self, @@ -57,11 +65,28 @@ impl Component for RenameBranchPopup { fn event(&mut self, ev: &Event) -> Result { if self.is_visible() { - if self.input.event(ev)?.is_consumed() { + let ev = match ev { + Event::Key(KeyEvent { + code: KeyCode::Char(c), + modifiers, + kind, + state, + }) => Cow::Owned(Event::Key(KeyEvent { + code: KeyCode::Char(normalize_branch_name_char( + *c, + )), + modifiers: *modifiers, + kind: *kind, + state: *state, + })), + _ => Cow::Borrowed(ev), + }; + + if self.input.event(&ev)?.is_consumed() { return Ok(EventState::Consumed); } - if let Event::Key(e) = ev { + if let Event::Key(e) = ev.as_ref() { if key_match(e, self.key_config.keys.enter) { self.rename_branch(); } @@ -186,3 +211,19 @@ impl RenameBranchPopup { } } } + +#[cfg(test)] +mod tests { + use super::*; + + #[test] + fn test_spaces_are_replaced_by_dashes_in_branch_name() { + let input = "feature/auto replace spaces in branch name"; + let output: String = + input.chars().map(normalize_branch_name_char).collect(); + assert_eq!( + output, + "feature/auto-replace-spaces-in-branch-name" + ); + } +}