forked from 1b-agent/opencadstudio-upstream
feat(plugins): expose document path to plugins via HostApi
OpenCADStudio/plugins#901 (comment) - Add HostApi::document_path(tab_id) returning Option<PathBuf>. - Add PluginRequest::DocumentPath and PluginResponse::DocumentPath for out-of-process plugins. - Implement the request in the IPC server and in both V3/V4 plugin-side HostApi proxies. - Implement HostSession::document_path by looking up the tab by id and returning its current_path.
This commit is contained in:
1 parent
3024869de0
commit
09ba67bfd1
6 files changed
+58
No files matched your search
@@ -12,6 +12,7 @@
|
||||
//! [`ensure_plugin_state`] helpers for the ergonomic typed access.
|
||||
|
||||
use std::any::Any;
|
||||
use std::path::PathBuf;
|
||||
|
||||
use serde::{Deserialize, Deserializer, Serialize, Serializer};
|
||||
|
||||
@@ -531,6 +532,15 @@ pub trait HostApi {
|
||||
fn add_entities(&mut self, entities: Vec<EntityType>) -> Vec<Handle> {
|
||||
entities.into_iter().map(|e| self.add_entity(e)).collect()
|
||||
}
|
||||
|
||||
/// Return the filesystem path of the document in tab `tab_id`, if any.
|
||||
/// Added after API v4; appended at the very end so older plugins compiled
|
||||
/// without it keep stable vtable indices. The default returns `None`;
|
||||
/// in-process hosts should override it to expose the real path.
|
||||
fn document_path(&self, tab_id: u64) -> Option<PathBuf> {
|
||||
let _ = tab_id;
|
||||
None
|
||||
}
|
||||
}
|
||||
|
||||
/// Simplified, read-only entity kind exposed by [`DocumentReader`].
|
||||
|
||||
@@ -401,6 +401,21 @@ impl HostApi for PluginHostApi {
|
||||
None => Box::new(EmptyDocumentReader),
|
||||
}
|
||||
}
|
||||
|
||||
fn document_path(&self, tab_id: u64) -> Option<std::path::PathBuf> {
|
||||
match self.client.request(PluginRequest::DocumentPath { tab_id }) {
|
||||
Ok(PluginResponse::DocumentPath(Some(path))) => Some(std::path::PathBuf::from(path)),
|
||||
Ok(PluginResponse::DocumentPath(None)) => None,
|
||||
Ok(other) => {
|
||||
eprintln!("[plugin] unexpected DocumentPath response: {other:?}");
|
||||
None
|
||||
}
|
||||
Err(e) => {
|
||||
eprintln!("[plugin] DocumentPath request failed: {e}");
|
||||
None
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/// Sentinel reader used when the shared-memory view could not be initialized.
|
||||
|
||||
@@ -136,6 +136,8 @@ pub enum PluginRequest {
|
||||
CloseDocumentViewV4 { tab_id: u64 },
|
||||
/// V4: ask the host for the stable tab identifier of the active tab.
|
||||
GetTabId,
|
||||
/// V4: ask the host for the filesystem path of the document in `tab_id`.
|
||||
DocumentPath { tab_id: u64 },
|
||||
}
|
||||
|
||||
/// Responses the host sends back for `PluginRequest`.
|
||||
@@ -160,6 +162,8 @@ pub enum PluginResponse {
|
||||
},
|
||||
/// V4: stable tab identifier of the active tab.
|
||||
TabId(u64),
|
||||
/// V4: filesystem path of the document in the requested tab, if any.
|
||||
DocumentPath(Option<String>),
|
||||
}
|
||||
|
||||
/// Messages sent from the host to the plugin runner.
|
||||
|
||||
@@ -74,5 +74,8 @@ pub fn handle_plugin_request(
|
||||
PluginResponse::Ok
|
||||
}
|
||||
GetTabId => PluginResponse::TabId(host.tab_id()),
|
||||
DocumentPath { tab_id } => {
|
||||
PluginResponse::DocumentPath(host.document_path(tab_id).map(|p| p.to_string_lossy().to_string()))
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -715,6 +715,21 @@ impl HostApi for V4PluginHostApi {
|
||||
view.take();
|
||||
}
|
||||
}
|
||||
|
||||
fn document_path(&self, tab_id: u64) -> Option<std::path::PathBuf> {
|
||||
match self.request(PluginRequest::DocumentPath { tab_id }) {
|
||||
Ok(PluginResponse::DocumentPath(Some(path))) => Some(std::path::PathBuf::from(path)),
|
||||
Ok(PluginResponse::DocumentPath(None)) => None,
|
||||
Ok(other) => {
|
||||
eprintln!("[plugin] unexpected DocumentPath response: {other:?}");
|
||||
None
|
||||
}
|
||||
Err(e) => {
|
||||
eprintln!("[plugin] DocumentPath request failed: {e}");
|
||||
None
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#[cfg(test)]
|
||||
|
||||
@@ -35,6 +35,14 @@ impl<'a> HostSession<'a> {
|
||||
self.app.tabs[self.tab].id
|
||||
}
|
||||
|
||||
pub fn document_path(&self, tab_id: u64) -> Option<std::path::PathBuf> {
|
||||
self.app
|
||||
.tabs
|
||||
.iter()
|
||||
.find(|t| t.id == tab_id)
|
||||
.and_then(|t| t.current_path.clone())
|
||||
}
|
||||
|
||||
#[cfg(not(target_arch = "wasm32"))]
|
||||
pub fn document_view_v4(&mut self, tab_id: u64) -> Option<ocs_plugin_api::shm::DocumentViewInfo> {
|
||||
if tab_id != self.tab_id() {
|
||||
@@ -341,6 +349,9 @@ impl HostApi for HostSession<'_> {
|
||||
fn tab_id(&self) -> u64 {
|
||||
self.tab_id()
|
||||
}
|
||||
fn document_path(&self, tab_id: u64) -> Option<std::path::PathBuf> {
|
||||
self.document_path(tab_id)
|
||||
}
|
||||
#[cfg(not(target_arch = "wasm32"))]
|
||||
fn document_view_v4(&mut self, tab_id: u64) -> Option<ocs_plugin_api::shm::DocumentViewInfo> {
|
||||
self.document_view_v4(tab_id)
|
||||
|
||||
Reference in new issue
Block a user