function openFolder(_path, opts = {}) {
	if (addedFolder.find((folder) => folder.url === _path)) {
		return;
	}

	const saveState = opts.saveState ?? true;
	const listState = opts.listState || {};
	const title = opts.name;
	let listFiles = opts.listFiles;

	if (!title) {
		throw new Error("Folder name is required");
	}

	const $root = collapsableList(title, "folder", {
		allCaps: true,
		ontoggle: () => expandList($root),
	});
	const $text = $root.$title.get(":scope>span.text");

	$root.id = "r" + _path.hashCode();
	$text.style.overflow = "hidden";
	$text.style.whiteSpace = "nowrap";
	$text.style.textOverflow = "ellipsis";
	$root.$title.dataset.type = "root";
	$root.$title.dataset.url = _path;
	$root.$title.dataset.name = title;

	$root.$ul.onclick =
		$root.$ul.oncontextmenu =
		$root.$title.onclick =
		$root.$title.oncontextmenu =
			handleItems;

	recents.addFolder(_path, opts);
	sidebarApps.get("files").append($root);

	const event = {
		url: _path,
		name: title,
	};

	const folder = {
		title,
		remove,
		listFiles,
		saveState,
		listState,
		url: _path,
		$node: $root,
		id: opts.id,
		clipBoard: {},
		reload() {
			$root.collapse();
			$root.expand();
		},
	};
	addedFolder.push(folder);

	editorManager.emit("update", "add-folder");
	editorManager.onupdate("add-folder", event);
	editorManager.emit("add-folder", event);

	(async () => {
		if (typeof listFiles !== "boolean") {
			const protocol = Url.getProtocol(_path).slice(0, -1);
			const type = /^(content|file)$/.test(protocol) ? "" : ` (${protocol})`;
			const message = strings["list files"].replace(
				"{name}",
				`${title}${type}`,
			);
			listFiles = await confirm(strings.confirm, message, true);
		}

		if (listFiles) {
			FileList.addRoot({ url: _path, name: title });
		}

		folder.listFiles = listFiles;
	})();

	if (listState[_path]) {
		$root.expand();
	}

	function remove(e) {
		if (e) {
			e.preventDefault();
			e.stopPropagation();
			e.stopImmediatePropagation();
		}

		if ($root.parentElement) {
			$root.remove();
		}

		const index = addedFolder.findIndex((folder) => folder.url === _path);
		if (index !== -1) addedFolder.splice(index, 1);
		editorManager.emit("update", "remove-folder");
		editorManager.onupdate("remove-folder", event);
		editorManager.emit("remove-folder", event);
	}
}
Open a folder in the sidebar
@param {string} _path
@param {object} opts
@param {string} opts.name
@param {string} [opts.id]
@param {boolean} [opts.saveState]
@param {boolean} [opts.listFiles]
@param {Map<string, boolean>} [opts.listState]