project_panel: Do not allow creating empty file/dir or file/dir with only whitespaces (#28240)
- Do not allow creating empty file or empty directory. - Do not allow creating file or directory with just whitespace. - Show error only in case whitespace. <img width="352" alt="image" src="https://github.com/user-attachments/assets/f6040332-59a6-4d09-bf07-2b4b1b8b9e03" /> Release Notes: - N/A
This commit is contained in:
parent
c21fdd212b
commit
7ee9109ade
2 changed files with 66 additions and 16 deletions
|
@ -1150,9 +1150,7 @@ impl ProjectPanel {
|
||||||
Some(state) => state,
|
Some(state) => state,
|
||||||
None => return,
|
None => return,
|
||||||
};
|
};
|
||||||
|
|
||||||
let filename = self.filename_editor.read(cx).text(cx);
|
let filename = self.filename_editor.read(cx).text(cx);
|
||||||
|
|
||||||
if !filename.is_empty() {
|
if !filename.is_empty() {
|
||||||
if let Some(worktree) = self
|
if let Some(worktree) = self
|
||||||
.project
|
.project
|
||||||
|
@ -1160,6 +1158,7 @@ impl ProjectPanel {
|
||||||
.worktree_for_id(edit_state.worktree_id, cx)
|
.worktree_for_id(edit_state.worktree_id, cx)
|
||||||
{
|
{
|
||||||
if let Some(entry) = worktree.read(cx).entry_for_id(edit_state.entry_id) {
|
if let Some(entry) = worktree.read(cx).entry_for_id(edit_state.entry_id) {
|
||||||
|
let mut already_exists = false;
|
||||||
if edit_state.is_new_entry() {
|
if edit_state.is_new_entry() {
|
||||||
let new_path = entry.path.join(filename.trim_start_matches('/'));
|
let new_path = entry.path.join(filename.trim_start_matches('/'));
|
||||||
if worktree
|
if worktree
|
||||||
|
@ -1167,12 +1166,7 @@ impl ProjectPanel {
|
||||||
.entry_for_path(new_path.as_path())
|
.entry_for_path(new_path.as_path())
|
||||||
.is_some()
|
.is_some()
|
||||||
{
|
{
|
||||||
edit_state.validation_state = ValidationState::Error(format!(
|
already_exists = true;
|
||||||
"File or directory '{}' already exists at location. Please choose a different name.",
|
|
||||||
filename
|
|
||||||
));
|
|
||||||
cx.notify();
|
|
||||||
return;
|
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
let new_path = if let Some(parent) = entry.path.clone().parent() {
|
let new_path = if let Some(parent) = entry.path.clone().parent() {
|
||||||
|
@ -1183,18 +1177,28 @@ impl ProjectPanel {
|
||||||
if let Some(existing) = worktree.read(cx).entry_for_path(new_path.as_path())
|
if let Some(existing) = worktree.read(cx).entry_for_path(new_path.as_path())
|
||||||
{
|
{
|
||||||
if existing.id != entry.id {
|
if existing.id != entry.id {
|
||||||
edit_state.validation_state = ValidationState::Error(
|
already_exists = true;
|
||||||
"File or directory already exists".to_string(),
|
|
||||||
);
|
|
||||||
cx.notify();
|
|
||||||
return;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
if already_exists {
|
||||||
|
edit_state.validation_state = ValidationState::Error(format!(
|
||||||
|
"File or directory '{}' already exists at location. Please choose a different name.",
|
||||||
|
filename
|
||||||
|
));
|
||||||
|
cx.notify();
|
||||||
|
return;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
let trimmed_filename = filename.trim();
|
||||||
if filename.trim() != filename {
|
if trimmed_filename.is_empty() {
|
||||||
|
edit_state.validation_state =
|
||||||
|
ValidationState::Error("File or directory name cannot be empty.".to_string());
|
||||||
|
cx.notify();
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
if trimmed_filename != filename {
|
||||||
edit_state.validation_state = ValidationState::Warning(
|
edit_state.validation_state = ValidationState::Warning(
|
||||||
"File or directory name contains leading or trailing whitespace.".to_string(),
|
"File or directory name contains leading or trailing whitespace.".to_string(),
|
||||||
);
|
);
|
||||||
|
@ -1202,7 +1206,6 @@ impl ProjectPanel {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
edit_state.validation_state = ValidationState::None;
|
edit_state.validation_state = ValidationState::None;
|
||||||
cx.notify();
|
cx.notify();
|
||||||
}
|
}
|
||||||
|
@ -1216,6 +1219,9 @@ impl ProjectPanel {
|
||||||
let worktree_id = edit_state.worktree_id;
|
let worktree_id = edit_state.worktree_id;
|
||||||
let is_new_entry = edit_state.is_new_entry();
|
let is_new_entry = edit_state.is_new_entry();
|
||||||
let filename = self.filename_editor.read(cx).text(cx);
|
let filename = self.filename_editor.read(cx).text(cx);
|
||||||
|
if filename.trim().is_empty() {
|
||||||
|
return None;
|
||||||
|
}
|
||||||
#[cfg(not(target_os = "windows"))]
|
#[cfg(not(target_os = "windows"))]
|
||||||
let filename_indicates_dir = filename.ends_with("/");
|
let filename_indicates_dir = filename.ends_with("/");
|
||||||
// On Windows, path separator could be either `/` or `\`.
|
// On Windows, path separator could be either `/` or `\`.
|
||||||
|
|
|
@ -766,6 +766,50 @@ async fn test_editing_files(cx: &mut gpui::TestAppContext) {
|
||||||
" .dockerignore",
|
" .dockerignore",
|
||||||
]
|
]
|
||||||
);
|
);
|
||||||
|
|
||||||
|
// Test empty filename and filename with only whitespace
|
||||||
|
panel.update_in(cx, |panel, window, cx| panel.new_file(&NewFile, window, cx));
|
||||||
|
assert_eq!(
|
||||||
|
visible_entries_as_strings(&panel, 0..10, cx),
|
||||||
|
&[
|
||||||
|
"v root1",
|
||||||
|
" > .git",
|
||||||
|
" > a",
|
||||||
|
" v b",
|
||||||
|
" > 3",
|
||||||
|
" > 4",
|
||||||
|
" > new-dir",
|
||||||
|
" [EDITOR: ''] <== selected",
|
||||||
|
" a-different-filename.tar.gz",
|
||||||
|
" > C",
|
||||||
|
]
|
||||||
|
);
|
||||||
|
panel.update_in(cx, |panel, window, cx| {
|
||||||
|
panel.filename_editor.update(cx, |editor, cx| {
|
||||||
|
editor.set_text("", window, cx);
|
||||||
|
});
|
||||||
|
assert!(panel.confirm_edit(window, cx).is_none());
|
||||||
|
panel.filename_editor.update(cx, |editor, cx| {
|
||||||
|
editor.set_text(" ", window, cx);
|
||||||
|
});
|
||||||
|
assert!(panel.confirm_edit(window, cx).is_none());
|
||||||
|
panel.cancel(&menu::Cancel, window, cx)
|
||||||
|
});
|
||||||
|
assert_eq!(
|
||||||
|
visible_entries_as_strings(&panel, 0..10, cx),
|
||||||
|
&[
|
||||||
|
"v root1",
|
||||||
|
" > .git",
|
||||||
|
" > a",
|
||||||
|
" v b",
|
||||||
|
" > 3",
|
||||||
|
" > 4",
|
||||||
|
" > new-dir",
|
||||||
|
" a-different-filename.tar.gz <== selected",
|
||||||
|
" > C",
|
||||||
|
" .dockerignore",
|
||||||
|
]
|
||||||
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
#[gpui::test(iterations = 10)]
|
#[gpui::test(iterations = 10)]
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue