summaryrefslogtreecommitdiff
path: root/helix-view/src/document.rs
diff options
context:
space:
mode:
Diffstat (limited to 'helix-view/src/document.rs')
-rw-r--r--helix-view/src/document.rs42
1 files changed, 30 insertions, 12 deletions
diff --git a/helix-view/src/document.rs b/helix-view/src/document.rs
index fd127e1b..9326fb79 100644
--- a/helix-view/src/document.rs
+++ b/helix-view/src/document.rs
@@ -7,10 +7,12 @@ use std::str::FromStr;
use std::sync::Arc;
use helix_core::{
- chars::{char_is_linebreak, char_is_whitespace},
+ auto_detect_line_ending,
+ chars::{char_is_line_ending, char_is_whitespace},
history::History,
syntax::{self, LanguageConfiguration},
- ChangeSet, Diagnostic, Rope, Selection, State, Syntax, Transaction,
+ ChangeSet, Diagnostic, LineEnding, Rope, Selection, State, Syntax, Transaction,
+ DEFAULT_LINE_ENDING,
};
use crate::{DocumentId, Theme, ViewId};
@@ -45,6 +47,9 @@ pub struct Document {
/// Current indent style.
pub indent_style: IndentStyle,
+ /// The document's default line ending.
+ pub line_ending: LineEnding,
+
syntax: Option<Syntax>,
// /// Corresponding language scope name. Usually `source.<lang>`.
pub(crate) language: Option<Arc<LanguageConfiguration>>,
@@ -232,6 +237,7 @@ impl Document {
history: Cell::new(History::default()),
last_saved_revision: 0,
language_server: None,
+ line_ending: DEFAULT_LINE_ENDING,
}
}
@@ -243,22 +249,26 @@ impl Document {
) -> Result<Self, Error> {
use std::{fs::File, io::BufReader};
- let doc = if !path.exists() {
- Rope::from("\n")
+ let mut doc = if !path.exists() {
+ Rope::from(DEFAULT_LINE_ENDING.as_str())
} else {
let file = File::open(&path).context(format!("unable to open {:?}", path))?;
- let mut doc = Rope::from_reader(BufReader::new(file))?;
- // add missing newline at the end of file
- if doc.len_bytes() == 0 || doc.byte(doc.len_bytes() - 1) != b'\n' {
- doc.insert_char(doc.len_chars(), '\n');
- }
- doc
+ Rope::from_reader(BufReader::new(file))?
};
+ // search for line endings
+ let line_ending = auto_detect_line_ending(&doc).unwrap_or(DEFAULT_LINE_ENDING);
+
+ // add missing newline at the end of file
+ if doc.len_bytes() == 0 || char_is_line_ending(doc.char(doc.len_chars() - 1)) {
+ doc.insert(doc.len_chars(), line_ending.as_str());
+ }
+
let mut doc = Self::new(doc);
// set the path and try detecting the language
doc.set_path(&path)?;
doc.detect_indent_style();
+ doc.set_line_ending(line_ending);
if let Some(loader) = config_loader {
doc.detect_language(theme, loader);
@@ -366,7 +376,7 @@ impl Document {
Some(' ') => false,
// Ignore blank lines.
- Some(c) if char_is_linebreak(c) => continue,
+ Some(c) if char_is_line_ending(c) => continue,
_ => {
prev_line_is_tabs = false;
@@ -390,7 +400,7 @@ impl Document {
c if char_is_whitespace(c) => count_is_done = true,
// Ignore blank lines.
- c if char_is_linebreak(c) => continue 'outer,
+ c if char_is_line_ending(c) => continue 'outer,
_ => break,
}
@@ -521,6 +531,10 @@ impl Document {
self.selections.insert(view_id, selection);
}
+ pub fn set_line_ending(&mut self, line_ending: LineEnding) {
+ self.line_ending = line_ending;
+ }
+
fn _apply(&mut self, transaction: &Transaction, view_id: ViewId) -> bool {
let old_doc = self.text().clone();
@@ -791,6 +805,10 @@ impl Document {
pub fn set_diagnostics(&mut self, diagnostics: Vec<Diagnostic>) {
self.diagnostics = diagnostics;
}
+
+ pub fn line_ending(&self) -> LineEnding {
+ self.line_ending
+ }
}
#[cfg(test)]