project_panel: Add warning error for leading or trailing whitespace when creating file or directory (#28215)
- Show yellow warning (instead or error) for leading/trailing whitespace. - Do not block user from creating it. - If you rename existing file/dir which contains leading/trailing whitespace, it will show error right away. <img width="250" alt="image" src="https://github.com/user-attachments/assets/562895ee-3a86-4ecd-bb38-703d1d8b8599" /> Release Notes: - Added warning for leading or trailing whitespace while renaming or creating new file or directory in Project Panel.
This commit is contained in:
parent
3b46fca64c
commit
956f359045
1 changed files with 55 additions and 23 deletions
|
@ -119,6 +119,13 @@ struct FoldedDirectoryDragTarget {
|
|||
is_delimiter_target: bool,
|
||||
}
|
||||
|
||||
#[derive(Clone, Debug)]
|
||||
enum ValidationState {
|
||||
None,
|
||||
Warning(String),
|
||||
Error(String),
|
||||
}
|
||||
|
||||
#[derive(Clone, Debug)]
|
||||
struct EditState {
|
||||
worktree_id: WorktreeId,
|
||||
|
@ -128,7 +135,7 @@ struct EditState {
|
|||
depth: usize,
|
||||
processing_filename: Option<String>,
|
||||
previously_focused: Option<SelectedEntry>,
|
||||
validation_error: bool,
|
||||
validation_state: ValidationState,
|
||||
}
|
||||
|
||||
impl EditState {
|
||||
|
@ -1143,7 +1150,9 @@ impl ProjectPanel {
|
|||
Some(state) => state,
|
||||
None => return,
|
||||
};
|
||||
|
||||
let filename = self.filename_editor.read(cx).text(cx);
|
||||
|
||||
if !filename.is_empty() {
|
||||
if let Some(worktree) = self
|
||||
.project
|
||||
|
@ -1158,7 +1167,10 @@ impl ProjectPanel {
|
|||
.entry_for_path(new_path.as_path())
|
||||
.is_some()
|
||||
{
|
||||
edit_state.validation_error = true;
|
||||
edit_state.validation_state = ValidationState::Error(format!(
|
||||
"File or directory '{}' already exists at location. Please choose a different name.",
|
||||
filename
|
||||
));
|
||||
cx.notify();
|
||||
return;
|
||||
}
|
||||
|
@ -1171,7 +1183,9 @@ impl ProjectPanel {
|
|||
if let Some(existing) = worktree.read(cx).entry_for_path(new_path.as_path())
|
||||
{
|
||||
if existing.id != entry.id {
|
||||
edit_state.validation_error = true;
|
||||
edit_state.validation_state = ValidationState::Error(
|
||||
"File or directory already exists".to_string(),
|
||||
);
|
||||
cx.notify();
|
||||
return;
|
||||
}
|
||||
|
@ -1179,8 +1193,17 @@ impl ProjectPanel {
|
|||
};
|
||||
}
|
||||
}
|
||||
|
||||
if filename.trim() != filename {
|
||||
edit_state.validation_state = ValidationState::Warning(
|
||||
"File or directory name contains leading or trailing whitespace.".to_string(),
|
||||
);
|
||||
cx.notify();
|
||||
return;
|
||||
}
|
||||
}
|
||||
edit_state.validation_error = false;
|
||||
|
||||
edit_state.validation_state = ValidationState::None;
|
||||
cx.notify();
|
||||
}
|
||||
|
||||
|
@ -1403,7 +1426,7 @@ impl ProjectPanel {
|
|||
processing_filename: None,
|
||||
previously_focused: self.selection,
|
||||
depth: 0,
|
||||
validation_error: false,
|
||||
validation_state: ValidationState::None,
|
||||
});
|
||||
self.filename_editor.update(cx, |editor, cx| {
|
||||
editor.clear(window, cx);
|
||||
|
@ -1453,7 +1476,7 @@ impl ProjectPanel {
|
|||
processing_filename: None,
|
||||
previously_focused: None,
|
||||
depth: 0,
|
||||
validation_error: false,
|
||||
validation_state: ValidationState::None,
|
||||
});
|
||||
let file_name = entry
|
||||
.path
|
||||
|
@ -3687,15 +3710,25 @@ impl ProjectPanel {
|
|||
item_colors.hover
|
||||
};
|
||||
|
||||
let validation_error =
|
||||
show_editor && self.edit_state.as_ref().is_some_and(|e| e.validation_error);
|
||||
let validation_color_and_message = if show_editor {
|
||||
match self
|
||||
.edit_state
|
||||
.as_ref()
|
||||
.map_or(ValidationState::None, |e| e.validation_state.clone())
|
||||
{
|
||||
ValidationState::Error(msg) => Some((Color::Error.color(cx), msg.clone())),
|
||||
ValidationState::Warning(msg) => Some((Color::Warning.color(cx), msg.clone())),
|
||||
ValidationState::None => None,
|
||||
}
|
||||
} else {
|
||||
None
|
||||
};
|
||||
|
||||
let border_color =
|
||||
if !self.mouse_down && is_active && self.focus_handle.contains_focused(window, cx) {
|
||||
if validation_error {
|
||||
Color::Error.color(cx)
|
||||
} else {
|
||||
item_colors.focused
|
||||
match validation_color_and_message {
|
||||
Some((color, _)) => color,
|
||||
None => item_colors.focused,
|
||||
}
|
||||
} else {
|
||||
bg_color
|
||||
|
@ -3703,10 +3736,9 @@ impl ProjectPanel {
|
|||
|
||||
let border_hover_color =
|
||||
if !self.mouse_down && is_active && self.focus_handle.contains_focused(window, cx) {
|
||||
if validation_error {
|
||||
Color::Error.color(cx)
|
||||
} else {
|
||||
item_colors.focused
|
||||
match validation_color_and_message {
|
||||
Some((color, _)) => color,
|
||||
None => item_colors.focused,
|
||||
}
|
||||
} else {
|
||||
bg_hover_color
|
||||
|
@ -4177,9 +4209,10 @@ impl ProjectPanel {
|
|||
))
|
||||
.overflow_x(),
|
||||
)
|
||||
.when(
|
||||
validation_error, |this| {
|
||||
this
|
||||
.when_some(
|
||||
validation_color_and_message,
|
||||
|this, (color, message)| {
|
||||
this
|
||||
.relative()
|
||||
.child(
|
||||
deferred(
|
||||
|
@ -4192,13 +4225,12 @@ impl ProjectPanel {
|
|||
.py_1()
|
||||
.px_2()
|
||||
.border_1()
|
||||
.border_color(Color::Error.color(cx))
|
||||
.border_color(color)
|
||||
.bg(cx.theme().colors().background)
|
||||
.child(
|
||||
Label::new(format!("{} already exists", self.filename_editor.read(cx).text(cx)))
|
||||
.color(Color::Error)
|
||||
Label::new(message)
|
||||
.color(Color::from(color))
|
||||
.size(LabelSize::Small)
|
||||
.truncate()
|
||||
)
|
||||
)
|
||||
)
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue