Coalesce consecutive spaces in new buffer tab titles (#32363)
VS Code has a behavior where it coalesces consecutive spaces in new buffer tab titles, which I quite like. This presents the content better and allows more meaningful content to be displayed, as consecutive spaces don't count towards the 40 character limit. VS Code <img width="1013" alt="SCR-20250608-uelt" src="https://github.com/user-attachments/assets/71a1fd4b-a506-4eab-b6a4-66096a12f1ad" /> Zed <img width="1136" alt="SCR-20250608-ueif" src="https://github.com/user-attachments/assets/f40fc3c9-0f0f-471d-93ed-be9568fbe778" /> Release Notes: - N/A
This commit is contained in:
parent
4fe05530b0
commit
ebea734515
3 changed files with 63 additions and 22 deletions
|
@ -18858,7 +18858,7 @@ impl Editor {
|
||||||
cx.emit(EditorEvent::BufferEdited);
|
cx.emit(EditorEvent::BufferEdited);
|
||||||
cx.emit(SearchEvent::MatchesInvalidated);
|
cx.emit(SearchEvent::MatchesInvalidated);
|
||||||
if *singleton_buffer_edited {
|
if *singleton_buffer_edited {
|
||||||
if let Some(buffer) = multibuffer.read(cx).as_singleton() {
|
if let Some(buffer) = edited_buffer {
|
||||||
if buffer.read(cx).file().is_none() {
|
if buffer.read(cx).file().is_none() {
|
||||||
cx.emit(EditorEvent::TitleChanged);
|
cx.emit(EditorEvent::TitleChanged);
|
||||||
}
|
}
|
||||||
|
|
|
@ -2600,27 +2600,58 @@ impl MultiBuffer {
|
||||||
return title.into();
|
return title.into();
|
||||||
}
|
}
|
||||||
|
|
||||||
self.as_singleton()
|
if let Some(buffer) = self.as_singleton() {
|
||||||
.and_then(|buffer| {
|
|
||||||
let buffer = buffer.read(cx);
|
let buffer = buffer.read(cx);
|
||||||
|
|
||||||
if let Some(file) = buffer.file() {
|
if let Some(file) = buffer.file() {
|
||||||
return Some(file.file_name(cx).to_string_lossy());
|
return file.file_name(cx).to_string_lossy();
|
||||||
}
|
}
|
||||||
|
|
||||||
let title = buffer
|
if let Some(title) = self.buffer_based_title(buffer) {
|
||||||
.snapshot()
|
return title;
|
||||||
.chars()
|
}
|
||||||
.skip_while(|ch| ch.is_whitespace())
|
};
|
||||||
.take_while(|&ch| ch != '\n')
|
|
||||||
.take(40)
|
|
||||||
.collect::<String>()
|
|
||||||
.trim_end()
|
|
||||||
.to_string();
|
|
||||||
|
|
||||||
(!title.is_empty()).then(|| title.into())
|
"untitled".into()
|
||||||
})
|
}
|
||||||
.unwrap_or("untitled".into())
|
|
||||||
|
fn buffer_based_title(&self, buffer: &Buffer) -> Option<Cow<str>> {
|
||||||
|
let mut is_leading_whitespace = true;
|
||||||
|
let mut count = 0;
|
||||||
|
let mut prev_was_space = false;
|
||||||
|
let mut title = String::new();
|
||||||
|
|
||||||
|
for ch in buffer.snapshot().chars() {
|
||||||
|
if is_leading_whitespace && ch.is_whitespace() {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
is_leading_whitespace = false;
|
||||||
|
|
||||||
|
if ch == '\n' || count >= 40 {
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
if ch.is_whitespace() {
|
||||||
|
if !prev_was_space {
|
||||||
|
title.push(' ');
|
||||||
|
count += 1;
|
||||||
|
prev_was_space = true;
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
title.push(ch);
|
||||||
|
count += 1;
|
||||||
|
prev_was_space = false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
let title = title.trim_end().to_string();
|
||||||
|
|
||||||
|
if !title.is_empty() {
|
||||||
|
return Some(title.into());
|
||||||
|
}
|
||||||
|
|
||||||
|
None
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn set_title(&mut self, title: String, cx: &mut Context<Self>) {
|
pub fn set_title(&mut self, title: String, cx: &mut Context<Self>) {
|
||||||
|
|
|
@ -3686,10 +3686,20 @@ fn test_new_empty_buffer_takes_trimmed_first_line_for_title(cx: &mut App) {
|
||||||
|
|
||||||
#[gpui::test]
|
#[gpui::test]
|
||||||
fn test_new_empty_buffer_uses_truncated_first_line_for_title(cx: &mut App) {
|
fn test_new_empty_buffer_uses_truncated_first_line_for_title(cx: &mut App) {
|
||||||
let title_after = ["a", "b", "c", "d"]
|
let title = "aaaaaaaaaabbbbbbbbbbccccccccccddddddddddeeeeeeeeee";
|
||||||
.map(|letter| letter.repeat(10))
|
let title_after = "aaaaaaaaaabbbbbbbbbbccccccccccdddddddddd";
|
||||||
.join("");
|
let buffer = cx.new(|cx| Buffer::local(title, cx));
|
||||||
let title = format!("{}{}", title_after, "e".repeat(10));
|
let multibuffer = cx.new(|cx| MultiBuffer::singleton(buffer.clone(), cx));
|
||||||
|
|
||||||
|
assert_eq!(multibuffer.read(cx).title(cx), title_after);
|
||||||
|
}
|
||||||
|
|
||||||
|
#[gpui::test]
|
||||||
|
fn test_new_empty_buffer_uses_truncated_first_line_for_title_after_merging_adjacent_spaces(
|
||||||
|
cx: &mut App,
|
||||||
|
) {
|
||||||
|
let title = "aaaaaaaaaabbbbbbbbbb ccccccccccddddddddddeeeeeeeeee";
|
||||||
|
let title_after = "aaaaaaaaaabbbbbbbbbb ccccccccccddddddddd";
|
||||||
let buffer = cx.new(|cx| Buffer::local(title, cx));
|
let buffer = cx.new(|cx| Buffer::local(title, cx));
|
||||||
let multibuffer = cx.new(|cx| MultiBuffer::singleton(buffer.clone(), cx));
|
let multibuffer = cx.new(|cx| MultiBuffer::singleton(buffer.clone(), cx));
|
||||||
|
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue