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 <gokulps15@gmail.com> * 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 <gokulps15@gmail.com> Co-authored-by: lazytanuki <43273245+lazytanuki@users.noreply.github.com> Co-authored-by: Seth Bromberger <sbromberger@users.noreply.github.com>
This commit is contained in:
parent
04a4033b6c
commit
e8730ca5fd
@ -49,6 +49,7 @@ ### `[editor]` Section
|
||||
| `auto-info` | Whether to display infoboxes | `true` |
|
||||
| `true-color` | Set to `true` to override automatic detection of terminal truecolor support in the event of a false negative. | `false` |
|
||||
| `rulers` | List of column positions at which to display the rulers. Can be overridden by language specific `rulers` in `languages.toml` file. | `[]` |
|
||||
| `bufferline` | Renders a line at the top of the editor displaying open buffers. Can be `always`, `never` or `multiple` (only shown if more than one buffer is in use) | `never` |
|
||||
| `color-modes` | Whether to color the mode indicator with different colors depending on the mode itself | `false` |
|
||||
|
||||
### `[editor.statusline]` Section
|
||||
|
@ -16,14 +16,14 @@
|
||||
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 @@ pub fn render_focused_view_elements(
|
||||
}
|
||||
}
|
||||
|
||||
/// 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 @@ fn render(&mut self, area: Rect, surface: &mut Surface, cx: &mut Context) {
|
||||
// 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();
|
||||
|
@ -162,6 +162,8 @@ pub struct Config {
|
||||
pub rulers: Vec<u16>,
|
||||
#[serde(default)]
|
||||
pub whitespace: WhitespaceConfig,
|
||||
/// Persistently display open buffers along the top
|
||||
pub bufferline: BufferLine,
|
||||
/// Vertical indent width guides.
|
||||
pub indent_guides: IndentGuidesConfig,
|
||||
/// Whether to color modes with different colors. Defaults to `false`.
|
||||
@ -367,6 +369,24 @@ fn default() -> Self {
|
||||
}
|
||||
}
|
||||
|
||||
/// bufferline render modes
|
||||
#[derive(Debug, Clone, PartialEq, Eq, Serialize, Deserialize)]
|
||||
#[serde(rename_all = "kebab-case")]
|
||||
pub enum BufferLine {
|
||||
/// Don't render bufferline
|
||||
Never,
|
||||
/// Always render
|
||||
Always,
|
||||
/// Only if multiple buffers are open
|
||||
Multiple,
|
||||
}
|
||||
|
||||
impl Default for BufferLine {
|
||||
fn default() -> Self {
|
||||
BufferLine::Never
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(Debug, Copy, Clone, PartialEq, Eq, Serialize, Deserialize)]
|
||||
#[serde(rename_all = "kebab-case")]
|
||||
pub enum LineNumber {
|
||||
@ -554,6 +574,7 @@ fn default() -> Self {
|
||||
terminal: get_terminal_provider(),
|
||||
rulers: Vec::new(),
|
||||
whitespace: WhitespaceConfig::default(),
|
||||
bufferline: BufferLine::default(),
|
||||
indent_guides: IndentGuidesConfig::default(),
|
||||
color_modes: false,
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user