main
1diff --git a/helix-term/src/ui/editor.rs b/helix-term/src/ui/editor.rs
2index 4f5081bf..57354e61 100644
3--- a/helix-term/src/ui/editor.rs
4+++ b/helix-term/src/ui/editor.rs
5@@ -32,7 +32,13 @@
6 keyboard::{KeyCode, KeyModifiers},
7 Document, DocumentId, Editor, Theme, View, ViewId,
8 };
9-use std::{mem::take, num::NonZeroUsize, ops, path::PathBuf, rc::Rc};
10+use std::{
11+ mem::take,
12+ num::NonZeroUsize,
13+ ops,
14+ path::{PathBuf, MAIN_SEPARATOR, MAIN_SEPARATOR_STR},
15+ rc::Rc,
16+};
17
18 use tui::{buffer::Buffer as Surface, text::Span};
19
20@@ -686,7 +692,6 @@ pub fn tabstop_highlights(doc: &Document, theme: &Theme) -> Option<OverlayHighli
21
22 /// Render bufferline at the top
23 pub fn render_bufferline(&mut self, editor: &Editor, viewport: Rect, surface: &mut Surface) {
24- let scratch = PathBuf::from(SCRATCH_BUFFER_NAME); // default filename to use for scratch buffer
25 surface.clear_with(
26 viewport,
27 editor
28@@ -711,13 +716,7 @@ pub fn render_bufferline(&mut self, editor: &Editor, viewport: Rect, surface: &m
29 self.bufferline_info.clear();
30
31 for doc in editor.documents() {
32- let fname = doc
33- .path()
34- .unwrap_or(&scratch)
35- .file_name()
36- .unwrap_or_default()
37- .to_str()
38- .unwrap_or_default();
39+ let fname = Self::make_document_name(doc, editor);
40
41 let style = if current_doc == doc.id() {
42 bufferline_active
43@@ -873,6 +872,63 @@ fn draw_element(
44 }
45 }
46
47+ fn make_document_name(doc: &Document, editor: &Editor) -> String {
48+ let scratch = PathBuf::from(SCRATCH_BUFFER_NAME); // default filename to use for scratch buffer
49+
50+ let paths: Vec<String> = editor
51+ .documents()
52+ .map(|d| {
53+ d.path()
54+ .unwrap_or(&scratch)
55+ .to_str()
56+ .unwrap_or_default()
57+ .to_string()
58+ })
59+ .collect();
60+
61+ let components: Vec<Vec<String>> = paths
62+ .iter()
63+ .map(|p| p.split(MAIN_SEPARATOR).map(String::from).collect())
64+ .collect();
65+
66+ let doc_path = doc
67+ .path()
68+ .unwrap_or(&scratch)
69+ .to_str()
70+ .unwrap_or_default()
71+ .to_string();
72+
73+ let doc_index = paths.iter().position(|p| p == &doc_path).unwrap();
74+ let doc_components_len = components[doc_index].len();
75+
76+ let mut k = 1;
77+
78+ loop {
79+ let start = doc_components_len.saturating_sub(k);
80+ let curr_doc: Vec<&str> = components[doc_index][start..]
81+ .iter()
82+ .map(|s| s.as_str())
83+ .collect();
84+
85+ let count = components
86+ .iter()
87+ .enumerate()
88+ .filter(|&(index, _)| index != doc_index)
89+ .filter(|&(_, parts)| {
90+ let len = parts.len();
91+ let start = len.saturating_sub(k);
92+ parts[start..] == curr_doc
93+ })
94+ .count();
95+
96+ if count == 0 {
97+ return curr_doc.join(MAIN_SEPARATOR_STR);
98+ }
99+
100+ k += 1;
101+ }
102+ }
103+
104 pub fn render_gutter<'d>(
105 editor: &'d Editor,
106 doc: &'d Document,