Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
60 changes: 48 additions & 12 deletions src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -7,28 +7,62 @@ use freedesktop_desktop_entry::DesktopEntry;
use rusqlite::{Connection, OpenFlags};
use zbus::{interface, zvariant::Value};

#[derive(Debug, Clone, PartialEq, Eq)]
pub enum ZedChannel {
Stable,
Nightly,
Preview,
Dev,
}

pub fn channel_from_desktop(name: &str, exec: &str) -> ZedChannel {
let name_lower = name.to_lowercase();
if name_lower.contains("nightly") {
return ZedChannel::Nightly;
}
if name_lower.contains("preview") {
return ZedChannel::Preview;
}
if name_lower.contains("dev") {
return ZedChannel::Dev;
}
let exec_lower = exec.to_lowercase();
if exec_lower.contains("nightly") {
return ZedChannel::Nightly;
}
if exec_lower.contains("preview") {
return ZedChannel::Preview;
}
if exec_lower.contains("dev") {
return ZedChannel::Dev;
}
ZedChannel::Stable
}

pub fn db_path_for_channel(channel: &ZedChannel) -> PathBuf {
let variant = match channel {
ZedChannel::Stable => "0-stable",
ZedChannel::Nightly => "0-nightly",
ZedChannel::Preview => "0-preview",
ZedChannel::Dev => "0-dev",
};
data_local_dir()
.unwrap_or_else(|| PathBuf::from("~/.local/share"))
.join(format!("zed/db/{}/db.sqlite", variant))
}

#[derive(Debug, Clone)]
pub struct ZedInstance {
pub label: String,
pub exec: String,
pub app_id: String,
pub icon: String,
pub channel: ZedChannel,
pub db_path: PathBuf,
}

pub const SCHEMA_HANDLER_ID: &str = "x-scheme-handler/zed";

pub fn db_path_for_exec(exec: &str) -> PathBuf {
let variant = if exec.to_lowercase().contains("dev") {
"0-dev"
} else {
"0-stable"
};
data_local_dir()
.unwrap_or_else(|| PathBuf::from("~/.local/share"))
.join(format!("zed/db/{}/db.sqlite", variant))
}

static ZED_INSTANCES_CACHE: Mutex<Option<Vec<ZedInstance>>> = Mutex::const_new(None);

pub async fn find_zed_instances() -> Vec<ZedInstance> {
Expand Down Expand Up @@ -97,14 +131,16 @@ pub async fn find_zed_instances() -> Vec<ZedInstance> {
.unwrap_or("zed")
.to_string();

let db_path = db_path_for_exec(&exec);
let channel = channel_from_desktop(&label, &exec);
let db_path = db_path_for_channel(&channel);

if db_path.exists() {
instances.push(ZedInstance {
label,
exec,
app_id,
icon,
channel,
db_path,
});
}
Expand Down
39 changes: 39 additions & 0 deletions tests/channel_test.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,39 @@
use krunner_zed::{ZedChannel, channel_from_desktop};

#[test]
fn channel_from_desktop_all_variants() {
// Name-based detection (primary signal)
assert_eq!(
channel_from_desktop("Zed", "/usr/bin/zed"),
ZedChannel::Stable
);
assert_eq!(
channel_from_desktop("Zed Nightly", "/home/u/.local/zed-nightly.app/bin/zed"),
ZedChannel::Nightly
);
assert_eq!(
channel_from_desktop("Zed Preview", "/home/u/.local/zed-preview.app/bin/zed"),
ZedChannel::Preview
);
assert_eq!(
channel_from_desktop("Zed Dev", "/home/u/.local/zed-dev.app/bin/zed"),
ZedChannel::Dev
);

// Exec-path fallback when name is plain "Zed"
assert_eq!(
channel_from_desktop("Zed", "/home/u/.local/zed-nightly.app/bin/zed"),
ZedChannel::Nightly
);
assert_eq!(
channel_from_desktop("Zed", "/home/u/.local/zed-preview.app/bin/zed"),
ZedChannel::Preview
);
assert_eq!(
channel_from_desktop("Zed", "/home/u/.local/zed-dev.app/bin/zed"),
ZedChannel::Dev
);

// zeditor stable alias — neither name nor exec contain a variant keyword
assert_eq!(channel_from_desktop("Zed", "zeditor"), ZedChannel::Stable);
}
2 changes: 1 addition & 1 deletion tests/matching_test.rs
Original file line number Diff line number Diff line change
Expand Up @@ -68,7 +68,7 @@ impl Drop for DbusGuard {
// ---------------------------------------------------------------------------

/// Creates the directory tree expected by `find_zed_instances` and
/// `db_path_for_exec` inside `base`:
/// `db_path_for_channel` inside `base`:
///
/// ```text
/// <base>/
Expand Down
Loading