select(extra, type = "all", title = strings["open recent"]) {
		const all = [];
		const MAX = 20;
		const shortName = (name) => {
			name = helpers.getVirtualPath(name);

			if (name.length > MAX) {
				return "..." + name.substr(-MAX - 3);
			}
			return name;
		};

		if (type === "dir" || type === "all") {
			let dirs = this.folders;
			for (let dir of dirs) {
				const { url } = dir;

				const dirValue = {
					type: "dir",
					val: dir,
				};

				const tailElement = tag("span", {
					className: "icon clearclose",
					dataset: {
						action: "clear",
					},
				});

				all.push({
					value: dirValue,
					text: shortName(url),
					icon: "folder",
					tailElement: tailElement,
					ontailclick: (e) => {
						const $item = e.currentTarget.closest(".tile");
						if ($item) $item.remove();
						this.removeFolder(dir.url);
					},
				});
			}
		}

		if (type === "file" || type === "all") {
			let files = this.files;
			for (let file of files) {
				if (!file) continue;
				const name = shortName(Url.parse(file).url);

				const fileValue = {
					type: "file",
					val: file,
				};
				const tailElement = tag("span", {
					className: "icon clearclose",
					dataset: {
						action: "clear",
					},
				});

				all.push({
					value: fileValue,
					text: name,
					icon: helpers.getIconForFile(name),
					tailElement: tailElement,
					ontailclick: (e) => {
						const $item = e.currentTarget.closest(".tile");
						if ($item) $item.remove();
						this.removeFile(file);
					},
				});
			}
		}

		if (type === "all") all.push(["clear", strings.clear, "icon clearclose"]);

		if (extra) {
			extra = extra.map((item) => {
				item[1] = shortName(item[1]);
				return item;
			});

			all.push(...extra);
		}

		return select(title, all, {
			textTransform: false,
		});
	}
@param {Array<Array<string, any, string>>} [extra]
@param {"file"|"dir"|"all"} [type]
@param {string} [title]
@returns {Promise<RecentPathData>}