diff --git a/Cargo.lock b/Cargo.lock index a1dcd128..1cf7bf19 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -1857,7 +1857,7 @@ name = "lapce-core" version = "0.0.12" dependencies = [ "itertools", - "lapce-proxy", + "lapce-rpc", "serde 1.0.130", "serde_json", "thiserror", @@ -1973,9 +1973,11 @@ dependencies = [ "anyhow", "crossbeam-channel", "jsonrpc-lite", + "lsp-types", "parking_lot", "serde 1.0.130", "serde_json", + "xi-rope", ] [[package]] @@ -2005,7 +2007,6 @@ dependencies = [ "itertools", "jsonrpc-lite", "lapce-data", - "lapce-proxy", "lapce-rpc", "lazy_static", "libloading", diff --git a/lapce-core/Cargo.toml b/lapce-core/Cargo.toml index 695cf7d6..53eee926 100644 --- a/lapce-core/Cargo.toml +++ b/lapce-core/Cargo.toml @@ -21,4 +21,4 @@ tree-sitter-php = { git = "https://github.com/tree-sitter/tree-sitter-php.git", tree-sitter-c = "0.20.1" tree-sitter-cpp = "0.20.0" xi-rope = { git = "https://github.com/lapce/xi-editor", features = ["serde"] } -lapce-proxy = { path = "../lapce-proxy" } +lapce-rpc = { path = "../lapce-rpc" } diff --git a/lapce-core/src/style.rs b/lapce-core/src/style.rs index ff04582d..704ad109 100644 --- a/lapce-core/src/style.rs +++ b/lapce-core/src/style.rs @@ -3,7 +3,7 @@ sync::atomic::{AtomicUsize, Ordering}, }; -use lapce_proxy::style::{LineStyle, Style}; +use lapce_rpc::style::{LineStyle, Style}; use thiserror::Error; use tree_sitter::{ Language, LossyUtf8, Node, Point, Query, QueryCaptures, QueryCursor, QueryError, @@ -829,10 +829,11 @@ fn next(&mut self) -> Option { } // If the node represents a reference, then try to find the corresponding // definition in the scope stack. - else if Some(capture.index) == layer.config.local_ref_capture_index && definition_highlight.is_none() { + else if Some(capture.index) == layer.config.local_ref_capture_index + && definition_highlight.is_none() + { definition_highlight = None; - if let Ok(name) = str::from_utf8(&self.source[range.clone()]) - { + if let Ok(name) = str::from_utf8(&self.source[range.clone()]) { for scope in layer.scope_stack.iter().rev() { if let Some(highlight) = scope.local_defs.iter().rev().find_map(|def| { diff --git a/lapce-core/src/syntax.rs b/lapce-core/src/syntax.rs index 13860fea..42831e85 100644 --- a/lapce-core/src/syntax.rs +++ b/lapce-core/src/syntax.rs @@ -6,7 +6,7 @@ }; use itertools::Itertools; -use lapce_proxy::style::Style; +use lapce_rpc::style::Style; use tree_sitter::{Node, Parser, Point, Tree}; use xi_rope::{ spans::{Spans, SpansBuilder}, diff --git a/lapce-data/src/buffer.rs b/lapce-data/src/buffer.rs index e641e2a2..27b4616a 100644 --- a/lapce-data/src/buffer.rs +++ b/lapce-data/src/buffer.rs @@ -7,8 +7,8 @@ use lapce_core::indent::{auto_detect_indent_style, IndentStyle}; use lapce_core::style::line_styles; use lapce_core::syntax::Syntax; -use lapce_proxy::dispatch::{BufferHeadResponse, NewBufferResponse}; -use lapce_proxy::style::{LineStyle, LineStyles, Style}; +use lapce_rpc::buffer::{BufferHeadResponse, BufferId, NewBufferResponse}; +use lapce_rpc::style::{LineStyle, LineStyles, Style}; use lsp_types::SemanticTokensLegend; use lsp_types::SemanticTokensServerCapabilities; use lsp_types::{CodeActionResponse, Position}; @@ -37,7 +37,7 @@ find::Find, movement::{ColPosition, LinePosition, Movement, SelRegion, Selection}, proxy::LapceProxy, - state::{Counter, Mode}, + state::Mode, }; #[allow(dead_code)] @@ -67,16 +67,6 @@ pub enum DiffResult { Right(T), } -#[derive(Eq, PartialEq, Hash, Copy, Clone, Debug, Serialize, Deserialize, Data)] -pub struct BufferId(pub u64); - -impl BufferId { - pub fn next() -> Self { - static BUFFER_ID_COUNTER: Counter = Counter::new(); - Self(BUFFER_ID_COUNTER.next()) - } -} - #[derive(Clone)] pub struct BufferUIState { #[allow(dead_code)] diff --git a/lapce-data/src/command.rs b/lapce-data/src/command.rs index 5cbf9767..607dd955 100644 --- a/lapce-data/src/command.rs +++ b/lapce-data/src/command.rs @@ -4,11 +4,9 @@ use druid::{Point, Rect, Selector, Size, WidgetId, WindowId}; use indexmap::IndexMap; use lapce_core::syntax::Syntax; -use lapce_proxy::{ - dispatch::{DiffInfo, FileNodeItem}, - plugin::PluginDescription, - style::Style, - terminal::TermId, +use lapce_rpc::{ + buffer::BufferId, file::FileNodeItem, plugin::PluginDescription, + source_control::DiffInfo, style::Style, terminal::TermId, }; use lsp_types::{ CodeActionResponse, CompletionItem, CompletionResponse, Location, Position, @@ -20,7 +18,6 @@ use xi_rope::{spans::Spans, Rope}; use crate::{ - buffer::BufferId, buffer::DiffLines, data::{EditorTabChild, MotionMode, SplitContent}, editor::EditorLocationNew, @@ -578,10 +575,7 @@ pub enum LapceUICommand { HideMenu, ShowMenu(Point, Arc>), UpdateSearch(String), - GlobalSearchResult( - String, - Arc>>, - ), + GlobalSearchResult(String, Arc>>), CancelFilePicker, SetWorkspace(LapceWorkspace), SetTheme(String, bool), diff --git a/lapce-data/src/completion.rs b/lapce-data/src/completion.rs index aee31759..2bcdaccd 100644 --- a/lapce-data/src/completion.rs +++ b/lapce-data/src/completion.rs @@ -4,12 +4,12 @@ use druid::{Command, EventCtx, ExtEventSink, Size, Target, WidgetId}; use fuzzy_matcher::{skim::SkimMatcherV2, FuzzyMatcher}; use itertools::Itertools; +use lapce_rpc::buffer::BufferId; use lsp_types::{CompletionItem, CompletionResponse, Position}; use regex::Regex; use std::str::FromStr; use crate::{ - buffer::BufferId, command::{LapceUICommand, LAPCE_UI_COMMAND}, movement::Movement, proxy::LapceProxy, diff --git a/lapce-data/src/data.rs b/lapce-data/src/data.rs index abf239ba..a75cdc33 100644 --- a/lapce-data/src/data.rs +++ b/lapce-data/src/data.rs @@ -16,9 +16,8 @@ Point, Rect, Size, Target, Vec2, WidgetId, WindowId, }; -use lapce_proxy::{ - dispatch::{FileDiff, FileNodeItem}, - plugin::PluginDescription, +use lapce_rpc::{ + file::FileNodeItem, plugin::PluginDescription, source_control::FileDiff, terminal::TermId, }; use lsp_types::{ diff --git a/lapce-data/src/editor.rs b/lapce-data/src/editor.rs index fb5541c0..2e14455f 100644 --- a/lapce-data/src/editor.rs +++ b/lapce-data/src/editor.rs @@ -20,15 +20,14 @@ use crate::proxy::path_from_url; use crate::state::LapceWorkspace; use crate::svg::get_svg; +use crate::{buffer::WordProperty, movement::CursorMode}; use crate::{ - buffer::BufferId, command::{LapceCommand, LapceUICommand, LAPCE_UI_COMMAND}, movement::{ColPosition, Movement, SelRegion, Selection}, split::SplitMoveDirection, state::Mode, state::VisualMode, }; -use crate::{buffer::WordProperty, movement::CursorMode}; use crate::{find::Find, split::SplitDirection}; use crate::{keypress::KeyPressFocus, movement::Cursor}; use crate::{movement::InsertDrift, panel::PanelPosition}; @@ -47,19 +46,20 @@ }; use druid::{Application, ExtEventSink, MouseEvent}; use lapce_core::syntax::Syntax; +use lapce_rpc::buffer::BufferId; use lsp_types::CompletionTextEdit; use lsp_types::{ CodeActionResponse, CompletionItem, DiagnosticSeverity, GotoDefinitionResponse, Location, Position, }; use serde_json::Value; +use std::cmp::Ordering; use std::collections::HashSet; use std::path::Path; use std::thread; use std::{collections::HashMap, sync::Arc}; use std::{iter::Iterator, path::PathBuf}; use std::{str::FromStr, time::Duration}; -use std::cmp::Ordering; use xi_rope::{RopeDelta, Transformer}; pub struct LapceUI {} @@ -665,24 +665,25 @@ pub fn apply_completion_item( ctx: &mut EventCtx, item: &CompletionItem, ) -> Result<()> { - let additional_edit: Option> = item.additional_text_edits.as_ref().map(|edits| { - edits - .iter() - .map(|edit| { - let selection = Selection::region( - self.buffer.offset_of_position( - &edit.range.start, - self.config.editor.tab_width, - ), - self.buffer.offset_of_position( - &edit.range.end, - self.config.editor.tab_width, - ), - ); - (selection, edit.new_text.clone()) - }) - .collect::>() - }); + let additional_edit: Option> = + item.additional_text_edits.as_ref().map(|edits| { + edits + .iter() + .map(|edit| { + let selection = Selection::region( + self.buffer.offset_of_position( + &edit.range.start, + self.config.editor.tab_width, + ), + self.buffer.offset_of_position( + &edit.range.end, + self.config.editor.tab_width, + ), + ); + (selection, edit.new_text.clone()) + }) + .collect::>() + }); let additioal_edit: Option> = additional_edit.as_ref().map(|edits| { edits .iter() @@ -788,8 +789,7 @@ pub fn apply_completion_item( &[ &[( &selection, - item.insert_text - .as_deref().unwrap_or(item.label.as_str()), + item.insert_text.as_deref().unwrap_or(item.label.as_str()), )][..], &additioal_edit.unwrap_or_default()[..], ] @@ -1729,8 +1729,12 @@ fn scroll( }; match new_line.cmp(&line) { - Ordering::Greater => self.do_move(ctx, &Movement::Down, new_line - line, mods), - Ordering::Less => self.do_move(ctx, &Movement::Up, line - new_line, mods), + Ordering::Greater => { + self.do_move(ctx, &Movement::Down, new_line - line, mods) + } + Ordering::Less => { + self.do_move(ctx, &Movement::Up, line - new_line, mods) + } _ => (), }; @@ -4791,7 +4795,10 @@ fn run_command( let _ = event_sink.submit_command( LAPCE_UI_COMMAND, LapceUICommand::ResolveCompletion( - buffer_id, rev, offset, Box::new(item), + buffer_id, + rev, + offset, + Box::new(item), ), Target::Widget(view_id), ); @@ -5385,7 +5392,8 @@ fn receive_char(&mut self, ctx: &mut EventCtx, c: &str) { || prop == WordProperty::Punctuation }) .unwrap_or(true); - if is_whitespace_or_punct && matching_pair_direction(c).unwrap_or(false) + if is_whitespace_or_punct + && matching_pair_direction(c).unwrap_or(false) { if let Some(c) = matching_char(c) { self.edit( diff --git a/lapce-data/src/explorer.rs b/lapce-data/src/explorer.rs index 093a01ed..8db50685 100644 --- a/lapce-data/src/explorer.rs +++ b/lapce-data/src/explorer.rs @@ -7,7 +7,7 @@ use druid::{Target, WidgetId}; use include_dir::{include_dir, Dir}; -use lapce_proxy::dispatch::FileNodeItem; +use lapce_rpc::file::FileNodeItem; use crate::proxy::LapceProxy; use crate::state::LapceWorkspace; diff --git a/lapce-data/src/lsp.rs b/lapce-data/src/lsp.rs index 1216f94c..4bc71f9d 100644 --- a/lapce-data/src/lsp.rs +++ b/lapce-data/src/lsp.rs @@ -1,14 +1,13 @@ use anyhow::{anyhow, Result}; use druid::{WidgetId, WindowId}; use jsonrpc_lite::Id; +use lapce_rpc::buffer::BufferId; use parking_lot::Mutex; use std::{collections::HashMap, io::BufRead, io::Write, process::Child, sync::Arc}; use lsp_types::*; use serde_json::Value; -use crate::buffer::BufferId; - pub type Callback = Box; const HEADER_CONTENT_LENGTH: &str = "content-length"; const HEADER_CONTENT_TYPE: &str = "content-type"; diff --git a/lapce-data/src/picker.rs b/lapce-data/src/picker.rs index b4a7ccea..4cfa55ad 100644 --- a/lapce-data/src/picker.rs +++ b/lapce-data/src/picker.rs @@ -4,7 +4,7 @@ }; use druid::WidgetId; -use lapce_proxy::dispatch::FileNodeItem; +use lapce_rpc::file::FileNodeItem; #[derive(Clone)] pub struct FilePickerData { diff --git a/lapce-data/src/proxy.rs b/lapce-data/src/proxy.rs index e7b7fd01..4d12013a 100644 --- a/lapce-data/src/proxy.rs +++ b/lapce-data/src/proxy.rs @@ -1,4 +1,3 @@ -use std::collections::HashMap; use std::io::BufReader; #[cfg(target_os = "windows")] use std::os::windows::process::CommandExt; @@ -13,19 +12,18 @@ use druid::Target; use druid::{ExtEventSink, WidgetId}; use flate2::read::GzDecoder; -use lapce_proxy::dispatch::FileDiff; -use lapce_proxy::dispatch::FileNodeItem; -use lapce_proxy::dispatch::{DiffInfo, Dispatcher}; -use lapce_proxy::plugin::PluginDescription; -use lapce_proxy::style::LineStyle; -use lapce_proxy::terminal::TermId; +use lapce_proxy::dispatch::Dispatcher; +use lapce_rpc::buffer::BufferId; +use lapce_rpc::core::{CoreNotification, CoreRequest}; +use lapce_rpc::plugin::PluginDescription; +use lapce_rpc::source_control::FileDiff; +use lapce_rpc::terminal::TermId; use lapce_rpc::RpcHandler; use lapce_rpc::{stdio_transport, Callback}; use lapce_rpc::{ControlFlow, Handler}; use lsp_types::CompletionItem; use lsp_types::Position; -use lsp_types::ProgressParams; -use lsp_types::PublishDiagnosticsParams; +use lsp_types::Url; use parking_lot::Mutex; use serde::{Deserialize, Serialize}; use serde_json::json; @@ -34,11 +32,11 @@ use xi_rope::{Interval, RopeDelta}; use crate::command::LapceUICommand; +use crate::command::LAPCE_UI_COMMAND; use crate::config::Config; use crate::state::LapceWorkspace; use crate::state::LapceWorkspaceType; use crate::terminal::RawTerminal; -use crate::{buffer::BufferId, command::LAPCE_UI_COMMAND}; pub const VERSION: &str = env!("CARGO_PKG_VERSION"); @@ -65,12 +63,13 @@ pub struct LapceProxy { } impl Handler for LapceProxy { - type Notification = Notification; - type Request = Request; + type Notification = CoreNotification; + type Request = CoreRequest; fn handle_notification(&mut self, rpc: Self::Notification) -> ControlFlow { + use lapce_rpc::core::CoreNotification::*; match rpc { - Notification::SemanticStyles { + SemanticStyles { rev, buffer_id, path, @@ -100,7 +99,7 @@ fn handle_notification(&mut self, rpc: Self::Notification) -> ControlFlow { ); }); } - Notification::ReloadBuffer { + ReloadBuffer { buffer_id, new_content, rev, @@ -111,21 +110,21 @@ fn handle_notification(&mut self, rpc: Self::Notification) -> ControlFlow { Target::Widget(self.tab_id), ); } - Notification::PublishDiagnostics { diagnostics } => { + PublishDiagnostics { diagnostics } => { let _ = self.event_sink.submit_command( LAPCE_UI_COMMAND, LapceUICommand::PublishDiagnostics(diagnostics), Target::Widget(self.tab_id), ); } - Notification::WorkDoneProgress { progress } => { + WorkDoneProgress { progress } => { let _ = self.event_sink.submit_command( LAPCE_UI_COMMAND, LapceUICommand::WorkDoneProgress(progress), Target::Widget(self.tab_id), ); } - Notification::InstalledPlugins { plugins } => { + InstalledPlugins { plugins } => { let _ = self.event_sink.submit_command( LAPCE_UI_COMMAND, LapceUICommand::UpdateInstalledPlugins(plugins), @@ -133,22 +132,22 @@ fn handle_notification(&mut self, rpc: Self::Notification) -> ControlFlow { ); } #[allow(unused_variables)] - Notification::ListDir { items } => {} + ListDir { items } => {} #[allow(unused_variables)] - Notification::DiffFiles { files } => {} - Notification::DiffInfo { diff } => { + DiffFiles { files } => {} + DiffInfo { diff } => { let _ = self.event_sink.submit_command( LAPCE_UI_COMMAND, LapceUICommand::UpdateDiffInfo(diff), Target::Widget(self.tab_id), ); } - Notification::UpdateTerminal { term_id, content } => { + UpdateTerminal { term_id, content } => { let _ = self .term_tx .send((term_id, TermEvent::UpdateContent(content))); } - Notification::CloseTerminal { term_id } => { + CloseTerminal { term_id } => { let _ = self.term_tx.send((term_id, TermEvent::CloseTerminal)); let _ = self.event_sink.submit_command( LAPCE_UI_COMMAND, @@ -156,14 +155,14 @@ fn handle_notification(&mut self, rpc: Self::Notification) -> ControlFlow { Target::Widget(self.tab_id), ); } - Notification::ProxyConnected {} => { + ProxyConnected {} => { let _ = self.event_sink.submit_command( LAPCE_UI_COMMAND, LapceUICommand::ProxyUpdateStatus(ProxyStatus::Connected), Target::Widget(self.tab_id), ); } - Notification::HomeDir { path } => { + HomeDir { path } => { let _ = self.event_sink.submit_command( LAPCE_UI_COMMAND, LapceUICommand::HomeDir(path), @@ -628,158 +627,6 @@ pub enum CursorShape { Hidden, } -#[derive(Debug, Clone, Serialize, Deserialize)] -#[serde(rename_all = "snake_case")] -#[serde(tag = "method", content = "params")] -pub enum Notification { - ProxyConnected {}, - SemanticStyles { - rev: u64, - buffer_id: BufferId, - path: PathBuf, - len: usize, - styles: Vec, - }, - ReloadBuffer { - buffer_id: BufferId, - new_content: String, - rev: u64, - }, - PublishDiagnostics { - diagnostics: PublishDiagnosticsParams, - }, - WorkDoneProgress { - progress: ProgressParams, - }, - HomeDir { - path: PathBuf, - }, - InstalledPlugins { - plugins: HashMap, - }, - ListDir { - items: Vec, - }, - DiffFiles { - files: Vec, - }, - DiffInfo { - diff: DiffInfo, - }, - UpdateTerminal { - term_id: TermId, - content: String, - }, - CloseTerminal { - term_id: TermId, - }, -} - -#[derive(Debug, Clone, Serialize, Deserialize)] -pub enum Request {} - -pub struct ProxyHandlerNew { - #[allow(dead_code)] - tab_id: WidgetId, - - #[allow(dead_code)] - term_tx: Sender<(TermId, TermEvent)>, - - #[allow(dead_code)] - event_sink: ExtEventSink, -} -// -// impl Handler for ProxyHandlerNew { -// type Notification = Notification; -// type Request = Request; -// -// fn handle_notification( -// &mut self, -// ctx: &xi_rpc::RpcCtx, -// rpc: Self::Notification, -// ) { -// match rpc { -// Notification::SemanticTokens { -// rev, -// buffer_id, -// path, -// tokens, -// } => { -// self.event_sink.submit_command( -// LAPCE_UI_COMMAND, -// LapceUICommand::UpdateSemanticTokens( -// buffer_id, path, rev, tokens, -// ), -// Target::Widget(self.tab_id), -// ); -// } -// Notification::ReloadBuffer { -// buffer_id, -// new_content, -// rev, -// } => { -// self.event_sink.submit_command( -// LAPCE_UI_COMMAND, -// LapceUICommand::ReloadBuffer(buffer_id, rev, new_content), -// Target::Widget(self.tab_id), -// ); -// } -// Notification::PublishDiagnostics { diagnostics } => { -// self.event_sink.submit_command( -// LAPCE_UI_COMMAND, -// LapceUICommand::PublishDiagnostics(diagnostics), -// Target::Widget(self.tab_id), -// ); -// } -// Notification::WorkDoneProgress { progress } => { -// self.event_sink.submit_command( -// LAPCE_UI_COMMAND, -// LapceUICommand::WorkDoneProgress(progress), -// Target::Widget(self.tab_id), -// ); -// } -// Notification::InstalledPlugins { plugins } => { -// self.event_sink.submit_command( -// LAPCE_UI_COMMAND, -// LapceUICommand::UpdateInstalledPlugins(plugins), -// Target::Widget(self.tab_id), -// ); -// } -// Notification::ListDir { items } => {} -// Notification::DiffFiles { files } => {} -// Notification::FileDiffs { diffs } => { -// self.event_sink.submit_command( -// LAPCE_UI_COMMAND, -// LapceUICommand::UpdateFileDiffs(diffs), -// Target::Widget(self.tab_id), -// ); -// } -// Notification::UpdateTerminal { term_id, content } => { -// self.term_tx -// .send((term_id, TermEvent::UpdateContent(content))); -// } -// Notification::CloseTerminal { term_id } => { -// self.term_tx.send((term_id, TermEvent::CloseTerminal)); -// self.event_sink.submit_command( -// LAPCE_UI_COMMAND, -// LapceUICommand::CloseTerminal(term_id), -// Target::Widget(self.tab_id), -// ); -// } -// } -// } -// -// fn handle_request( -// &mut self, -// ctx: &xi_rpc::RpcCtx, -// rpc: Self::Request, -// ) -> Result { -// Err(xi_rpc::RemoteError::InvalidRequest(None)) -// } -// } - -use lsp_types::Url; - // Rust-analyzer returns paths in the form of "file:///:/...", which gets parsed into URL // as "/://" which is then interpreted by PathBuf::new() as a UNIX-like path from root. // This function strips the additional / from the beginning, if the first segment is a drive letter. diff --git a/lapce-data/src/source_control.rs b/lapce-data/src/source_control.rs index 67534035..c6c520a7 100644 --- a/lapce-data/src/source_control.rs +++ b/lapce-data/src/source_control.rs @@ -1,5 +1,5 @@ use druid::{Command, Env, EventCtx, Modifiers, Target, WidgetId}; -use lapce_proxy::dispatch::FileDiff; +use lapce_rpc::source_control::FileDiff; use crate::{ command::{CommandExecuted, LapceCommand, LapceUICommand, LAPCE_UI_COMMAND}, diff --git a/lapce-data/src/terminal.rs b/lapce-data/src/terminal.rs index 078dfb58..ac3a1336 100644 --- a/lapce-data/src/terminal.rs +++ b/lapce-data/src/terminal.rs @@ -15,7 +15,7 @@ WidgetId, }; use hashbrown::HashMap; -use lapce_proxy::terminal::TermId; +use lapce_rpc::terminal::TermId; use parking_lot::Mutex; use crate::{ diff --git a/lapce-proxy/src/buffer.rs b/lapce-proxy/src/buffer.rs index ef13d135..7c39f693 100644 --- a/lapce-proxy/src/buffer.rs +++ b/lapce-proxy/src/buffer.rs @@ -1,5 +1,6 @@ use anyhow::{anyhow, Result}; use crossbeam_channel::Sender; +use lapce_rpc::buffer::BufferId; use std::ffi::OsString; use std::fs; use std::fs::File; @@ -9,12 +10,8 @@ use std::{borrow::Cow, path::Path, time::SystemTime}; use lsp_types::*; -use serde::{Deserialize, Serialize}; use xi_rope::{interval::IntervalBounds, rope::Rope, RopeDelta}; -#[derive(Eq, PartialEq, Hash, Copy, Clone, Debug, Serialize, Deserialize)] -pub struct BufferId(pub usize); - pub struct Buffer { pub language_id: String, pub id: BufferId, diff --git a/lapce-proxy/src/dispatch.rs b/lapce-proxy/src/dispatch.rs index 79a1fcce..55861790 100644 --- a/lapce-proxy/src/dispatch.rs +++ b/lapce-proxy/src/dispatch.rs @@ -1,7 +1,7 @@ -use crate::buffer::{get_mod_time, Buffer, BufferId}; +use crate::buffer::{get_mod_time, Buffer}; use crate::lsp::LspCatalog; -use crate::plugin::{PluginCatalog, PluginDescription}; -use crate::terminal::{TermId, Terminal}; +use crate::plugin::PluginCatalog; +use crate::terminal::Terminal; use alacritty_terminal::event_loop::Msg; use alacritty_terminal::term::SizeInfo; use anyhow::{anyhow, Context, Result}; @@ -12,21 +12,23 @@ use grep_regex::RegexMatcherBuilder; use grep_searcher::sinks::UTF8; use grep_searcher::SearcherBuilder; +use lapce_rpc::buffer::{BufferHeadResponse, BufferId, NewBufferResponse}; +use lapce_rpc::file::FileNodeItem; +use lapce_rpc::proxy::{ProxyNotification, ProxyRequest}; +use lapce_rpc::source_control::{DiffInfo, FileDiff}; +use lapce_rpc::terminal::TermId; use lapce_rpc::{self, Call, RequestId, RpcObject}; -use lsp_types::{CompletionItem, Position, TextDocumentContentChangeEvent}; +use lsp_types::TextDocumentContentChangeEvent; use notify::Watcher; use parking_lot::Mutex; -use serde::{Deserialize, Serialize}; use serde_json::json; use serde_json::Value; -use std::cmp::Ordering; use std::collections::HashMap; +use std::fs; use std::path::{Path, PathBuf}; use std::sync::Arc; use std::thread; -use std::{cmp, fs}; use std::{collections::HashSet, io::BufRead}; -use xi_rope::RopeDelta; #[derive(Clone)] pub struct Dispatcher { @@ -112,222 +114,6 @@ fn handle_event(&mut self, event: notify::Result) { } } -#[derive(Debug, Clone, Serialize, Deserialize)] -#[serde(rename_all = "snake_case")] -#[serde(tag = "method", content = "params")] -pub enum Notification { - Initialize { - workspace: PathBuf, - }, - Shutdown {}, - Update { - buffer_id: BufferId, - delta: RopeDelta, - rev: u64, - }, - NewTerminal { - term_id: TermId, - cwd: Option, - shell: String, - }, - InstallPlugin { - plugin: PluginDescription, - }, - GitCommit { - message: String, - diffs: Vec, - }, - TerminalWrite { - term_id: TermId, - content: String, - }, - TerminalResize { - term_id: TermId, - width: usize, - height: usize, - }, - TerminalClose { - term_id: TermId, - }, -} - -#[derive(Debug, Clone, Serialize, Deserialize)] -#[serde(rename_all = "snake_case")] -#[serde(tag = "method", content = "params")] -pub enum Request { - NewBuffer { - buffer_id: BufferId, - path: PathBuf, - }, - BufferHead { - buffer_id: BufferId, - path: PathBuf, - }, - GetCompletion { - request_id: usize, - buffer_id: BufferId, - position: Position, - }, - GlobalSearch { - pattern: String, - }, - CompletionResolve { - buffer_id: BufferId, - completion_item: Box, - }, - GetSignature { - buffer_id: BufferId, - position: Position, - }, - GetReferences { - buffer_id: BufferId, - position: Position, - }, - GetDefinition { - request_id: usize, - buffer_id: BufferId, - position: Position, - }, - GetCodeActions { - buffer_id: BufferId, - position: Position, - }, - GetDocumentSymbols { - buffer_id: BufferId, - }, - GetDocumentFormatting { - buffer_id: BufferId, - }, - GetFiles { - path: String, - }, - ReadDir { - path: PathBuf, - }, - Save { - rev: u64, - buffer_id: BufferId, - }, -} - -#[derive(Debug, Clone, Serialize, Deserialize)] -pub struct NewBufferResponse { - pub content: String, -} - -#[derive(Debug, Clone, Serialize, Deserialize)] -pub struct BufferHeadResponse { - pub id: String, - pub content: String, -} - -#[derive(Debug, Clone, Serialize, Deserialize, PartialEq, Default)] -pub struct DiffInfo { - pub head: String, - pub branches: Vec, - pub diffs: Vec, -} - -#[derive(Debug, Clone, Serialize, Deserialize, PartialEq)] -pub enum FileDiff { - Modified(PathBuf), - Added(PathBuf), - Deleted(PathBuf), - Renamed(PathBuf, PathBuf), -} - -impl FileDiff { - pub fn path(&self) -> &PathBuf { - match &self { - FileDiff::Modified(p) - | FileDiff::Added(p) - | FileDiff::Deleted(p) - | FileDiff::Renamed(_, p) => p, - } - } -} - -#[derive(Debug, Clone, Serialize, Deserialize, PartialEq, Eq)] -pub struct FileNodeItem { - pub path_buf: PathBuf, - pub is_dir: bool, - pub read: bool, - pub open: bool, - pub children: HashMap, - pub children_open_count: usize, -} - -impl std::cmp::PartialOrd for FileNodeItem { - fn partial_cmp(&self, other: &Self) -> Option { - let self_dir = self.is_dir; - let other_dir = other.is_dir; - if self_dir && !other_dir { - return Some(cmp::Ordering::Less); - } - if !self_dir && other_dir { - return Some(cmp::Ordering::Greater); - } - - let self_file_name = self.path_buf.file_name()?.to_str()?.to_lowercase(); - let other_file_name = other.path_buf.file_name()?.to_str()?.to_lowercase(); - if self_file_name.starts_with('.') && !other_file_name.starts_with('.') { - return Some(cmp::Ordering::Less); - } - if !self_file_name.starts_with('.') && other_file_name.starts_with('.') { - return Some(cmp::Ordering::Greater); - } - self_file_name.partial_cmp(&other_file_name) - } -} - -impl FileNodeItem { - pub fn sorted_children(&self) -> Vec<&FileNodeItem> { - let mut children = self - .children - .iter() - .map(|(_, item)| item) - .collect::>(); - children.sort_by(|a, b| match (a.is_dir, b.is_dir) { - (true, true) => a - .path_buf - .to_str() - .unwrap() - .cmp(b.path_buf.to_str().unwrap()), - (true, false) => Ordering::Less, - (false, true) => Ordering::Greater, - (false, false) => a - .path_buf - .to_str() - .unwrap() - .cmp(b.path_buf.to_str().unwrap()), - }); - children - } - - pub fn sorted_children_mut(&mut self) -> Vec<&mut FileNodeItem> { - let mut children = self - .children - .iter_mut() - .map(|(_, item)| item) - .collect::>(); - children.sort_by(|a, b| match (a.is_dir, b.is_dir) { - (true, true) => a - .path_buf - .to_str() - .unwrap() - .cmp(b.path_buf.to_str().unwrap()), - (true, false) => Ordering::Less, - (false, true) => Ordering::Greater, - (false, false) => a - .path_buf - .to_str() - .unwrap() - .cmp(b.path_buf.to_str().unwrap()), - }); - children - } -} - impl Dispatcher { pub fn new(sender: Sender) -> Dispatcher { let plugins = PluginCatalog::new(); @@ -388,12 +174,12 @@ pub fn mainloop(&self, receiver: Receiver) -> Result<()> { let rpc: RpcObject = msg.into(); if rpc.is_response() { } else { - match rpc.into_rpc::() { + match rpc.into_rpc::() { Ok(Call::Request(id, request)) => { self.handle_request(id, request); } Ok(Call::Notification(notification)) => { - if let Notification::Shutdown {} = ¬ification { + if let ProxyNotification::Shutdown {} = ¬ification { for (_, sender) in self.terminals.lock().iter() { #[allow(deprecated)] let _ = sender.send(Msg::Shutdown); @@ -484,9 +270,10 @@ pub fn send_notification(&self, method: &str, params: Value) { })); } - fn handle_notification(&self, rpc: Notification) { + fn handle_notification(&self, rpc: ProxyNotification) { + use ProxyNotification::*; match rpc { - Notification::Initialize { workspace } => { + Initialize { workspace } => { *self.workspace.lock() = Some(workspace.clone()); let _ = self .watcher @@ -504,8 +291,8 @@ fn handle_notification(&self, rpc: Notification) { *self.last_diff.lock() = diff; } } - Notification::Shutdown {} => {} - Notification::Update { + Shutdown {} => {} + Update { buffer_id, delta, rev, @@ -516,7 +303,7 @@ fn handle_notification(&self, rpc: Notification) { self.lsp.lock().update(buffer, &content_change, buffer.rev); } } - Notification::InstallPlugin { plugin } => { + InstallPlugin { plugin } => { let catalog = self.plugins.clone(); let dispatcher = self.clone(); std::thread::spawn(move || { @@ -533,7 +320,7 @@ fn handle_notification(&self, rpc: Notification) { ); }); } - Notification::NewTerminal { + NewTerminal { term_id, cwd, shell, @@ -546,21 +333,21 @@ fn handle_notification(&self, rpc: Notification) { terminal.run(dispatcher); }); } - Notification::TerminalClose { term_id } => { + TerminalClose { term_id } => { let mut terminals = self.terminals.lock(); if let Some(tx) = terminals.remove(&term_id) { #[allow(deprecated)] let _ = tx.send(Msg::Shutdown); } } - Notification::TerminalWrite { term_id, content } => { + TerminalWrite { term_id, content } => { let terminals = self.terminals.lock(); let tx = terminals.get(&term_id).unwrap(); #[allow(deprecated)] let _ = tx.send(Msg::Input(content.into_bytes().into())); } - Notification::TerminalResize { + TerminalResize { term_id, width, height, @@ -581,7 +368,7 @@ fn handle_notification(&self, rpc: Notification) { let _ = tx.send(Msg::Resize(size)); } } - Notification::GitCommit { message, diffs } => { + GitCommit { message, diffs } => { if let Some(workspace) = self.workspace.lock().clone() { if let Err(_e) = git_commit(&workspace, &message, diffs) {} } @@ -589,9 +376,10 @@ fn handle_notification(&self, rpc: Notification) { } } - fn handle_request(&self, id: RequestId, rpc: Request) { + fn handle_request(&self, id: RequestId, rpc: ProxyRequest) { + use ProxyRequest::*; match rpc { - Request::NewBuffer { buffer_id, path } => { + NewBuffer { buffer_id, path } => { let _ = self .watcher .lock() @@ -612,7 +400,7 @@ fn handle_request(&self, id: RequestId, rpc: Request) { })); } #[allow(unused_variables)] - Request::BufferHead { buffer_id, path } => { + BufferHead { buffer_id, path } => { if let Some(workspace) = self.workspace.lock().clone() { let result = file_get_head(&workspace, &path); if let Ok((_blob_id, content)) = result { @@ -627,7 +415,7 @@ fn handle_request(&self, id: RequestId, rpc: Request) { } } } - Request::GetCompletion { + GetCompletion { buffer_id, position, request_id, @@ -638,7 +426,7 @@ fn handle_request(&self, id: RequestId, rpc: Request) { .lock() .get_completion(id, request_id, buffer, position); } - Request::CompletionResolve { + CompletionResolve { buffer_id, completion_item, } => { @@ -648,7 +436,7 @@ fn handle_request(&self, id: RequestId, rpc: Request) { .lock() .completion_resolve(id, buffer, &completion_item); } - Request::GetSignature { + GetSignature { buffer_id, position, } => { @@ -656,7 +444,7 @@ fn handle_request(&self, id: RequestId, rpc: Request) { let buffer = buffers.get(&buffer_id).unwrap(); self.lsp.lock().get_signature(id, buffer, position); } - Request::GetReferences { + GetReferences { buffer_id, position, } => { @@ -664,7 +452,7 @@ fn handle_request(&self, id: RequestId, rpc: Request) { let buffer = buffers.get(&buffer_id).unwrap(); self.lsp.lock().get_references(id, buffer, position); } - Request::GetDefinition { + GetDefinition { buffer_id, position, request_id, @@ -675,7 +463,7 @@ fn handle_request(&self, id: RequestId, rpc: Request) { .lock() .get_definition(id, request_id, buffer, position); } - Request::GetCodeActions { + GetCodeActions { buffer_id, position, } => { @@ -683,17 +471,17 @@ fn handle_request(&self, id: RequestId, rpc: Request) { let buffer = buffers.get(&buffer_id).unwrap(); self.lsp.lock().get_code_actions(id, buffer, position); } - Request::GetDocumentSymbols { buffer_id } => { + GetDocumentSymbols { buffer_id } => { let buffers = self.buffers.lock(); let buffer = buffers.get(&buffer_id).unwrap(); self.lsp.lock().get_document_symbols(id, buffer); } - Request::GetDocumentFormatting { buffer_id } => { + GetDocumentFormatting { buffer_id } => { let buffers = self.buffers.lock(); let buffer = buffers.get(&buffer_id).unwrap(); self.lsp.lock().get_document_formatting(id, buffer); } - Request::ReadDir { path } => { + ReadDir { path } => { let local_dispatcher = self.clone(); thread::spawn(move || { let result = fs::read_dir(path) @@ -720,7 +508,7 @@ fn handle_request(&self, id: RequestId, rpc: Request) { }); } #[allow(unused_variables)] - Request::GetFiles { path } => { + GetFiles { path } => { if let Some(workspace) = self.workspace.lock().clone() { let local_dispatcher = self.clone(); thread::spawn(move || { @@ -737,14 +525,14 @@ fn handle_request(&self, id: RequestId, rpc: Request) { }); } } - Request::Save { rev, buffer_id } => { + Save { rev, buffer_id } => { let mut buffers = self.buffers.lock(); let buffer = buffers.get_mut(&buffer_id).unwrap(); let resp = buffer.save(rev).map(|_r| json!({})); self.lsp.lock().save_buffer(buffer); self.respond(id, resp); } - Request::GlobalSearch { pattern } => { + GlobalSearch { pattern } => { if let Some(workspace) = self.workspace.lock().clone() { let local_dispatcher = self.clone(); thread::spawn(move || { @@ -769,24 +557,18 @@ fn handle_request(&self, id: RequestId, rpc: Request) { .unwrap(); line_matches.push(( lnum, - ( - mymatch.start(), - mymatch.end(), - ), + (mymatch.start(), mymatch.end()), line.to_string(), )); Ok(true) }), ); if !line_matches.is_empty() { - matches.insert( - path.clone(), - line_matches, - ); + matches + .insert(path.clone(), line_matches); } } } - } } local_dispatcher diff --git a/lapce-proxy/src/lib.rs b/lapce-proxy/src/lib.rs index 4fa75bc0..794d83f0 100644 --- a/lapce-proxy/src/lib.rs +++ b/lapce-proxy/src/lib.rs @@ -2,7 +2,6 @@ pub mod dispatch; pub mod lsp; pub mod plugin; -pub mod style; pub mod terminal; use dispatch::Dispatcher; diff --git a/lapce-proxy/src/lsp.rs b/lapce-proxy/src/lsp.rs index 42b1002b..bdc62956 100644 --- a/lapce-proxy/src/lsp.rs +++ b/lapce-proxy/src/lsp.rs @@ -13,14 +13,17 @@ use anyhow::{anyhow, Result}; use jsonrpc_lite::{Id, JsonRpc, Params}; -use lapce_rpc::RequestId; +use lapce_rpc::{ + buffer::BufferId, + style::{LineStyle, Style}, + RequestId, +}; use lsp_types::*; use parking_lot::Mutex; use serde_json::{json, to_value, Value}; +use crate::buffer::Buffer; use crate::dispatch::Dispatcher; -use crate::{buffer::Buffer, style::LineStyle}; -use crate::{buffer::BufferId, style::Style}; pub type Callback = Box; const HEADER_CONTENT_LENGTH: &str = "content-length"; diff --git a/lapce-proxy/src/plugin.rs b/lapce-proxy/src/plugin.rs index 90301d95..b961ecfe 100644 --- a/lapce-proxy/src/plugin.rs +++ b/lapce-proxy/src/plugin.rs @@ -1,6 +1,8 @@ use anyhow::{anyhow, Result}; use home::home_dir; use hotwatch::Hotwatch; +use lapce_rpc::counter::Counter; +use lapce_rpc::plugin::{PluginDescription, PluginId, PluginInfo}; use serde::de::DeserializeOwned; use serde::{Deserialize, Serialize}; use serde_json::Value; @@ -24,42 +26,6 @@ pub type PluginName = String; -#[derive(Clone, Debug, Default)] -pub struct Counter(usize); - -impl Iterator for Counter { - type Item = usize; - fn next(&mut self) -> Option { - let n = self.0; - self.0 += 1; - Some(n) - } -} - -#[derive(Eq, PartialEq, Hash, Clone, Debug, Serialize, Deserialize)] -pub struct PluginId(pub usize); - -#[derive(Deserialize, Clone, Debug, Serialize)] -#[serde(rename_all = "kebab-case")] -pub struct PluginDescription { - pub name: String, - pub version: String, - pub display_name: String, - pub author: String, - pub description: String, - pub repository: String, - pub wasm: String, - dir: Option, - configuration: Option, -} - -#[derive(Serialize, Clone)] -pub struct PluginInfo { - arch: String, - os: String, - configuration: Option, -} - #[derive(WasmerEnv, Clone)] pub(crate) struct PluginEnv { wasi_env: WasiEnv, @@ -83,7 +49,7 @@ pub struct PluginCatalog { impl PluginCatalog { pub fn new() -> PluginCatalog { PluginCatalog { - id_counter: Counter::default(), + id_counter: Counter::new(), items: HashMap::new(), plugins: HashMap::new(), store: wasmer::Store::default(), @@ -218,7 +184,7 @@ fn start_plugin( } pub fn next_plugin_id(&mut self) -> PluginId { - PluginId(self.id_counter.next().unwrap()) + PluginId(self.id_counter.next()) } } diff --git a/lapce-proxy/src/terminal.rs b/lapce-proxy/src/terminal.rs index 7e05081c..d7bef28c 100644 --- a/lapce-proxy/src/terminal.rs +++ b/lapce-proxy/src/terminal.rs @@ -15,6 +15,7 @@ tty::{self, setup_env, EventedPty, EventedReadWrite}, }; use directories::BaseDirs; +use lapce_rpc::terminal::TermId; #[cfg(not(windows))] use mio::unix::UnixReady; #[allow(deprecated)] @@ -22,7 +23,6 @@ channel::{channel, Receiver, Sender}, Events, PollOpt, Ready, }; -use serde::{Deserialize, Serialize}; use serde_json::json; use crate::dispatch::Dispatcher; @@ -41,16 +41,6 @@ pub fn next(&self) -> u64 { } } -#[derive(Eq, PartialEq, Hash, Copy, Clone, Debug, Serialize, Deserialize)] -pub struct TermId(pub u64); - -impl TermId { - pub fn next() -> Self { - static TERMINAL_ID_COUNTER: Counter = Counter::new(); - Self(TERMINAL_ID_COUNTER.next()) - } -} - pub type TermConfig = alacritty_terminal::config::Config; pub struct Terminal { diff --git a/lapce-rpc/Cargo.toml b/lapce-rpc/Cargo.toml index bb2c369c..d53212b4 100644 --- a/lapce-rpc/Cargo.toml +++ b/lapce-rpc/Cargo.toml @@ -11,3 +11,5 @@ serde_json = "1.0.59" serde = "1.0" jsonrpc-lite = "0.5.0" crossbeam-channel = "0.5.0" +lsp-types = { version = "0.89.2", features = ["proposed"] } +xi-rope = { git = "https://github.com/lapce/xi-editor", features = ["serde"] } diff --git a/lapce-rpc/src/buffer.rs b/lapce-rpc/src/buffer.rs new file mode 100644 index 00000000..b2403b3f --- /dev/null +++ b/lapce-rpc/src/buffer.rs @@ -0,0 +1,24 @@ +use serde::{Deserialize, Serialize}; + +use crate::counter::Counter; + +#[derive(Eq, PartialEq, Hash, Copy, Clone, Debug, Serialize, Deserialize)] +pub struct BufferId(pub u64); + +impl BufferId { + pub fn next() -> Self { + static BUFFER_ID_COUNTER: Counter = Counter::new(); + Self(BUFFER_ID_COUNTER.next()) + } +} + +#[derive(Debug, Clone, Serialize, Deserialize)] +pub struct NewBufferResponse { + pub content: String, +} + +#[derive(Debug, Clone, Serialize, Deserialize)] +pub struct BufferHeadResponse { + pub id: String, + pub content: String, +} diff --git a/lapce-rpc/src/core.rs b/lapce-rpc/src/core.rs new file mode 100644 index 00000000..4bb0392d --- /dev/null +++ b/lapce-rpc/src/core.rs @@ -0,0 +1,58 @@ +use lsp_types::{ProgressParams, PublishDiagnosticsParams}; +use serde::{Deserialize, Serialize}; +use std::{collections::HashMap, path::PathBuf}; + +use crate::{ + buffer::BufferId, file::FileNodeItem, plugin::PluginDescription, + source_control::DiffInfo, style::LineStyle, terminal::TermId, +}; + +#[derive(Debug, Clone, Serialize, Deserialize)] +#[serde(rename_all = "snake_case")] +#[serde(tag = "method", content = "params")] +pub enum CoreNotification { + ProxyConnected {}, + SemanticStyles { + rev: u64, + buffer_id: BufferId, + path: PathBuf, + len: usize, + styles: Vec, + }, + ReloadBuffer { + buffer_id: BufferId, + new_content: String, + rev: u64, + }, + PublishDiagnostics { + diagnostics: PublishDiagnosticsParams, + }, + WorkDoneProgress { + progress: ProgressParams, + }, + HomeDir { + path: PathBuf, + }, + InstalledPlugins { + plugins: HashMap, + }, + ListDir { + items: Vec, + }, + DiffFiles { + files: Vec, + }, + DiffInfo { + diff: DiffInfo, + }, + UpdateTerminal { + term_id: TermId, + content: String, + }, + CloseTerminal { + term_id: TermId, + }, +} + +#[derive(Debug, Clone, Serialize, Deserialize)] +pub enum CoreRequest {} diff --git a/lapce-rpc/src/counter.rs b/lapce-rpc/src/counter.rs new file mode 100644 index 00000000..7d14d7f8 --- /dev/null +++ b/lapce-rpc/src/counter.rs @@ -0,0 +1,13 @@ +use std::sync::atomic::{self, AtomicU64}; + +pub struct Counter(AtomicU64); + +impl Counter { + pub const fn new() -> Counter { + Counter(AtomicU64::new(1)) + } + + pub fn next(&self) -> u64 { + self.0.fetch_add(1, atomic::Ordering::Relaxed) + } +} diff --git a/lapce-rpc/src/file.rs b/lapce-rpc/src/file.rs new file mode 100644 index 00000000..ff00a60d --- /dev/null +++ b/lapce-rpc/src/file.rs @@ -0,0 +1,88 @@ +use std::{ + cmp::{self, Ordering}, + collections::HashMap, + path::PathBuf, +}; + +use serde::{Deserialize, Serialize}; + +#[derive(Debug, Clone, Serialize, Deserialize, PartialEq, Eq)] +pub struct FileNodeItem { + pub path_buf: PathBuf, + pub is_dir: bool, + pub read: bool, + pub open: bool, + pub children: HashMap, + pub children_open_count: usize, +} + +impl std::cmp::PartialOrd for FileNodeItem { + fn partial_cmp(&self, other: &Self) -> Option { + let self_dir = self.is_dir; + let other_dir = other.is_dir; + if self_dir && !other_dir { + return Some(cmp::Ordering::Less); + } + if !self_dir && other_dir { + return Some(cmp::Ordering::Greater); + } + + let self_file_name = self.path_buf.file_name()?.to_str()?.to_lowercase(); + let other_file_name = other.path_buf.file_name()?.to_str()?.to_lowercase(); + if self_file_name.starts_with('.') && !other_file_name.starts_with('.') { + return Some(cmp::Ordering::Less); + } + if !self_file_name.starts_with('.') && other_file_name.starts_with('.') { + return Some(cmp::Ordering::Greater); + } + self_file_name.partial_cmp(&other_file_name) + } +} + +impl FileNodeItem { + pub fn sorted_children(&self) -> Vec<&FileNodeItem> { + let mut children = self + .children + .iter() + .map(|(_, item)| item) + .collect::>(); + children.sort_by(|a, b| match (a.is_dir, b.is_dir) { + (true, true) => a + .path_buf + .to_str() + .unwrap() + .cmp(b.path_buf.to_str().unwrap()), + (true, false) => Ordering::Less, + (false, true) => Ordering::Greater, + (false, false) => a + .path_buf + .to_str() + .unwrap() + .cmp(b.path_buf.to_str().unwrap()), + }); + children + } + + pub fn sorted_children_mut(&mut self) -> Vec<&mut FileNodeItem> { + let mut children = self + .children + .iter_mut() + .map(|(_, item)| item) + .collect::>(); + children.sort_by(|a, b| match (a.is_dir, b.is_dir) { + (true, true) => a + .path_buf + .to_str() + .unwrap() + .cmp(b.path_buf.to_str().unwrap()), + (true, false) => Ordering::Less, + (false, true) => Ordering::Greater, + (false, false) => a + .path_buf + .to_str() + .unwrap() + .cmp(b.path_buf.to_str().unwrap()), + }); + children + } +} diff --git a/lapce-rpc/src/lib.rs b/lapce-rpc/src/lib.rs index 8b4d800e..fecea5a2 100644 --- a/lapce-rpc/src/lib.rs +++ b/lapce-rpc/src/lib.rs @@ -1,5 +1,14 @@ +pub mod buffer; +pub mod core; +pub mod counter; +pub mod file; mod parse; +pub mod plugin; +pub mod proxy; +pub mod source_control; mod stdio; +pub mod style; +pub mod terminal; use std::collections::HashMap; use std::io::stdin; diff --git a/lapce-rpc/src/plugin.rs b/lapce-rpc/src/plugin.rs new file mode 100644 index 00000000..7c1355e7 --- /dev/null +++ b/lapce-rpc/src/plugin.rs @@ -0,0 +1,28 @@ +use std::path::PathBuf; + +use serde::{Deserialize, Serialize}; +use serde_json::Value; + +#[derive(Eq, PartialEq, Hash, Clone, Debug, Serialize, Deserialize)] +pub struct PluginId(pub u64); + +#[derive(Deserialize, Clone, Debug, Serialize)] +#[serde(rename_all = "kebab-case")] +pub struct PluginDescription { + pub name: String, + pub version: String, + pub display_name: String, + pub author: String, + pub description: String, + pub repository: String, + pub wasm: String, + pub dir: Option, + pub configuration: Option, +} + +#[derive(Serialize, Clone)] +pub struct PluginInfo { + pub arch: String, + pub os: String, + pub configuration: Option, +} diff --git a/lapce-rpc/src/proxy.rs b/lapce-rpc/src/proxy.rs new file mode 100644 index 00000000..530eb561 --- /dev/null +++ b/lapce-rpc/src/proxy.rs @@ -0,0 +1,108 @@ +use std::path::PathBuf; + +use lsp_types::{CompletionItem, Position}; +use serde::{Deserialize, Serialize}; +use xi_rope::RopeDelta; + +use crate::{ + buffer::BufferId, plugin::PluginDescription, source_control::FileDiff, + terminal::TermId, +}; + +#[derive(Debug, Clone, Serialize, Deserialize)] +#[serde(rename_all = "snake_case")] +#[serde(tag = "method", content = "params")] +pub enum ProxyNotification { + Initialize { + workspace: PathBuf, + }, + Shutdown {}, + Update { + buffer_id: BufferId, + delta: RopeDelta, + rev: u64, + }, + NewTerminal { + term_id: TermId, + cwd: Option, + shell: String, + }, + InstallPlugin { + plugin: PluginDescription, + }, + GitCommit { + message: String, + diffs: Vec, + }, + TerminalWrite { + term_id: TermId, + content: String, + }, + TerminalResize { + term_id: TermId, + width: usize, + height: usize, + }, + TerminalClose { + term_id: TermId, + }, +} + +#[derive(Debug, Clone, Serialize, Deserialize)] +#[serde(rename_all = "snake_case")] +#[serde(tag = "method", content = "params")] +pub enum ProxyRequest { + NewBuffer { + buffer_id: BufferId, + path: PathBuf, + }, + BufferHead { + buffer_id: BufferId, + path: PathBuf, + }, + GetCompletion { + request_id: usize, + buffer_id: BufferId, + position: Position, + }, + GlobalSearch { + pattern: String, + }, + CompletionResolve { + buffer_id: BufferId, + completion_item: Box, + }, + GetSignature { + buffer_id: BufferId, + position: Position, + }, + GetReferences { + buffer_id: BufferId, + position: Position, + }, + GetDefinition { + request_id: usize, + buffer_id: BufferId, + position: Position, + }, + GetCodeActions { + buffer_id: BufferId, + position: Position, + }, + GetDocumentSymbols { + buffer_id: BufferId, + }, + GetDocumentFormatting { + buffer_id: BufferId, + }, + GetFiles { + path: String, + }, + ReadDir { + path: PathBuf, + }, + Save { + rev: u64, + buffer_id: BufferId, + }, +} diff --git a/lapce-rpc/src/source_control.rs b/lapce-rpc/src/source_control.rs new file mode 100644 index 00000000..32e782b9 --- /dev/null +++ b/lapce-rpc/src/source_control.rs @@ -0,0 +1,29 @@ +use std::path::PathBuf; + +use serde::{Deserialize, Serialize}; + +#[derive(Debug, Clone, Serialize, Deserialize, PartialEq, Default)] +pub struct DiffInfo { + pub head: String, + pub branches: Vec, + pub diffs: Vec, +} + +#[derive(Debug, Clone, Serialize, Deserialize, PartialEq)] +pub enum FileDiff { + Modified(PathBuf), + Added(PathBuf), + Deleted(PathBuf), + Renamed(PathBuf, PathBuf), +} + +impl FileDiff { + pub fn path(&self) -> &PathBuf { + match &self { + FileDiff::Modified(p) + | FileDiff::Added(p) + | FileDiff::Deleted(p) + | FileDiff::Renamed(_, p) => p, + } + } +} diff --git a/lapce-proxy/src/style.rs b/lapce-rpc/src/style.rs similarity index 100% rename from lapce-proxy/src/style.rs rename to lapce-rpc/src/style.rs diff --git a/lapce-rpc/src/terminal.rs b/lapce-rpc/src/terminal.rs new file mode 100644 index 00000000..e5c47042 --- /dev/null +++ b/lapce-rpc/src/terminal.rs @@ -0,0 +1,13 @@ +use serde::{Deserialize, Serialize}; + +use crate::counter::Counter; + +#[derive(Eq, PartialEq, Hash, Copy, Clone, Debug, Serialize, Deserialize)] +pub struct TermId(pub u64); + +impl TermId { + pub fn next() -> Self { + static TERMINAL_ID_COUNTER: Counter = Counter::new(); + Self(TERMINAL_ID_COUNTER.next()) + } +} diff --git a/lapce-ui/Cargo.toml b/lapce-ui/Cargo.toml index eb28ba02..14eba158 100644 --- a/lapce-ui/Cargo.toml +++ b/lapce-ui/Cargo.toml @@ -48,10 +48,8 @@ druid = { git = "https://github.com/lapce/druid", features = [ "svg", "im", "ser #druid = { path = "../../druid/druid", features = ["svg", "im" , "serde"] } toml = { version = "0.5.8", features = ["preserve_order"] } structdesc = { git = "https://github.com/lapce/structdesc" } -#structdesc = { path = "../../structdesc" } lapce-data = { path = "../lapce-data" } lapce-rpc = { path = "../lapce-rpc" } -lapce-proxy = { path = "../lapce-proxy" } [build-dependencies] cc = "1" diff --git a/lapce-ui/src/editor.rs b/lapce-ui/src/editor.rs index 274cf724..be341dbd 100644 --- a/lapce-ui/src/editor.rs +++ b/lapce-ui/src/editor.rs @@ -1,7 +1,7 @@ +use std::cmp::Ordering; use std::{ cell::RefCell, iter::Iterator, rc::Rc, str::FromStr, sync::Arc, time::Instant, }; -use std::cmp::Ordering; use druid::{ kurbo::Line, @@ -12,7 +12,7 @@ UpdateCtx, Vec2, Widget, WidgetExt, WidgetId, WidgetPod, }; use lapce_data::{ - buffer::{matching_pair_direction, BufferContent, BufferId, LocalBufferKind}, + buffer::{matching_pair_direction, BufferContent, LocalBufferKind}, command::{ CommandTarget, EnsureVisiblePosition, LapceCommand, LapceCommandNew, LapceUICommand, LapceWorkbenchCommand, LAPCE_NEW_COMMAND, LAPCE_UI_COMMAND, @@ -30,6 +30,7 @@ split::{SplitDirection, SplitMoveDirection}, state::{Mode, VisualMode}, }; +use lapce_rpc::buffer::BufferId; use lsp_types::{DocumentChanges, TextEdit, Url, WorkspaceEdit}; use strum::EnumMessage; @@ -271,7 +272,7 @@ fn event( let new_index = match mouse_index.cmp(from_index) { Ordering::Greater => Some(mouse_index - 1), Ordering::Equal => Some(mouse_index), - Ordering::Less => None + Ordering::Less => None, }; if let Some(new_index) = new_index { if new_index != *from_index { @@ -2672,7 +2673,7 @@ fn get_workspace_edit_edits<'a>( ) -> Option> { match get_workspace_edit_changes_edits(url, workspace_edit) { Some(x) => Some(x), - None => get_workspace_edit_document_changes_edits(url, workspace_edit) + None => get_workspace_edit_document_changes_edits(url, workspace_edit), } } diff --git a/lapce-ui/src/explorer.rs b/lapce-ui/src/explorer.rs index 2771ed66..43148d0e 100644 --- a/lapce-ui/src/explorer.rs +++ b/lapce-ui/src/explorer.rs @@ -16,7 +16,7 @@ split::SplitDirection, }; use lapce_data::{data::PanelKind, explorer::FileExplorerData}; -use lapce_proxy::dispatch::FileNodeItem; +use lapce_rpc::file::FileNodeItem; use crate::{ panel::{LapcePanel, PanelHeaderKind}, diff --git a/lapce-ui/src/picker.rs b/lapce-ui/src/picker.rs index a8b180e6..d818b49b 100644 --- a/lapce-ui/src/picker.rs +++ b/lapce-ui/src/picker.rs @@ -16,7 +16,7 @@ config::LapceTheme, data::LapceTabData, }; -use lapce_proxy::dispatch::FileNodeItem; +use lapce_rpc::file::FileNodeItem; use crate::{ editor::LapceEditorView, diff --git a/lapce-ui/src/plugin.rs b/lapce-ui/src/plugin.rs index 3d13e218..67f8d6b3 100644 --- a/lapce-ui/src/plugin.rs +++ b/lapce-ui/src/plugin.rs @@ -9,7 +9,7 @@ data::{LapceTabData, PanelKind}, split::SplitDirection, }; -use lapce_proxy::plugin::PluginDescription; +use lapce_rpc::plugin::PluginDescription; use strum_macros::Display; use crate::panel::{LapcePanel, PanelHeaderKind}; diff --git a/lapce-ui/src/source_control.rs b/lapce-ui/src/source_control.rs index a264ac5e..ad56c940 100644 --- a/lapce-ui/src/source_control.rs +++ b/lapce-ui/src/source_control.rs @@ -16,7 +16,7 @@ split::{SplitDirection, SplitMoveDirection}, state::Mode, }; -use lapce_proxy::dispatch::FileDiff; +use lapce_rpc::source_control::FileDiff; use crate::{ editor::LapceEditorView, diff --git a/lapce-ui/src/split.rs b/lapce-ui/src/split.rs index 5ee2652c..45bf0239 100644 --- a/lapce-ui/src/split.rs +++ b/lapce-ui/src/split.rs @@ -28,7 +28,7 @@ split::{SplitDirection, SplitMoveDirection}, terminal::LapceTerminalData, }; -use lapce_proxy::terminal::TermId; +use lapce_rpc::terminal::TermId; use strum::EnumMessage; pub struct LapceDynamicSplit { diff --git a/lapce-ui/src/terminal.rs b/lapce-ui/src/terminal.rs index 0eb506c9..de2f1636 100644 --- a/lapce-ui/src/terminal.rs +++ b/lapce-ui/src/terminal.rs @@ -25,7 +25,7 @@ state::Mode, terminal::{LapceTerminalData, LapceTerminalViewData}, }; -use lapce_proxy::terminal::TermId; +use lapce_rpc::terminal::TermId; use unicode_width::UnicodeWidthChar; use crate::{