mirror of https://github.com/lapce/lapce.git
re architecture
This commit is contained in:
parent
bc0717a7e6
commit
f4e11aee00
|
@ -1339,6 +1339,15 @@ dependencies = [
|
|||
"libc",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "home"
|
||||
version = "0.5.3"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "2456aef2e6b6a9784192ae780c0f15bc57df0e918585282325e8c8ac27737654"
|
||||
dependencies = [
|
||||
"winapi 0.3.9",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "humantime"
|
||||
version = "1.3.0"
|
||||
|
@ -1610,6 +1619,7 @@ dependencies = [
|
|||
"git2",
|
||||
"include_dir",
|
||||
"jsonrpc-lite",
|
||||
"lapce-proxy",
|
||||
"lazy_static 1.4.0",
|
||||
"lsp-types 0.82.0",
|
||||
"openssh",
|
||||
|
@ -1627,6 +1637,7 @@ dependencies = [
|
|||
"xi-core-lib",
|
||||
"xi-rope",
|
||||
"xi-rpc",
|
||||
"xi-trace",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
|
@ -1648,8 +1659,11 @@ dependencies = [
|
|||
name = "lapce-proxy"
|
||||
version = "0.0.1"
|
||||
dependencies = [
|
||||
"anyhow",
|
||||
"home",
|
||||
"serde",
|
||||
"serde_json",
|
||||
"toml",
|
||||
"xi-rope",
|
||||
"xi-rpc",
|
||||
]
|
||||
|
|
|
@ -5,6 +5,8 @@ authors = ["Dongdong Zhou <dzhou121@gmail.com>"]
|
|||
edition = "2018"
|
||||
|
||||
[dependencies]
|
||||
lapce-proxy = { path = "../proxy" }
|
||||
xi-trace = { path = "../../xi-editor/rust/trace/" }
|
||||
git2 = "0.13"
|
||||
openssh = "0.7.0"
|
||||
tokio = { version = "0.3.3", features = ["full"] }
|
||||
|
|
|
@ -110,11 +110,21 @@ pub fn new(
|
|||
event_sink: ExtEventSink,
|
||||
sender: Sender<(WindowId, WidgetId, BufferId, u64)>,
|
||||
) -> Buffer {
|
||||
let rope = if let Ok(rope) = load_file(&window_id, &tab_id, path) {
|
||||
rope
|
||||
} else {
|
||||
Rope::from("")
|
||||
};
|
||||
let state = LAPCE_APP_STATE.get_tab_state(&window_id, &tab_id);
|
||||
let content = state
|
||||
.proxy
|
||||
.lock()
|
||||
.as_ref()
|
||||
.unwrap()
|
||||
.new_buffer(buffer_id, PathBuf::from(path.to_string()))
|
||||
.unwrap();
|
||||
let rope = Rope::from_str(&content).unwrap();
|
||||
|
||||
// let rope = if let Ok(rope) = load_file(&window_id, &tab_id, path) {
|
||||
// rope
|
||||
// } else {
|
||||
// Rope::from("")
|
||||
// };
|
||||
let mut parser = new_parser(LapceLanguage::Rust);
|
||||
let tree = parser.parse(&rope.to_string(), None).unwrap();
|
||||
|
||||
|
@ -150,7 +160,6 @@ pub fn new(
|
|||
|
||||
let language_id = buffer.language_id.clone();
|
||||
|
||||
let state = LAPCE_APP_STATE.get_tab_state(&window_id, &tab_id);
|
||||
state.plugins.lock().new_buffer(&PluginBufferInfo {
|
||||
buffer_id: buffer_id.clone(),
|
||||
language_id: buffer.language_id.clone(),
|
||||
|
|
|
@ -3050,7 +3050,8 @@ fn paint(&mut self, ctx: &mut PaintCtx, data: &LapceUIState, env: &Env) {
|
|||
};
|
||||
let x = (last_line.to_string().len() - content.to_string().len())
|
||||
as f64
|
||||
* width;
|
||||
* width
|
||||
+ 10.0;
|
||||
let content = content.to_string();
|
||||
if let Some(text_layout) = self.text_layouts.get_mut(&content) {
|
||||
if text_layout.text != content {
|
||||
|
@ -3294,8 +3295,11 @@ fn paint_selection(
|
|||
&Mode::Visual => (),
|
||||
_ => return,
|
||||
}
|
||||
let start = buffer.offset_of_line(start_line);
|
||||
let last_line = buffer.last_line();
|
||||
if start_line > last_line {
|
||||
return;
|
||||
}
|
||||
let start = buffer.offset_of_line(start_line);
|
||||
let mut end_line = start_line + number_lines;
|
||||
if end_line > last_line {
|
||||
end_line = last_line;
|
||||
|
|
|
@ -25,15 +25,26 @@
|
|||
};
|
||||
use git2::Oid;
|
||||
use git2::Repository;
|
||||
use lapce_proxy::dispatch::NewBufferResponse;
|
||||
use lazy_static::lazy_static;
|
||||
use parking_lot::Mutex;
|
||||
use serde::{Deserialize, Deserializer, Serialize};
|
||||
use serde_json::json;
|
||||
use std::io::BufReader;
|
||||
use std::path::Path;
|
||||
use std::process::Child;
|
||||
use std::process::Command;
|
||||
use std::process::Stdio;
|
||||
use std::sync::mpsc::{channel, Receiver, Sender};
|
||||
use std::{
|
||||
collections::HashMap, fs::File, io::Read, path::PathBuf, str::FromStr,
|
||||
sync::Arc, thread,
|
||||
};
|
||||
use toml;
|
||||
use xi_rpc::Handler;
|
||||
use xi_rpc::RpcLoop;
|
||||
use xi_rpc::RpcPeer;
|
||||
use xi_trace::enable_tracing;
|
||||
|
||||
lazy_static! {
|
||||
//pub static ref LAPCE_STATE: LapceState = LapceState::new();
|
||||
|
@ -290,30 +301,11 @@ pub struct LapceTabState {
|
|||
pub plugins: Arc<Mutex<PluginCatalog>>,
|
||||
pub lsp: Arc<Mutex<LspCatalog>>,
|
||||
pub ssh_session: Arc<Mutex<Option<SshSession>>>,
|
||||
pub proxy: Arc<Mutex<Option<LapceProxy>>>,
|
||||
}
|
||||
|
||||
impl LapceTabState {
|
||||
pub fn new(window_id: WindowId) -> LapceTabState {
|
||||
let repo = Repository::open("/Users/Lulu/lapce").unwrap();
|
||||
let head = repo.head().unwrap();
|
||||
let tree = head.peel_to_tree().unwrap();
|
||||
// let tree = repo.find_tree(oid).unwrap();
|
||||
let tree_entry = tree.get_path(&PathBuf::from("Cargo.toml")).unwrap();
|
||||
let blob = repo.find_blob(tree_entry.id()).unwrap();
|
||||
let mut patch = git2::Patch::from_blob_and_buffer(
|
||||
&blob,
|
||||
None,
|
||||
"lsjdf".as_bytes(),
|
||||
None,
|
||||
None,
|
||||
)
|
||||
.unwrap();
|
||||
for i in 0..patch.num_hunks() {
|
||||
let hunk = patch.hunk(i).unwrap();
|
||||
println!("hunk {:?}", hunk);
|
||||
}
|
||||
println!("diff {}", patch.to_buf().unwrap().as_str().unwrap());
|
||||
|
||||
let workspace = LapceWorkspace {
|
||||
kind: LapceWorkspaceType::Local,
|
||||
path: PathBuf::from("/Users/Lulu/lapce"),
|
||||
|
@ -352,7 +344,9 @@ pub fn new(window_id: WindowId) -> LapceTabState {
|
|||
tab_id.clone(),
|
||||
))),
|
||||
ssh_session: Arc::new(Mutex::new(None)),
|
||||
proxy: Arc::new(Mutex::new(None)),
|
||||
};
|
||||
start_proxy_process(window_id, tab_id);
|
||||
let local_state = state.clone();
|
||||
thread::spawn(move || {
|
||||
local_state.start_plugin();
|
||||
|
@ -582,6 +576,89 @@ pub fn set_container(&mut self, container: WidgetId) {
|
|||
}
|
||||
}
|
||||
|
||||
pub struct LapceProxy {
|
||||
peer: RpcPeer,
|
||||
process: Child,
|
||||
}
|
||||
|
||||
impl LapceProxy {
|
||||
pub fn new_buffer(&self, buffer_id: BufferId, path: PathBuf) -> Result<String> {
|
||||
enable_tracing();
|
||||
let result = self
|
||||
.peer
|
||||
.send_rpc_request(
|
||||
"new_buffer",
|
||||
&json!({ "buffer_id": buffer_id, "path": path }),
|
||||
)
|
||||
.map_err(|e| anyhow!("{:?}", e))?;
|
||||
|
||||
let resp: NewBufferResponse = serde_json::from_value(result)?;
|
||||
return Ok(resp.content);
|
||||
}
|
||||
}
|
||||
|
||||
fn start_proxy_process(window_id: WindowId, tab_id: WidgetId) {
|
||||
thread::spawn(move || {
|
||||
let child = Command::new("/Users/Lulu/lapce/target/debug/lapce-proxy")
|
||||
.stdin(Stdio::piped())
|
||||
.stdout(Stdio::piped())
|
||||
.spawn();
|
||||
if child.is_err() {
|
||||
println!("can't start proxy {:?}", child);
|
||||
return;
|
||||
}
|
||||
let mut child = child.unwrap();
|
||||
let child_stdin = child.stdin.take().unwrap();
|
||||
let child_stdout = child.stdout.take().unwrap();
|
||||
let mut looper = RpcLoop::new(child_stdin);
|
||||
let peer: RpcPeer = Box::new(looper.get_raw_peer());
|
||||
let proxy = LapceProxy {
|
||||
peer,
|
||||
process: child,
|
||||
};
|
||||
{
|
||||
let state = LAPCE_APP_STATE.get_tab_state(&window_id, &tab_id);
|
||||
*state.proxy.lock() = Some(proxy);
|
||||
}
|
||||
|
||||
let mut handler = ProxyHandler {};
|
||||
if let Err(e) =
|
||||
looper.mainloop(|| BufReader::new(child_stdout), &mut handler)
|
||||
{
|
||||
println!("proxy main loop failed {:?}", e);
|
||||
}
|
||||
println!("proxy main loop exit");
|
||||
});
|
||||
}
|
||||
|
||||
#[derive(Debug, Clone, Serialize, Deserialize)]
|
||||
pub enum Notification {}
|
||||
|
||||
#[derive(Debug, Clone, Serialize, Deserialize)]
|
||||
pub enum Request {}
|
||||
|
||||
pub struct ProxyHandler {}
|
||||
|
||||
impl Handler for ProxyHandler {
|
||||
type Notification = Notification;
|
||||
type Request = Request;
|
||||
|
||||
fn handle_notification(
|
||||
&mut self,
|
||||
ctx: &xi_rpc::RpcCtx,
|
||||
rpc: Self::Notification,
|
||||
) {
|
||||
}
|
||||
|
||||
fn handle_request(
|
||||
&mut self,
|
||||
ctx: &xi_rpc::RpcCtx,
|
||||
rpc: Self::Request,
|
||||
) -> Result<serde_json::Value, xi_rpc::RemoteError> {
|
||||
Err(xi_rpc::RemoteError::InvalidRequest(None))
|
||||
}
|
||||
}
|
||||
|
||||
pub fn hex_to_color(hex: &str) -> Result<Color> {
|
||||
let hex = hex.trim_start_matches("#");
|
||||
let (r, g, b, a) = match hex.len() {
|
||||
|
|
|
@ -9,3 +9,6 @@ xi-rpc = { path = "../../xi-editor/rust/rpc/" }
|
|||
xi-rope = { path = "../../xi-editor/rust/rope/" }
|
||||
serde = { version = "1.0", features = ["derive"] }
|
||||
serde_json = "1.0.59"
|
||||
anyhow = "1.0.32"
|
||||
home = "0.5.3"
|
||||
toml = "0.5.6"
|
||||
|
|
|
@ -1,3 +1,8 @@
|
|||
use anyhow::Result;
|
||||
use std::fs::File;
|
||||
use std::io::Read;
|
||||
use std::path::PathBuf;
|
||||
|
||||
use serde::{Deserialize, Deserializer, Serialize};
|
||||
use xi_rope::{
|
||||
interval::IntervalBounds, rope::Rope, Cursor, Delta, DeltaBuilder, Interval,
|
||||
|
@ -10,4 +15,23 @@
|
|||
pub struct Buffer {
|
||||
pub id: BufferId,
|
||||
pub rope: Rope,
|
||||
pub path: PathBuf,
|
||||
}
|
||||
|
||||
impl Buffer {
|
||||
pub fn new(id: BufferId, path: PathBuf) -> Buffer {
|
||||
let rope = if let Ok(rope) = load_file(&path) {
|
||||
rope
|
||||
} else {
|
||||
Rope::from("")
|
||||
};
|
||||
Buffer { id, rope, path }
|
||||
}
|
||||
}
|
||||
|
||||
fn load_file(path: &PathBuf) -> Result<Rope> {
|
||||
let mut f = File::open(path)?;
|
||||
let mut bytes = Vec::new();
|
||||
f.read_to_end(&mut bytes)?;
|
||||
Ok(Rope::from(std::str::from_utf8(&bytes)?))
|
||||
}
|
||||
|
|
|
@ -0,0 +1,12 @@
|
|||
use xi_rpc::RpcPeer;
|
||||
|
||||
#[derive(Clone)]
|
||||
pub struct CoreProxy {
|
||||
pub peer: RpcPeer,
|
||||
}
|
||||
|
||||
impl CoreProxy {
|
||||
pub fn new(peer: RpcPeer) -> Self {
|
||||
Self { peer }
|
||||
}
|
||||
}
|
|
@ -1,23 +1,47 @@
|
|||
use crate::buffer::{Buffer, BufferId};
|
||||
use crate::core_proxy::CoreProxy;
|
||||
use crate::plugin::PluginCatalog;
|
||||
use serde::{Deserialize, Deserializer, Serialize};
|
||||
use serde_json::Value;
|
||||
use std::collections::HashMap;
|
||||
use std::path::PathBuf;
|
||||
use std::sync::Arc;
|
||||
use std::sync::Mutex;
|
||||
use xi_rpc::RpcPeer;
|
||||
use xi_rpc::{Handler, RpcCtx};
|
||||
|
||||
pub struct Dispatcher {
|
||||
peer: RpcPeer,
|
||||
buffers: HashMap<BufferId, Buffer>,
|
||||
plugins: Arc<Mutex<PluginCatalog>>,
|
||||
}
|
||||
|
||||
#[derive(Debug, Clone, Serialize, Deserialize)]
|
||||
#[serde(rename_all = "snake_case")]
|
||||
#[serde(tag = "method", content = "params")]
|
||||
pub enum Notification {}
|
||||
|
||||
#[derive(Debug, Clone, Serialize, Deserialize)]
|
||||
pub enum Request {}
|
||||
#[serde(rename_all = "snake_case")]
|
||||
#[serde(tag = "method", content = "params")]
|
||||
pub enum Request {
|
||||
NewBuffer { buffer_id: BufferId, path: PathBuf },
|
||||
}
|
||||
|
||||
#[derive(Debug, Clone, Serialize, Deserialize)]
|
||||
pub struct NewBufferResponse {
|
||||
pub content: String,
|
||||
}
|
||||
|
||||
impl Dispatcher {
|
||||
pub fn new() -> Dispatcher {
|
||||
pub fn new(peer: RpcPeer) -> Dispatcher {
|
||||
let mut plugins = PluginCatalog::new();
|
||||
plugins.reload();
|
||||
plugins.start_all(CoreProxy::new(peer.clone()));
|
||||
Dispatcher {
|
||||
peer,
|
||||
buffers: HashMap::new(),
|
||||
plugins: Arc::new(Mutex::new(plugins)),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -33,6 +57,15 @@ fn handle_request(
|
|||
ctx: &RpcCtx,
|
||||
rpc: Self::Request,
|
||||
) -> Result<Value, xi_rpc::RemoteError> {
|
||||
match rpc {
|
||||
Request::NewBuffer { buffer_id, path } => {
|
||||
let buffer = Buffer::new(buffer_id, path);
|
||||
let content = buffer.rope.to_string();
|
||||
self.buffers.insert(buffer_id, buffer);
|
||||
let resp = NewBufferResponse { content };
|
||||
return Ok(serde_json::to_value(resp).unwrap());
|
||||
}
|
||||
}
|
||||
Err(xi_rpc::RemoteError::InvalidRequest(None))
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1,16 +1,19 @@
|
|||
pub mod buffer;
|
||||
pub mod core_proxy;
|
||||
pub mod dispatch;
|
||||
pub mod plugin;
|
||||
|
||||
use dispatch::Dispatcher;
|
||||
use xi_rpc::RpcLoop;
|
||||
use std::io;
|
||||
use xi_rpc::RpcLoop;
|
||||
use xi_rpc::RpcPeer;
|
||||
|
||||
pub fn mainloop() {
|
||||
let stdin = io::stdin();
|
||||
let stdout = io::stdout();
|
||||
let mut rpc_looper = RpcLoop::new(stdout);
|
||||
let mut dispatcher = Dispatcher::new();
|
||||
let peer: RpcPeer = Box::new(rpc_looper.get_raw_peer());
|
||||
let mut dispatcher = Dispatcher::new(peer);
|
||||
let result = rpc_looper.mainloop(|| stdin.lock(), &mut dispatcher);
|
||||
eprintln!("rpc looper stopped {:?}", result);
|
||||
}
|
||||
|
|
|
@ -1,30 +1,241 @@
|
|||
use anyhow::Result;
|
||||
use home::home_dir;
|
||||
use serde::{Deserialize, Serialize};
|
||||
use serde_json::json;
|
||||
use serde_json::Value;
|
||||
use std::collections::HashMap;
|
||||
use std::fs;
|
||||
use std::io::BufReader;
|
||||
use std::io::Read;
|
||||
use std::path::PathBuf;
|
||||
use std::process::Child;
|
||||
use std::process::Command;
|
||||
use std::process::Stdio;
|
||||
use std::sync::Arc;
|
||||
use std::thread;
|
||||
use toml;
|
||||
use xi_rpc::Handler;
|
||||
use xi_rpc::RpcLoop;
|
||||
use xi_rpc::RpcPeer;
|
||||
|
||||
use crate::buffer::BufferId;
|
||||
use crate::core_proxy::CoreProxy;
|
||||
|
||||
pub type PluginName = String;
|
||||
|
||||
#[derive(Clone, Debug, Default)]
|
||||
pub struct Counter(usize);
|
||||
|
||||
impl Counter {
|
||||
pub fn next(&mut self) -> usize {
|
||||
let n = self.0;
|
||||
self.0 = n + 1;
|
||||
n + 1
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(Eq, PartialEq, Hash, Clone, Debug, Serialize, Deserialize)]
|
||||
pub struct PluginId(pub usize);
|
||||
|
||||
#[derive(Deserialize, Clone)]
|
||||
pub struct PluginDescription {
|
||||
pub name: String,
|
||||
pub version: String,
|
||||
pub exec_path: PathBuf,
|
||||
dir: PathBuf,
|
||||
}
|
||||
|
||||
pub struct Plugin {
|
||||
id: PluginId,
|
||||
core: CoreProxy,
|
||||
peer: RpcPeer,
|
||||
name: String,
|
||||
process: Child,
|
||||
}
|
||||
|
||||
pub struct PluginCatalog {
|
||||
id_counter: Counter,
|
||||
items: HashMap<PluginName, PluginDescription>,
|
||||
}
|
||||
|
||||
impl PluginCatalog {
|
||||
pub fn new() -> PluginCatalog {
|
||||
PluginCatalog {
|
||||
id_counter: Counter::default(),
|
||||
items: HashMap::new(),
|
||||
}
|
||||
}
|
||||
|
||||
pub fn reload(&mut self) {
|
||||
println!("plugin reload from paths");
|
||||
eprintln!("plugin reload from paths");
|
||||
self.items.clear();
|
||||
self.load();
|
||||
}
|
||||
|
||||
pub fn load(&mut self) {}
|
||||
pub fn load(&mut self) {
|
||||
let all_manifests = find_all_manifests();
|
||||
for manifest_path in &all_manifests {
|
||||
match load_manifest(manifest_path) {
|
||||
Err(e) => (),
|
||||
Ok(manifest) => {
|
||||
self.items.insert(manifest.name.clone(), manifest);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
pub fn start_all(&mut self, core: CoreProxy) {
|
||||
for (_, manifest) in self.items.clone().iter() {
|
||||
start_plugin_process(
|
||||
self.next_plugin_id(),
|
||||
core.clone(),
|
||||
manifest.clone(),
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
pub fn next_plugin_id(&mut self) -> PluginId {
|
||||
PluginId(self.id_counter.next())
|
||||
}
|
||||
}
|
||||
|
||||
fn start_plugin_process(
|
||||
id: PluginId,
|
||||
core: CoreProxy,
|
||||
plugin_desc: PluginDescription,
|
||||
) {
|
||||
thread::spawn(move || {
|
||||
let parts: Vec<&str> = plugin_desc
|
||||
.exec_path
|
||||
.to_str()
|
||||
.unwrap()
|
||||
.split(" ")
|
||||
.into_iter()
|
||||
.collect();
|
||||
let mut child = Command::new(parts[0]);
|
||||
for part in &parts[1..] {
|
||||
child.arg(part);
|
||||
}
|
||||
child.current_dir(&plugin_desc.dir);
|
||||
let child = child.stdin(Stdio::piped()).stdout(Stdio::piped()).spawn();
|
||||
if child.is_err() {
|
||||
eprintln!("can't start proxy {:?}", child);
|
||||
return;
|
||||
}
|
||||
let mut child = child.unwrap();
|
||||
let child_stdin = child.stdin.take().unwrap();
|
||||
let child_stdout = child.stdout.take().unwrap();
|
||||
let mut looper = RpcLoop::new(child_stdin);
|
||||
let peer: RpcPeer = Box::new(looper.get_raw_peer());
|
||||
let name = plugin_desc.name.clone();
|
||||
let plugin = Plugin {
|
||||
id,
|
||||
core: core.clone(),
|
||||
peer,
|
||||
process: child,
|
||||
name,
|
||||
};
|
||||
eprintln!("plugin main loop starting {:?}", &plugin_desc.exec_path);
|
||||
plugin.initialize();
|
||||
let mut handler = PluginHandler { core };
|
||||
if let Err(e) =
|
||||
looper.mainloop(|| BufReader::new(child_stdout), &mut handler)
|
||||
{
|
||||
eprintln!("plugin main loop failed {} {:?}", e, &plugin_desc.dir);
|
||||
}
|
||||
eprintln!("plugin main loop exit {:?}", plugin_desc.dir);
|
||||
});
|
||||
}
|
||||
|
||||
#[derive(Serialize, Deserialize, Debug)]
|
||||
#[serde(rename_all = "snake_case")]
|
||||
#[serde(tag = "method", content = "params")]
|
||||
pub enum PluginNotification {
|
||||
StartLspServer {
|
||||
exec_path: String,
|
||||
language_id: String,
|
||||
options: Option<Value>,
|
||||
},
|
||||
}
|
||||
|
||||
#[derive(Serialize, Deserialize, Debug)]
|
||||
pub enum PluginRequest {}
|
||||
|
||||
pub struct PluginHandler {
|
||||
core: CoreProxy,
|
||||
}
|
||||
|
||||
impl Handler for PluginHandler {
|
||||
type Notification = PluginNotification;
|
||||
type Request = PluginRequest;
|
||||
|
||||
fn handle_notification(
|
||||
&mut self,
|
||||
ctx: &xi_rpc::RpcCtx,
|
||||
rpc: Self::Notification,
|
||||
) {
|
||||
match &rpc {
|
||||
PluginNotification::StartLspServer {
|
||||
exec_path,
|
||||
language_id,
|
||||
options,
|
||||
} => {
|
||||
self.core.peer.send_rpc_notification(
|
||||
"start_lsp_server",
|
||||
&serde_json::to_value(&rpc).unwrap(),
|
||||
);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
fn handle_request(
|
||||
&mut self,
|
||||
ctx: &xi_rpc::RpcCtx,
|
||||
rpc: Self::Request,
|
||||
) -> Result<serde_json::Value, xi_rpc::RemoteError> {
|
||||
Err(xi_rpc::RemoteError::InvalidRequest(None))
|
||||
}
|
||||
}
|
||||
|
||||
impl Plugin {
|
||||
pub fn initialize(&self) {
|
||||
self.peer.send_rpc_notification(
|
||||
"initialize",
|
||||
&json!({
|
||||
"plugin_id": self.id,
|
||||
}),
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
fn find_all_manifests() -> Vec<PathBuf> {
|
||||
let mut manifest_paths = Vec::new();
|
||||
let home = home_dir().unwrap();
|
||||
let path = home.join(".lapce").join("plugins");
|
||||
path.read_dir().map(|dir| {
|
||||
dir.flat_map(|item| item.map(|p| p.path()).ok())
|
||||
.map(|dir| dir.join("manifest.toml"))
|
||||
.filter(|f| f.exists())
|
||||
.for_each(|f| manifest_paths.push(f))
|
||||
});
|
||||
eprintln!("proxy mainfiest paths {:?}", manifest_paths);
|
||||
manifest_paths
|
||||
}
|
||||
|
||||
fn load_manifest(path: &PathBuf) -> Result<PluginDescription> {
|
||||
let mut file = fs::File::open(&path)?;
|
||||
let mut contents = String::new();
|
||||
file.read_to_string(&mut contents)?;
|
||||
let mut manifest: PluginDescription = toml::from_str(&contents)?;
|
||||
// normalize relative paths
|
||||
//manifest.dir = Some(path.parent().unwrap().canonicalize()?);
|
||||
// if manifest.exec_path.starts_with("./") {
|
||||
manifest.dir = path.parent().unwrap().canonicalize()?;
|
||||
manifest.exec_path = path
|
||||
.parent()
|
||||
.unwrap()
|
||||
.join(manifest.exec_path)
|
||||
.canonicalize()?;
|
||||
// }
|
||||
Ok(manifest)
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue