Skip to content

Commit

Permalink
add config for default line ending
Browse files Browse the repository at this point in the history
  • Loading branch information
CptPotato committed Jan 21, 2023
1 parent 68fc109 commit 1eb7bb3
Show file tree
Hide file tree
Showing 6 changed files with 100 additions and 36 deletions.
2 changes: 1 addition & 1 deletion helix-core/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -103,5 +103,5 @@ pub use syntax::Syntax;

pub use diagnostic::Diagnostic;

pub use line_ending::{LineEnding, DEFAULT_LINE_ENDING};
pub use line_ending::LineEnding;
pub use transaction::{Assoc, Change, ChangeSet, Operation, Transaction};
16 changes: 11 additions & 5 deletions helix-core/src/line_ending.rs
Original file line number Diff line number Diff line change
@@ -1,10 +1,5 @@
use crate::{Rope, RopeSlice};

#[cfg(target_os = "windows")]
pub const DEFAULT_LINE_ENDING: LineEnding = LineEnding::Crlf;
#[cfg(not(target_os = "windows"))]
pub const DEFAULT_LINE_ENDING: LineEnding = LineEnding::LF;

/// Represents one of the valid Unicode line endings.
#[derive(PartialEq, Eq, Copy, Clone, Debug)]
pub enum LineEnding {
Expand Down Expand Up @@ -112,6 +107,17 @@ impl LineEnding {
None
}
}

/// The platform's native line ending.
///
/// [`LineEnding::Crlf`] on Windows, otherwise [`LineEnding::LF`].
#[inline]
pub fn native() -> Self {
#[cfg(target_os = "windows")]
return LineEnding::Crlf;
#[cfg(not(target_os = "windows"))]
return LineEnding::LF;
}
}

#[inline]
Expand Down
3 changes: 2 additions & 1 deletion helix-term/src/ui/picker.rs
Original file line number Diff line number Diff line change
Expand Up @@ -178,8 +178,9 @@ impl<T: Item> FilePicker<T> {
CachedPreview::LargeFile
}
_ => {
let line_ending = editor.config().default_line_ending.into();
// TODO: enable syntax highlighting; blocked by async rendering
Document::open(path, None, None)
Document::open(path, None, line_ending, None)
.map(|doc| CachedPreview::Document(Box::new(doc)))
.unwrap_or(CachedPreview::NotFound)
}
Expand Down
35 changes: 19 additions & 16 deletions helix-view/src/document.rs
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,6 @@ use helix_core::{
line_ending::auto_detect_line_ending,
syntax::{self, LanguageConfiguration},
ChangeSet, Diagnostic, LineEnding, Rope, RopeBuilder, Selection, Syntax, Transaction,
DEFAULT_LINE_ENDING,
};

use crate::editor::RedrawHandle;
Expand Down Expand Up @@ -351,7 +350,15 @@ use helix_lsp::lsp;
use url::Url;

