main
1diff --git a/helix-term/src/ui/editor.rs b/helix-term/src/ui/editor.rs
2index 05cf7769..4f5081bf 100644
3--- a/helix-term/src/ui/editor.rs
4+++ b/helix-term/src/ui/editor.rs
5@@ -43,6 +43,7 @@ pub struct EditorView {
6 pub(crate) last_insert: (commands::MappableCommand, Vec<InsertEvent>),
7 pub(crate) completion: Option<Completion>,
8 spinners: ProgressSpinners,
9+ bufferline_info: BufferLineInfo,
10 /// Tracks if the terminal window is focused by reaction to terminal focus events
11 terminal_focused: bool,
12 }
13@@ -67,6 +68,7 @@ pub fn new(keymaps: Keymaps) -> Self {
14 last_insert: (commands::MappableCommand::normal_mode, Vec::new()),
15 completion: None,
16 spinners: ProgressSpinners::default(),
17+ bufferline_info: BufferLineInfo::default(),
18 terminal_focused: true,
19 }
20 }
21@@ -683,7 +685,7 @@ pub fn tabstop_highlights(doc: &Document, theme: &Theme) -> Option<OverlayHighli
22 }
23
24 /// Render bufferline at the top
25- pub fn render_bufferline(editor: &Editor, viewport: Rect, surface: &mut Surface) {
26+ pub fn render_bufferline(&mut self, editor: &Editor, viewport: Rect, surface: &mut Surface) {
27 let scratch = PathBuf::from(SCRATCH_BUFFER_NAME); // default filename to use for scratch buffer
28 surface.clear_with(
29 viewport,
30@@ -706,6 +708,8 @@ pub fn render_bufferline(editor: &Editor, viewport: Rect, surface: &mut Surface)
31 let mut x = viewport.x;
32 let current_doc = view!(editor).doc;
33
34+ self.bufferline_info.clear();
35+
36 for doc in editor.documents() {
37 let fname = doc
38 .path()
39@@ -725,9 +729,14 @@ pub fn render_bufferline(editor: &Editor, viewport: Rect, surface: &mut Surface)
40 let used_width = viewport.x.saturating_sub(x);
41 let rem_width = surface.area.width.saturating_sub(used_width);
42
43+ let start_x = x;
44 x = surface
45 .set_stringn(x, viewport.y, &text, rem_width as usize, style)
46 .0;
47+ let end_x = x.min(surface.area.right());
48+
49+ self.bufferline_info
50+ .add_buffer_info(doc.id(), start_x..end_x);
51
52 if x >= surface.area.right() {
53 break;
54@@ -1396,6 +1405,14 @@ fn handle_mouse_event(
55 MouseEventKind::Down(MouseButton::Left) => {
56 let editor = &mut cxt.editor;
57
58+ if is_bufferline_visible(editor) && row == 0 {
59+ if let Some(buffer_info) = self.bufferline_info.get_clicked_buffer(column) {
60+ editor.switch(buffer_info.document_id, helix_view::editor::Action::Replace);
61+ }
62+
63+ return EventResult::Consumed(None);
64+ }
65+
66 if let Some((pos, view_id)) = pos_and_view(editor, row, column, true) {
67 editor.focus(view_id);
68
69@@ -1778,12 +1795,7 @@ fn render(&mut self, area: Rect, surface: &mut Surface, cx: &mut Context) {
70 surface.set_style(area, cx.editor.theme.get("ui.background"));
71 let config = cx.editor.config();
72
73- // check if bufferline should be rendered
74- let use_bufferline = match config.bufferline {
75- BufferLine::Always => true,
76- BufferLine::Multiple if cx.editor.documents.len() > 1 => true,
77- _ => false,
78- };
79+ let use_bufferline = is_bufferline_visible(cx.editor);
80
81 let mut area = area;
82
83@@ -1811,7 +1823,7 @@ fn render(&mut self, area: Rect, surface: &mut Surface, cx: &mut Context) {
84 cx.editor.resize(editor_area);
85
86 if use_bufferline {
87- Self::render_bufferline(cx.editor, area.with_height(1), surface);
88+ self.render_bufferline(cx.editor, area.with_height(1), surface);
89 }
90
91 let views: Vec<(ViewId, bool)> = {
92@@ -1936,6 +1948,47 @@ fn cursor(&self, _area: Rect, editor: &Editor) -> (Option<Position>, CursorKind)
93 }
94 }
95
96+#[derive(Debug, Default)]
97+struct BufferLineInfo {
98+ visible_buffers: Vec<BufferInfo>,
99+}
100+
101+impl BufferLineInfo {
102+ fn clear(&mut self) {
103+ self.visible_buffers.clear();
104+ }
105+
106+ fn add_buffer_info(&mut self, document_id: DocumentId, columns: std::ops::Range<u16>) {
107+ self.visible_buffers.push(BufferInfo {
108+ document_id,
109+ columns,
110+ });
111+ }
112+
113+ fn get_clicked_buffer(&self, column: u16) -> Option<&BufferInfo> {
114+ self.visible_buffers
115+ .iter()
116+ .find(|cell| cell.columns.contains(&column))
117+ }
118+}
119+
120+#[derive(Debug)]
121+struct BufferInfo {
122+ document_id: DocumentId,
123+ // The bufferline column span used to show the document name
124+ columns: std::ops::Range<u16>,
125+}
126+
127+fn is_bufferline_visible(editor: &Editor) -> bool {
128+ let config = editor.config();
129+
130+ match config.bufferline {
131+ BufferLine::Always => true,
132+ BufferLine::Multiple => editor.documents.len() > 1,
133+ BufferLine::Never => false,
134+ }
135+}
136+
137 fn canonicalize_key(key: &mut KeyEvent) {
138 if let KeyEvent {
139 code: KeyCode::Char(_),