From e8730ca5fd72e3bb275b4d825de40475eabea174 Mon Sep 17 00:00:00 2001 From: aaron404 Date: Thu, 1 Sep 2022 22:39:38 -0400 Subject: initial implementation of bufferline (#2759) * initial implementation of bufferline * fixed lint * changed to 'bufferline', added enum for config modes, some cleanup * fixed lint * added file modification indicator * removed redundant code, added proper themeing with fallback, changed 'file modified' indicator * remove commented code * Update helix-term/src/ui/editor.rs simplify text and offset computation Co-authored-by: Gokul Soumya * add ui.bufferline.background key for themes Co-authored-by: lazytanuki <43273245+lazytanuki@users.noreply.github.com> * address PR comments * Update helix-term/src/ui/editor.rs * simplify computation of editor area: * change to set_stringn to avoid overflow * Update configuration.md Updates documentation to reflect decision re: defaulting to never showing bufferline. * addressed pr comments * fix build error * address pr comments * revert accidental change Co-authored-by: Gokul Soumya Co-authored-by: lazytanuki <43273245+lazytanuki@users.noreply.github.com> Co-authored-by: Seth Bromberger --- helix-term/src/ui/editor.rs | 78 +++++++++++++++++++++++++++++++++++++++++++-- 1 file changed, 75 insertions(+), 3 deletions(-) (limited to 'helix-term') diff --git a/helix-term/src/ui/editor.rs b/helix-term/src/ui/editor.rs index fa437a7e..d0def9ba 100644 --- a/helix-term/src/ui/editor.rs +++ b/helix-term/src/ui/editor.rs @@ -16,14 +16,14 @@ use helix_core::{ LineEnding, Position, Range, Selection, Transaction, }; use helix_view::{ - document::Mode, + document::{Mode, SCRATCH_BUFFER_NAME}, editor::{CompleteAction, CursorShapeConfig}, graphics::{Color, CursorKind, Modifier, Rect, Style}, input::{KeyEvent, MouseButton, MouseEvent, MouseEventKind}, keyboard::{KeyCode, KeyModifiers}, Document, Editor, Theme, View, }; -use std::borrow::Cow; +use std::{borrow::Cow, path::PathBuf}; use tui::buffer::Buffer as Surface; @@ -619,6 +619,59 @@ impl EditorView { } } + /// Render bufferline at the top + pub fn render_bufferline(editor: &Editor, viewport: Rect, surface: &mut Surface) { + let scratch = PathBuf::from(SCRATCH_BUFFER_NAME); // default filename to use for scratch buffer + surface.clear_with( + viewport, + editor + .theme + .try_get("ui.bufferline.background") + .unwrap_or_else(|| editor.theme.get("ui.statusline")), + ); + + let bufferline_active = editor + .theme + .try_get("ui.bufferline.active") + .unwrap_or_else(|| editor.theme.get("ui.statusline.active")); + + let bufferline_inactive = editor + .theme + .try_get("ui.bufferline") + .unwrap_or_else(|| editor.theme.get("ui.statusline.inactive")); + + let mut x = viewport.x; + let current_doc = view!(editor).doc; + + for doc in editor.documents() { + let fname = doc + .path() + .unwrap_or(&scratch) + .file_name() + .unwrap_or_default() + .to_str() + .unwrap_or_default(); + + let style = if current_doc == doc.id() { + bufferline_active + } else { + bufferline_inactive + }; + + let text = format!(" {}{} ", fname, if doc.is_modified() { "[+]" } else { "" }); + let used_width = viewport.x.saturating_sub(x); + let rem_width = surface.area.width.saturating_sub(used_width); + + x = surface + .set_stringn(x, viewport.y, text, rem_width as usize, style) + .0; + + if x >= surface.area.right() { + break; + } + } + } + pub fn render_gutter( editor: &Editor, doc: &Document, @@ -1291,8 +1344,27 @@ impl Component for EditorView { // clear with background color surface.set_style(area, cx.editor.theme.get("ui.background")); let config = cx.editor.config(); + + // check if bufferline should be rendered + use helix_view::editor::BufferLine; + let use_bufferline = match config.bufferline { + BufferLine::Always => true, + BufferLine::Multiple if cx.editor.documents.len() > 1 => true, + _ => false, + }; + + // -1 for commandline and -1 for bufferline + let mut editor_area = area.clip_bottom(1); + if use_bufferline { + editor_area = editor_area.clip_top(1); + } + // if the terminal size suddenly changed, we need to trigger a resize - cx.editor.resize(area.clip_bottom(1)); // -1 from bottom for commandline + cx.editor.resize(editor_area); + + if use_bufferline { + Self::render_bufferline(cx.editor, area.with_height(1), surface); + } for (view, is_focused) in cx.editor.tree.views() { let doc = cx.editor.document(view.doc).unwrap(); -- cgit v1.2.3-70-g09d2