From c9d09f6f9897cf0e8d6823067ed61eed1809d6d1 Mon Sep 17 00:00:00 2001 From: Nathan Vegdahl Date: Sat, 31 Jan 2015 15:06:04 -0800 Subject: [PATCH] Moved line_ending_type out of Buffer and into Editor. --- src/buffer/mod.rs | 4 +-- src/editor/mod.rs | 73 ++++++++++++++++++++++++++++++++++++++++++++++ src/files.rs | 5 +--- src/term_ui/mod.rs | 4 +-- todo.md | 2 -- 5 files changed, 77 insertions(+), 11 deletions(-) diff --git a/src/buffer/mod.rs b/src/buffer/mod.rs index ec95782..ef64675 100644 --- a/src/buffer/mod.rs +++ b/src/buffer/mod.rs @@ -2,7 +2,7 @@ use std::mem; -use self::line::{Line, LineEnding}; +use self::line::Line; use self::node::{BufferNode, BufferNodeGraphemeIter, BufferNodeLineIter}; use self::undo_stack::{UndoStack}; use self::undo_stack::Operation::*; @@ -23,7 +23,6 @@ mod undo_stack; pub struct Buffer { text: BufferNode, undo_stack: UndoStack, - pub line_ending_type: LineEnding, pub formatter: T, } @@ -33,7 +32,6 @@ impl Buffer { Buffer { text: BufferNode::new(&formatter), undo_stack: UndoStack::new(), - line_ending_type: LineEnding::LF, formatter: formatter, } } diff --git a/src/editor/mod.rs b/src/editor/mod.rs index 032aef9..606624f 100644 --- a/src/editor/mod.rs +++ b/src/editor/mod.rs @@ -1,6 +1,7 @@ #![allow(dead_code)] use buffer::Buffer; +use buffer::line::LineEnding; use buffer::line_formatter::LineFormatter; use buffer::line_formatter::RoundingBehavior::*; use std::path::Path; @@ -15,6 +16,7 @@ mod cursor; pub struct Editor { pub buffer: Buffer, pub file_path: Path, + pub line_ending_type: LineEnding, pub soft_tabs: bool, pub soft_tab_width: u8, pub dirty: bool, @@ -34,6 +36,7 @@ impl Editor { Editor { buffer: Buffer::new(formatter), file_path: Path::new(""), + line_ending_type: LineEnding::LF, soft_tabs: false, soft_tab_width: 4, dirty: false, @@ -53,6 +56,7 @@ impl Editor { let mut ed = Editor { buffer: buf, file_path: path.clone(), + line_ending_type: LineEnding::LF, soft_tabs: false, soft_tab_width: 4, dirty: false, @@ -68,6 +72,7 @@ impl Editor { //cur.update_vis_start(&(ed.buffer)); //ed.cursors.add_cursor(cur); + ed.auto_detect_line_ending(); ed.auto_detect_indentation_style(); return ed; @@ -80,6 +85,74 @@ impl Editor { } } + pub fn auto_detect_line_ending(&mut self) { + let mut line_ending_histogram: [usize; 8] = [0, 0, 0, 0, 0, 0, 0, 0]; + + // Collect statistics + let mut line_i: usize = 0; + for line in self.buffer.line_iter() { + match line.ending { + LineEnding::None => { + }, + LineEnding::CRLF => { + line_ending_histogram[0] += 1; + }, + LineEnding::LF => { + line_ending_histogram[1] += 1; + }, + LineEnding::VT => { + line_ending_histogram[2] += 1; + }, + LineEnding::FF => { + line_ending_histogram[3] += 1; + }, + LineEnding::CR => { + line_ending_histogram[4] += 1; + }, + LineEnding::NEL => { + line_ending_histogram[5] += 1; + }, + LineEnding::LS => { + line_ending_histogram[6] += 1; + }, + LineEnding::PS => { + line_ending_histogram[7] += 1; + }, + } + + // Stop after 100 lines + line_i += 1; + if line_i > 100 { + break; + } + } + + // Analyze stats and make a determination + let mut lei = 0; + let mut le_count = 0; + for i in 0us..8 { + if line_ending_histogram[i] > le_count { + lei = i; + le_count = line_ending_histogram[i]; + } + } + + if le_count > 0 { + self.line_ending_type = match lei { + 0 => LineEnding::CRLF, + 1 => LineEnding::LF, + 2 => LineEnding::VT, + 3 => LineEnding::FF, + 4 => LineEnding::CR, + 5 => LineEnding::NEL, + 6 => LineEnding::LS, + 7 => LineEnding::PS, + + _ => LineEnding::LF, + }; + } + } + pub fn auto_detect_indentation_style(&mut self) { let mut tab_blocks: usize = 0; let mut space_blocks: usize = 0; diff --git a/src/files.rs b/src/files.rs index 074cccb..01f53c3 100644 --- a/src/files.rs +++ b/src/files.rs @@ -2,7 +2,7 @@ use std::old_io::{IoResult, BufferedReader, BufferedWriter}; use std::old_io::fs::File; use std::path::Path; -use buffer::line::{Line, LineEnding, line_ending_to_str}; +use buffer::line::{Line, line_ending_to_str}; use buffer::line_formatter::LineFormatter; use buffer::Buffer as TextBuffer; @@ -12,9 +12,6 @@ pub fn load_file_to_buffer(path: &Path, lf: T) -> IoResult { - let nl = line_ending_to_str(self.editor.buffer.line_ending_type); + let nl = line_ending_to_str(self.editor.line_ending_type); self.editor.insert_text_at_cursor(nl); }, @@ -327,7 +327,7 @@ impl TermUI { self.rb.print(c2.1 - pstring.len(), c1.0, rustbox::RB_NORMAL, foreground, background, &pstring[]); // Text encoding info and tab style - let nl = match editor.buffer.line_ending_type { + let nl = match editor.line_ending_type { LineEnding::None => "None", LineEnding::CRLF => "CRLF", LineEnding::LF => "LF", diff --git a/todo.md b/todo.md index ca7075e..d7e5a09 100644 --- a/todo.md +++ b/todo.md @@ -25,10 +25,8 @@ only recognizes LF and CRLF. - File loading is currently very slow. Investigate. - Line number display -- Line wrapping - File opening by entering path - UI that wraps editors, for split view. - Persistent infinite undo -- Multiple cursors - "Projects"