@@ -272,6 +272,7 @@ impl Command {
272
272
// TODO: different description ?
273
273
goto_line_end_newline, "Goto line end" ,
274
274
goto_first_nonwhitespace, "Goto first non-blank in line" ,
275
+ trim_selections, "Trim whitespace from selections" ,
275
276
extend_to_line_start, "Extend to line start" ,
276
277
extend_to_line_end, "Extend to line end" ,
277
278
extend_to_line_end_newline, "Extend to line end" ,
@@ -584,6 +585,34 @@ fn goto_first_nonwhitespace(cx: &mut Context) {
584
585
doc. set_selection ( view. id , selection) ;
585
586
}
586
587
588
+ fn trim_selections ( cx : & mut Context ) {
589
+ let ( view, doc) = current ! ( cx. editor) ;
590
+ let text = doc. text ( ) . slice ( ..) ;
591
+
592
+ static END_REGEX : Lazy < Regex > = Lazy :: new ( || Regex :: new ( r"\S\s+$" ) . unwrap ( ) ) ;
593
+
594
+ let selection = doc. selection ( view. id ) . clone ( ) . transform ( |range| {
595
+ let mut start = range. from ( ) ;
596
+ let mut end = range. to ( ) ;
597
+ let start_byte = text. char_to_byte ( start) ;
598
+
599
+ start += text
600
+ . chars_at ( start)
601
+ . position ( |x| !x. is_whitespace ( ) )
602
+ . unwrap_or ( 0 ) ;
603
+
604
+ if let Some ( pos) = END_REGEX . find ( & range. fragment ( text) ) {
605
+ end = text. byte_to_char ( start_byte + pos. start ( ) ) + 1 ;
606
+ }
607
+ if range. anchor < range. head {
608
+ Range :: new ( start, end)
609
+ } else {
610
+ Range :: new ( end, start)
611
+ }
612
+ } ) ;
613
+ doc. set_selection ( view. id , selection) ;
614
+ }
615
+
587
616
fn goto_window ( cx : & mut Context , align : Align ) {
588
617
let ( view, doc) = current ! ( cx. editor) ;
589
618
0 commit comments