diff options
Diffstat (limited to 'helix-view')
-rw-r--r-- | helix-view/src/document.rs | 35 | ||||
-rw-r--r-- | helix-view/src/editor.rs | 13 | ||||
-rw-r--r-- | helix-view/src/view.rs | 14 |
3 files changed, 26 insertions, 36 deletions
diff --git a/helix-view/src/document.rs b/helix-view/src/document.rs index c751785d..84de4c43 100644 --- a/helix-view/src/document.rs +++ b/helix-view/src/document.rs @@ -306,19 +306,6 @@ pub async fn to_writer<'a, W: tokio::io::AsyncWriteExt + Unpin + ?Sized>( Ok(()) } -/// Inserts the final line ending into `rope` if it's missing. [Why?](https://stackoverflow.com/questions/729692/why-should-text-files-end-with-a-newline) -pub fn with_line_ending(rope: &mut Rope) -> LineEnding { - // search for line endings - let line_ending = auto_detect_line_ending(rope).unwrap_or(DEFAULT_LINE_ENDING); - - // add missing newline at the end of file - if rope.len_bytes() == 0 || !char_is_line_ending(rope.char(rope.len_chars() - 1)) { - rope.insert(rope.len_chars(), line_ending.as_str()); - } - - line_ending -} - /// Like std::mem::replace() except it allows the replacement value to be mapped from the /// original value. fn take_with<T, F>(mut_ref: &mut T, closure: F) @@ -456,7 +443,7 @@ impl Document { theme: Option<&Theme>, config_loader: Option<&syntax::Loader>, ) -> Result<Self, Error> { - let (mut rope, encoding) = if path.exists() { + let (rope, encoding) = if path.exists() { let mut file = std::fs::File::open(&path).context(format!("unable to open {:?}", path))?; from_reader(&mut file, encoding)? @@ -465,7 +452,6 @@ impl Document { (Rope::from(DEFAULT_LINE_ENDING.as_str()), encoding) }; - let line_ending = with_line_ending(&mut rope); let mut doc = Self::from(rope, Some(encoding)); // set the path and try detecting the language @@ -474,9 +460,9 @@ impl Document { doc.detect_language(theme, loader); } - // Detect indentation style and set line ending. + // Detect indentation style and line ending. doc.detect_indent_style(); - doc.line_ending = line_ending; + doc.line_ending = auto_detect_line_ending(&doc.text).unwrap_or(DEFAULT_LINE_ENDING); Ok(doc) } @@ -605,17 +591,16 @@ impl Document { } let mut file = std::fs::File::open(path.unwrap())?; - let (mut rope, ..) = from_reader(&mut file, Some(encoding))?; - let line_ending = with_line_ending(&mut rope); + let (rope, ..) = from_reader(&mut file, Some(encoding))?; let transaction = helix_core::diff::compare_ropes(self.text(), &rope); self.apply(&transaction, view_id); self.append_changes_to_history(view_id); self.reset_modified(); - // Detect indentation style and set line ending. + // Detect indentation style and line ending. self.detect_indent_style(); - self.line_ending = line_ending; + self.line_ending = auto_detect_line_ending(&self.text).unwrap_or(DEFAULT_LINE_ENDING); Ok(()) } @@ -1089,7 +1074,7 @@ impl Document { impl Default for Document { fn default() -> Self { - let text = Rope::from(DEFAULT_LINE_ENDING.as_str()); + let text = Rope::from(""); Self::from(text, None) } } @@ -1214,11 +1199,7 @@ mod test { #[test] fn test_line_ending() { - if cfg!(windows) { - assert_eq!(Document::default().text().to_string(), "\r\n"); - } else { - assert_eq!(Document::default().text().to_string(), "\n"); - } + assert_eq!(Document::default().text().to_string(), ""); } macro_rules! test_decode { diff --git a/helix-view/src/editor.rs b/helix-view/src/editor.rs index 7ff689df..7e8548e7 100644 --- a/helix-view/src/editor.rs +++ b/helix-view/src/editor.rs @@ -138,12 +138,14 @@ impl Editor { let (view, doc) = current!(self); // initialize selection for view - let selection = doc - .selections + doc.selections .entry(view.id) .or_insert_with(|| Selection::point(0)); // TODO: reuse align_view - let pos = selection.cursor(); + let pos = doc + .selection(view.id) + .primary() + .cursor(doc.text().slice(..)); let line = doc.text().char_to_line(pos); view.first_line = line.saturating_sub(view.area.height as usize / 2); @@ -293,7 +295,10 @@ impl Editor { const OFFSET: u16 = 7; // 1 diagnostic + 5 linenr + 1 gutter let view = view!(self); let doc = &self.documents[view.doc]; - let cursor = doc.selection(view.id).cursor(); + let cursor = doc + .selection(view.id) + .primary() + .cursor(doc.text().slice(..)); if let Some(mut pos) = view.screen_coords_at_pos(doc, doc.text().slice(..), cursor) { pos.col += view.area.x as usize + OFFSET as usize; pos.row += view.area.y as usize; diff --git a/helix-view/src/view.rs b/helix-view/src/view.rs index 24df7a4f..6b0c3c2a 100644 --- a/helix-view/src/view.rs +++ b/helix-view/src/view.rs @@ -84,18 +84,21 @@ impl View { } pub fn ensure_cursor_in_view(&mut self, doc: &Document) { - let cursor = doc.selection(self.id).cursor(); + let cursor = doc + .selection(self.id) + .primary() + .cursor(doc.text().slice(..)); let pos = coords_at_pos(doc.text().slice(..), cursor); let line = pos.row; let col = pos.col; let height = self.area.height.saturating_sub(1); // - 1 for statusline - let last_line = self.first_line + height as usize; + let last_line = (self.first_line + height as usize).saturating_sub(1); let scrolloff = PADDING.min(self.area.height as usize / 2); // TODO: user pref // TODO: not ideal const OFFSET: usize = 7; // 1 diagnostic + 5 linenr + 1 gutter - let last_col = self.first_col + (self.area.width as usize - OFFSET); + let last_col = (self.first_col + self.area.width as usize).saturating_sub(OFFSET + 1); if line > last_line.saturating_sub(scrolloff) { // scroll down @@ -119,8 +122,9 @@ impl View { pub fn last_line(&self, doc: &Document) -> usize { let height = self.area.height.saturating_sub(1); // - 1 for statusline std::cmp::min( - self.first_line + height as usize, - doc.text().len_lines() - 1, + // Saturating subs to make it inclusive zero indexing. + (self.first_line + height as usize).saturating_sub(1), + doc.text().len_lines().saturating_sub(1), ) } |