aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--book/src/configuration.md1
-rw-r--r--helix-term/src/ui/editor.rs78
-rw-r--r--helix-view/src/editor.rs21
3 files changed, 97 insertions, 3 deletions
diff --git a/book/src/configuration.md b/book/src/configuration.md
index affd497c..fdabe768 100644
--- a/book/src/configuration.md
+++ b/book/src/configuration.md
@@ -49,6 +49,7 @@ You may also specify a file to use for configuration with the `-c` or
| `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
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();
diff --git a/helix-view/src/editor.rs b/helix-view/src/editor.rs
index ed1813b3..65e64b16 100644
--- a/helix-view/src/editor.rs
+++ b/helix-view/src/editor.rs
@@ -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 @@ impl Default for CursorShapeConfig {
}
}
+/// 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 @@ impl Default for Config {
terminal: get_terminal_provider(),
rulers: Vec::new(),
whitespace: WhitespaceConfig::default(),
+ bufferline: BufferLine::default(),
indent_guides: IndentGuidesConfig::default(),
color_modes: false,
}