diff --git a/crates/ide-extension/src/manifest.rs b/crates/ide-extension/src/manifest.rs index 17d3c6992..132aba1e7 100644 --- a/crates/ide-extension/src/manifest.rs +++ b/crates/ide-extension/src/manifest.rs @@ -32,7 +32,7 @@ use std::path::{Component, Path, PathBuf}; pub const MANIFEST_FILE: &str = "plugin.toml"; /// The plugin API (engine) version this host implements. -pub const ENGINE_VERSION: &str = "1.4.0"; +pub const ENGINE_VERSION: &str = "1.5.0"; /// The 0.1 API, still accepted for contribution-only packages and 0.1 components. pub const LEGACY_API: &str = "0.1"; /// Marketplace categories, in the order they are shown. diff --git a/crates/ide-host/src/mcp/reports.rs b/crates/ide-host/src/mcp/reports.rs index 343ddba77..51b2cebbc 100644 --- a/crates/ide-host/src/mcp/reports.rs +++ b/crates/ide-host/src/mcp/reports.rs @@ -28,6 +28,8 @@ pub struct Reports(RwLock); struct State { windows: HashMap, focused: Option, + /// Windows in the order they were last focused, the most recent last. + focus_order: Vec, remote: HashMap, libraries: HashMap>, } @@ -46,8 +48,16 @@ impl Reports { state.windows.entry(window.into()).or_default().focused = editor; if focused { state.focused = Some(window.into()); + state.focus_order.retain(|w| w != window); + state.focus_order.push(window.into()); } } + /// Sorts `windows` by when they were last focused, the most recent first; windows + /// never focused keep their order after them. + pub(crate) fn most_recently_focused_first(&self, windows: &mut [String]) { + let order = &self.0.read().focus_order; + windows.sort_by_key(|w| std::cmp::Reverse(order.iter().position(|o| o == w))); + } pub fn report_problems(&self, window: &str, reset: bool, files: Vec) { let mut state = self.0.write(); let problems = &mut state.windows.entry(window.into()).or_default().problems; @@ -68,6 +78,7 @@ impl Reports { state.windows.remove(window); state.remote.remove(window); state.libraries.remove(window); + state.focus_order.retain(|w| w != window); if state.focused.as_deref() == Some(window) { state.focused = None; } @@ -122,3 +133,24 @@ impl Reports { files.into_iter().map(|(path, items)| FileProblems { path: path.into(), items }).collect() } } + +#[cfg(test)] +mod tests { + use super::*; + + #[test] + fn windows_sort_by_their_last_focus() { + let reports = Reports::default(); + for window in ["a", "b", "a", "c"] { + reports.set_focused_editor(window, None, true); + } + reports.set_focused_editor("b", None, false); + let mut windows: Vec = ["a", "b", "c", "never"].map(String::from).into(); + reports.most_recently_focused_first(&mut windows); + assert_eq!(windows, ["c", "a", "b", "never"]); + reports.forget_window("c"); + let mut windows: Vec = ["never", "c", "b", "a"].map(String::from).into(); + reports.most_recently_focused_first(&mut windows); + assert_eq!(windows, ["a", "b", "never", "c"]); + } +} diff --git a/crates/ide-host/src/plugins/api.rs b/crates/ide-host/src/plugins/api.rs index 70892f2de..ef6dc82f7 100644 --- a/crates/ide-host/src/plugins/api.rs +++ b/crates/ide-host/src/plugins/api.rs @@ -110,6 +110,10 @@ pub trait PluginWorkspace: Send + Sync { fn trusted(&self, root: &Path) -> bool; /// Root of the project open in `window`. fn project_of(&self, window: &str) -> Option; + /// Windows showing the open project at `root`, the most recently focused first. + fn project_windows(&self, _root: &Path) -> Vec { + Vec::new() + } /// Shows `items` as producer `source`'s diagnostics of `path` (replacing earlier ones). fn publish_diagnostics(&self, source: &str, path: &Path, items: Vec) -> Result<(), HostError>; @@ -1758,17 +1762,31 @@ impl HostApi for PluginApi { body: String, actions: Vec, ) -> Result<(), HostError> { - if !actions.is_empty() { - let commands = self.shared.ui.items("commands", Some(self.id())); - if let Some(a) = actions.iter().find(|a| !commands.iter().any(|c| c.key == a.command)) { - return Err(HostError::NotFound(format!("the plugin declares no command {:?}", a.command))); - } - } + check_actions(self, &actions)?; let plugin_id = self.id().to_owned(); self.shared.sink.emit(client, PluginEvent::Notification { plugin_id, level, title, body, actions }); Ok(()) } + fn notify_project( + &self, + root: &Path, + level: NotificationLevel, + title: String, + body: String, + actions: Vec, + ) -> Result<(), HostError> { + check_actions(self, &actions)?; + let windows = self.shared.workspace().map(|w| w.project_windows(root)).unwrap_or_default(); + let window = windows + .into_iter() + .find(|w| !self.shared.client_closed(w)) + .ok_or_else(|| HostError::NotFound(format!("the project {} is not open", root.display())))?; + let plugin_id = self.id().to_owned(); + self.shared.sink.emit(Some(&window), PluginEvent::Notification { plugin_id, level, title, body, actions }); + Ok(()) + } + fn copy_to_clipboard(&self, client: Option<&str>, text: String) -> Result<(), HostError> { let client = from_window(client, "copy to the clipboard")?; self.shared.sink.emit(Some(client), PluginEvent::CopyToClipboard { plugin_id: self.id().to_owned(), text }); @@ -2718,6 +2736,15 @@ fn not_writable(path: &Path, e: ide_core::error::IdeError) -> HostError { } } +/// Notification buttons must name commands the plugin declares. +fn check_actions(api: &PluginApi, actions: &[ide_plugin::NotificationAction]) -> Result<(), HostError> { + let commands = if actions.is_empty() { Vec::new() } else { api.shared.ui.items("commands", Some(api.id())) }; + match actions.iter().find(|a| !commands.iter().any(|c| c.key == a.command)) { + Some(a) => Err(HostError::NotFound(format!("the plugin declares no command {:?}", a.command))), + None => Ok(()), + } +} + /// [`PluginWorkspace`] over the desktop host's open projects. pub struct HostWorkspace(pub std::sync::Weak); @@ -3016,6 +3043,13 @@ impl PluginWorkspace for HostWorkspace { self.0.upgrade()?.project(window).ok().map(|p| p.root.clone()) } + fn project_windows(&self, root: &Path) -> Vec { + let Some(host) = self.0.upgrade() else { return Vec::new() }; + let mut windows = host.windows_for_root(root); + host.mcp_reports.most_recently_focused_first(&mut windows); + windows + } + fn publish_diagnostics( &self, source: &str, diff --git a/crates/ide-host/tests/plugins.rs b/crates/ide-host/tests/plugins.rs index 749af1155..8486ad291 100644 --- a/crates/ide-host/tests/plugins.rs +++ b/crates/ide-host/tests/plugins.rs @@ -126,6 +126,10 @@ impl PluginWorkspace for TestWorkspace { fn trusted(&self, _root: &Path) -> bool { self.trusted } + fn project_windows(&self, root: &Path) -> Vec { + // `main` shows the fixture project; other open roots have no window left. + if root == self.root { vec!["closing".into(), "main".into()] } else { Vec::new() } + } fn project_of(&self, _window: &str) -> Option { if let Some(left) = self.project_queries_left.lock().as_mut() { if *left == 0 { @@ -4801,6 +4805,40 @@ fn notification_actions_keep_commands_and_window_scope() { assert_eq!(f.status("jobs"), PluginStatus::Active, "a refused notification leaves the plugin running"); } +#[test] +fn project_notifications_go_to_a_window_of_that_project_only() { + let f = fixture(Limits::default()); + f.install(&sample("jobs")); + f.host.set_capability("jobs", "project.read", false).unwrap(); + f.host.forget_client("closing"); + let other = f.project.parent().unwrap().join("other"); + std::fs::create_dir(&other).unwrap(); + f.workspace.other_roots.lock().push(other.clone()); + f.take_events(); + let notifications = |f: &Fixture| { + f.take_events() + .into_iter() + .filter_map(|(client, event)| match event { + PluginEvent::Notification { title, actions, .. } => Some((client, title, actions)), + _ => None, + }) + .collect::>() + }; + // A scheduled call has no invoking window; a closing window is skipped. + let path = f.project.join("notes.txt").to_string_lossy().into_owned(); + f.host.run_command("jobs", "notify-project", Some(&path), Invocation::default()).unwrap(); + let sent = notifications(&f); + assert_eq!(sent.len(), 1); + assert_eq!((sent[0].0.as_deref(), sent[0].1.as_str()), (Some("main"), "Project update")); + assert_eq!((sent[0].2[0].command.as_str(), sent[0].2[0].argument.as_deref()), ("context", Some(path.as_str()))); + // A project without a window fails without falling back to another one, even when invoked from one. + let path = other.join("notes.txt").to_string_lossy().into_owned(); + let error = f.host.run_command("jobs", "notify-project", Some(&path), f.inv()).unwrap_err().message; + assert!(error.contains("not open"), "{error}"); + assert!(notifications(&f).is_empty()); + assert_eq!(f.status("jobs"), PluginStatus::Active); +} + #[test] fn directory_prompts_and_project_requests_use_the_calling_window_without_a_capability() { use ide_plugin::Prompt; diff --git a/crates/ide-plugin/src/runtime.rs b/crates/ide-plugin/src/runtime.rs index c2c43eb90..a3c2e0030 100644 --- a/crates/ide-plugin/src/runtime.rs +++ b/crates/ide-plugin/src/runtime.rs @@ -54,7 +54,7 @@ use views_bindings::exports::openidea::plugin::view_provider as wit_view; use views_bindings::openidea::plugin::view_types as wit_vt; /// The API version of the world above, `major.minor` of [`host_api`]. -pub const API_VERSION: &str = "1.4"; +pub const API_VERSION: &str = "1.5"; const EPOCH_TICK: Duration = Duration::from_millis(10); pub(crate) const MAX_TEXT: usize = 1 << 20; pub(crate) const MAX_TITLE: usize = 256; @@ -259,6 +259,19 @@ pub trait HostApi: Send + Sync { body: String, actions: Vec, ) -> Result<(), HostError>; + /// [`HostApi::notify`] in the most recently focused window of the open project at + /// `root`; not-found (and nothing shown) once it has closed. + fn notify_project( + &self, + root: &Path, + level: NotificationLevel, + title: String, + body: String, + actions: Vec, + ) -> Result<(), HostError> { + let _ = (root, level, title, body, actions); + Err(HostError::NotFound("project notifications unavailable".into())) + } fn copy_to_clipboard(&self, client: Option<&str>, text: String) -> Result<(), HostError> { let _ = (client, text); Ok(()) diff --git a/crates/ide-plugin/src/wit_host.rs b/crates/ide-plugin/src/wit_host.rs index 30d6869f9..15faa434d 100644 --- a/crates/ide-plugin/src/wit_host.rs +++ b/crates/ide-plugin/src/wit_host.rs @@ -362,6 +362,25 @@ impl StoreData { } } +/// Checks `ui.notify` buttons; the host checks that their commands are declared. +fn notification_actions(actions: Vec) -> Result, wit::Error> { + const MAX_ACTIONS: usize = 3; + if actions.len() > MAX_ACTIONS { + return Err(wit::Error::Invalid(format!("a notification has at most {MAX_ACTIONS} actions"))); + } + let mut checked = Vec::with_capacity(actions.len()); + for a in actions { + if a.label.trim().is_empty() || a.label.len() > 256 || a.label.chars().any(char::is_control) { + return Err(wit::Error::Invalid(format!("invalid action label {:?}", a.label))); + } + if a.argument.as_ref().is_some_and(|arg| arg.len() > 64 << 10) { + return Err(wit::Error::Invalid("an action argument is limited to 64 KiB".into())); + } + checked.push(crate::NotificationAction { label: a.label, command: a.command, argument: a.argument }); + } + Ok(checked) +} + impl ui::Host for StoreData { fn notify( &mut self, @@ -370,22 +389,29 @@ impl ui::Host for StoreData { body: String, actions: Vec, ) -> Fallible<()> { - const MAX_ACTIONS: usize = 3; - if actions.len() > MAX_ACTIONS { - return Ok(Err(wit::Error::Invalid(format!("a notification has at most {MAX_ACTIONS} actions")))); - } - let mut checked = Vec::with_capacity(actions.len()); - for a in actions { - if a.label.trim().is_empty() || a.label.len() > 256 || a.label.chars().any(char::is_control) { - return Ok(Err(wit::Error::Invalid(format!("invalid action label {:?}", a.label)))); - } - if a.argument.as_ref().is_some_and(|arg| arg.len() > 64 << 10) { - return Ok(Err(wit::Error::Invalid("an action argument is limited to 64 KiB".into()))); - } - checked.push(crate::NotificationAction { label: a.label, command: a.command, argument: a.argument }); - } + let actions = match notification_actions(actions) { + Ok(actions) => actions, + Err(e) => return Ok(Err(e)), + }; let (title, body) = (clip(title, MAX_TITLE), clip(body, 16 << 10)); - Ok(self.host.notify(self.client(), notification_level(level), title, body, checked).map_err(to_wit)) + Ok(self.host.notify(self.client(), notification_level(level), title, body, actions).map_err(to_wit)) + } + + fn notify_project( + &mut self, + target: Resource, + level: wit::NotificationLevel, + title: String, + body: String, + actions: Vec, + ) -> Fallible<()> { + let actions = match notification_actions(actions) { + Ok(actions) => actions, + Err(e) => return Ok(Err(e)), + }; + let root = self.table.get(&target)?.root.clone(); + let (title, body) = (clip(title, MAX_TITLE), clip(body, 16 << 10)); + Ok(self.host.notify_project(&root, notification_level(level), title, body, actions).map_err(to_wit)) } fn show_notification( diff --git a/crates/ide-plugin/tests/api_compat.rs b/crates/ide-plugin/tests/api_compat.rs index 95825fedb..df519c824 100644 --- a/crates/ide-plugin/tests/api_compat.rs +++ b/crates/ide-plugin/tests/api_compat.rs @@ -91,15 +91,15 @@ fn the_sdk_carries_the_hosts_wit() { #[test] fn the_version_check_runs_compatible_components_and_explains_the_rest() { - let host = v("1.4.0"); - for ok in ["1.0.0", "1.3.0", "1.3.7", "1.4.0", "1.0.0-rc.1"] { + let host = v("1.5.0"); + for ok in ["1.0.0", "1.3.0", "1.4.7", "1.5.0", "1.0.0-rc.1"] { assert_eq!(check_api(&v(ok), &host), Ok(()), "{ok}"); } - let newer = check_api(&v("1.5.0"), &host).unwrap_err(); - assert!(newer.contains("1.5") && newer.contains("update OpenIDEA"), "{newer}"); + let newer = check_api(&v("1.6.0"), &host).unwrap_err(); + assert!(newer.contains("1.6") && newer.contains("update OpenIDEA"), "{newer}"); assert!(check_api(&v("2.0.0"), &host).unwrap_err().contains("update OpenIDEA")); let older = check_api(&v("0.2.0"), &host).unwrap_err(); - assert!(older.contains("rebuild it with the 1.4 SDK"), "{older}"); + assert!(older.contains("rebuild it with the 1.5 SDK"), "{older}"); // 0.x: every minor is its own API. assert_eq!(check_api(&v("0.2.0"), &v("0.2.5")), Ok(())); assert!(check_api(&v("0.1.0"), &v("0.2.0")).is_err()); diff --git a/crates/ide-plugin/tests/fixtures/api14/dist/plugin.wasm b/crates/ide-plugin/tests/fixtures/api14/dist/plugin.wasm index 5bdcd679c..d502fc01e 100644 Binary files a/crates/ide-plugin/tests/fixtures/api14/dist/plugin.wasm and b/crates/ide-plugin/tests/fixtures/api14/dist/plugin.wasm differ diff --git a/crates/ide-plugin/tests/fixtures/api14/dist/plugin.wasm.sources b/crates/ide-plugin/tests/fixtures/api14/dist/plugin.wasm.sources index 75010fdb6..9614ab69b 100644 --- a/crates/ide-plugin/tests/fixtures/api14/dist/plugin.wasm.sources +++ b/crates/ide-plugin/tests/fixtures/api14/dist/plugin.wasm.sources @@ -1 +1 @@ -4647fa9aec9732e3dd824efccd61b1c6b9c36645a3586f402f6a7a47419db61f +9963d6606bb6b859bebe1f55892488944f6d5e3308e6c0109f38f4b1a67b01f5 diff --git a/crates/ide-plugin/tests/fixtures/commit/dist/plugin.wasm b/crates/ide-plugin/tests/fixtures/commit/dist/plugin.wasm index 8d716ad4a..26ad29ee6 100644 Binary files a/crates/ide-plugin/tests/fixtures/commit/dist/plugin.wasm and b/crates/ide-plugin/tests/fixtures/commit/dist/plugin.wasm differ diff --git a/crates/ide-plugin/tests/fixtures/commit/dist/plugin.wasm.sources b/crates/ide-plugin/tests/fixtures/commit/dist/plugin.wasm.sources index a24dbad77..6be37d252 100644 --- a/crates/ide-plugin/tests/fixtures/commit/dist/plugin.wasm.sources +++ b/crates/ide-plugin/tests/fixtures/commit/dist/plugin.wasm.sources @@ -1 +1 @@ -6787b195df1057176ea9fcf11d0fcaf8cd347fc182fab94fe3a229063deed831 +7ab9937fdb2e78d0d62d9b85b78a0a6d9511224f85908c3a5a5e9c0d4b5e7e14 diff --git a/crates/ide-plugin/tests/fixtures/data-tools/dist/plugin.wasm b/crates/ide-plugin/tests/fixtures/data-tools/dist/plugin.wasm index d921b4400..92b99d171 100644 Binary files a/crates/ide-plugin/tests/fixtures/data-tools/dist/plugin.wasm and b/crates/ide-plugin/tests/fixtures/data-tools/dist/plugin.wasm differ diff --git a/crates/ide-plugin/tests/fixtures/data-tools/dist/plugin.wasm.sources b/crates/ide-plugin/tests/fixtures/data-tools/dist/plugin.wasm.sources index b0c063aff..ce39222a7 100644 --- a/crates/ide-plugin/tests/fixtures/data-tools/dist/plugin.wasm.sources +++ b/crates/ide-plugin/tests/fixtures/data-tools/dist/plugin.wasm.sources @@ -1 +1 @@ -c2d17076337b1225ef8b0323b335a3b03bf022485088957c520e0cb797d7df7d +cf1f91d8accf8339bf6e22bef5067bfe3cba75d38cd30d8748b0aa451ee2495b diff --git a/crates/ide-plugin/tests/fixtures/detail-views/dist/plugin.wasm b/crates/ide-plugin/tests/fixtures/detail-views/dist/plugin.wasm index 7197508c8..b6f1e864f 100644 Binary files a/crates/ide-plugin/tests/fixtures/detail-views/dist/plugin.wasm and b/crates/ide-plugin/tests/fixtures/detail-views/dist/plugin.wasm differ diff --git a/crates/ide-plugin/tests/fixtures/detail-views/dist/plugin.wasm.sources b/crates/ide-plugin/tests/fixtures/detail-views/dist/plugin.wasm.sources index 745fa2d97..70a1b7919 100644 --- a/crates/ide-plugin/tests/fixtures/detail-views/dist/plugin.wasm.sources +++ b/crates/ide-plugin/tests/fixtures/detail-views/dist/plugin.wasm.sources @@ -1 +1 @@ -415a4cd17c573aeeb1b45d4b1af55834eab5e686c4f624495323e4fb63c3ac71 +12ad7d649d752f2a40b28dee718a3e04b64597496ab43787c084e3cb774ccfe6 diff --git a/crates/ide-plugin/tests/fixtures/diagnostics/dist/plugin.wasm b/crates/ide-plugin/tests/fixtures/diagnostics/dist/plugin.wasm index 37c4e7f30..41617e221 100644 Binary files a/crates/ide-plugin/tests/fixtures/diagnostics/dist/plugin.wasm and b/crates/ide-plugin/tests/fixtures/diagnostics/dist/plugin.wasm differ diff --git a/crates/ide-plugin/tests/fixtures/diagnostics/dist/plugin.wasm.sources b/crates/ide-plugin/tests/fixtures/diagnostics/dist/plugin.wasm.sources index 4ae8aef3d..9efa52f3b 100644 --- a/crates/ide-plugin/tests/fixtures/diagnostics/dist/plugin.wasm.sources +++ b/crates/ide-plugin/tests/fixtures/diagnostics/dist/plugin.wasm.sources @@ -1 +1 @@ -5f502b7650acd5d07bffba8016680248b5ceac0926013916ff351562e3c6d831 +4bfce353b3c94490c5f95a046cd2371042b243c326bd63c65619e1489d7ab889 diff --git a/crates/ide-plugin/tests/fixtures/endpoints/dist/plugin.wasm b/crates/ide-plugin/tests/fixtures/endpoints/dist/plugin.wasm index 91b128fd7..b3e645acc 100644 Binary files a/crates/ide-plugin/tests/fixtures/endpoints/dist/plugin.wasm and b/crates/ide-plugin/tests/fixtures/endpoints/dist/plugin.wasm differ diff --git a/crates/ide-plugin/tests/fixtures/endpoints/dist/plugin.wasm.sources b/crates/ide-plugin/tests/fixtures/endpoints/dist/plugin.wasm.sources index fc61faa67..fe2f2322e 100644 --- a/crates/ide-plugin/tests/fixtures/endpoints/dist/plugin.wasm.sources +++ b/crates/ide-plugin/tests/fixtures/endpoints/dist/plugin.wasm.sources @@ -1 +1 @@ -19e8d460269999aeac7b4021bfedb803ad0d68c24ce1c22f058070fb406a64c3 +cfbd6aac217a7baea907affe4e1e7f89d1330843398e913e68b71f3a99cfb71b diff --git a/crates/ide-plugin/tests/fixtures/execution/dist/plugin.wasm b/crates/ide-plugin/tests/fixtures/execution/dist/plugin.wasm index 07476e17a..3ab139925 100644 Binary files a/crates/ide-plugin/tests/fixtures/execution/dist/plugin.wasm and b/crates/ide-plugin/tests/fixtures/execution/dist/plugin.wasm differ diff --git a/crates/ide-plugin/tests/fixtures/execution/dist/plugin.wasm.sources b/crates/ide-plugin/tests/fixtures/execution/dist/plugin.wasm.sources index b0a3bfa73..45808d3c0 100644 --- a/crates/ide-plugin/tests/fixtures/execution/dist/plugin.wasm.sources +++ b/crates/ide-plugin/tests/fixtures/execution/dist/plugin.wasm.sources @@ -1 +1 @@ -63809abb0f8a4f40b0c0f465062cc8ba0ebfd03d41a108ff19866e6565eda931 +dcf00138820979f523bd93e1f6b08c627c6f061ae5b6e91b340646f905593cf3 diff --git a/crates/ide-plugin/tests/fixtures/file-templates/dist/plugin.wasm b/crates/ide-plugin/tests/fixtures/file-templates/dist/plugin.wasm index c026fa17e..c6824bfb6 100644 Binary files a/crates/ide-plugin/tests/fixtures/file-templates/dist/plugin.wasm and b/crates/ide-plugin/tests/fixtures/file-templates/dist/plugin.wasm differ diff --git a/crates/ide-plugin/tests/fixtures/file-templates/dist/plugin.wasm.sources b/crates/ide-plugin/tests/fixtures/file-templates/dist/plugin.wasm.sources index e65bfe3e6..8e79cf0b8 100644 --- a/crates/ide-plugin/tests/fixtures/file-templates/dist/plugin.wasm.sources +++ b/crates/ide-plugin/tests/fixtures/file-templates/dist/plugin.wasm.sources @@ -1 +1 @@ -99c968b98d8f1d895c428b4048451275bd322e7070aa0a020737097efea17eb1 +98e0e01e8405ae7501e89c0dab06e6672b5240a831b19e8fbf0604a3171b31e9 diff --git a/crates/ide-plugin/tests/fixtures/files-events/dist/plugin.wasm b/crates/ide-plugin/tests/fixtures/files-events/dist/plugin.wasm index fdba6cd26..1e603dbe0 100644 Binary files a/crates/ide-plugin/tests/fixtures/files-events/dist/plugin.wasm and b/crates/ide-plugin/tests/fixtures/files-events/dist/plugin.wasm differ diff --git a/crates/ide-plugin/tests/fixtures/files-events/dist/plugin.wasm.sources b/crates/ide-plugin/tests/fixtures/files-events/dist/plugin.wasm.sources index 6217ed1c2..5cdb67f37 100644 --- a/crates/ide-plugin/tests/fixtures/files-events/dist/plugin.wasm.sources +++ b/crates/ide-plugin/tests/fixtures/files-events/dist/plugin.wasm.sources @@ -1 +1 @@ -c40a0fd8c6cf791e70ba0335c6cf0b2c82b250670ebad59b185e3e8719172409 +fcee11f27ff9ae0038e8067712e269ccd49423372f692e9351c24f82906aafad diff --git a/crates/ide-plugin/tests/fixtures/grouped-views/dist/plugin.wasm b/crates/ide-plugin/tests/fixtures/grouped-views/dist/plugin.wasm index 704fc1115..f86ea2602 100644 Binary files a/crates/ide-plugin/tests/fixtures/grouped-views/dist/plugin.wasm and b/crates/ide-plugin/tests/fixtures/grouped-views/dist/plugin.wasm differ diff --git a/crates/ide-plugin/tests/fixtures/grouped-views/dist/plugin.wasm.sources b/crates/ide-plugin/tests/fixtures/grouped-views/dist/plugin.wasm.sources index d9150f1a6..73090cbeb 100644 --- a/crates/ide-plugin/tests/fixtures/grouped-views/dist/plugin.wasm.sources +++ b/crates/ide-plugin/tests/fixtures/grouped-views/dist/plugin.wasm.sources @@ -1 +1 @@ -162774155d8b49d53b0c0c055736bd098723c66b02c0e1dc4389985982c57282 +5c777d7b146277fa803587d1788a7359b08478def00c4574dd565d784200e39a diff --git a/crates/ide-plugin/tests/fixtures/hello/dist/plugin.wasm b/crates/ide-plugin/tests/fixtures/hello/dist/plugin.wasm index a6cc6567e..368c8e196 100644 Binary files a/crates/ide-plugin/tests/fixtures/hello/dist/plugin.wasm and b/crates/ide-plugin/tests/fixtures/hello/dist/plugin.wasm differ diff --git a/crates/ide-plugin/tests/fixtures/hello/dist/plugin.wasm.sources b/crates/ide-plugin/tests/fixtures/hello/dist/plugin.wasm.sources index 70ae6f136..af581b368 100644 --- a/crates/ide-plugin/tests/fixtures/hello/dist/plugin.wasm.sources +++ b/crates/ide-plugin/tests/fixtures/hello/dist/plugin.wasm.sources @@ -1 +1 @@ -39e3de11f69c09348906878367318157fca9a777f9ac1c4fb6ed303fa058e5a2 +825b9ee483796efd24fcfe358b94f4667d87e311475769ec9e41ba9af6d03a6a diff --git a/crates/ide-plugin/tests/fixtures/hover/dist/plugin.wasm b/crates/ide-plugin/tests/fixtures/hover/dist/plugin.wasm index d7f853d24..b2542284f 100644 Binary files a/crates/ide-plugin/tests/fixtures/hover/dist/plugin.wasm and b/crates/ide-plugin/tests/fixtures/hover/dist/plugin.wasm differ diff --git a/crates/ide-plugin/tests/fixtures/hover/dist/plugin.wasm.sources b/crates/ide-plugin/tests/fixtures/hover/dist/plugin.wasm.sources index 3ddf4be2a..cabd09f25 100644 --- a/crates/ide-plugin/tests/fixtures/hover/dist/plugin.wasm.sources +++ b/crates/ide-plugin/tests/fixtures/hover/dist/plugin.wasm.sources @@ -1 +1 @@ -4a3f595d2a6a9b79da7e316a3da86c287e9761ea670319c331467e7b10639663 +45b8cbd2ed7635ce04651937574dde9cf441dd619d76b8996f522c671950eaee diff --git a/crates/ide-plugin/tests/fixtures/indexer/dist/plugin.wasm b/crates/ide-plugin/tests/fixtures/indexer/dist/plugin.wasm index 9ead8900a..d60a97fea 100644 Binary files a/crates/ide-plugin/tests/fixtures/indexer/dist/plugin.wasm and b/crates/ide-plugin/tests/fixtures/indexer/dist/plugin.wasm differ diff --git a/crates/ide-plugin/tests/fixtures/indexer/dist/plugin.wasm.sources b/crates/ide-plugin/tests/fixtures/indexer/dist/plugin.wasm.sources index dcd46bcda..d152e6aa2 100644 --- a/crates/ide-plugin/tests/fixtures/indexer/dist/plugin.wasm.sources +++ b/crates/ide-plugin/tests/fixtures/indexer/dist/plugin.wasm.sources @@ -1 +1 @@ -bede1f0eaec356e3e35302e65e85531870625560bc9a3197f1acb58969beb4bd +e456b7ddf087ffbf2df62431bf9df47fad1929079c99a941a5deaf30599109f9 diff --git a/crates/ide-plugin/tests/fixtures/inlay-hints/dist/plugin.wasm b/crates/ide-plugin/tests/fixtures/inlay-hints/dist/plugin.wasm index 75d7e93a4..1c4124f65 100644 Binary files a/crates/ide-plugin/tests/fixtures/inlay-hints/dist/plugin.wasm and b/crates/ide-plugin/tests/fixtures/inlay-hints/dist/plugin.wasm differ diff --git a/crates/ide-plugin/tests/fixtures/inlay-hints/dist/plugin.wasm.sources b/crates/ide-plugin/tests/fixtures/inlay-hints/dist/plugin.wasm.sources index 6887c25d5..15e2f5c85 100644 --- a/crates/ide-plugin/tests/fixtures/inlay-hints/dist/plugin.wasm.sources +++ b/crates/ide-plugin/tests/fixtures/inlay-hints/dist/plugin.wasm.sources @@ -1 +1 @@ -ad2dc0ad12adb9c6b25017b2cef78b7496e96d1bb6e88b24ea9b7b682120e786 +e0d8b590ad6ffd9569c6362802b2be909cb34b37b18cc8cc8492f9c460610e20 diff --git a/crates/ide-plugin/tests/fixtures/jobs/dist/plugin.wasm b/crates/ide-plugin/tests/fixtures/jobs/dist/plugin.wasm index fef4c6628..0a3c25d93 100644 Binary files a/crates/ide-plugin/tests/fixtures/jobs/dist/plugin.wasm and b/crates/ide-plugin/tests/fixtures/jobs/dist/plugin.wasm differ diff --git a/crates/ide-plugin/tests/fixtures/jobs/dist/plugin.wasm.sources b/crates/ide-plugin/tests/fixtures/jobs/dist/plugin.wasm.sources index 535ef30b6..0c7a230d4 100644 --- a/crates/ide-plugin/tests/fixtures/jobs/dist/plugin.wasm.sources +++ b/crates/ide-plugin/tests/fixtures/jobs/dist/plugin.wasm.sources @@ -1 +1 @@ -2c329cf7af36c9d65ed5b6be7c2a017c7a5a6214a4893cab7ae574acb76fe62f +d2512203db3e5c6df93e9ccd5ff8daed8f1ebd28462b8caf7d500e814d3b6671 diff --git a/crates/ide-plugin/tests/fixtures/jobs/src/lib.rs b/crates/ide-plugin/tests/fixtures/jobs/src/lib.rs index 6373b8e5e..4f7103c3b 100644 --- a/crates/ide-plugin/tests/fixtures/jobs/src/lib.rs +++ b/crates/ide-plugin/tests/fixtures/jobs/src/lib.rs @@ -75,6 +75,14 @@ impl Plugin for Jobs { )?; Ok(None) } + "notify-project" => { + // The argument is a path in the target project, as a scheduled check would have. + let path = arg.unwrap_or_default(); + let project = host::project_of(path).ok_or("no project contains the path")?; + let action = openidea_plugin::NotificationAction::new("Disable", "context").argument(path); + project.notify(NotificationLevel::Info, "Project update", path, &[action])?; + Ok(None) + } "copy" => { host::copy_to_clipboard(arg.unwrap_or_default())?; Ok(None) diff --git a/crates/ide-plugin/tests/fixtures/language-features/dist/plugin.wasm b/crates/ide-plugin/tests/fixtures/language-features/dist/plugin.wasm index c7ac7feb2..dc0efa3ca 100644 Binary files a/crates/ide-plugin/tests/fixtures/language-features/dist/plugin.wasm and b/crates/ide-plugin/tests/fixtures/language-features/dist/plugin.wasm differ diff --git a/crates/ide-plugin/tests/fixtures/language-features/dist/plugin.wasm.sources b/crates/ide-plugin/tests/fixtures/language-features/dist/plugin.wasm.sources index 7f06c4850..8022395dc 100644 --- a/crates/ide-plugin/tests/fixtures/language-features/dist/plugin.wasm.sources +++ b/crates/ide-plugin/tests/fixtures/language-features/dist/plugin.wasm.sources @@ -1 +1 @@ -39c85942177e937e48f32bcde86a0068dac484ba028a8d6785a5a2728db9e11b +b32da5137b552cfad2557716343ed8ac9236b34fec018e3f2facc7b78b67e72a diff --git a/crates/ide-plugin/tests/fixtures/misbehave/dist/plugin.wasm b/crates/ide-plugin/tests/fixtures/misbehave/dist/plugin.wasm index 2a180d2c1..cde75d225 100644 Binary files a/crates/ide-plugin/tests/fixtures/misbehave/dist/plugin.wasm and b/crates/ide-plugin/tests/fixtures/misbehave/dist/plugin.wasm differ diff --git a/crates/ide-plugin/tests/fixtures/misbehave/dist/plugin.wasm.sources b/crates/ide-plugin/tests/fixtures/misbehave/dist/plugin.wasm.sources index 9d59fc312..9192c16d6 100644 --- a/crates/ide-plugin/tests/fixtures/misbehave/dist/plugin.wasm.sources +++ b/crates/ide-plugin/tests/fixtures/misbehave/dist/plugin.wasm.sources @@ -1 +1 @@ -30a8cc05a40c7b99a78700430ae87d025ad7567b44384fdb696119aa421f8174 +ae58467cdb6e98a491d739884eee96d239f80451de749950d81f4fd480edba58 diff --git a/crates/ide-plugin/tests/fixtures/misbehave/src/lib.rs b/crates/ide-plugin/tests/fixtures/misbehave/src/lib.rs index 18234bec2..00284f69f 100644 --- a/crates/ide-plugin/tests/fixtures/misbehave/src/lib.rs +++ b/crates/ide-plugin/tests/fixtures/misbehave/src/lib.rs @@ -5,9 +5,9 @@ wit_bindgen::generate!({ inline: " package fixture:misbehave; world misbehave { - include openidea:plugin/plugin-syntax@1.4.0; - export openidea:plugin/providers@1.4.0; - export openidea:plugin/file-actions@1.4.0; + include openidea:plugin/plugin-syntax@1.5.0; + export openidea:plugin/providers@1.5.0; + export openidea:plugin/file-actions@1.5.0; } ", path: "../../../../../wit", diff --git a/crates/ide-plugin/tests/fixtures/path-events/dist/plugin.wasm b/crates/ide-plugin/tests/fixtures/path-events/dist/plugin.wasm index ac24fadae..74fde0674 100644 Binary files a/crates/ide-plugin/tests/fixtures/path-events/dist/plugin.wasm and b/crates/ide-plugin/tests/fixtures/path-events/dist/plugin.wasm differ diff --git a/crates/ide-plugin/tests/fixtures/path-events/dist/plugin.wasm.sources b/crates/ide-plugin/tests/fixtures/path-events/dist/plugin.wasm.sources index 5c9f9836b..c01ff98f4 100644 --- a/crates/ide-plugin/tests/fixtures/path-events/dist/plugin.wasm.sources +++ b/crates/ide-plugin/tests/fixtures/path-events/dist/plugin.wasm.sources @@ -1 +1 @@ -5f9c92b23c00269ec2b5dc8829ce526a8fc4c0d76ecb2925ec9a06ffeac5f0b4 +e378c85a4fe395c7b172065a33a2f15ad76852ac42d4099d2cf1f64540e13143 diff --git a/crates/ide-plugin/tests/fixtures/private-dir/dist/plugin.wasm b/crates/ide-plugin/tests/fixtures/private-dir/dist/plugin.wasm index 7b7305fb5..7d2615e10 100644 Binary files a/crates/ide-plugin/tests/fixtures/private-dir/dist/plugin.wasm and b/crates/ide-plugin/tests/fixtures/private-dir/dist/plugin.wasm differ diff --git a/crates/ide-plugin/tests/fixtures/private-dir/dist/plugin.wasm.sources b/crates/ide-plugin/tests/fixtures/private-dir/dist/plugin.wasm.sources index 4739b4f92..ca4e97913 100644 --- a/crates/ide-plugin/tests/fixtures/private-dir/dist/plugin.wasm.sources +++ b/crates/ide-plugin/tests/fixtures/private-dir/dist/plugin.wasm.sources @@ -1 +1 @@ -d695409029a66c8a44f524072be1d47ed974fc8810f6fe1d8d068765184d4028 +23dc9ab1affb5b0c0166a5bb2bffb8a273a5c9eed0c06d402f16a1440b835639 diff --git a/crates/ide-plugin/tests/fixtures/semantic-tokens/dist/plugin.wasm b/crates/ide-plugin/tests/fixtures/semantic-tokens/dist/plugin.wasm index 883742c9d..fb23fd987 100644 Binary files a/crates/ide-plugin/tests/fixtures/semantic-tokens/dist/plugin.wasm and b/crates/ide-plugin/tests/fixtures/semantic-tokens/dist/plugin.wasm differ diff --git a/crates/ide-plugin/tests/fixtures/semantic-tokens/dist/plugin.wasm.sources b/crates/ide-plugin/tests/fixtures/semantic-tokens/dist/plugin.wasm.sources index 73bfc36a1..9f9738d67 100644 --- a/crates/ide-plugin/tests/fixtures/semantic-tokens/dist/plugin.wasm.sources +++ b/crates/ide-plugin/tests/fixtures/semantic-tokens/dist/plugin.wasm.sources @@ -1 +1 @@ -d5e81a43dc2c5298d0aaafd70c0bd91ab6cc040d70224d2936349de41253735f +d82fa182c8d5a029451addbf3b9792419446849911949e61052fca181d7758ce diff --git a/crates/ide-plugin/tests/fixtures/settings-pages/dist/plugin.wasm b/crates/ide-plugin/tests/fixtures/settings-pages/dist/plugin.wasm index 82c1b2f44..16a0b5910 100644 Binary files a/crates/ide-plugin/tests/fixtures/settings-pages/dist/plugin.wasm and b/crates/ide-plugin/tests/fixtures/settings-pages/dist/plugin.wasm differ diff --git a/crates/ide-plugin/tests/fixtures/settings-pages/dist/plugin.wasm.sources b/crates/ide-plugin/tests/fixtures/settings-pages/dist/plugin.wasm.sources index 512389bf7..e1f7768b6 100644 --- a/crates/ide-plugin/tests/fixtures/settings-pages/dist/plugin.wasm.sources +++ b/crates/ide-plugin/tests/fixtures/settings-pages/dist/plugin.wasm.sources @@ -1 +1 @@ -c29076023ccedf2da8fd9e5a851a47bbe7131b97713c8140a20cd55608a1cc0d +12337d77078aeb678567c0dc87c746a78454656ed52a2e51dd0bb81f19d90da3 diff --git a/crates/ide-plugin/tests/fixtures/storage/dist/plugin.wasm b/crates/ide-plugin/tests/fixtures/storage/dist/plugin.wasm index cbfc1524c..f324ede69 100644 Binary files a/crates/ide-plugin/tests/fixtures/storage/dist/plugin.wasm and b/crates/ide-plugin/tests/fixtures/storage/dist/plugin.wasm differ diff --git a/crates/ide-plugin/tests/fixtures/storage/dist/plugin.wasm.sources b/crates/ide-plugin/tests/fixtures/storage/dist/plugin.wasm.sources index 4a92be09f..b3957b4a8 100644 --- a/crates/ide-plugin/tests/fixtures/storage/dist/plugin.wasm.sources +++ b/crates/ide-plugin/tests/fixtures/storage/dist/plugin.wasm.sources @@ -1 +1 @@ -616157bd77dc272f9e2dfed4c54c9d65fca110e55ad01f92b7c4f8a6136537b4 +9048b66162a39a518d117cd473f6192827bc05737ff5132324c54eb8295b060b diff --git a/crates/ide-plugin/tests/fixtures/symbols/dist/plugin.wasm b/crates/ide-plugin/tests/fixtures/symbols/dist/plugin.wasm index 228ca9e39..9da6dcb9e 100644 Binary files a/crates/ide-plugin/tests/fixtures/symbols/dist/plugin.wasm and b/crates/ide-plugin/tests/fixtures/symbols/dist/plugin.wasm differ diff --git a/crates/ide-plugin/tests/fixtures/symbols/dist/plugin.wasm.sources b/crates/ide-plugin/tests/fixtures/symbols/dist/plugin.wasm.sources index 4c26b5f91..0edf612e1 100644 --- a/crates/ide-plugin/tests/fixtures/symbols/dist/plugin.wasm.sources +++ b/crates/ide-plugin/tests/fixtures/symbols/dist/plugin.wasm.sources @@ -1 +1 @@ -022f216f0f4ca5da56f4b2fabf5ee4a987d5e9f9a752feecbb438f9b00b1acf4 +274f7e74f19aabf9368c2b9a107494d82a2013d4adda645bde6d9ccda4007769 diff --git a/crates/ide-plugin/tests/fixtures/tables/dist/plugin.wasm b/crates/ide-plugin/tests/fixtures/tables/dist/plugin.wasm index 7ed6ce40b..9a5dbc30f 100644 Binary files a/crates/ide-plugin/tests/fixtures/tables/dist/plugin.wasm and b/crates/ide-plugin/tests/fixtures/tables/dist/plugin.wasm differ diff --git a/crates/ide-plugin/tests/fixtures/tables/dist/plugin.wasm.sources b/crates/ide-plugin/tests/fixtures/tables/dist/plugin.wasm.sources index b0d33305d..f4e67900e 100644 --- a/crates/ide-plugin/tests/fixtures/tables/dist/plugin.wasm.sources +++ b/crates/ide-plugin/tests/fixtures/tables/dist/plugin.wasm.sources @@ -1 +1 @@ -626f0e0c83e69704c0365c273b6f63d43278ee37786f38ed467ce908c30eadf7 +e9082dc0f4c9c4fc682e16821d36f7fa42be9c82b75ac28edbee6a869dc86b8b diff --git a/crates/ide-plugin/tests/fixtures/web-content/dist/plugin.wasm b/crates/ide-plugin/tests/fixtures/web-content/dist/plugin.wasm index aa61e4998..d8d399879 100644 Binary files a/crates/ide-plugin/tests/fixtures/web-content/dist/plugin.wasm and b/crates/ide-plugin/tests/fixtures/web-content/dist/plugin.wasm differ diff --git a/crates/ide-plugin/tests/fixtures/web-content/dist/plugin.wasm.sources b/crates/ide-plugin/tests/fixtures/web-content/dist/plugin.wasm.sources index 5fa8950ef..2e7dcf499 100644 --- a/crates/ide-plugin/tests/fixtures/web-content/dist/plugin.wasm.sources +++ b/crates/ide-plugin/tests/fixtures/web-content/dist/plugin.wasm.sources @@ -1 +1 @@ -aa141701049f5c6c0d045341c3337344ed7a368800f08237b1b7812cce216814 +0028a0439e8bb234fb0cc5138e1c27d5c2c8443bed12963a69f0bd8b3818ec7b diff --git a/crates/ide-plugin/tests/fixtures/web-log/dist/plugin.wasm b/crates/ide-plugin/tests/fixtures/web-log/dist/plugin.wasm index 82022e0ed..75c5f5dac 100644 Binary files a/crates/ide-plugin/tests/fixtures/web-log/dist/plugin.wasm and b/crates/ide-plugin/tests/fixtures/web-log/dist/plugin.wasm differ diff --git a/crates/ide-plugin/tests/fixtures/web-log/dist/plugin.wasm.sources b/crates/ide-plugin/tests/fixtures/web-log/dist/plugin.wasm.sources index 43039f704..78a68fa7e 100644 --- a/crates/ide-plugin/tests/fixtures/web-log/dist/plugin.wasm.sources +++ b/crates/ide-plugin/tests/fixtures/web-log/dist/plugin.wasm.sources @@ -1 +1 @@ -d6c40099cc959ef2dead996beeb4acd73c1327597cd029674026c6f2bc878300 +f3b633e9e34a5343f318e4e451ffe1c87a6d1ac6d0dc01a57588ea99380dd8d4 diff --git a/crates/ide-plugin/tests/fixtures/web-pty/dist/plugin.wasm b/crates/ide-plugin/tests/fixtures/web-pty/dist/plugin.wasm index 2ab1c4e4b..7f798adaf 100644 Binary files a/crates/ide-plugin/tests/fixtures/web-pty/dist/plugin.wasm and b/crates/ide-plugin/tests/fixtures/web-pty/dist/plugin.wasm differ diff --git a/crates/ide-plugin/tests/fixtures/web-pty/dist/plugin.wasm.sources b/crates/ide-plugin/tests/fixtures/web-pty/dist/plugin.wasm.sources index 601107faf..3e990dd79 100644 --- a/crates/ide-plugin/tests/fixtures/web-pty/dist/plugin.wasm.sources +++ b/crates/ide-plugin/tests/fixtures/web-pty/dist/plugin.wasm.sources @@ -1 +1 @@ -3201f643cf868f7a358ba812f9c90e06b982d864ed141b6b4c3fdeee13cb1559 +02fba523571a945b16055e83ee72400f69ecb64238556e933cfd5c2c92c8ea10 diff --git a/plugins/README.md b/plugins/README.md index 96182e1f8..f9782672e 100644 --- a/plugins/README.md +++ b/plugins/README.md @@ -37,7 +37,7 @@ sdk/rust/openidea-plugin/ # the Rust SDK (host API, Plugin trait, mock host) crates/ide-plugin/tests/fixtures/ # test plugins: hello, jobs, language-toy, misbehave, semantic-tokens, hover, commit, inlay-hints ``` -The plugin API is defined in [`wit/`](../wit/) (`openidea:plugin@1.4.0`, world +The plugin API is defined in [`wit/`](../wit/) (`openidea:plugin@1.5.0`, world `plugin`). ## 1. Quick start @@ -365,9 +365,19 @@ are always available. Calling a gated function without its capability returns ## 3. Writing code (Rust SDK) +### API 1.5 + +API 1.5.0 is planned for the next OpenIDEA release. Use +`engines.openidea = "^1.5"` and the matching SDK. Released 1.4 plugins keep +working. New in 1.5: + +- [Notifications for a project](#notifications-with-commands): + `Project::notify` shows a notification in a window of that project only, + also from scheduled or background work. + ### API 1.4 -API 1.4.0 is planned for the next OpenIDEA release. Use +API 1.4.0 shipped with OpenIDEA 0.1.40. Use `engines.openidea = "^1.4"` and the matching SDK. Released 1.3 plugins keep working. New in 1.4: @@ -525,6 +535,7 @@ then run `openidea-plugin check`. | `host::output_append(channel, text)`, `output_clear`, `output_reveal` | `output.{append,clear,reveal}` | API 1.4: read-only Output tabs; 32 named channels per plugin, each a 1 MiB UTF-8 ring buffer. Reveal requires the invoking window. | | `host::set_context(key, value)`, `remove_context` | `ui.{set,remove}-context` | Sets `plugin..` for `when` clauses in the window the call came from (`true`, `3.5`, `"text"`; `ContextValue`). Key 1–64 of `A-Za-z0-9_-`, 100 per plugin; gone when the plugin stops. | | `host::notify(level, title, body)` | `ui.show-notification` | Balloon in the window the command or events came from (every window otherwise). | +| `Project::notify(level, title, body, actions)` | `ui.notify-project` | API 1.5: balloon only in a window of that project (the most recently focused one), with or without an invoking window; see _Notifications with commands_. | | `host::copy_to_clipboard(text)` | `ui.copy-to-clipboard` | Copies `text` to the system clipboard. Needs `clipboard`. | | `host::open_url(url)` | `ui.open-url` | Opens an `http://` or `https://` URL in the user's default browser. | | `host::pick(title, items)`, `pick_many` | `ui.pick`, `ui.pick-many` | Picks key(s) from `PickItem`s, or `None` when dismissed. From a command/event or code-action resolution in its editor window (else `invalid`); waiting is excluded from the budget. | @@ -2254,8 +2265,8 @@ the API itself follows _Evolving the plugin API_ below. ## 10. Evolving the plugin API Released versions are frozen: 1.0.0 shipped with OpenIDEA 0.1.36, 1.1.0 -with 0.1.37, 1.2.0 with 0.1.38 and 1.3.0 with 0.1.39. API 1.4.0 is planned -with the next release. wasmtime decides what stays compatible: it resolves interface names +with 0.1.37, 1.2.0 with 0.1.38, 1.3.0 with 0.1.39 and 1.4.0 with 0.1.40. +API 1.5.0 is planned with the next release. wasmtime decides what stays compatible: it resolves interface names by semver (a component importing `openidea:plugin/x@1.0.0` links against a host defining `@1.1.0`, and the host finds its exports the same way), but function types must match exactly — a record with another field count, or a @@ -2382,6 +2393,29 @@ its normal editor and project context. No capability is needed. Invalid or undeclared actions reject the whole notification. Labels are limited to 256 bytes and arguments to 64 KiB. Plain `host::notify` behaves as before. +Both go to the window the command or event came from, or to every window when +there is none (a scheduled call, for instance). To reach one project from such +work, call `notify` on that [`Project`](#the-api) (API 1.5, `ui.notify-project`), +with the same actions and limits: + +```rust +for project in host::projects()? { + if let Some(update) = check_for_update(&project)? { + let disable = NotificationAction::new("Disable automatic checks", "disable-checks") + .argument(project.root()?); + project.notify(NotificationLevel::Info, "Update available", &update, &[disable])?; + } +} +``` + +- It shows only in a window of that project: the most recently focused one + when the project is open in several. +- A button runs its command with an invocation from that window, so + `ctx.project()` is the notification's project. +- If the project has closed by the time of the call, the call fails with + `Error::NotFound` and shows nothing; it never falls back to another window. + A balloon already shown goes away with its window. + ### Selecting plugin tests (API 1.4, unreleased) A plugin using `framework = "plugin"` can implement `TestResults::select_tests` diff --git a/plugins/official/ai-completion/dist/plugin.wasm b/plugins/official/ai-completion/dist/plugin.wasm index f0ecc3db1..f03968c39 100644 Binary files a/plugins/official/ai-completion/dist/plugin.wasm and b/plugins/official/ai-completion/dist/plugin.wasm differ diff --git a/plugins/official/ai-completion/dist/plugin.wasm.sources b/plugins/official/ai-completion/dist/plugin.wasm.sources index 01b21dc3c..8bbfb5ac7 100644 --- a/plugins/official/ai-completion/dist/plugin.wasm.sources +++ b/plugins/official/ai-completion/dist/plugin.wasm.sources @@ -1 +1 @@ -e3c11d8969a1b8b52e7e745b558d12f804ebf533e7f0f3fe614ffe6f7b9c9468 +bb67a1b003840ecc2d0c056a0b0af3474b08ac095239c1f4d02b7a7aab5b526c diff --git a/plugins/official/blame-annotations/dist/plugin.wasm b/plugins/official/blame-annotations/dist/plugin.wasm index e587d7424..54a38d42d 100644 Binary files a/plugins/official/blame-annotations/dist/plugin.wasm and b/plugins/official/blame-annotations/dist/plugin.wasm differ diff --git a/plugins/official/blame-annotations/dist/plugin.wasm.sources b/plugins/official/blame-annotations/dist/plugin.wasm.sources index 2273eeffd..a7bcc6398 100644 --- a/plugins/official/blame-annotations/dist/plugin.wasm.sources +++ b/plugins/official/blame-annotations/dist/plugin.wasm.sources @@ -1 +1 @@ -b28ccfd442c6348e0826680ec97391cbe4ec6a93a27ff02e40f47341e21586b4 +a6289739f5b644ea559ba18298741205ea0bedce7bd1dd2b367309101e8ffb1e diff --git a/plugins/official/checkstyle/dist/plugin.wasm b/plugins/official/checkstyle/dist/plugin.wasm index d365a3c23..924c606c2 100644 Binary files a/plugins/official/checkstyle/dist/plugin.wasm and b/plugins/official/checkstyle/dist/plugin.wasm differ diff --git a/plugins/official/checkstyle/dist/plugin.wasm.sources b/plugins/official/checkstyle/dist/plugin.wasm.sources index 77c26c9be..870903222 100644 --- a/plugins/official/checkstyle/dist/plugin.wasm.sources +++ b/plugins/official/checkstyle/dist/plugin.wasm.sources @@ -1 +1 @@ -d669a2600b0c59e91ac8a9b875a24bddf0eeddd404ce7b67da31733861a846b8 +767ff8329456fe3a1f324f571b22124707244a61ff5b6ea2c7ed88f909d202e8 diff --git a/plugins/official/container-runner/dist/plugin.wasm b/plugins/official/container-runner/dist/plugin.wasm index 13f0d8ac4..4edd70fa3 100644 Binary files a/plugins/official/container-runner/dist/plugin.wasm and b/plugins/official/container-runner/dist/plugin.wasm differ diff --git a/plugins/official/container-runner/dist/plugin.wasm.sources b/plugins/official/container-runner/dist/plugin.wasm.sources index 783e10d71..8b8b475a4 100644 --- a/plugins/official/container-runner/dist/plugin.wasm.sources +++ b/plugins/official/container-runner/dist/plugin.wasm.sources @@ -1 +1 @@ -a5f0ebce6d30e0dc03769ebe5cb82d3704c5ccc32207aa2b3f5500de7b1a9152 +edb2a28419861c6f2d7cd5c300fa9f3120df5c17fb94596814635a9d97bf56d7 diff --git a/plugins/official/csv-editor/dist/plugin.wasm b/plugins/official/csv-editor/dist/plugin.wasm index 180db9233..0f8e6e7ca 100644 Binary files a/plugins/official/csv-editor/dist/plugin.wasm and b/plugins/official/csv-editor/dist/plugin.wasm differ diff --git a/plugins/official/csv-editor/dist/plugin.wasm.sources b/plugins/official/csv-editor/dist/plugin.wasm.sources index 784a626bd..5d08f5be2 100644 --- a/plugins/official/csv-editor/dist/plugin.wasm.sources +++ b/plugins/official/csv-editor/dist/plugin.wasm.sources @@ -1 +1 @@ -ee3ccb648ca4b98a0359521c4cd895b5e7336fd65101563f2ca82b8cbaeedc3d +debc0eccd6eb6a93bafecb0d6eca8feb26a3436d9154a278b877eaee567dce80 diff --git a/plugins/official/git-toolbox/dist/plugin.wasm b/plugins/official/git-toolbox/dist/plugin.wasm index 18426a611..2ca33302a 100644 Binary files a/plugins/official/git-toolbox/dist/plugin.wasm and b/plugins/official/git-toolbox/dist/plugin.wasm differ diff --git a/plugins/official/git-toolbox/dist/plugin.wasm.sources b/plugins/official/git-toolbox/dist/plugin.wasm.sources index 19fc760c6..9dd73fdaf 100644 --- a/plugins/official/git-toolbox/dist/plugin.wasm.sources +++ b/plugins/official/git-toolbox/dist/plugin.wasm.sources @@ -1 +1 @@ -51f7167dd5ed21ed37e227bd3b100a5be5a57e7890a494c942fdd036b1307993 +6e7cea8633d117d65b293c35bf332d8f4474ab1fdea88aedb37aa189e130857d diff --git a/plugins/official/graphviz/dist/plugin.wasm b/plugins/official/graphviz/dist/plugin.wasm index 403852a4c..7fd071433 100644 Binary files a/plugins/official/graphviz/dist/plugin.wasm and b/plugins/official/graphviz/dist/plugin.wasm differ diff --git a/plugins/official/graphviz/dist/plugin.wasm.sources b/plugins/official/graphviz/dist/plugin.wasm.sources index 6d2cdb427..3dbbdd82c 100644 --- a/plugins/official/graphviz/dist/plugin.wasm.sources +++ b/plugins/official/graphviz/dist/plugin.wasm.sources @@ -1 +1 @@ -cd860e7a652951aaa42029da23fdeee7a3c09ab1bfcbfb0d1bb6c89036fc8817 +e3a0ef77e0c7b54307751d24cc899a0cf782149ebf98833fc1d7b990b369cced diff --git a/plugins/official/key-promoter/dist/plugin.wasm b/plugins/official/key-promoter/dist/plugin.wasm index a3dacfd42..bd4b75dda 100644 Binary files a/plugins/official/key-promoter/dist/plugin.wasm and b/plugins/official/key-promoter/dist/plugin.wasm differ diff --git a/plugins/official/key-promoter/dist/plugin.wasm.sources b/plugins/official/key-promoter/dist/plugin.wasm.sources index 19b7b5604..7852ffe4f 100644 --- a/plugins/official/key-promoter/dist/plugin.wasm.sources +++ b/plugins/official/key-promoter/dist/plugin.wasm.sources @@ -1 +1 @@ -db3ee94b5cf4234cee7d61e08a9f8629d7e7f6adbf11208b54cd4ea44cf1fc13 +39e75e8fc6d9227dce2efc7e29ffc03d4b1a2364e4710d74a4b255850bef1928 diff --git a/plugins/official/license-header/dist/plugin.wasm b/plugins/official/license-header/dist/plugin.wasm index 7f13fe3ca..40e81a11a 100644 Binary files a/plugins/official/license-header/dist/plugin.wasm and b/plugins/official/license-header/dist/plugin.wasm differ diff --git a/plugins/official/license-header/dist/plugin.wasm.sources b/plugins/official/license-header/dist/plugin.wasm.sources index 32875ff17..dc8d961b5 100644 --- a/plugins/official/license-header/dist/plugin.wasm.sources +++ b/plugins/official/license-header/dist/plugin.wasm.sources @@ -1 +1 @@ -76d13e772046b192485ea59c7720177b563986e0167475c449a9a5c7430ef908 +bd06b9b59b6515a1fd8a71271a4d8bb5280b685f400e141eba7365e7daabc7ea diff --git a/plugins/official/mybatis/dist/plugin.wasm b/plugins/official/mybatis/dist/plugin.wasm index 14b74de75..518c0347c 100644 Binary files a/plugins/official/mybatis/dist/plugin.wasm and b/plugins/official/mybatis/dist/plugin.wasm differ diff --git a/plugins/official/mybatis/dist/plugin.wasm.sources b/plugins/official/mybatis/dist/plugin.wasm.sources index c8d4649db..ff7c5ea2d 100644 --- a/plugins/official/mybatis/dist/plugin.wasm.sources +++ b/plugins/official/mybatis/dist/plugin.wasm.sources @@ -1 +1 @@ -a22c9e7ebf79b2d5926424a028edc09aef40293db9ebc959d9ececa1f0ebe4ca +3e04301385edee3c3693a89860e49b9d933ee3ad22046cd9cda320c10e64cec4 diff --git a/plugins/official/regex-tester/dist/plugin.wasm b/plugins/official/regex-tester/dist/plugin.wasm index 686d70ed3..a2a10fa93 100644 Binary files a/plugins/official/regex-tester/dist/plugin.wasm and b/plugins/official/regex-tester/dist/plugin.wasm differ diff --git a/plugins/official/regex-tester/dist/plugin.wasm.sources b/plugins/official/regex-tester/dist/plugin.wasm.sources index afb2fb7a6..f89683169 100644 --- a/plugins/official/regex-tester/dist/plugin.wasm.sources +++ b/plugins/official/regex-tester/dist/plugin.wasm.sources @@ -1 +1 @@ -fcc3d666fd1e89363fa8668dd10f89efc49f2376766282b734de4b719fdc9aff +e60ead150d753c9824eeed0279ebe0a14f7ad226a2b90977ebeba646397b407b diff --git a/plugins/official/solidity/dist/plugin.wasm b/plugins/official/solidity/dist/plugin.wasm index 4b490f21d..4f20be292 100644 Binary files a/plugins/official/solidity/dist/plugin.wasm and b/plugins/official/solidity/dist/plugin.wasm differ diff --git a/plugins/official/solidity/dist/plugin.wasm.sources b/plugins/official/solidity/dist/plugin.wasm.sources index 5a18d3887..0806debc8 100644 --- a/plugins/official/solidity/dist/plugin.wasm.sources +++ b/plugins/official/solidity/dist/plugin.wasm.sources @@ -1 +1 @@ -2eb742315f877e3251f992884160ed4d9a2940ee12a7d4d7a52669238d495930 +b8d20ee5966943cd298ab16a61b1552ddc523b2669ec2d11ad97bb1a86045ce6 diff --git a/plugins/official/string-tools/dist/plugin.wasm b/plugins/official/string-tools/dist/plugin.wasm index 5912af33d..ce75054dc 100644 Binary files a/plugins/official/string-tools/dist/plugin.wasm and b/plugins/official/string-tools/dist/plugin.wasm differ diff --git a/plugins/official/string-tools/dist/plugin.wasm.sources b/plugins/official/string-tools/dist/plugin.wasm.sources index 3c0fba9b4..b9fd8193e 100644 --- a/plugins/official/string-tools/dist/plugin.wasm.sources +++ b/plugins/official/string-tools/dist/plugin.wasm.sources @@ -1 +1 @@ -c2feb6a4cd0e9908f078a3d0074732cfce653cc57cce9d1907838598515048ee +65fa71854546a7b19f7afe86642bc1e2c4eee9a7a08a71f87d307c68c95410d0 diff --git a/plugins/official/test-runner/dist/plugin.wasm b/plugins/official/test-runner/dist/plugin.wasm index 52238d677..537fc1c81 100644 Binary files a/plugins/official/test-runner/dist/plugin.wasm and b/plugins/official/test-runner/dist/plugin.wasm differ diff --git a/plugins/official/test-runner/dist/plugin.wasm.sources b/plugins/official/test-runner/dist/plugin.wasm.sources index 0e681748d..64f58c3b5 100644 --- a/plugins/official/test-runner/dist/plugin.wasm.sources +++ b/plugins/official/test-runner/dist/plugin.wasm.sources @@ -1 +1 @@ -590b46034f6c39592a27cabd5b0b76809e7f7133d258f322604614ecb3479317 +ce6fdce3010c8d836b452ebac7d0c7e42bf507b35f814ff448696a0541788d4a diff --git a/plugins/official/todo-finder/dist/plugin.wasm b/plugins/official/todo-finder/dist/plugin.wasm index b548e7ef0..3db4f0906 100644 Binary files a/plugins/official/todo-finder/dist/plugin.wasm and b/plugins/official/todo-finder/dist/plugin.wasm differ diff --git a/plugins/official/todo-finder/dist/plugin.wasm.sources b/plugins/official/todo-finder/dist/plugin.wasm.sources index 9b090f0ca..746318c7d 100644 --- a/plugins/official/todo-finder/dist/plugin.wasm.sources +++ b/plugins/official/todo-finder/dist/plugin.wasm.sources @@ -1 +1 @@ -0d068ea0f0851e6e3166af0a91f290da8dc3f4a852b86050e7f7ced214a39124 +1d3689b3b18946e41753390f5e37cd6870374884831c5c5e0fd66606a1bfb659 diff --git a/sdk/rust/openidea-plugin/src/host.rs b/sdk/rust/openidea-plugin/src/host.rs index b492677a0..7da979629 100644 --- a/sdk/rust/openidea-plugin/src/host.rs +++ b/sdk/rust/openidea-plugin/src/host.rs @@ -82,6 +82,29 @@ mod imp { wit::ui::notify(level, title, body, &actions).map_err(error) } + pub fn notify_project( + p: &ProjectRes, + level: NotificationLevel, + title: &str, + body: &str, + actions: &[NotificationAction], + ) -> Result<(), Error> { + let level = match level { + NotificationLevel::Info => wit::types::NotificationLevel::Info, + NotificationLevel::Warning => wit::types::NotificationLevel::Warning, + NotificationLevel::Error => wit::types::NotificationLevel::Error, + }; + let actions: Vec<_> = actions + .iter() + .map(|a| wit::ui::NotificationAction { + label: a.label.clone(), + command: a.command.clone(), + argument: a.argument.clone(), + }) + .collect(); + wit::ui::notify_project(p, level, title, body, &actions).map_err(error) + } + pub fn set_status_item(id: &str, item: &StatusItem) { let item = wit::ui::StatusItem { text: item.text.clone(), @@ -939,6 +962,20 @@ impl Project { imp::vcs_diff(&self.inner, path, against) } + /// [`notify_with_actions`] in a window of this project only (API 1.5), also from + /// scheduled or background work: the most recently focused one when it is open in + /// several, and its buttons run there. Once the project has closed this is + /// [`Error::NotFound`] and nothing is shown. Needs no capability. + pub fn notify( + &self, + level: NotificationLevel, + title: &str, + body: &str, + actions: &[NotificationAction], + ) -> Result<(), Error> { + imp::notify_project(&self.inner, level, title, body, actions) + } + /// Absolute path of the root. Needs `project.read`. pub fn root(&self) -> Result { imp::project_root(&self.inner) diff --git a/sdk/rust/openidea-plugin/src/lib.rs b/sdk/rust/openidea-plugin/src/lib.rs index 1c8025ad9..6c81ef186 100644 --- a/sdk/rust/openidea-plugin/src/lib.rs +++ b/sdk/rust/openidea-plugin/src/lib.rs @@ -98,7 +98,7 @@ pub mod providers_bindings { export_macro_name: "__export_editor_providers_world", default_bindings_module: "openidea_plugin::providers_bindings", with: { - "openidea:plugin/types@1.4.0": crate::bindings::openidea::plugin::types, + "openidea:plugin/types@1.5.0": crate::bindings::openidea::plugin::types, }, }); } @@ -115,10 +115,10 @@ pub mod views_bindings { export_macro_name: "__export_views_world", default_bindings_module: "openidea_plugin::views_bindings", with: { - "openidea:plugin/types@1.4.0": crate::bindings::openidea::plugin::types, - "openidea:plugin/workspace@1.4.0": crate::bindings::openidea::plugin::workspace, - "openidea:plugin/editor@1.4.0": crate::bindings::openidea::plugin::editor, - "openidea:plugin/invocation@1.4.0": crate::bindings::openidea::plugin::invocation, + "openidea:plugin/types@1.5.0": crate::bindings::openidea::plugin::types, + "openidea:plugin/workspace@1.5.0": crate::bindings::openidea::plugin::workspace, + "openidea:plugin/editor@1.5.0": crate::bindings::openidea::plugin::editor, + "openidea:plugin/invocation@1.5.0": crate::bindings::openidea::plugin::invocation, }, }); } @@ -130,7 +130,7 @@ pub mod indexing_bindings { world: "indexing", path: "wit", pub_export_macro: true, export_macro_name: "__export_indexing_world", default_bindings_module: "openidea_plugin::indexing_bindings", - with: { "openidea:plugin/types@1.4.0": crate::bindings::openidea::plugin::types }, + with: { "openidea:plugin/types@1.5.0": crate::bindings::openidea::plugin::types }, }); } @@ -142,10 +142,10 @@ pub mod details_bindings { export_macro_name: "__export_details_world", default_bindings_module: "openidea_plugin::details_bindings", with: { - "openidea:plugin/types@1.4.0": crate::bindings::openidea::plugin::types, - "openidea:plugin/workspace@1.4.0": crate::bindings::openidea::plugin::workspace, - "openidea:plugin/editor@1.4.0": crate::bindings::openidea::plugin::editor, - "openidea:plugin/invocation@1.4.0": crate::bindings::openidea::plugin::invocation, + "openidea:plugin/types@1.5.0": crate::bindings::openidea::plugin::types, + "openidea:plugin/workspace@1.5.0": crate::bindings::openidea::plugin::workspace, + "openidea:plugin/editor@1.5.0": crate::bindings::openidea::plugin::editor, + "openidea:plugin/invocation@1.5.0": crate::bindings::openidea::plugin::invocation, }, }); } @@ -157,7 +157,7 @@ pub mod semantic_bindings { world: "semantic-tokens", path: "wit", pub_export_macro: true, export_macro_name: "__export_semantic_tokens_world", default_bindings_module: "openidea_plugin::semantic_bindings", - with: { "openidea:plugin/types@1.4.0": crate::bindings::openidea::plugin::types }, + with: { "openidea:plugin/types@1.5.0": crate::bindings::openidea::plugin::types }, }); } @@ -169,8 +169,8 @@ pub mod diagnostics_bindings { export_macro_name: "__export_diagnostics_world", default_bindings_module: "openidea_plugin::diagnostics_bindings", with: { - "openidea:plugin/types@1.4.0": crate::bindings::openidea::plugin::types, - "openidea:plugin/diagnostics@1.4.0": crate::bindings::openidea::plugin::diagnostics, + "openidea:plugin/types@1.5.0": crate::bindings::openidea::plugin::types, + "openidea:plugin/diagnostics@1.5.0": crate::bindings::openidea::plugin::diagnostics, }, }); } @@ -182,7 +182,7 @@ pub mod hover_bindings { world: "hover", path: "wit", pub_export_macro: true, export_macro_name: "__export_hover_world", default_bindings_module: "openidea_plugin::hover_bindings", - with: { "openidea:plugin/types@1.4.0": crate::bindings::openidea::plugin::types }, + with: { "openidea:plugin/types@1.5.0": crate::bindings::openidea::plugin::types }, }); } @@ -194,11 +194,11 @@ pub mod commit_checks_bindings { export_macro_name: "__export_commit_checks_world", default_bindings_module: "openidea_plugin::commit_checks_bindings", with: { - "openidea:plugin/types@1.4.0": crate::bindings::openidea::plugin::types, - "openidea:plugin/workspace@1.4.0": crate::bindings::openidea::plugin::workspace, - "openidea:plugin/editor@1.4.0": crate::bindings::openidea::plugin::editor, - "openidea:plugin/invocation@1.4.0": crate::bindings::openidea::plugin::invocation, - "openidea:plugin/commit@1.4.0": crate::bindings::openidea::plugin::commit, + "openidea:plugin/types@1.5.0": crate::bindings::openidea::plugin::types, + "openidea:plugin/workspace@1.5.0": crate::bindings::openidea::plugin::workspace, + "openidea:plugin/editor@1.5.0": crate::bindings::openidea::plugin::editor, + "openidea:plugin/invocation@1.5.0": crate::bindings::openidea::plugin::invocation, + "openidea:plugin/commit@1.5.0": crate::bindings::openidea::plugin::commit, }, }); } @@ -210,7 +210,7 @@ pub mod inlay_bindings { world: "inlay-hints", path: "wit", pub_export_macro: true, export_macro_name: "__export_inlay_hints_world", default_bindings_module: "openidea_plugin::inlay_bindings", - with: { "openidea:plugin/types@1.4.0": crate::bindings::openidea::plugin::types }, + with: { "openidea:plugin/types@1.5.0": crate::bindings::openidea::plugin::types }, }); } @@ -221,7 +221,7 @@ pub mod file_actions_bindings { world: "file-actions-provider", path: "wit", pub_export_macro: true, export_macro_name: "__export_file_actions_world", default_bindings_module: "openidea_plugin::file_actions_bindings", - with: { "openidea:plugin/types@1.4.0": crate::bindings::openidea::plugin::types }, + with: { "openidea:plugin/types@1.5.0": crate::bindings::openidea::plugin::types }, }); } @@ -233,16 +233,16 @@ pub mod endpoints_bindings { export_macro_name: "__export_endpoints_world", default_bindings_module: "openidea_plugin::endpoints_bindings", with: { - "openidea:plugin/types@1.4.0": crate::bindings::openidea::plugin::types, - "openidea:plugin/workspace@1.4.0": crate::bindings::openidea::plugin::workspace, - "openidea:plugin/editor@1.4.0": crate::bindings::openidea::plugin::editor, - "openidea:plugin/invocation@1.4.0": crate::bindings::openidea::plugin::invocation, + "openidea:plugin/types@1.5.0": crate::bindings::openidea::plugin::types, + "openidea:plugin/workspace@1.5.0": crate::bindings::openidea::plugin::workspace, + "openidea:plugin/editor@1.5.0": crate::bindings::openidea::plugin::editor, + "openidea:plugin/invocation@1.5.0": crate::bindings::openidea::plugin::invocation, }, }); } /// The plugin API version this SDK targets. -pub const API_VERSION: &str = "1.3"; +pub const API_VERSION: &str = "1.5"; /// A plugin. One instance lives as long as the plugin's Wasm instance (until /// it is disabled, crashes or is reclaimed when idle). @@ -1304,7 +1304,7 @@ pub mod run_configurations_bindings { pub mod test_results_bindings { wit_bindgen::generate!({ world: "test-results-provider", path: "wit", pub_export_macro: true, export_macro_name: "__export_tests_world", default_bindings_module: "openidea_plugin::test_results_bindings", - with: { "openidea:plugin/types@1.4.0": crate::bindings::openidea::plugin::types }, + with: { "openidea:plugin/types@1.5.0": crate::bindings::openidea::plugin::types }, }); } #[doc(hidden)] @@ -1342,7 +1342,7 @@ pub mod language_features; pub mod language_features_bindings { wit_bindgen::generate!({world: "editor-language-features", path: "wit", pub_export_macro: true, export_macro_name: "__export_language_features_world", default_bindings_module: "openidea_plugin::language_features_bindings", - with: { "openidea:plugin/types@1.4.0": crate::bindings::openidea::plugin::types }, + with: { "openidea:plugin/types@1.5.0": crate::bindings::openidea::plugin::types }, }); } @@ -1374,7 +1374,7 @@ fn gutter_actions(doc: $crate::language_features_bindings::exports::openidea::pl pub mod injections_bindings { wit_bindgen::generate!({world: "language-injections", path: "wit", pub_export_macro: true, export_macro_name: "__export_injections_world", default_bindings_module: "openidea_plugin::injections_bindings", - with: { "openidea:plugin/types@1.4.0": crate::bindings::openidea::plugin::types }, + with: { "openidea:plugin/types@1.5.0": crate::bindings::openidea::plugin::types }, }); } @@ -1404,8 +1404,8 @@ pub mod mcp_bindings { wit_bindgen::generate!({ world: "mcp-tools", path: "wit", pub_export_macro: true, export_macro_name: "__export_mcp_world", default_bindings_module: "openidea_plugin::mcp_bindings", with: { - "openidea:plugin/types@1.4.0": crate::bindings::openidea::plugin::types, - "openidea:plugin/invocation@1.4.0": crate::bindings::openidea::plugin::invocation, + "openidea:plugin/types@1.5.0": crate::bindings::openidea::plugin::types, + "openidea:plugin/invocation@1.5.0": crate::bindings::openidea::plugin::invocation, }, }); } diff --git a/sdk/rust/openidea-plugin/src/mock.rs b/sdk/rust/openidea-plugin/src/mock.rs index bb02de632..2681d6e84 100644 --- a/sdk/rust/openidea-plugin/src/mock.rs +++ b/sdk/rust/openidea-plugin/src/mock.rs @@ -96,6 +96,7 @@ struct State { selected_paths: Vec, notifications: Vec, action_notifications: Vec, + project_notifications: Vec<(String, ActionNotification)>, logs: Vec<(LogLevel, String)>, status: BTreeMap, window_status: BTreeMap, @@ -341,6 +342,11 @@ impl MockHost { self.state.borrow().action_notifications.clone() } + /// Notifications sent to a project (`Project::notify`), with its root, in publication order. + pub fn project_notifications(&self) -> Vec<(String, ActionNotification)> { + self.state.borrow().project_notifications.clone() + } + pub fn logs(&self) -> Vec<(LogLevel, String)> { self.state.borrow().logs.clone() } @@ -773,6 +779,35 @@ pub mod current { body: &str, actions: &[NotificationAction], ) -> Result<(), Error> { + check_actions(actions)?; + with(|s| { + let notification = Notification { level, title: title.into(), body: body.into() }; + s.notifications.push(notification.clone()); + s.action_notifications.push(ActionNotification { notification, actions: actions.to_vec() }); + }); + Ok(()) + } + + /// The checks of `notify_with_actions`; a project no longer open is `NotFound`. + pub fn notify_project( + p: &ProjectRes, + level: NotificationLevel, + title: &str, + body: &str, + actions: &[NotificationAction], + ) -> Result<(), Error> { + let open = with(|s| s.root.iter().chain(&s.other_projects).any(|root| *root == p.root)); + if !open { + return Err(Error::NotFound(format!("the project {} is not open", p.root))); + } + check_actions(actions)?; + let notification = Notification { level, title: title.into(), body: body.into() }; + let sent = ActionNotification { notification, actions: actions.to_vec() }; + with(|s| s.project_notifications.push((p.root.clone(), sent))); + Ok(()) + } + + fn check_actions(actions: &[NotificationAction]) -> Result<(), Error> { if actions.len() > 3 { return Err(Error::Invalid("a notification has at most 3 actions".into())); } @@ -784,11 +819,6 @@ pub mod current { return Err(Error::Invalid("an action argument is limited to 64 KiB".into())); } } - with(|s| { - let notification = Notification { level, title: title.into(), body: body.into() }; - s.notifications.push(notification.clone()); - s.action_notifications.push(ActionNotification { notification, actions: actions.to_vec() }); - }); Ok(()) } @@ -2371,6 +2401,24 @@ mod tests { assert_eq!(mock.notifications().len(), 1); } + #[test] + fn project_notifications_need_an_open_project() { + let mock = MockHost::install(); + mock.add_project("/other"); + let action = NotificationAction::new("Disable", "disable").argument("/other"); + let other = host::project_of("/other/a.txt").unwrap(); + other.notify(NotificationLevel::Info, "Update", "", std::slice::from_ref(&action)).unwrap(); + let sent = mock.project_notifications(); + assert_eq!((sent[0].0.as_str(), &sent[0].1.actions), ("/other", &vec![action.clone()])); + assert!(mock.notifications().is_empty() && mock.notifications_with_actions().is_empty()); + let too_many: [_; 4] = std::array::from_fn(|_| action.clone()); + assert!(matches!(other.notify(NotificationLevel::Info, "Update", "", &too_many), Err(Error::Invalid(_)))); + let project = host::project_of("/project/a.txt").unwrap(); + mock.set_project_root(None); + assert!(matches!(project.notify(NotificationLevel::Info, "Update", "", &[]), Err(Error::NotFound(_)))); + assert_eq!(mock.project_notifications().len(), 1); + } + #[test] fn files_outside_the_project_need_an_fs_read_grant() { let mock = MockHost::install().with_capabilities(&["fs.read:/opt/tool"]); diff --git a/sdk/rust/openidea-plugin/wit/commit.wit b/sdk/rust/openidea-plugin/wit/commit.wit index 91dbe0e28..b2b91a22a 100644 --- a/sdk/rust/openidea-plugin/wit/commit.wit +++ b/sdk/rust/openidea-plugin/wit/commit.wit @@ -1,4 +1,4 @@ -package openidea:plugin@1.4.0; +package openidea:plugin@1.5.0; /// The commit being prepared in the window the current command or event came /// from (the Commit tool window, or the Commit dialog while it is open): the diff --git a/sdk/rust/openidea-plugin/wit/database.wit b/sdk/rust/openidea-plugin/wit/database.wit index 4e77bd9c8..f5d820703 100644 --- a/sdk/rust/openidea-plugin/wit/database.wit +++ b/sdk/rust/openidea-plugin/wit/database.wit @@ -1,4 +1,4 @@ -package openidea:plugin@1.4.0; +package openidea:plugin@1.5.0; /// Plugin-owned project data sources. Requires database.sources and project trust. /// Runs on the Database subsystem's host, including on remote project servers. diff --git a/sdk/rust/openidea-plugin/wit/decorations.wit b/sdk/rust/openidea-plugin/wit/decorations.wit index 1c5a033e6..d3d7e9bf6 100644 --- a/sdk/rust/openidea-plugin/wit/decorations.wit +++ b/sdk/rust/openidea-plugin/wit/decorations.wit @@ -1,4 +1,4 @@ -package openidea:plugin@1.4.0; +package openidea:plugin@1.5.0; /// Project-scoped decorations (API 1.4). Requires project.read; paths must be inside /// an open project. Sets belong to the plugin and disappear when it stops. diff --git a/sdk/rust/openidea-plugin/wit/details.wit b/sdk/rust/openidea-plugin/wit/details.wit index f7342991d..6f1b4b2f5 100644 --- a/sdk/rust/openidea-plugin/wit/details.wit +++ b/sdk/rust/openidea-plugin/wit/details.wit @@ -1,4 +1,4 @@ -package openidea:plugin@1.4.0; +package openidea:plugin@1.5.0; /// What the pane beside the Services tree shows for a plugin's node. interface detail-types { diff --git a/sdk/rust/openidea-plugin/wit/diagnostics.wit b/sdk/rust/openidea-plugin/wit/diagnostics.wit index 499335fde..bb57fc6fb 100644 --- a/sdk/rust/openidea-plugin/wit/diagnostics.wit +++ b/sdk/rust/openidea-plugin/wit/diagnostics.wit @@ -1,4 +1,4 @@ -package openidea:plugin@1.4.0; +package openidea:plugin@1.5.0; /// Optional export (world `plugin-diagnostics`): problems in the current, /// possibly unsaved document, for the languages declared with the diff --git a/sdk/rust/openidea-plugin/wit/endpoints.wit b/sdk/rust/openidea-plugin/wit/endpoints.wit index f4a446fe0..30b8a5c10 100644 --- a/sdk/rust/openidea-plugin/wit/endpoints.wit +++ b/sdk/rust/openidea-plugin/wit/endpoints.wit @@ -1,4 +1,4 @@ -package openidea:plugin@1.4.0; +package openidea:plugin@1.5.0; /// HTTP endpoints found in a project (`[[contributes.endpoints]]`). interface endpoints-provider { diff --git a/sdk/rust/openidea-plugin/wit/events.wit b/sdk/rust/openidea-plugin/wit/events.wit index f52030971..b8ac40a21 100644 --- a/sdk/rust/openidea-plugin/wit/events.wit +++ b/sdk/rust/openidea-plugin/wit/events.wit @@ -1,4 +1,4 @@ -package openidea:plugin@1.4.0; +package openidea:plugin@1.5.0; /// Workbench events, delivered in batches to `event-handler.handle`. interface events { diff --git a/sdk/rust/openidea-plugin/wit/exports.wit b/sdk/rust/openidea-plugin/wit/exports.wit index 434b29ceb..9a003a9c1 100644 --- a/sdk/rust/openidea-plugin/wit/exports.wit +++ b/sdk/rust/openidea-plugin/wit/exports.wit @@ -1,4 +1,4 @@ -package openidea:plugin@1.4.0; +package openidea:plugin@1.5.0; interface lifecycle { use types.{context, error}; diff --git a/sdk/rust/openidea-plugin/wit/file-actions.wit b/sdk/rust/openidea-plugin/wit/file-actions.wit index 12b4aec17..ed5ddc9fd 100644 --- a/sdk/rust/openidea-plugin/wit/file-actions.wit +++ b/sdk/rust/openidea-plugin/wit/file-actions.wit @@ -1,4 +1,4 @@ -package openidea:plugin@1.4.0; +package openidea:plugin@1.5.0; /// Optional export (world `plugin-file-actions`): quick fixes and /// refactorings that create, rename or delete files, next to the text edits diff --git a/sdk/rust/openidea-plugin/wit/fs.wit b/sdk/rust/openidea-plugin/wit/fs.wit index c1a96cf83..3acc44efe 100644 --- a/sdk/rust/openidea-plugin/wit/fs.wit +++ b/sdk/rust/openidea-plugin/wit/fs.wit @@ -1,4 +1,4 @@ -package openidea:plugin@1.4.0; +package openidea:plugin@1.5.0; /// Files outside the open projects: the configuration of the program a /// plugin integrates with, a tool installed elsewhere, a licence file. diff --git a/sdk/rust/openidea-plugin/wit/host.wit b/sdk/rust/openidea-plugin/wit/host.wit index c5ce20fbe..f612a97f1 100644 --- a/sdk/rust/openidea-plugin/wit/host.wit +++ b/sdk/rust/openidea-plugin/wit/host.wit @@ -1,4 +1,4 @@ -package openidea:plugin@1.4.0; +package openidea:plugin@1.5.0; /// Writes to the IDE log, tagged with the plugin id. interface log { @@ -9,6 +9,7 @@ interface log { interface ui { use types.{error, notification-level}; + use workspace.{project}; record status-item { text: string, @@ -50,6 +51,12 @@ interface ui { /// dismisses the balloon and runs the command in its window. An invalid /// action or an undeclared command fails the call and shows nothing. notify: func(level: notification-level, title: string, body: string, actions: list) -> result<_, error>; + /// `notify` in a window of `target` only (API 1.5), with or without an + /// invoking window: the most recently focused one when the project is open + /// in several. Actions run in that window. A project closed by the time of + /// the call fails it with `not-found` and shows nothing; there is no + /// fallback to another window. A shown balloon goes away with its window. + notify-project: func(target: borrow, level: notification-level, title: string, body: string, actions: list) -> result<_, error>; /// Shows or updates the plugin's status bar item `id` in every window. set-status-item: func(id: string, item: status-item); remove-status-item: func(id: string); diff --git a/sdk/rust/openidea-plugin/wit/hover.wit b/sdk/rust/openidea-plugin/wit/hover.wit index 5ddde792e..45d2409be 100644 --- a/sdk/rust/openidea-plugin/wit/hover.wit +++ b/sdk/rust/openidea-plugin/wit/hover.wit @@ -1,4 +1,4 @@ -package openidea:plugin@1.4.0; +package openidea:plugin@1.5.0; /// Optional export (world `plugin-hover`): Markdown added to the hover of /// documents of the languages declared with the `hover` provider kind, diff --git a/sdk/rust/openidea-plugin/wit/indexing.wit b/sdk/rust/openidea-plugin/wit/indexing.wit index 227aab726..6efbc8eb1 100644 --- a/sdk/rust/openidea-plugin/wit/indexing.wit +++ b/sdk/rust/openidea-plugin/wit/indexing.wit @@ -1,4 +1,4 @@ -package openidea:plugin@1.4.0; +package openidea:plugin@1.5.0; /// Cross-file associations a plugin publishes for the files it declares under /// `[[contributes.documentIndexers]]`. The host calls `index` in cancellable diff --git a/sdk/rust/openidea-plugin/wit/injections.wit b/sdk/rust/openidea-plugin/wit/injections.wit index 016e5b905..605f9c861 100644 --- a/sdk/rust/openidea-plugin/wit/injections.wit +++ b/sdk/rust/openidea-plugin/wit/injections.wit @@ -1,4 +1,4 @@ -package openidea:plugin@1.4.0; +package openidea:plugin@1.5.0; /// Embedded languages. The host routes plugin providers and configured language /// servers inside these ranges, preserving host-document UTF-16 coordinates. diff --git a/sdk/rust/openidea-plugin/wit/inlay.wit b/sdk/rust/openidea-plugin/wit/inlay.wit index 1098869a5..aa96b69bf 100644 --- a/sdk/rust/openidea-plugin/wit/inlay.wit +++ b/sdk/rust/openidea-plugin/wit/inlay.wit @@ -1,4 +1,4 @@ -package openidea:plugin@1.4.0; +package openidea:plugin@1.5.0; /// Optional export (world `plugin-inlay-hints`): inline hints in documents of /// the languages declared with the `inlay-hints` provider kind, including diff --git a/sdk/rust/openidea-plugin/wit/io.wit b/sdk/rust/openidea-plugin/wit/io.wit index b27e48d62..fae4e6620 100644 --- a/sdk/rust/openidea-plugin/wit/io.wit +++ b/sdk/rust/openidea-plugin/wit/io.wit @@ -1,4 +1,4 @@ -package openidea:plugin@1.4.0; +package openidea:plugin@1.5.0; /// Problems in files, shown in the editor and the Problems view. interface diagnostics { diff --git a/sdk/rust/openidea-plugin/wit/language-features.wit b/sdk/rust/openidea-plugin/wit/language-features.wit index c47c4b621..a20253749 100644 --- a/sdk/rust/openidea-plugin/wit/language-features.wit +++ b/sdk/rust/openidea-plugin/wit/language-features.wit @@ -1,4 +1,4 @@ -package openidea:plugin@1.4.0; +package openidea:plugin@1.5.0; /// Additional language features, called only for declared API 1.4 provider kinds. /// Editor calls have a 50 ms soft / 500 ms hard budget; formatting has 5 seconds. diff --git a/sdk/rust/openidea-plugin/wit/mcp.wit b/sdk/rust/openidea-plugin/wit/mcp.wit index e250f5496..8d2c811b5 100644 --- a/sdk/rust/openidea-plugin/wit/mcp.wit +++ b/sdk/rust/openidea-plugin/wit/mcp.wit @@ -1,4 +1,4 @@ -package openidea:plugin@1.4.0; +package openidea:plugin@1.5.0; /// Discovery of the IDE's built-in MCP server; never exposes its URL or token. interface mcp { diff --git a/sdk/rust/openidea-plugin/wit/plugin.wit b/sdk/rust/openidea-plugin/wit/plugin.wit index 04c707d20..3b3f4d0eb 100644 --- a/sdk/rust/openidea-plugin/wit/plugin.wit +++ b/sdk/rust/openidea-plugin/wit/plugin.wit @@ -8,7 +8,7 @@ /// `fs` and `workspace`, and everything else goes through the imports below, /// gated by the capabilities granted in `plugin.toml` (a missing one returns /// `error::denied`). -package openidea:plugin@1.4.0; +package openidea:plugin@1.5.0; world plugin { import log; diff --git a/sdk/rust/openidea-plugin/wit/providers.wit b/sdk/rust/openidea-plugin/wit/providers.wit index 8c0713ec6..870464617 100644 --- a/sdk/rust/openidea-plugin/wit/providers.wit +++ b/sdk/rust/openidea-plugin/wit/providers.wit @@ -1,4 +1,4 @@ -package openidea:plugin@1.4.0; +package openidea:plugin@1.5.0; /// Editor features a plugin provides for the languages it declares under /// `[[contributes.providers]]` (the host calls only declared kinds). They run diff --git a/sdk/rust/openidea-plugin/wit/run-targets.wit b/sdk/rust/openidea-plugin/wit/run-targets.wit index ee436a9a5..247cecb08 100644 --- a/sdk/rust/openidea-plugin/wit/run-targets.wit +++ b/sdk/rust/openidea-plugin/wit/run-targets.wit @@ -1,4 +1,4 @@ -package openidea:plugin@1.4.0; +package openidea:plugin@1.5.0; /// Project-scoped targets owned by the registering plugin (API 1.4). interface run-targets { diff --git a/sdk/rust/openidea-plugin/wit/run.wit b/sdk/rust/openidea-plugin/wit/run.wit index 6c62534e2..357eaba72 100644 --- a/sdk/rust/openidea-plugin/wit/run.wit +++ b/sdk/rust/openidea-plugin/wit/run.wit @@ -1,4 +1,4 @@ -package openidea:plugin@1.4.0; +package openidea:plugin@1.5.0; /// Launches this plugin's configurations in the invoking window's Run tool window. interface run { diff --git a/sdk/rust/openidea-plugin/wit/semantic.wit b/sdk/rust/openidea-plugin/wit/semantic.wit index 586c324e6..459a43117 100644 --- a/sdk/rust/openidea-plugin/wit/semantic.wit +++ b/sdk/rust/openidea-plugin/wit/semantic.wit @@ -1,4 +1,4 @@ -package openidea:plugin@1.4.0; +package openidea:plugin@1.5.0; /// Optional export (world `plugin-semantic-tokens`): semantic colouring of /// documents of the languages declared with the `semantic-tokens` provider diff --git a/sdk/rust/openidea-plugin/wit/types.wit b/sdk/rust/openidea-plugin/wit/types.wit index 4192e783c..f151ca9a6 100644 --- a/sdk/rust/openidea-plugin/wit/types.wit +++ b/sdk/rust/openidea-plugin/wit/types.wit @@ -1,4 +1,4 @@ -package openidea:plugin@1.4.0; +package openidea:plugin@1.5.0; /// Shared types. Positions are 0-based lines and UTF-16 code unit columns, /// as in the editor and LSP. diff --git a/sdk/rust/openidea-plugin/wit/views.wit b/sdk/rust/openidea-plugin/wit/views.wit index a34be2d46..288884d2e 100644 --- a/sdk/rust/openidea-plugin/wit/views.wit +++ b/sdk/rust/openidea-plugin/wit/views.wit @@ -1,4 +1,4 @@ -package openidea:plugin@1.4.0; +package openidea:plugin@1.5.0; /// Declarative views: tool windows declared /// under `[[contributes.views]]` and custom editors under diff --git a/sdk/rust/openidea-plugin/wit/workspace.wit b/sdk/rust/openidea-plugin/wit/workspace.wit index 7c1e9dd19..2be7981f5 100644 --- a/sdk/rust/openidea-plugin/wit/workspace.wit +++ b/sdk/rust/openidea-plugin/wit/workspace.wit @@ -1,4 +1,4 @@ -package openidea:plugin@1.4.0; +package openidea:plugin@1.5.0; interface workspace { use types.{error, location}; diff --git a/wit/commit.wit b/wit/commit.wit index 91dbe0e28..b2b91a22a 100644 --- a/wit/commit.wit +++ b/wit/commit.wit @@ -1,4 +1,4 @@ -package openidea:plugin@1.4.0; +package openidea:plugin@1.5.0; /// The commit being prepared in the window the current command or event came /// from (the Commit tool window, or the Commit dialog while it is open): the diff --git a/wit/database.wit b/wit/database.wit index 4e77bd9c8..f5d820703 100644 --- a/wit/database.wit +++ b/wit/database.wit @@ -1,4 +1,4 @@ -package openidea:plugin@1.4.0; +package openidea:plugin@1.5.0; /// Plugin-owned project data sources. Requires database.sources and project trust. /// Runs on the Database subsystem's host, including on remote project servers. diff --git a/wit/decorations.wit b/wit/decorations.wit index 1c5a033e6..d3d7e9bf6 100644 --- a/wit/decorations.wit +++ b/wit/decorations.wit @@ -1,4 +1,4 @@ -package openidea:plugin@1.4.0; +package openidea:plugin@1.5.0; /// Project-scoped decorations (API 1.4). Requires project.read; paths must be inside /// an open project. Sets belong to the plugin and disappear when it stops. diff --git a/wit/details.wit b/wit/details.wit index f7342991d..6f1b4b2f5 100644 --- a/wit/details.wit +++ b/wit/details.wit @@ -1,4 +1,4 @@ -package openidea:plugin@1.4.0; +package openidea:plugin@1.5.0; /// What the pane beside the Services tree shows for a plugin's node. interface detail-types { diff --git a/wit/diagnostics.wit b/wit/diagnostics.wit index 499335fde..bb57fc6fb 100644 --- a/wit/diagnostics.wit +++ b/wit/diagnostics.wit @@ -1,4 +1,4 @@ -package openidea:plugin@1.4.0; +package openidea:plugin@1.5.0; /// Optional export (world `plugin-diagnostics`): problems in the current, /// possibly unsaved document, for the languages declared with the diff --git a/wit/endpoints.wit b/wit/endpoints.wit index f4a446fe0..30b8a5c10 100644 --- a/wit/endpoints.wit +++ b/wit/endpoints.wit @@ -1,4 +1,4 @@ -package openidea:plugin@1.4.0; +package openidea:plugin@1.5.0; /// HTTP endpoints found in a project (`[[contributes.endpoints]]`). interface endpoints-provider { diff --git a/wit/events.wit b/wit/events.wit index f52030971..b8ac40a21 100644 --- a/wit/events.wit +++ b/wit/events.wit @@ -1,4 +1,4 @@ -package openidea:plugin@1.4.0; +package openidea:plugin@1.5.0; /// Workbench events, delivered in batches to `event-handler.handle`. interface events { diff --git a/wit/exports.wit b/wit/exports.wit index 434b29ceb..9a003a9c1 100644 --- a/wit/exports.wit +++ b/wit/exports.wit @@ -1,4 +1,4 @@ -package openidea:plugin@1.4.0; +package openidea:plugin@1.5.0; interface lifecycle { use types.{context, error}; diff --git a/wit/file-actions.wit b/wit/file-actions.wit index 12b4aec17..ed5ddc9fd 100644 --- a/wit/file-actions.wit +++ b/wit/file-actions.wit @@ -1,4 +1,4 @@ -package openidea:plugin@1.4.0; +package openidea:plugin@1.5.0; /// Optional export (world `plugin-file-actions`): quick fixes and /// refactorings that create, rename or delete files, next to the text edits diff --git a/wit/fs.wit b/wit/fs.wit index c1a96cf83..3acc44efe 100644 --- a/wit/fs.wit +++ b/wit/fs.wit @@ -1,4 +1,4 @@ -package openidea:plugin@1.4.0; +package openidea:plugin@1.5.0; /// Files outside the open projects: the configuration of the program a /// plugin integrates with, a tool installed elsewhere, a licence file. diff --git a/wit/host.wit b/wit/host.wit index c5ce20fbe..f612a97f1 100644 --- a/wit/host.wit +++ b/wit/host.wit @@ -1,4 +1,4 @@ -package openidea:plugin@1.4.0; +package openidea:plugin@1.5.0; /// Writes to the IDE log, tagged with the plugin id. interface log { @@ -9,6 +9,7 @@ interface log { interface ui { use types.{error, notification-level}; + use workspace.{project}; record status-item { text: string, @@ -50,6 +51,12 @@ interface ui { /// dismisses the balloon and runs the command in its window. An invalid /// action or an undeclared command fails the call and shows nothing. notify: func(level: notification-level, title: string, body: string, actions: list) -> result<_, error>; + /// `notify` in a window of `target` only (API 1.5), with or without an + /// invoking window: the most recently focused one when the project is open + /// in several. Actions run in that window. A project closed by the time of + /// the call fails it with `not-found` and shows nothing; there is no + /// fallback to another window. A shown balloon goes away with its window. + notify-project: func(target: borrow, level: notification-level, title: string, body: string, actions: list) -> result<_, error>; /// Shows or updates the plugin's status bar item `id` in every window. set-status-item: func(id: string, item: status-item); remove-status-item: func(id: string); diff --git a/wit/hover.wit b/wit/hover.wit index 5ddde792e..45d2409be 100644 --- a/wit/hover.wit +++ b/wit/hover.wit @@ -1,4 +1,4 @@ -package openidea:plugin@1.4.0; +package openidea:plugin@1.5.0; /// Optional export (world `plugin-hover`): Markdown added to the hover of /// documents of the languages declared with the `hover` provider kind, diff --git a/wit/indexing.wit b/wit/indexing.wit index 227aab726..6efbc8eb1 100644 --- a/wit/indexing.wit +++ b/wit/indexing.wit @@ -1,4 +1,4 @@ -package openidea:plugin@1.4.0; +package openidea:plugin@1.5.0; /// Cross-file associations a plugin publishes for the files it declares under /// `[[contributes.documentIndexers]]`. The host calls `index` in cancellable diff --git a/wit/injections.wit b/wit/injections.wit index 016e5b905..605f9c861 100644 --- a/wit/injections.wit +++ b/wit/injections.wit @@ -1,4 +1,4 @@ -package openidea:plugin@1.4.0; +package openidea:plugin@1.5.0; /// Embedded languages. The host routes plugin providers and configured language /// servers inside these ranges, preserving host-document UTF-16 coordinates. diff --git a/wit/inlay.wit b/wit/inlay.wit index 1098869a5..aa96b69bf 100644 --- a/wit/inlay.wit +++ b/wit/inlay.wit @@ -1,4 +1,4 @@ -package openidea:plugin@1.4.0; +package openidea:plugin@1.5.0; /// Optional export (world `plugin-inlay-hints`): inline hints in documents of /// the languages declared with the `inlay-hints` provider kind, including diff --git a/wit/io.wit b/wit/io.wit index b27e48d62..fae4e6620 100644 --- a/wit/io.wit +++ b/wit/io.wit @@ -1,4 +1,4 @@ -package openidea:plugin@1.4.0; +package openidea:plugin@1.5.0; /// Problems in files, shown in the editor and the Problems view. interface diagnostics { diff --git a/wit/language-features.wit b/wit/language-features.wit index c47c4b621..a20253749 100644 --- a/wit/language-features.wit +++ b/wit/language-features.wit @@ -1,4 +1,4 @@ -package openidea:plugin@1.4.0; +package openidea:plugin@1.5.0; /// Additional language features, called only for declared API 1.4 provider kinds. /// Editor calls have a 50 ms soft / 500 ms hard budget; formatting has 5 seconds. diff --git a/wit/mcp.wit b/wit/mcp.wit index e250f5496..8d2c811b5 100644 --- a/wit/mcp.wit +++ b/wit/mcp.wit @@ -1,4 +1,4 @@ -package openidea:plugin@1.4.0; +package openidea:plugin@1.5.0; /// Discovery of the IDE's built-in MCP server; never exposes its URL or token. interface mcp { diff --git a/wit/plugin.wit b/wit/plugin.wit index 04c707d20..3b3f4d0eb 100644 --- a/wit/plugin.wit +++ b/wit/plugin.wit @@ -8,7 +8,7 @@ /// `fs` and `workspace`, and everything else goes through the imports below, /// gated by the capabilities granted in `plugin.toml` (a missing one returns /// `error::denied`). -package openidea:plugin@1.4.0; +package openidea:plugin@1.5.0; world plugin { import log; diff --git a/wit/providers.wit b/wit/providers.wit index 8c0713ec6..870464617 100644 --- a/wit/providers.wit +++ b/wit/providers.wit @@ -1,4 +1,4 @@ -package openidea:plugin@1.4.0; +package openidea:plugin@1.5.0; /// Editor features a plugin provides for the languages it declares under /// `[[contributes.providers]]` (the host calls only declared kinds). They run diff --git a/wit/run-targets.wit b/wit/run-targets.wit index ee436a9a5..247cecb08 100644 --- a/wit/run-targets.wit +++ b/wit/run-targets.wit @@ -1,4 +1,4 @@ -package openidea:plugin@1.4.0; +package openidea:plugin@1.5.0; /// Project-scoped targets owned by the registering plugin (API 1.4). interface run-targets { diff --git a/wit/run.wit b/wit/run.wit index 6c62534e2..357eaba72 100644 --- a/wit/run.wit +++ b/wit/run.wit @@ -1,4 +1,4 @@ -package openidea:plugin@1.4.0; +package openidea:plugin@1.5.0; /// Launches this plugin's configurations in the invoking window's Run tool window. interface run { diff --git a/wit/semantic.wit b/wit/semantic.wit index 586c324e6..459a43117 100644 --- a/wit/semantic.wit +++ b/wit/semantic.wit @@ -1,4 +1,4 @@ -package openidea:plugin@1.4.0; +package openidea:plugin@1.5.0; /// Optional export (world `plugin-semantic-tokens`): semantic colouring of /// documents of the languages declared with the `semantic-tokens` provider diff --git a/wit/types.wit b/wit/types.wit index 4192e783c..f151ca9a6 100644 --- a/wit/types.wit +++ b/wit/types.wit @@ -1,4 +1,4 @@ -package openidea:plugin@1.4.0; +package openidea:plugin@1.5.0; /// Shared types. Positions are 0-based lines and UTF-16 code unit columns, /// as in the editor and LSP. diff --git a/wit/views.wit b/wit/views.wit index a34be2d46..288884d2e 100644 --- a/wit/views.wit +++ b/wit/views.wit @@ -1,4 +1,4 @@ -package openidea:plugin@1.4.0; +package openidea:plugin@1.5.0; /// Declarative views: tool windows declared /// under `[[contributes.views]]` and custom editors under diff --git a/wit/workspace.wit b/wit/workspace.wit index 7c1e9dd19..2be7981f5 100644 --- a/wit/workspace.wit +++ b/wit/workspace.wit @@ -1,4 +1,4 @@ -package openidea:plugin@1.4.0; +package openidea:plugin@1.5.0; interface workspace { use types.{error, location};