Repository navigation
feat(folders): create a new folder while picking one to open - #881
Merged
Merged
Conversation
Starting a project in an empty folder meant leaving codeg to make the folder first: the Open folder dialog could only pick a directory that already existed, and in web mode there was no other way to make one on the server at all. The dialog's directory browser now has a New folder button beside Home and Up. It opens a name box at the top of the listing; Enter creates the folder in the directory being listed, and the browser moves into it, so Next opens it as the workspace. Escape or the X cancels without closing the dialog. A rejected name is explained under the box, which keeps what was typed. DirectoryBrowser takes this as an opt-in allowCreateFolder prop, so the other pickers that embed it are unchanged. The folder is made by create_directory_core, shared by the Tauri command and POST /api/create_directory. It trims the name and rejects empty names, "." and "..", path separators and control characters (plus the names and characters Windows reserves, on Windows), needs an absolute, existing parent, creates exactly one directory, and reports an existing entry of that name, symlinks included, instead of reusing or following it. Errors are a thiserror enum mapped onto the existing error codes (400/404/409/403/500) with i18n keys, translated in all ten locales. The native folder picker now asks for canCreateDirectories, the macOS panel's own New Folder button. tauri-plugin-dialog already defaults it to on; this keeps it on.
…ated Escape closed the row even while its request was running, though the X is disabled then. Closing it cleared the busy flag, so the dialog's Next came back mid-request; a failure that landed afterwards was dropped without a word, and a success still moved the browser into the folder the user had just cancelled. Escape now does what the X does: while the folder is being created it is still claimed, so the dialog stays open, but it cancels nothing. The listener moves into the row, so it reads the IME guard spread on the name box instead of the path box's.
Windows reads the superscript digits ¹ ² ³ as port numbers, so COM¹ to COM³ and LPT¹ to LPT³ are device names reserved in every directory, like COM1 and LPT1. Reject them with the other device names.
Home, Up and Enter in the path box stayed live during the create request. Moving closed the row, which cleared the busy flag, so the dialog's Next came back mid-request; a failure that landed afterwards was dropped, and a success pulled the browser into the new folder over wherever the user had gone. They now wait for the request, like the row's Escape and X.
Double-clicking a row while a folder was being created opened that row and moved the dialog on to its links step. That unmounts the browser without it ever going inactive, so its session guard never moved, and the create's late answer still reached the host's onValueChange. Back on the first step, through "Change" or a reopened dialog, it overwrote the user's new pick, and Next opened the folder made earlier. A navigation left running the same way had the same gap. The browser now notes when it unmounts, and a create or a navigation that settles after that leaves the host alone. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
The row's Escape asks its own IME guard, but nothing failed when that check went: Chromium and WebKit flag the composition on the key event itself. A composition seen only through compositionstart now has a test. Two assertions join existing tests: a failure that lands after Escape hands the host its confirm back, and Home comes back once the folder is made, as Up already did. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Collaborator
|
codeg work task |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Summary
Adds New folder to the directory browser of the Open Folder dialog, so a project can start from an empty folder without leaving codeg: name the folder, and the browser moves into it, ready for Next. It works the same in the desktop app and in server/web mode, since the browser lists the filesystem of whichever host serves the workspace. The desktop app's native folder picker now also asks the macOS panel for its own New Folder button.
Behavior
document, which runs before any handler on the input, so the browser claims Escape onwindowwhile the name box has focus.DirectoryBrowsergets an opt-inallowCreateFolderprop. Only the Open Folder dialog's first step turns it on. Its link-targets step and the other pickers that embed the browser (clone destination, worktree path, project boot) are unchanged.create_directory(parentPath, name)is a Tauri command andPOST /api/create_directory. Both callcreate_directory_core, which returns the new folder's path: the parent as given, joined with the name.CreateDirectoryError, athiserrorenum):.or.., or contains/,\, NUL or any other control character. On Windows it is also rejected if it contains< > : " | ? *, ends with a dot (Windows strips a trailing dot without saying so), or is a device name such asCONornul.txt.create_dir, nevercreate_dir_all). A missing parent is an error, and nothing above the new folder is created.create_diralso refuses an existing path, so a name taken between the check and the creation gets the same error.DirectoryBrowser.newFolder.errors, and the browser renders it withtoLocalizedErrorMessage. The new strings are translated in all ten locales.openFileDialogpassescanCreateDirectories: truefor directory picks. tauri-plugin-dialog 2.6 already defaults this to true on macOS, so the call keeps current behavior in place rather than changing it. The Windows and Linux folder dialogs have a new-folder button of their own.list_directory_entries, the endpoint can reach whatever the server process can, and it adds no restriction of its own.Verification
commands::create_directory:.,.., and NUL and other control characters;../x,..\x,a/b, absolute names);en.json.directory-browser.test.tsx:workspace-folder-dialog.test.tsx: creating a folder and opening it with Next, and no New folder button when picking link targets.platform.test.ts: directory picks ask forcanCreateDirectories.codeg-server:..each showed their error;