window: Add user-defined project name overrides.

This commit is contained in:
Vincent Piquet 2025-08-21 20:20:18 +02:00
parent 81cb24810b
commit c825d02998
4 changed files with 47 additions and 11 deletions

View file

@ -1,4 +1,5 @@
{
"project_name": null,
// The name of the Zed theme to use for the UI.
//
// `mode` is one of:

View file

@ -28,10 +28,13 @@ use gpui::{
Subscription, WeakEntity, Window, actions, div,
};
use onboarding_banner::OnboardingBanner;
use project::Project;
use settings::Settings as _;
use project::{Project, WorktreeSettings};
use settings::{Settings, SettingsLocation};
use settings_ui::keybindings;
use std::sync::Arc;
use std::{
path::Path,
sync::Arc,
};
use theme::ActiveTheme;
use title_bar_settings::TitleBarSettings;
use ui::{
@ -425,14 +428,24 @@ impl TitleBar {
}
pub fn render_project_name(&self, cx: &mut Context<Self>) -> impl IntoElement {
let name = {
let mut names = self.project.read(cx).visible_worktrees(cx).map(|worktree| {
let name = self
.project
.read(cx)
.visible_worktrees(cx)
.map(|worktree| {
let worktree = worktree.read(cx);
worktree.root_name()
});
let settings_location = SettingsLocation {
worktree_id: worktree.id(),
path: Path::new(""),
};
names.next()
};
let settings = WorktreeSettings::get(Some(settings_location), cx);
match &settings.project_name {
Some(name) => name.as_str(),
None => worktree.root_name(),
}
})
.next();
let is_project_selected = name.is_some();
let name = if let Some(name) = name {
util::truncate_and_trailoff(name, MAX_PROJECT_NAME_LENGTH)

View file

@ -72,13 +72,14 @@ pub use persistence::{
use postage::stream::Stream;
use project::{
DirectoryLister, Project, ProjectEntryId, ProjectPath, ResolvedPath, Worktree, WorktreeId,
WorktreeSettings,
debugger::{breakpoint_store::BreakpointStoreEvent, session::ThreadStatus},
};
use remote::{SshClientDelegate, SshConnectionOptions, ssh_session::ConnectionIdentifier};
use schemars::JsonSchema;
use serde::Deserialize;
use session::AppSession;
use settings::{Settings, update_settings_file};
use settings::{Settings, SettingsLocation, update_settings_file};
use shared_screen::SharedScreen;
use sqlez::{
bindable::{Bind, Column, StaticColumnCount},
@ -4346,7 +4347,19 @@ impl Workspace {
let project = self.project().read(cx);
let mut title = String::new();
for (i, name) in project.worktree_root_names(cx).enumerate() {
for (i, worktree) in project.worktrees(cx).enumerate() {
let name = {
let settings_location = SettingsLocation {
worktree_id: worktree.read(cx).id(),
path: Path::new(""),
};
let settings = WorktreeSettings::get(Some(settings_location), cx);
match &settings.project_name {
Some(name) => name.as_str(),
None => worktree.read(cx).root_name(),
}
};
if i > 0 {
title.push_str(", ");
}

View file

@ -9,6 +9,7 @@ use util::paths::PathMatcher;
#[derive(Clone, PartialEq, Eq)]
pub struct WorktreeSettings {
pub project_name: Option<String>,
pub file_scan_inclusions: PathMatcher,
pub file_scan_exclusions: PathMatcher,
pub private_files: PathMatcher,
@ -33,6 +34,13 @@ impl WorktreeSettings {
#[derive(Clone, Default, Serialize, Deserialize, JsonSchema)]
pub struct WorktreeSettingsContent {
/// The displayed name of this project. If not set, the root directory name
/// will be displayed.
///
/// Default: none
#[serde(default)]
pub project_name: Option<String>,
/// Completely ignore files matching globs from `file_scan_exclusions`. Overrides
/// `file_scan_inclusions`.
///
@ -94,6 +102,7 @@ impl Settings for WorktreeSettings {
&parsed_file_scan_inclusions,
"file_scan_inclusions",
)?,
project_name: result.project_name,
})
}