on master help sign in
trying out line ending helper functions in commands.rs
a4f5a01Jan Hrastnik
helix-core/src/lib.rs+3−1
@@ -110,5 +110,7 @@ pub use syntax::Syntax;
110pub use diagnostic::Diagnostic;
110pub use diagnostic::Diagnostic;
111pub use state::State;
111pub use state::State;
112
112
113+pub use line_ending::{
113−pub use line_ending::{auto_detect_line_ending, LineEnding, DEFAULT_LINE_ENDING};
114+ auto_detect_line_ending, rope_slice_to_line_ending, LineEnding, DEFAULT_LINE_ENDING,
115+};
114pub use transaction::{Assoc, Change, ChangeSet, Operation, Transaction};
116pub use transaction::{Assoc, Change, ChangeSet, Operation, Transaction};
helix-core/src/line_ending.rs+7−1
@@ -31,6 +31,9 @@ pub fn str_to_line_ending(g: &str) -> Option<LineEnding> {
31 "\u{000D}" => Some(LineEnding::CR),
31 "\u{000D}" => Some(LineEnding::CR),
32 "\u{0085}" => Some(LineEnding::Nel),
32 "\u{0085}" => Some(LineEnding::Nel),
33 "\u{2028}" => Some(LineEnding::LS),
33 "\u{2028}" => Some(LineEnding::LS),
34+ "\u{000B}" => Some(LineEnding::VT),
35+ "\u{000C}" => Some(LineEnding::FF),
36+ "\u{2029}" => Some(LineEnding::PS),
34 // Not a line ending
37 // Not a line ending
35 _ => None,
38 _ => None,
36 }
39 }
@@ -58,7 +61,10 @@ pub fn auto_detect_line_ending(doc: &Rope) -> Option<LineEnding> {
58 _ => None,
61 _ => None,
59 };
62 };
60 if ending.is_some() {
63 if ending.is_some() {
64+ match ending {
65+ Some(LineEnding::VT) | Some(LineEnding::FF) | Some(LineEnding::PS) => {}
61− return ending;
66+ _ => return ending,
67+ }
62 }
68 }
63 }
69 }
64 ending
70 ending
helix-term/src/commands.rs+34−10
@@ -4,9 +4,14 @@ use helix_core::{
4 movement::{self, Direction},
4 movement::{self, Direction},
5 object, pos_at_coords,
5 object, pos_at_coords,
6 regex::{self, Regex},
6 regex::{self, Regex},
7+<<<<<<< HEAD
7 register::{self, Register, Registers},
8 register::{self, Register, Registers},
8 search, selection, Change, ChangeSet, Position, Range, Rope, RopeSlice, Selection, SmallVec,
9 search, selection, Change, ChangeSet, Position, Range, Rope, RopeSlice, Selection, SmallVec,
9 Tendril, Transaction,
10 Tendril, Transaction,
11+=======
12+ register, search, selection, Change, ChangeSet, LineEnding, Position, Range, Rope, RopeSlice,
13+ Selection, SmallVec, Tendril, Transaction,
14+>>>>>>> 856fd95 (trying out line ending helper functions in commands.rs)
10};
15};
11
16
12use helix_view::{
17use helix_view::{
@@ -184,8 +189,14 @@ pub fn move_line_end(cx: &mut Context) {
184 let line = text.char_to_line(range.head);
189 let line = text.char_to_line(range.head);
185
190
186 // Line end is pos at the start of next line - 1
191 // Line end is pos at the start of next line - 1
187− // subtract another 1 because the line ends with \n
192+ // subtract 3 if the line ending is \r\n, otherwise subtract 2 as I assume all others are just 1 char length
193+ let pos =
188− let pos = text.line_to_char(line + 1).saturating_sub(2);
194+ text.line_to_char(line + 1)
195+ .saturating_sub(if doc.line_ending == LineEnding::Crlf {
196+ 3
197+ } else {
198+ 2
199+ });
189 Range::new(pos, pos)
200 Range::new(pos, pos)
190 });
201 });
191
202
@@ -337,7 +348,7 @@ where
337 KeyEvent {
348 KeyEvent {
338 code: KeyCode::Enter,
349 code: KeyCode::Enter,
339 ..
350 ..
340− } => '\n',
351+ } => '\n', // TODO: we should be calling doc.line_ending() here
341 KeyEvent {
352 KeyEvent {
342 code: KeyCode::Char(ch),
353 code: KeyCode::Char(ch),
343 ..
354 ..
@@ -465,7 +476,7 @@ pub fn replace(cx: &mut Context) {
465 KeyEvent {
476 KeyEvent {
466 code: KeyCode::Enter,
477 code: KeyCode::Enter,
467 ..
478 ..
468− } => Some('\n'),
479+ } => Some('\n'), // TODO: we should be calling doc.line_ending() here
469 _ => None,
480 _ => None,
470 };
481 };
471
482
@@ -606,8 +617,14 @@ pub fn extend_line_end(cx: &mut Context) {
606 let line = text.char_to_line(range.head);
617 let line = text.char_to_line(range.head);
607
618
608 // Line end is pos at the start of next line - 1
619 // Line end is pos at the start of next line - 1
609− // subtract another 1 because the line ends with \n
620+ // subtract 3 if the line ending is \r\n, otherwise subtract 2 as I assume all others are just 1 char length
621+ let pos =
610− let pos = text.line_to_char(line + 1).saturating_sub(2);
622+ text.line_to_char(line + 1)
623+ .saturating_sub(if doc.line_ending == LineEnding::Crlf {
624+ 3
625+ } else {
626+ 2
627+ });
611 Range::new(range.anchor, pos)
628 Range::new(range.anchor, pos)
612 });
629 });
613
630
@@ -896,7 +913,7 @@ pub fn append_mode(cx: &mut Context) {
896 if selection.iter().any(|range| range.head == end) {
913 if selection.iter().any(|range| range.head == end) {
897 let transaction = Transaction::change(
914 let transaction = Transaction::change(
898 doc.text(),
915 doc.text(),
899− std::array::IntoIter::new([(end, end, Some(Tendril::from_char('\n')))]),
916+ std::array::IntoIter::new([(end, end, Some(Tendril::from_char('\n')))]), // TODO: change \n to doc.line_ending()
900 );
917 );
901 doc.apply(&transaction, view.id);
918 doc.apply(&transaction, view.id);
902 }
919 }
@@ -1523,7 +1540,7 @@ fn open(cx: &mut Context, open: Open) {
1523 );
1540 );
1524 let indent = doc.indent_unit().repeat(indent_level);
1541 let indent = doc.indent_unit().repeat(indent_level);
1525 let mut text = String::with_capacity(1 + indent.len());
1542 let mut text = String::with_capacity(1 + indent.len());
1526− text.push('\n');
1543+ text.push_str(doc.line_ending());
1527 text.push_str(&indent);
1544 text.push_str(&indent);
1528 let text = text.repeat(count);
1545 let text = text.repeat(count);
1529
1546
@@ -2131,7 +2148,7 @@ pub mod insert {
2131 );
2148 );
2132 let indent = doc.indent_unit().repeat(indent_level);
2149 let indent = doc.indent_unit().repeat(indent_level);
2133 let mut text = String::with_capacity(1 + indent.len());
2150 let mut text = String::with_capacity(1 + indent.len());
2134− text.push('\n');
2151+ text.push_str(doc.line_ending());
2135 text.push_str(&indent);
2152 text.push_str(&indent);
2136
2153
2137 let head = pos + offs + text.chars().count();
2154 let head = pos + offs + text.chars().count();
@@ -2152,7 +2169,7 @@ pub mod insert {
2152 if helix_core::auto_pairs::PAIRS.contains(&(prev, curr)) {
2169 if helix_core::auto_pairs::PAIRS.contains(&(prev, curr)) {
2153 // another newline, indent the end bracket one level less
2170 // another newline, indent the end bracket one level less
2154 let indent = doc.indent_unit().repeat(indent_level.saturating_sub(1));
2171 let indent = doc.indent_unit().repeat(indent_level.saturating_sub(1));
2155− text.push('\n');
2172+ text.push_str(doc.line_ending());
2156 text.push_str(&indent);
2173 text.push_str(&indent);
2157 }
2174 }
2158
2175
@@ -2268,8 +2285,15 @@ fn paste_impl(
2268 .unwrap(),
2285 .unwrap(),
2269 );
2286 );
2270
2287
2288+<<<<<<< HEAD
2271 // if any of values ends \n it's linewise paste
2289 // if any of values ends \n it's linewise paste
2272 let linewise = values.iter().any(|value| value.ends_with('\n'));
2290 let linewise = values.iter().any(|value| value.ends_with('\n'));
2291+=======
2292+ // if any of values ends \n it's linewise paste
2293+ let linewise = values
2294+ .iter()
2295+ .any(|value| value.ends_with(doc.line_ending()));
2296+>>>>>>> 856fd95 (trying out line ending helper functions in commands.rs)
2273
2297
2274 let mut values = values.iter().cloned().map(Tendril::from).chain(repeat);
2298 let mut values = values.iter().cloned().map(Tendril::from).chain(repeat);
2275
2299
helix-term/src/ui/editor.rs+2−2
@@ -7,7 +7,7 @@ use crate::{
7};
7};
8
8
9use helix_core::{
9use helix_core::{
10− coords_at_pos,
10+ coords_at_pos, rope_slice_to_line_ending,
11 syntax::{self, HighlightEvent},
11 syntax::{self, HighlightEvent},
12 Position, Range,
12 Position, Range,
13};
13};
@@ -179,7 +179,7 @@ impl EditorView {
179
179
180 // iterate over range char by char
180 // iterate over range char by char
181 for grapheme in RopeGraphemes::new(text) {
181 for grapheme in RopeGraphemes::new(text) {
182− if grapheme == "\n" || grapheme == "\r\n" {
182+ if rope_slice_to_line_ending(&grapheme).is_some() {
183 visual_x = 0;
183 visual_x = 0;
184 line += 1;
184 line += 1;
185
185
helix-view/src/document.rs+1−1
@@ -76,7 +76,7 @@ pub struct Document {
76
76
77 diagnostics: Vec<Diagnostic>,
77 diagnostics: Vec<Diagnostic>,
78 language_server: Option<Arc<helix_lsp::Client>>,
78 language_server: Option<Arc<helix_lsp::Client>>,
79− line_ending: LineEnding,
79+ pub line_ending: LineEnding,
80}
80}
81
81
82use std::fmt;
82use std::fmt;