diff --git a/README.md b/README.md index c5a39f3..ba9fdcd 100644 --- a/README.md +++ b/README.md @@ -1,6 +1,6 @@ # Albert Zed Workspaces Plugin -Quickly find and open your Zed workspaces right from your favourite launcher. +Quickly find and open your Zed workspaces right from your favorite launcher. **Note:** This plugin is not officially associated with Zed or Zed Industries in any way. @@ -10,6 +10,8 @@ To install, copy or symlink this directory to `~/.local/share/albert/python/plug Or just run `git clone https://github.com/HarshNarayanJha/albert_zed_workspaces ~/.local/share/albert/python/plugins/albert_zed_workspaces/` +**Note:** For macOS users, be sure to go to `Zed > Install CLI` option to have `zed` in path so that the plugin can detect it. + ### Development Setup I use the Zed Editor (naturally). Python Development includes `pyright` as `lsp` and `ruff` as `linter`. diff --git a/__init__.py b/__init__.py index 8a7cb87..042826a 100644 --- a/__init__.py +++ b/__init__.py @@ -3,15 +3,16 @@ """ This plugin allows you to quickly open workspaces in Zed Editor -Disclaimer: This plugin has no affiliation with Zed Industries. The icons are used under the terms specified there. +Disclaimer: This plugin is not officially affiliated with Zed or Zed Industries. """ +import logging import sqlite3 from dataclasses import dataclass from pathlib import Path from shutil import which from sys import platform -from typing import cast, override +from typing import override from albert import ( # pyright: ignore[reportMissingModuleSource] Action, @@ -39,22 +40,20 @@ class Workspace: id: str name: str - path: str + paths: list[str] last_opened: int @dataclass class Editor: name: str - icon: Path - icon_system: str + icon: str config_dir_prefix: str binary: str | None - def __init__(self, name: str, icon: Path, icon_system: str, config_dir_prefix: str, binaries: list[str]): + def __init__(self, name: str, icon: str, config_dir_prefix: str, binaries: list[str]): self.name = name self.icon = icon - self.icon_system = icon_system self.config_dir_prefix = config_dir_prefix self.binary = self._find_binary(binaries) @@ -69,7 +68,7 @@ def list_workspaces(self) -> list[Workspace]: if platform == "darwin": config_dir = Path.home() / "Library" / "Application Support" - dirs = list(config_dir.glob(f"{self.config_dir_prefix}*/")) + dirs = list(config_dir.glob(f"{self.config_dir_prefix}/")) if not dirs: return [] latest = sorted(dirs)[-1] @@ -80,22 +79,23 @@ def _parse_recent_workspaces(self, recent_workspaces_file: Path) -> list[Workspa workspaces: list[Workspace] = [] with sqlite3.connect(recent_workspaces_file) as conn: cursor = conn.cursor() - cursor.execute("SELECT workspace_id, local_paths, timestamp FROM workspaces") + cursor.execute("SELECT workspace_id, paths, timestamp FROM workspaces") for row in cursor: if not row[1]: continue w_id = row[0] - local_path = "/" + "/".join(row[1].decode().split("/")[1:]) + paths= row[1].split('\n') timestamp = int(isoparse(row[2]).timestamp()) - w_name = local_path.split("/")[-1] + w_name = ', '.join([path.split("/")[-1] for path in paths]) - workspaces.append(Workspace(id=w_id, name=w_name, path=local_path, last_opened=timestamp)) + workspaces.append(Workspace(id=w_id, name=w_name, paths=paths, last_opened=timestamp)) return workspaces - except FileNotFoundError: + except sqlite3.OperationalError: + logging.error(f"Please update your Zed to the latest version for {recent_workspaces_file}") return [] @@ -104,25 +104,27 @@ def __init__(self): PluginInstance.__init__(self) TriggerQueryHandler.__init__(self) - self._systemicon: bool = cast(bool, self.readConfig("systemicon", bool)) - - plugin_dir = Path(__file__).parent - zed_dir_name = "zed" if platform == "darwin": zed_dir_name = "Zed" + icon = "qfip:/Applications/Zed.app" + icon_preview = "qfip:/Applications/Zed-Preview.app" + elif platform == "linux": + zed_dir_name = "zed" + icon = "xdg:zed" + icon_preview = "xdg:zed-preview" + else: + raise NotImplementedError(f"Unsupported platform: {platform}") editors = [ Editor( name="Zed Editor", - icon=plugin_dir / "icons" / "zed-stable.png", - icon_system="xdg:zed", + icon=icon, config_dir_prefix=f"{zed_dir_name}/db/0-stable", binaries=["zed", "zeditor", "zedit", "zed-cli"], ), Editor( name="Zed Editor (Preview)", - icon=plugin_dir / "icons" / "zed-preview.png", - icon_system="xdg:zed-preview", + icon=icon_preview, config_dir_prefix=f"{zed_dir_name}/db/0-preview", binaries=["zed", "zeditor", "zedit", "zed-cli"], ), @@ -144,8 +146,8 @@ def handleTriggerQuery(self, query: Query): m = Matcher(query.string) for editor in self.editors: workspaces = editor.list_workspaces() - workspaces = [p for p in workspaces if Path(p.path).exists()] - workspaces = [p for p in workspaces if m.match(p.name) or m.match(p.path)] + workspaces = [p for p in workspaces if all(Path(path).exists() for path in p.paths)] + workspaces = [p for p in workspaces if m.match(p.name) or any(m.match(path) for path in p.paths)] editor_workspace_pairs.extend([(editor, p) for p in workspaces]) # sort by last opened @@ -157,33 +159,23 @@ def _make_item(self, editor: Editor, workspace: Workspace, query: Query) -> Item return StandardItem( id=str(workspace.id), text=workspace.name, - subtext=workspace.path, + subtext=';'.join(workspace.paths), inputActionText=query.trigger + workspace.name, - iconUrls=[editor.icon_system if self._systemicon else f"file:{editor.icon}"], + iconUrls=[editor.icon], actions=[ Action( "Open", "Open in %s" % editor.name, - lambda selected_workspace=workspace.path: runDetachedProcess( + lambda selected_workspace=workspace.paths: runDetachedProcess( # Binary has to be valid here - [editor.binary, selected_workspace] # pyright: ignore[reportArgumentType] + [editor.binary] + selected_workspace # pyright: ignore[reportArgumentType] ), ) ], ) - @property - def systemicon(self) -> bool: - return self._systemicon - - @systemicon.setter - def systemicon(self, value: bool) -> None: - self._systemicon = value - self.writeConfig("systemicon", value) - @override def configWidget(self): return [ {"type": "label", "text": str(__doc__).strip(), "widget_properties": {"textFormat": "Qt::MarkdownText"}}, - {"type": "checkbox", "property": "systemicon", "label": "Use System Icon for Zed", "default": True}, ] diff --git a/icons/zed-preview.png b/icons/zed-preview.png deleted file mode 100644 index d7fec60..0000000 Binary files a/icons/zed-preview.png and /dev/null differ diff --git a/icons/zed-stable.png b/icons/zed-stable.png deleted file mode 100644 index f4f4647..0000000 Binary files a/icons/zed-stable.png and /dev/null differ diff --git a/pyproject.toml b/pyproject.toml index f7ba111..d183535 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -1,6 +1,6 @@ [project] name = "albert-plugin-python-zed-workspaces" -version = "1.0" +version = "1.1" authors = [{ name = "Harsh Narayan Jha", email = "harshnj@proton.me" }] description = "Open your Zed workspaces" readme = "README.md"