From f67e1ee1723592a4e6279197317d46759cd05976 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Bla=C5=BE=20Hrastnik?= Date: Wed, 16 Mar 2022 18:02:37 +0900 Subject: [PATCH] Put esoteric line endings behind a feature flag --- helix-core/Cargo.toml | 2 +- helix-core/src/line_ending.rs | 57 ++++++++++++++++++++++++++++---- helix-term/src/commands/typed.rs | 7 ++++ 3 files changed, 58 insertions(+), 8 deletions(-) diff --git a/helix-core/Cargo.toml b/helix-core/Cargo.toml index 2c557a0e..150f6b4e 100644 --- a/helix-core/Cargo.toml +++ b/helix-core/Cargo.toml @@ -17,7 +17,7 @@ unicode-lines = ["ropey/unicode_lines"] helix-loader = { version = "0.6", path = "../helix-loader" } # ropey = "1.3" -ropey = { git = "https://github.com/cessen/ropey", default-features = false, features = ["cr_lines"] } +ropey = { git = "https://github.com/cessen/ropey", default-features = false } smallvec = "1.8" smartstring = "1.0.0" unicode-segmentation = "1.9" diff --git a/helix-core/src/line_ending.rs b/helix-core/src/line_ending.rs index 8eb426e1..60e0acfa 100644 --- a/helix-core/src/line_ending.rs +++ b/helix-core/src/line_ending.rs @@ -10,12 +10,18 @@ pub const DEFAULT_LINE_ENDING: LineEnding = LineEnding::LF; pub enum LineEnding { Crlf, // CarriageReturn followed by LineFeed LF, // U+000A -- LineFeed - VT, // U+000B -- VerticalTab - FF, // U+000C -- FormFeed - CR, // U+000D -- CarriageReturn - Nel, // U+0085 -- NextLine - LS, // U+2028 -- Line Separator - PS, // U+2029 -- ParagraphSeparator + #[cfg(feature = "unicode-lines")] + VT, // U+000B -- VerticalTab + #[cfg(feature = "unicode-lines")] + FF, // U+000C -- FormFeed + #[cfg(feature = "unicode-lines")] + CR, // U+000D -- CarriageReturn + #[cfg(feature = "unicode-lines")] + Nel, // U+0085 -- NextLine + #[cfg(feature = "unicode-lines")] + LS, // U+2028 -- Line Separator + #[cfg(feature = "unicode-lines")] + PS, // U+2029 -- ParagraphSeparator } impl LineEnding { @@ -32,11 +38,17 @@ impl LineEnding { match self { Self::Crlf => "\u{000D}\u{000A}", Self::LF => "\u{000A}", + #[cfg(feature = "unicode-lines")] Self::VT => "\u{000B}", + #[cfg(feature = "unicode-lines")] Self::FF => "\u{000C}", + #[cfg(feature = "unicode-lines")] Self::CR => "\u{000D}", + #[cfg(feature = "unicode-lines")] Self::Nel => "\u{0085}", + #[cfg(feature = "unicode-lines")] Self::LS => "\u{2028}", + #[cfg(feature = "unicode-lines")] Self::PS => "\u{2029}", } } @@ -45,11 +57,17 @@ impl LineEnding { pub const fn from_char(ch: char) -> Option { match ch { '\u{000A}' => Some(LineEnding::LF), + #[cfg(feature = "unicode-lines")] '\u{000B}' => Some(LineEnding::VT), + #[cfg(feature = "unicode-lines")] '\u{000C}' => Some(LineEnding::FF), + #[cfg(feature = "unicode-lines")] '\u{000D}' => Some(LineEnding::CR), + #[cfg(feature = "unicode-lines")] '\u{0085}' => Some(LineEnding::Nel), + #[cfg(feature = "unicode-lines")] '\u{2028}' => Some(LineEnding::LS), + #[cfg(feature = "unicode-lines")] '\u{2029}' => Some(LineEnding::PS), // Not a line ending _ => None, @@ -65,11 +83,17 @@ impl LineEnding { match g { "\u{000D}\u{000A}" => Some(LineEnding::Crlf), "\u{000A}" => Some(LineEnding::LF), + #[cfg(feature = "unicode-lines")] "\u{000B}" => Some(LineEnding::VT), + #[cfg(feature = "unicode-lines")] "\u{000C}" => Some(LineEnding::FF), + #[cfg(feature = "unicode-lines")] "\u{000D}" => Some(LineEnding::CR), + #[cfg(feature = "unicode-lines")] "\u{0085}" => Some(LineEnding::Nel), + #[cfg(feature = "unicode-lines")] "\u{2028}" => Some(LineEnding::LS), + #[cfg(feature = "unicode-lines")] "\u{2029}" => Some(LineEnding::PS), // Not a line ending _ => None, @@ -101,7 +125,9 @@ pub fn auto_detect_line_ending(doc: &Rope) -> Option { // are being matched, as they might be special-use only for line in doc.lines().take(100) { match get_line_ending(&line) { - None | Some(LineEnding::VT) | Some(LineEnding::FF) | Some(LineEnding::PS) => {} + None => {} + #[cfg(feature = "unicode-lines")] + Some(LineEnding::VT) | Some(LineEnding::FF) | Some(LineEnding::PS) => {} ending => return ending, } } @@ -128,6 +154,19 @@ pub fn get_line_ending(line: &RopeSlice) -> Option { LineEnding::from_str(g2).or_else(|| LineEnding::from_str(g1)) } +#[cfg(not(feature = "unicode-lines"))] +/// Returns the passed line's line ending, if any. +pub fn get_line_ending_of_str(line: &str) -> Option { + if line.ends_with("\u{000D}\u{000A}") { + Some(LineEnding::Crlf) + } else if line.ends_with('\u{000A}') { + Some(LineEnding::LF) + } else { + None + } +} + +#[cfg(feature = "unicode-lines")] /// Returns the passed line's line ending, if any. pub fn get_line_ending_of_str(line: &str) -> Option { if line.ends_with("\u{000D}\u{000A}") { @@ -211,6 +250,7 @@ mod line_ending_tests { #[test] fn str_to_line_ending() { + #[cfg(feature = "unicode-lines")] assert_eq!(LineEnding::from_str("\r"), Some(LineEnding::CR)); assert_eq!(LineEnding::from_str("\n"), Some(LineEnding::LF)); assert_eq!(LineEnding::from_str("\r\n"), Some(LineEnding::Crlf)); @@ -220,6 +260,7 @@ mod line_ending_tests { #[test] fn rope_slice_to_line_ending() { let r = Rope::from_str("hello\r\n"); + #[cfg(feature = "unicode-lines")] assert_eq!( LineEnding::from_rope_slice(&r.slice(5..6)), Some(LineEnding::CR) @@ -238,6 +279,7 @@ mod line_ending_tests { #[test] fn get_line_ending_rope_slice() { let r = Rope::from_str("Hello\rworld\nhow\r\nare you?"); + #[cfg(feature = "unicode-lines")] assert_eq!(get_line_ending(&r.slice(..6)), Some(LineEnding::CR)); assert_eq!(get_line_ending(&r.slice(..12)), Some(LineEnding::LF)); assert_eq!(get_line_ending(&r.slice(..17)), Some(LineEnding::Crlf)); @@ -247,6 +289,7 @@ mod line_ending_tests { #[test] fn get_line_ending_str() { let text = "Hello\rworld\nhow\r\nare you?"; + #[cfg(feature = "unicode-lines")] assert_eq!(get_line_ending_of_str(&text[..6]), Some(LineEnding::CR)); assert_eq!(get_line_ending_of_str(&text[..12]), Some(LineEnding::LF)); assert_eq!(get_line_ending_of_str(&text[..17]), Some(LineEnding::Crlf)); diff --git a/helix-term/src/commands/typed.rs b/helix-term/src/commands/typed.rs index 0801b236..d35b7082 100644 --- a/helix-term/src/commands/typed.rs +++ b/helix-term/src/commands/typed.rs @@ -288,11 +288,15 @@ fn set_line_ending( cx.editor.set_status(match line_ending { Crlf => "crlf", LF => "line feed", + #[cfg(feature = "unicode-lines")] FF => "form feed", + #[cfg(feature = "unicode-lines")] CR => "carriage return", + #[cfg(feature = "unicode-lines")] Nel => "next line", // These should never be a document's default line ending. + #[cfg(feature = "unicode-lines")] VT | LS | PS => "error", }); @@ -307,10 +311,13 @@ fn set_line_ending( // Attempt to parse argument as a line ending. let line_ending = match arg { // We check for CR first because it shares a common prefix with CRLF. + #[cfg(feature = "unicode-lines")] arg if arg.starts_with("cr") => CR, arg if arg.starts_with("crlf") => Crlf, arg if arg.starts_with("lf") => LF, + #[cfg(feature = "unicode-lines")] arg if arg.starts_with("ff") => FF, + #[cfg(feature = "unicode-lines")] arg if arg.starts_with("nel") => Nel, _ => bail!("invalid line ending"), };