impl Document {
pub fn from(text: Rope, encoding: Option<&'static encoding::Encoding>) -> Self {
pub fn new(line_ending: LineEnding) -> Self {
Self::from(Rope::from(line_ending.as_str()), None, line_ending)
}

pub fn from(
text: Rope,
encoding: Option<&'static encoding::Encoding>,
line_ending: LineEnding,
) -> Self {
let encoding = encoding.unwrap_or(encoding::UTF_8);
let changes = ChangeSet::new(&text);
let old_state = None;
Expand All @@ -363,7 +370,7 @@ impl Document {
text,
selections: HashMap::default(),
indent_style: DEFAULT_INDENT,
line_ending: DEFAULT_LINE_ENDING,
line_ending,
restore_cursor: false,
syntax: None,
language: None,
Expand All @@ -386,6 +393,7 @@ impl Document {
pub fn open(
path: &Path,
encoding: Option<&'static encoding::Encoding>,
default_line_ending: LineEnding,
config_loader: Option<Arc<syntax::Loader>>,
) -> Result<Self, Error> {
// Open the file if it exists, otherwise assume it is a new file (and thus empty).
Expand All @@ -395,10 +403,10 @@ impl Document {
from_reader(&mut file, encoding)?
} else {
let encoding = encoding.unwrap_or(encoding::UTF_8);
(Rope::from(DEFAULT_LINE_ENDING.as_str()), encoding)
(Rope::from(default_line_ending.as_str()), encoding)
};

let mut doc = Self::from(rope, Some(encoding));
let mut doc = Self::from(rope, Some(encoding), default_line_ending);

// set the path and try detecting the language
doc.set_path(Some(path))?;
Expand Down Expand Up @@ -619,14 +627,16 @@ impl Document {

/// Detect the indentation used in the file, or otherwise defaults to the language indentation
/// configured in `languages.toml`, with a fallback to tabs if it isn't specified. Line ending
/// is likewise auto-detected, and will fallback to the default OS line ending.
/// is likewise auto-detected, and will remain unchanged if no line endings were detected.
pub fn detect_indent_and_line_ending(&mut self) {
self.indent_style = auto_detect_indent_style(&self.text).unwrap_or_else(|| {
self.language_config()
.and_then(|config| config.indent.as_ref())
.map_or(DEFAULT_INDENT, |config| IndentStyle::from_str(&config.unit))
});
self.line_ending = auto_detect_line_ending(&self.text).unwrap_or(DEFAULT_LINE_ENDING);
if let Some(line_ending) = auto_detect_line_ending(&self.text) {
self.line_ending = line_ending;
}
}

/// Reload the document from its path.
Expand Down Expand Up @@ -1197,13 +1207,6 @@ impl Document {
}
}

impl Default for Document {
fn default() -> Self {
let text = Rope::from(DEFAULT_LINE_ENDING.as_str());
Self::from(text, None)
}
}

#[derive(Clone, Debug)]
pub enum FormatterError {
SpawningFailed {
Expand Down Expand Up @@ -1245,7 +1248,7 @@ mod test {
fn changeset_to_changes_ignore_line_endings() {
use helix_lsp::{lsp, Client, OffsetEncoding};
let text = Rope::from("hello\r\nworld");
let mut doc = Document::from(text, None);
let mut doc = Document::from(text, None, LineEnding::LF);
let view = ViewId::default();
doc.set_selection(view, Selection::single(0, 0));

Expand Down Expand Up @@ -1279,7 +1282,7 @@ mod test {
fn changeset_to_changes() {
use helix_lsp::{lsp, Client, OffsetEncoding};
let text = Rope::from("hello");
let mut doc = Document::from(text, None);
let mut doc = Document::from(text, None, LineEnding::LF);
let view = ViewId::default();
doc.set_selection(view, Selection::single(5, 5));

Expand Down
68 changes: 61 additions & 7 deletions helix-view/src/editor.rs
Original file line number Diff line number Diff line change
Expand Up @@ -38,12 +38,12 @@ use anyhow::{anyhow, bail, Error};

pub use helix_core::diagnostic::Severity;
pub use helix_core::register::Registers;
use helix_core::Position;
use helix_core::{
auto_pairs::AutoPairs,
syntax::{self, AutoPairConfig},
Change,
};
use helix_core::{LineEnding, Position};
use helix_dap as dap;
use helix_lsp::lsp;

Expand Down Expand Up @@ -168,7 +168,7 @@ pub struct Config {
pub search: SearchConfig,
pub lsp: LspConfig,
pub terminal: Option<TerminalConfig>,
/// Column numbers at which to draw the rulers. Default to `[]`, meaning no rulers.
/// Column numbers at which to draw the rulers. Defaults to `[]`, meaning no rulers.
pub rulers: Vec<u16>,
#[serde(default)]
pub whitespace: WhitespaceConfig,
Expand All @@ -178,6 +178,8 @@ pub struct Config {
pub indent_guides: IndentGuidesConfig,
/// Whether to color modes with different colors. Defaults to `false`.
pub color_modes: bool,
/// Which line ending to choose for new documents. Defaults to `native`. i.e. `crlf` on Windows, otherwise `lf`.
pub default_line_ending: LineEndingConfig,
}

#[derive(Debug, Default, Clone, PartialEq, Eq, Serialize, Deserialize)]
Expand Down Expand Up @@ -259,7 +261,7 @@ impl Default for LspConfig {
pub struct SearchConfig {
/// Smart case: Case insensitive searching unless pattern contains upper case characters. Defaults to true.
pub smart_case: bool,
/// Whether the search should wrap after depleting the matches. Default to true.
/// Whether the search should wrap after depleting the matches. Defaults to true.
pub wrap_around: bool,
}

Expand Down Expand Up @@ -592,6 +594,51 @@ impl Default for IndentGuidesConfig {
}
}

/// Line ending configuration.
#[derive(Debug, Copy, Clone, PartialEq, Eq, Serialize, Deserialize)]
#[serde(rename_all = "lowercase")]
pub enum LineEndingConfig {
/// The platform's native line ending.
///
/// `crlf` on Windows, otherwise `lf`.
Native,
/// Line feed.
LF,
/// Carriage return followed by line feed.
Crlf,
/// Form feed.
#[cfg(feature = "unicode-lines")]
FF,
/// Carriage return.
#[cfg(feature = "unicode-lines")]
CR,
/// Next line.
#[cfg(feature = "unicode-lines")]
Nel,
}

impl Default for LineEndingConfig {
fn default() -> Self {
LineEndingConfig::Native
}
}

impl Into<LineEnding> for LineEndingConfig {
fn into(self) -> LineEnding {
match self {
LineEndingConfig::Native => LineEnding::native(),
LineEndingConfig::LF => LineEnding::LF,
LineEndingConfig::Crlf => LineEnding::Crlf,
#[cfg(feature = "unicode-lines")]
LineEndingConfig::FF => LineEnding::FF,
#[cfg(feature = "unicode-lines")]
LineEndingConfig::CR => LineEnding::CR,
#[cfg(feature = "unicode-lines")]
LineEndingConfig::Nel => LineEnding::Nel,
}
}
}

impl Default for Config {
fn default() -> Self {
Self {
Expand Down Expand Up @@ -633,6 +680,7 @@ impl Default for Config {
bufferline: BufferLine::default(),
indent_guides: IndentGuidesConfig::default(),
color_modes: false,
default_line_ending: LineEndingConfig::default(),
}
}
}
Expand Down Expand Up @@ -1118,12 +1166,14 @@ impl Editor {
}

pub fn new_file(&mut self, action: Action) -> DocumentId {
self.new_file_from_document(action, Document::default())
let line_ending = self.config().default_line_ending.into();
self.new_file_from_document(action, Document::new(line_ending))
}

pub fn new_file_from_stdin(&mut self, action: Action) -> Result<DocumentId, Error> {
let (rope, encoding) = crate::document::from_reader(&mut stdin(), None)?;
Ok(self.new_file_from_document(action, Document::from(rope, Some(encoding))))
let line_ending = self.config().default_line_ending.into();
Ok(self.new_file_from_document(action, Document::from(rope, Some(encoding), line_ending)))
}

// ??? possible use for integration tests
Expand All @@ -1134,7 +1184,8 @@ impl Editor {
let id = if let Some(id) = id {
id
} else {
let mut doc = Document::open(&path, None, Some(self.syn_loader.clone()))?;
let line_ending = self.config().default_line_ending.into();
let mut doc = Document::open(&path, None, line_ending, Some(self.syn_loader.clone()))?;

let _ = Self::launch_language_server(&mut self.language_servers, &mut doc);
if let Some(diff_base) = self.diff_providers.get_diff_base(&path) {
Expand Down Expand Up @@ -1220,7 +1271,10 @@ impl Editor {
.iter()
.map(|(&doc_id, _)| doc_id)
.next()
.unwrap_or_else(|| self.new_document(Document::default()));
.unwrap_or_else(|| {
let line_ending = self.config().default_line_ending.into();
self.new_document(Document::new(line_ending))
});
let view = View::new(doc_id, self.config().gutters.clone());
let view_id = self.tree.insert(view);
let doc = doc_mut!(self, &doc_id);
Expand Down
12 changes: 6 additions & 6 deletions helix-view/src/view.rs
Original file line number Diff line number Diff line change
Expand Up @@ -415,7 +415,7 @@ impl View {
#[cfg(test)]
mod tests {
use super::*;
use helix_core::Rope;
use helix_core::{LineEnding, Rope};
const OFFSET: u16 = 3; // 1 diagnostic + 2 linenr (< 100 lines)
const OFFSET_WITHOUT_LINE_NUMBERS: u16 = 1; // 1 diagnostic
// const OFFSET: u16 = GUTTERS.iter().map(|(_, width)| *width as u16).sum();
Expand All @@ -430,7 +430,7 @@ mod tests {
);
view.area = Rect::new(40, 40, 40, 40);
let rope = Rope::from_str("abc\n\tdef");
let doc = Document::from(rope, None);
let doc = Document::from(rope, None, LineEnding::LF);

assert_eq!(view.text_pos_at_screen_coords(&doc, 40, 2, 4), None);

Expand Down Expand Up @@ -476,7 +476,7 @@ mod tests {
let mut view = View::new(DocumentId::default(), vec![GutterType::Diagnostics]);
view.area = Rect::new(40, 40, 40, 40);
let rope = Rope::from_str("abc\n\tdef");
let doc = Document::from(rope, None);
let doc = Document::from(rope, None, LineEnding::LF);
assert_eq!(
view.text_pos_at_screen_coords(&doc, 41, 40 + OFFSET_WITHOUT_LINE_NUMBERS + 1, 4),
Some(4)
Expand All @@ -488,7 +488,7 @@ mod tests {
let mut view = View::new(DocumentId::default(), vec![]);
view.area = Rect::new(40, 40, 40, 40);
let rope = Rope::from_str("abc\n\tdef");
let doc = Document::from(rope, None);
let doc = Document::from(rope, None, LineEnding::LF);
assert_eq!(view.text_pos_at_screen_coords(&doc, 41, 40 + 1, 4), Some(4));
}

Expand All @@ -500,7 +500,7 @@ mod tests {
);
view.area = Rect::new(40, 40, 40, 40);
let rope = Rope::from_str("Hi! こんにちは皆さん");
let doc = Document::from(rope, None);
let doc = Document::from(rope, None, LineEnding::LF);

assert_eq!(
view.text_pos_at_screen_coords(&doc, 40, 40 + OFFSET, 4),
Expand Down Expand Up @@ -540,7 +540,7 @@ mod tests {
);
view.area = Rect::new(40, 40, 40, 40);
let rope = Rope::from_str("Hèl̀l̀ò world!");
let doc = Document::from(rope, None);
let doc = Document::from(rope, None, LineEnding::LF);

assert_eq!(
view.text_pos_at_screen_coords(&doc, 40, 40 + OFFSET, 4),
Expand Down

0 comments on commit 1eb7bb3

Please sign in to comment.