aboutsummaryrefslogtreecommitdiff
path: root/helix-core/src
diff options
context:
space:
mode:
Diffstat (limited to 'helix-core/src')
-rw-r--r--helix-core/src/lib.rs2
-rw-r--r--helix-core/src/line_ending.rs23
2 files changed, 19 insertions, 6 deletions
diff --git a/helix-core/src/lib.rs b/helix-core/src/lib.rs
index 55365500..3f6bea5a 100644
--- a/helix-core/src/lib.rs
+++ b/helix-core/src/lib.rs
@@ -111,6 +111,6 @@ pub use diagnostic::Diagnostic;
pub use state::State;
pub use line_ending::{
- auto_detect_line_ending, rope_slice_to_line_ending, LineEnding, DEFAULT_LINE_ENDING,
+ auto_detect_line_ending, rope_slice_to_line_ending, LineEnding, DEFAULT_LINE_ENDING, get_line_ending
};
pub use transaction::{Assoc, Change, ChangeSet, Operation, Transaction};
diff --git a/helix-core/src/line_ending.rs b/helix-core/src/line_ending.rs
index f9d67b57..423f4b92 100644
--- a/helix-core/src/line_ending.rs
+++ b/helix-core/src/line_ending.rs
@@ -14,7 +14,7 @@ pub enum LineEnding {
}
impl LineEnding {
- pub fn len(&self) -> usize {
+ pub fn len_chars(&self) -> usize {
match self {
Self::Crlf => 2,
_ => 1,
@@ -28,10 +28,9 @@ impl LineEnding {
Self::Nel => "\u{0085}",
Self::LS => "\u{2028}",
Self::CR => "\u{000D}",
- _ => panic!(
- "Unexpected line ending: {:?}, expected Crlf, LF, CR, Nel, or LS.",
- self
- ),
+ Self::VT => "\u{000B}",
+ Self::FF => "\u{000C}",
+ Self::PS => "\u{2029}",
}
}
}
@@ -93,6 +92,20 @@ pub fn auto_detect_line_ending(doc: &Rope) -> Option<LineEnding> {
ending
}
+/// Returns the passed line's line ending, if any.
+pub fn get_line_ending(line: &RopeSlice) -> Option<LineEnding> {
+ // Last character as str.
+ let g1 = line.slice(line.len_chars().saturating_sub(1)..).as_str().unwrap();
+
+ // Last two characters as str, or empty str if they're not contiguous.
+ // It's fine to punt on the non-contiguous case, because Ropey guarantees
+ // that CRLF is always contiguous.
+ let g2 = line.slice(line.len_chars().saturating_sub(2)..).as_str().unwrap_or("");
+
+ // First check the two-character case for CRLF, then check the single-character case.
+ str_to_line_ending(g2).or_else(|| str_to_line_ending(g1))
+}
+
#[cfg(target_os = "windows")]
pub const DEFAULT_LINE_ENDING: LineEnding = LineEnding::Crlf;
#[cfg(not(target_os = "windows"))]