on master help sign in
Update `replace` command to use document line ending setting.
23d6188Nathan Vegdahl
helix-term/src/commands.rs+19−12
@@ -1,13 +1,15 @@
1use helix_core::{
1use helix_core::{
2 comment, coords_at_pos, find_first_non_whitespace_char, find_root, graphemes, indent,
2 comment, coords_at_pos, find_first_non_whitespace_char, find_root, graphemes, indent,
3+ line_ending::{
3− line_ending::{get_line_ending, get_line_ending_of_str, line_end_char_index},
4+ get_line_ending, get_line_ending_of_str, line_end_char_index, str_is_line_ending,
5+ },
4 match_brackets,
6 match_brackets,
5 movement::{self, Direction},
7 movement::{self, Direction},
6 object, pos_at_coords,
8 object, pos_at_coords,
7 regex::{self, Regex},
9 regex::{self, Regex},
8 register::{self, Register, Registers},
10 register::{self, Register, Registers},
9− search, selection, Change, ChangeSet, LineEnding, Position, Range, Rope, RopeSlice, Selection,
11+ search, selection, Change, ChangeSet, LineEnding, Position, Range, Rope, RopeGraphemes,
10− SmallVec, Tendril, Transaction, DEFAULT_LINE_ENDING,
12+ RopeSlice, Selection, SmallVec, Tendril, Transaction, DEFAULT_LINE_ENDING,
11};
13};
12
14
13use helix_view::{
15use helix_view::{
@@ -577,32 +579,37 @@ fn extend_first_nonwhitespace(cx: &mut Context) {
577}
579}
578
580
579fn replace(cx: &mut Context) {
581fn replace(cx: &mut Context) {
582+ let mut buf = [0u8; 4]; // To hold utf8 encoded char.
583+
580 // need to wait for next key
584 // need to wait for next key
581 cx.on_next_key(move |cx, event| {
585 cx.on_next_key(move |cx, event| {
586+ let (view, doc) = current!(cx.editor);
582 let ch = match event {
587 let ch = match event {
583 KeyEvent {
588 KeyEvent {
584 code: KeyCode::Char(ch),
589 code: KeyCode::Char(ch),
585 ..
590 ..
586− } => Some(ch),
591+ } => Some(&ch.encode_utf8(&mut buf[..])[..]),
587 KeyEvent {
592 KeyEvent {
588 code: KeyCode::Enter,
593 code: KeyCode::Enter,
589 ..
594 ..
590− } => Some('\n'), // TODO: use the document's default line ending.
595+ } => Some(doc.line_ending.as_str()),
591 _ => None,
596 _ => None,
592 };
597 };
593
598
594 if let Some(ch) = ch {
599 if let Some(ch) = ch {
595− let (view, doc) = current!(cx.editor);
596−
597 let transaction =
600 let transaction =
598 Transaction::change_by_selection(doc.text(), doc.selection(view.id), |range| {
601 Transaction::change_by_selection(doc.text(), doc.selection(view.id), |range| {
599 let max_to = doc.text().len_chars().saturating_sub(1);
602 let max_to = doc.text().len_chars().saturating_sub(1);
600 let to = std::cmp::min(max_to, range.to() + 1);
603 let to = std::cmp::min(max_to, range.to() + 1);
601− let text: String = doc
604+ let text: String = RopeGraphemes::new(doc.text().slice(range.from()..to))
602− .text()
605+ .map(|g| {
603− .slice(range.from()..to)
606+ let cow: Cow<str> = g.into();
604− .chars()
607+ if str_is_line_ending(&cow) {
608+ cow
605− .map(|c| if c == '\n' { '\n' } else { ch })
609+ } else {
610+ ch.into()
611+ }
612+ })
606 .collect();
613 .collect();
607
614
608 (range.from(), to, Some(text.into()))
615 (range.from(), to, Some(text.into()))