Keep several folders open in one window: a backend and its frontend, an app and the package it depends on. One file tree, one Quick Open, one Project Search and one set of language servers cover them all.
Adding and Removing Folders#
- Add: run Add Folder to Workspace… from the Command Palette or the File menu, or right-click the Files tree and choose Add Folder to Workspace…. Pick a folder; it joins the workspace below the others. On macOS you can pick several folders at once; on Linux and Windows the picker takes one folder at a time.
- Drag and drop: drop folders from Finder, Explorer or your file manager onto the Files tree or anywhere in the window. They join the workspace as with Add Folder to Workspace…; drop them on the bar along the top of the window, or hold Option (macOS) or Alt, to open them as the workspace instead. Files dropped with them open in the editor. See Dropping Files and Folders.
-
Open Project (
Cmd/Ctrl + O) and Open Recent ask where a project goes while another is open: Current Window, New Window, or Add to Workspace, which adds it as another folder. -
From the command line:
lumide app api webopens one window withappas the first folder andapiandwebadded;lumide --add <folder>…adds folders to the window you used last. See Command Line. - Remove: right-click a folder's row in the Files tree and choose Remove Folder from Workspace. Remove Folder from Workspace in the Command Palette removes the folder of the file selected in the tree or open in the editor. Nothing on disk changes, and open tabs stay open.
- Reorder: drag a folder's row onto another folder's row to take its place; a line above or below the row shows where it goes. Or right-click a folder's row and choose Move Folder Up or Move Folder Down. Without a workspace file, only the folders below the first one can be dragged, and only among themselves.
The folder the window was opened with comes first and stays first: it names the workspace and holds its settings and recent-projects entry. Moving it, moving another folder above it or removing it offers to save the workspace as a workspace file first, after which any folder can move or go.
Adding your home folder, the root of the file system, a folder that holds the first folder, one with more than 1,000 items at its top level or one too slow to list, such as a network folder, asks first: Lumide watches and scans every file in a workspace folder, which can slow it down and, on Linux, use up the system's file watches.
A folder that is already in the workspace is not added twice, even through a symbolic link or, on macOS and Windows, with different letter case. You can add a folder inside another one, such as one package of a monorepo, or one the outer folder skips, such as
build/generated or node_modules/my-package: Lumide watches, scans and searches it as a folder of its own, and reads each file once.
Workspace Files#
A workspace file (*.lumide-workspace) keeps a workspace's folders in a file you can commit, share or keep anywhere. Its window is the file's: the layout, tabs and Recent Projects entry are kept for the file, not for a folder.
- Save Workspace As… (Command Palette, File menu, or the project menu in the title bar) writes the file. The window's folders, in order, go into it, along with what Lumide kept for the window, such as its layout and tabs; nothing closes. The folder's own workspace stays as it was, so opening the folder alone still brings back its added folders.
-
Open Workspace from File… opens one. So do Recent Projects,
lumide team.lumide-workspace, double-clicking it on macOS, and dropping it on the Dock icon. A workspace file that a window has open brings that window to the front; otherwise it opens in an empty window or a new one. - Rename Workspace… names the workspace. The title bar and Recent Projects show the name; without one they show the file's name.
With a workspace file, any folder can be moved or removed, the first one too; only the last folder stays. The first folder is the primary one, for what uses one folder (settings, the Dart SDK, Agent Chat). When the first folder changes, Lumide opens the workspace again around the new one, saving your files first and bringing your tabs back. When the first folder is missing, the next one that exists is primary while it is missing; the file keeps the missing folder first, so it is primary again once it is back.
{
"version": 1,
"name": "Shop",
"folders": [
{ "path": "app" },
{ "path": "../api", "name": "Backend" },
{ "path": "/Users/me/code/design-tokens" }
]
}
-
pathis relative to the file or absolute. Lumide writes a folder you add relative when it is inside the file's folder or its parent folder (app,../api), and absolute otherwise; a path you wrote keeps its form. -
namegives a folder the name it shows by in the Files tree, tabs, Quick Open, Project Search and the title bar. -
settingsholds the workspace settings, as a settings file does. See Settings. - Comments and trailing commas are fine. Entries without a path are skipped, and fields Lumide does not know are kept when it saves the file, though comments are not.
-
Edits made to the file outside Lumide, such as in another editor or by
git pull, apply while it is open: its folders, name and settings. When Lumide writes the file, it writes over the file as it is then, so it keeps what changed elsewhere; when you changed the same value in both places, the file's value stays and Lumide says so. -
When the open file is moved, renamed or deleted, Lumide says so and the workspace stays open as it was, without writing the file back:
Save Workspace As… keeps it in a file again. If the file comes back to its place, as after
git checkout, what you changed meanwhile is written over it, keeping what changed elsewhere. - A file saved by a newer version of Lumide opens read-only, as folders saved by a newer version do.
Trust covers the workspace file too: its settings can point at programs Lumide runs, such as a terminal's shell or an SDK, so a workspace file is trusted on its own, by where it is, like each of its folders. Opening a workspace file you have not trusted asks about it, even when you trust all of its folders, and its settings apply only once you trust it. A file you move or copy elsewhere asks again. A file you save with
Save Workspace As… from a trusted window is trusted.
Remote SSH, browser and guest windows don't open workspace files yet. Untitled workspaces, which VS Code keeps for a window with several folders and no file, are not needed: a folder's window already keeps its added folders.
Command Line#
| Command | What it does |
|---|---|
lumide app api web |
Opens one window:
app
is the first folder,
api
and
web
are added. Files among the arguments open there as editors.
|
lumide --add api web |
Adds the folders to the Lumide window you used last, or opens them in a new window when none runs. |
lumide shop.lumide-workspace |
Opens the workspace file, in the window that has it open, else an empty or new window. Folders among the arguments are added to it, files open as editors. With several workspace files, the first opens. |
Folders join as with Add Folder to Workspace…: a folder you have not trusted asks first in a trusted workspace. The added folders are saved with the first folder, so they come back the next time you open it.
lumide <path> sends a file to the window with the deepest folder that holds it, added folders included. A file inside a folder given with it opens with that folder, so
lumide proj proj/README.md opens both in one window. Choosing Open With › Lumide
on several folders in a file manager opens them in one window, as lumide app api does. A folder that a window already has, as its first or an added folder, brings that window to the front.
The Files Tree#
With one folder the tree looks as always. With several, each folder is a top-level row in bold. Folders with the same name show the parent folder that tells them apart, such as app (client) and app (server). A folder inside another one shows twice: as its own row and inside its parent, and both stay in sync.
A folder's row can't be renamed, moved on disk or deleted from the tree; dragging it reorders the workspace's folders, and dropping files and folders on it moves them into it as before. Its menu creates files and folders, finds in files within it, reveals it in your file manager, pastes into it, copies its path, runs plugin commands and removes it from the workspace.
Tabs#
Tabs of files with the same name show the nearest parent folder that tells them apart, such as user.dart …/models
and user.dart …/views, only while both are open in the same tab group. When the files are in different workspace folders, the tab shows the folder's label instead:
main.dart app (client).
The Window's Name#
The top bar names the folder of the file you are editing, by the same label as its row in the Files tree, followed by how many other folders the workspace has: xp_ui +2, app (server) +2. With no file open, or a file outside every folder, it names the first folder. Hover it to list every folder, the first marked (primary). The file path in the status bar starts with the same label. A guest's window names the shared folders the same way, by the host's labels, and counts only shared folders: when the folder it joined with is no longer shared, it names the first shared one, and the tooltip marks the other not shared.
Search, Quick Open and Git#
-
Quick Open lists files from every folder. With several folders, paths start with the folder's label, and a query that starts with a label and
/lists only that folder's files:api/serverfindsserver.dartin the api folder only, andapp (server)/lists the files of app (server). A chip next to the query names the folder. -
Project Search searches every folder and shows each result under its folder's name. Pick the folders to search from the folder picker under the file patterns; the workspace remembers your pick, also after you reopen it.
Find in Files… on a folder in the Files tree, in any workspace folder, searches that folder, even when another folder has the same name. File patterns match paths inside each folder, and
./<label>/scopes a pattern to one folder, such as./api/**. See File Patterns. -
Git: the tree, the editor gutter and blame show each folder's Git status. Folders of one repository, such as packages of a monorepo, share one
git status, and each folder sees its own paths. A folder that its parent repository ignores is not ignored as a whole. - Git commands act on the repository of the file you are editing; the branch indicator names it and switches to another, and Fetch All, Pull All and Push All… work in every repository. C.O.R.G.I. opens on that repository; click the repository name there to switch, with same-named repositories labelled as in the Files tree; folders outside Git are not listed. Its All Repositories switch lists the changes of every repository, commits one message to several, and merges their histories. See Several Repositories.
- Problems and Tests list files under their folder.
- Local History lists the files of every folder under the folder's name. See Local History.
Language Servers and Terminals#
- Language servers learn every folder of the workspace. A server that follows folder changes is told when a folder joins or leaves; a server that takes folders but not changes restarts once with the new folders, even after several quick adds. AI completion servers are told when a folder joins or leaves.
- A language server that does not use workspace folders runs once per folder, rooted at that folder, so each file is analyzed in its own project. Its copy for a folder starts when you open the folder's first file for that language. A file in a folder inside another folder uses the inner folder's server; a file outside every folder uses the first folder's. Plugins can ask for a server per folder even when it takes workspace folders.
-
A folder's server stops when the folder is removed, and its open files move to the server of the folder that now holds them. It also stops once none of its files has been open for 10 minutes,
language_servers.idle_timeout_minutesin Settings (0 keeps it running); it starts again with the next file. -
At most 8 copies of one language server run at once,
language_servers.max_folder_instances. Files in further folders use the first folder's server, and Lumide tells you once; they move to their own folder's server once another one stops. - The runtime popup lists each folder's server with the folder's label, such as Pyright — api. Restart restarts that folder's server only; Stop and Disable apply to every folder.
- Go to Symbol in Workspace asks every server and lists each symbol once, and the Problems panel shows each file's problems from its own folder's server.
- Multi-file edits from language servers, such as Rename, apply in every folder.
- A new terminal starts in the folder of the file you are editing, else in the first folder; its tab names the folder when it is not the first, such as Terminal — api. New Terminal in Folder... asks which folder, and Open in Terminal on a folder's row in the Files tree opens one there.
-
In Dart, going to a
package:location uses thepackage_config.jsonnearest to the file you are editing, within its folder, so two folders can use different versions of a package of the same name. A package that folder doesn't know is looked up in the other folders. Stack frames in the debugger resolve from the folder the program runs in.
Agent Chat#
The agent works in the first folder and knows every other one: its first message lists each folder by name and full path.
@ mentions, file search, AGENTS.md rules, Git and the sandbox cover all folders. See
Agent Chat with Several Folders.
Run, Debug and Tests#
-
Each folder can have its own
.sofluffy/lumide/launch.json, and launch providers list targets for every folder. The launch dropdown names the folder after each configuration,${workspaceFolder}is the configuration's own folder, and${workspaceFolder:name}names another one. See Several Folders. -
New Launch Configuration… on any folder's row adds to that folder's
launch.json. - Tests run in the folder and package that hold them.
- Plugin processes started without a working directory run in the folder of the file you are editing, else in the first folder.
SDKs#
-
Each folder can use its own SDK: an
.fvmrcor Puro environment in the folder, or a Workspace selection in the SDK Manager, where a picker chooses the folder. - One Dart language server runs for the whole workspace, since it takes workspace folders, with the SDK of the first folder. When folders resolve to different Dart SDKs, Lumide says so once and names the SDK analysis uses. Plugins can still run and test each folder with its own SDK.
Settings#
Each folder can have its own .sofluffy/lumide/settings.json. The first folder's file holds the workspace settings, unless the window opened a
workspace file; an added folder's file applies to the files inside it, over the workspace settings, for settings that can differ between folders: tab size, spaces, format on save, soft wrap and other editor behavior, inline blame, a new terminal's default profile and plugin configuration. A file in a folder inside another folder takes the inner folder's settings. Theme, fonts, keymap, AI and other settings that apply to the whole window come from the user and workspace settings only. Edit a folder's settings in the Settings editor's
Folder tab; changes to the file apply at once. Like workspace settings, they apply only in a trusted workspace. See
Folder Settings.
With a workspace file, its settings section holds the workspace settings, window settings such as the theme included, and the first folder's file is a folder file like the others: for each file, its folder's settings come first, then the workspace file's, the user's and the defaults. The Settings editor's
Workspace tab edits the file's settings, keeping the rest of the file;
Save Workspace As… from a folder's window copies the first folder's settings into the new file. Changes you make to the file's
settings outside Lumide apply at once.
Sharing#
Sharing a workspace of several folders lets you pick which folders guests see: all of them at first. You can change the folders you share while sharing, from the
Sharing dialog; the Files tree marks the shared ones. Guests see exactly those folders, as the folders of their window, by your labels,
names from a workspace file included, and in your order, the folder a guest joined with first in its window; Quick Open,
./<label>/ patterns and ${workspaceFolder:name} use those labels too. Moving or renaming a folder reaches guests at once, and a shared folder that went missing offers to be shared again once it is back. The host's language servers tell guests nothing about the others: no locations, links or paths to files there, paths in hovers and diagnostics reading
…, and no progress messages from a server that also works on them. A guest's file uses the server the host's own files of its folder use, also for a folder the host doesn't share inside one it does, and past the cap on folder servers the first shared folder's. Guests see the host's folder servers only for the folders they share, labelled as those folders, and a guest's restart restarts only those. When the host stops sharing a folder, guests' diagnostics and Problems for it clear and their connections to its server close; when it shares one again, its Problems come back. Guests can't add, remove, move or rename folders, also not by dropping them on the window: the commands say the host chooses them. Each shared folder brings the host's tab size, spaces and format on save for its files, a folder's own settings and language overrides included, so guests indent and format as the host does; see
The host's editor settings.
Remote SSH Windows#
A Remote SSH window holds several folders on its host, as a local window does.
Add Folder to Workspace… browses the host's folders: type a path, or ~ for your home folder, open folders to go down and
.. to go up, then click Add. Locate… on a missing folder browses the same way. Folders on your own computer can't join an SSH window: Open Project and Open Recent don't offer
Add to Workspace there, and dropped folders are refused.
The folders are kept for the host and the first folder, so a folder with the same path on your computer or on another host keeps its own. So are the window's layout and tabs, which folders you trust and the
Local History of their files: trusting /home/me/app
on one host trusts it nowhere else. The host here is the user, host name and port you connected with.
Earlier versions kept the layout, trust and Local History of an SSH window by path alone, where a folder with the same path on your computer or on another host could share them. The first time you open such a folder again, Lumide carries them over to the host only when nothing else used that path: Recent Projects or the folder's saved state names this host, with its port, and names neither your computer nor another host for it. Otherwise the window starts with a fresh layout and asks about trust again; the old state stays with the path. Recent Projects shows them under the SSH entry, and reopening it brings them back; a folder that is gone from the host stays listed as
missing. The Files tree, Quick Open, Project Search, Git, language servers, terminals and run configurations cover every folder, all on the host. Workspace files don't open in SSH windows yet, so the first folder stays first. Browser windows on
lumide_server serve hold several of the server's folders the same way, kept in the browser.
Trust#
A workspace is trusted only when all of its folders are. Adding a folder you have not trusted to a trusted workspace asks first: Trust and Add trusts it, Cancel leaves it out. In a restricted workspace, folders are added without asking and stay restricted. Trust and Continue in the trust dialog trusts the folders it lists; a folder added while the dialog was open stays restricted until you trust it too.
When Lumide Reopens#
Reopening the first folder, from Recent Projects or lumide <path>, brings the other folders back; a workspace file brings back its own folders. Recent Projects shows how many folders a project adds, such as
+2 folders, with their names, and its filter finds a project by an added folder's name.
A folder that was moved, deleted or can't be reached in time (such as a disconnected network drive) stays listed as missing, and nothing reads or watches it. Lumide checks again when it comes to the front and when a folder is deleted, so a folder that comes back is used again. Right-click a missing folder for:
- Locate…: pick where the folder went. It takes the missing folder's place in the list, and is asked about like a new folder when you have not trusted it. Local History of the files at the old path stays under that path.
- Retry: check the folder again now, such as after reconnecting a drive.
Folders saved by a newer version of Lumide open as they were, read-only: Lumide says so, and adding or removing folders waits until you update.
Limits#
- Settings that apply to the whole window, such as the theme, and the Dart SDK source (System, Managed or Custom) in the SDK Manager come from the workspace settings: the first folder's, or a workspace file's. Agent Chat works in the first folder, and reads Agent Skills and MCP servers from it.
- Remote SSH windows and browser windows read no folder settings. Guest windows of a shared workspace read none of their own either; they take the host's tab size, spaces and format on save for each shared folder.
- On Linux, each folder uses file watches like a window of its own; adding a folder that holds a large tree, such as your home folder, uses many. When the folders hit the system's watch limit, Lumide tells you once.
Next Steps#
- Workspaces & Loose Files — Opening projects and single files.
- Project Search — Searching across files.
