From 3f9de825c129b646e8c578a436b4a32c6bc84fdb Mon Sep 17 00:00:00 2001 From: Dongdong Zhou Date: Mon, 21 Mar 2022 14:01:23 +0000 Subject: [PATCH] show version in settings --- lapce-data/src/proxy.rs | 2 +- lapce-ui/src/proxy.rs | 757 --------------------------------------- lapce-ui/src/settings.rs | 24 +- 3 files changed, 19 insertions(+), 764 deletions(-) delete mode 100644 lapce-ui/src/proxy.rs diff --git a/lapce-data/src/proxy.rs b/lapce-data/src/proxy.rs index 34fc5ab7..68eaba3a 100644 --- a/lapce-data/src/proxy.rs +++ b/lapce-data/src/proxy.rs @@ -40,7 +40,7 @@ use crate::terminal::RawTerminal; use crate::{buffer::BufferId, command::LAPCE_UI_COMMAND}; -const VERSION: &str = env!("CARGO_PKG_VERSION"); +pub const VERSION: &str = env!("CARGO_PKG_VERSION"); pub enum TermEvent { NewTerminal(Arc>), diff --git a/lapce-ui/src/proxy.rs b/lapce-ui/src/proxy.rs deleted file mode 100644 index 7a284dfc..00000000 --- a/lapce-ui/src/proxy.rs +++ /dev/null @@ -1,757 +0,0 @@ -use std::collections::HashMap; -use std::io::BufReader; -#[cfg(target_os = "windows")] -use std::os::windows::process::CommandExt; -use std::path::Path; -use std::process::{Command, Stdio}; -use std::thread; -use std::{path::PathBuf, sync::Arc}; - -use anyhow::{anyhow, Result}; -use crossbeam_channel::Receiver; -use crossbeam_channel::Sender; -use druid::Target; -use druid::{ExtEventSink, WidgetId}; -use flate2::read::GzDecoder; -use lapce_data::{ - buffer::BufferId, - command::{LapceUICommand, LAPCE_UI_COMMAND}, - config::Config, - state::{LapceWorkspace, LapceWorkspaceType}, -}; -use lapce_proxy::dispatch::FileDiff; -use lapce_proxy::dispatch::FileNodeItem; -use lapce_proxy::dispatch::{DiffInfo, Dispatcher}; -use lapce_proxy::plugin::PluginDescription; -use lapce_proxy::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 parking_lot::Mutex; -use serde::{Deserialize, Serialize}; -use serde_json::json; -use serde_json::Value; -use xi_rope::RopeDelta; - -use crate::terminal::RawTerminal; - -const VERSION: &str = env!("CARGO_PKG_VERSION"); - -pub enum TermEvent { - NewTerminal(Arc>), - UpdateContent(String), - CloseTerminal, -} - -#[derive(Clone, Copy, Debug)] -pub enum ProxyStatus { - Connecting, - Connected, - Disconnected, -} - -#[derive(Clone)] -pub struct LapceProxy { - pub tab_id: WidgetId, - rpc: RpcHandler, - proxy_receiver: Arc>, - term_tx: Sender<(TermId, TermEvent)>, - event_sink: ExtEventSink, -} - -impl Handler for LapceProxy { - type Notification = Notification; - type Request = Request; - - fn handle_notification(&mut self, rpc: Self::Notification) -> ControlFlow { - match rpc { - Notification::SemanticTokens { - rev, - buffer_id, - path, - tokens, - } => { - let _ = 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, - } => { - let _ = self.event_sink.submit_command( - LAPCE_UI_COMMAND, - LapceUICommand::ReloadBuffer(buffer_id, rev, new_content), - Target::Widget(self.tab_id), - ); - } - Notification::PublishDiagnostics { diagnostics } => { - let _ = self.event_sink.submit_command( - LAPCE_UI_COMMAND, - LapceUICommand::PublishDiagnostics(diagnostics), - Target::Widget(self.tab_id), - ); - } - Notification::WorkDoneProgress { progress } => { - let _ = self.event_sink.submit_command( - LAPCE_UI_COMMAND, - LapceUICommand::WorkDoneProgress(progress), - Target::Widget(self.tab_id), - ); - } - Notification::InstalledPlugins { plugins } => { - let _ = self.event_sink.submit_command( - LAPCE_UI_COMMAND, - LapceUICommand::UpdateInstalledPlugins(plugins), - Target::Widget(self.tab_id), - ); - } - #[allow(unused_variables)] - Notification::ListDir { items } => {} - #[allow(unused_variables)] - Notification::DiffFiles { files } => {} - Notification::DiffInfo { diff } => { - let _ = self.event_sink.submit_command( - LAPCE_UI_COMMAND, - LapceUICommand::UpdateDiffInfo(diff), - Target::Widget(self.tab_id), - ); - } - Notification::UpdateTerminal { term_id, content } => { - let _ = self - .term_tx - .send((term_id, TermEvent::UpdateContent(content))); - } - Notification::CloseTerminal { term_id } => { - let _ = self.term_tx.send((term_id, TermEvent::CloseTerminal)); - let _ = self.event_sink.submit_command( - LAPCE_UI_COMMAND, - LapceUICommand::CloseTerminal(term_id), - Target::Widget(self.tab_id), - ); - } - Notification::ProxyConnected {} => { - let _ = self.event_sink.submit_command( - LAPCE_UI_COMMAND, - LapceUICommand::ProxyUpdateStatus(ProxyStatus::Connected), - Target::Widget(self.tab_id), - ); - } - Notification::HomeDir { path } => { - let _ = self.event_sink.submit_command( - LAPCE_UI_COMMAND, - LapceUICommand::HomeDir(path), - Target::Widget(self.tab_id), - ); - } - } - ControlFlow::Continue - } - - fn handle_request(&mut self, _rpc: Self::Request) -> Result { - Err(json!("unimplemented")) - } -} - -impl LapceProxy { - pub fn new( - tab_id: WidgetId, - workspace: LapceWorkspace, - term_tx: Sender<(TermId, TermEvent)>, - event_sink: ExtEventSink, - ) -> Self { - let (proxy_sender, proxy_receiver) = crossbeam_channel::unbounded(); - let rpc = RpcHandler::new(proxy_sender); - let proxy = Self { - tab_id, - rpc, - proxy_receiver: Arc::new(proxy_receiver), - term_tx, - event_sink: event_sink.clone(), - }; - - let local_proxy = proxy.clone(); - thread::spawn(move || { - let _ = event_sink.submit_command( - LAPCE_UI_COMMAND, - LapceUICommand::ProxyUpdateStatus(ProxyStatus::Connecting), - Target::Widget(tab_id), - ); - let _ = local_proxy.start(workspace.clone()); - let _ = event_sink.submit_command( - LAPCE_UI_COMMAND, - LapceUICommand::ProxyUpdateStatus(ProxyStatus::Disconnected), - Target::Widget(tab_id), - ); - }); - - proxy - } - - fn start(&self, workspace: LapceWorkspace) -> Result<()> { - if let Some(path) = workspace.path.as_ref() { - self.initialize(path.clone()); - } - let (core_sender, core_receiver) = crossbeam_channel::unbounded(); - match workspace.kind { - LapceWorkspaceType::Local => { - let proxy_reciever = (*self.proxy_receiver).clone(); - thread::spawn(move || { - let dispatcher = Dispatcher::new(core_sender); - let _ = dispatcher.mainloop(proxy_reciever); - }); - - let mut proxy = self.clone(); - let mut handler = self.clone(); - proxy.rpc.mainloop(core_receiver, &mut handler); - } - LapceWorkspaceType::RemoteSSH(user, host) => { - let ssh_args = &[ - "-o", - "ControlMaster=auto", - "-o", - "ControlPath=~/.ssh/cm-%r@%h:%p", - "-o", - "ControlPersist=30m", - "-o", - "ConnectTimeout=15", - ]; - let mut cmd = Command::new("ssh"); - #[cfg(target_os = "windows")] - let cmd = cmd.creation_flags(0x08000000); - let cmd = cmd - .arg(format!("{}@{}", user, host)) - .args(ssh_args) - .arg("test") - .arg("-e") - .arg(format!("~/.lapce/lapce-proxy-{}", VERSION)) - .output()?; - if !cmd.status.success() { - let local_proxy_file = Config::dir() - .ok_or_else(|| anyhow!("can't find config dir"))? - .join(format!("lapce-proxy-{}", VERSION)); - if !local_proxy_file.exists() { - let url = format!("https://github.com/lapce/lapce/releases/download/v{VERSION}/lapce-proxy-linux.gz"); - let mut resp = - reqwest::blocking::get(url).expect("request failed"); - let mut out = std::fs::File::create(&local_proxy_file) - .expect("failed to create file"); - let mut gz = GzDecoder::new(&mut resp); - std::io::copy(&mut gz, &mut out) - .expect("failed to copy content"); - } - - let mut cmd = Command::new("ssh"); - #[cfg(target_os = "windows")] - let cmd = cmd.creation_flags(0x08000000); - cmd.arg(format!("{}@{}", user, host)) - .args(ssh_args) - .arg("mkdir") - .arg("~/.lapce/") - .output()?; - - let mut cmd = Command::new("scp"); - #[cfg(target_os = "windows")] - let cmd = cmd.creation_flags(0x08000000); - cmd.args(ssh_args) - .arg(&local_proxy_file) - .arg(format!("{user}@{host}:~/.lapce/lapce-proxy-{VERSION}")) - .output()?; - - let mut cmd = Command::new("ssh"); - #[cfg(target_os = "windows")] - let cmd = cmd.creation_flags(0x08000000); - cmd.arg(format!("{}@{}", user, host)) - .args(ssh_args) - .arg("chmod") - .arg("+x") - .arg(format!("~/.lapce/lapce-proxy-{}", VERSION)) - .output()?; - } - - let mut child = Command::new("ssh"); - #[cfg(target_os = "windows")] - let child = child.creation_flags(0x08000000); - let mut child = child - .arg(format!("{}@{}", user, host)) - .args(ssh_args) - .arg(format!("~/.lapce/lapce-proxy-{}", VERSION)) - .stdin(Stdio::piped()) - .stdout(Stdio::piped()) - .spawn()?; - let stdin = child - .stdin - .take() - .ok_or_else(|| anyhow!("can't find stdin"))?; - let stdout = BufReader::new( - child - .stdout - .take() - .ok_or_else(|| anyhow!("can't find stdout"))?, - ); - - let proxy_reciever = (*self.proxy_receiver).clone(); - stdio_transport(stdin, proxy_reciever, stdout, core_sender); - - let mut handler = self.clone(); - let mut proxy = self.clone(); - proxy.rpc.mainloop(core_receiver, &mut handler); - } - } - Ok(()) - } - - pub fn initialize(&self, workspace: PathBuf) { - self.rpc.send_rpc_notification( - "initialize", - &json!({ - "workspace": workspace, - }), - ) - } - - pub fn terminal_close(&self, term_id: TermId) { - self.rpc.send_rpc_notification( - "terminal_close", - &json!({ - "term_id": term_id, - }), - ) - } - - pub fn terminal_resize(&self, term_id: TermId, width: usize, height: usize) { - self.rpc.send_rpc_notification( - "terminal_resize", - &json!({ - "term_id": term_id, - "width": width, - "height": height, - }), - ) - } - - pub fn terminal_write(&self, term_id: TermId, content: &str) { - self.rpc.send_rpc_notification( - "terminal_write", - &json!({ - "term_id": term_id, - "content": content, - }), - ) - } - - pub fn new_terminal( - &self, - term_id: TermId, - cwd: Option, - raw: Arc>, - ) { - let _ = self.term_tx.send((term_id, TermEvent::NewTerminal(raw))); - self.rpc.send_rpc_notification( - "new_terminal", - &json!({ - "term_id": term_id, - "cwd": cwd, - }), - ) - } - - pub fn git_commit(&self, message: &str, diffs: Vec) { - self.rpc.send_rpc_notification( - "git_commit", - &json!({ - "message": message, - "diffs": diffs, - }), - ) - } - - pub fn install_plugin(&self, plugin: &PluginDescription) { - self.rpc - .send_rpc_notification("install_plugin", &json!({ "plugin": plugin })); - } - - pub fn get_buffer_head( - &self, - buffer_id: BufferId, - path: PathBuf, - f: Box, - ) { - self.rpc.send_rpc_request_async( - "buffer_head", - &json!({ "buffer_id": buffer_id, "path": path, }), - f, - ); - } - - pub fn global_search(&self, pattern: String, f: Box) { - self.rpc.send_rpc_request_async( - "global_search", - &json!({ "pattern": pattern }), - f, - ); - } - - pub fn new_buffer( - &self, - buffer_id: BufferId, - path: PathBuf, - f: Box, - ) { - self.rpc.send_rpc_request_async( - "new_buffer", - &json!({ "buffer_id": buffer_id, "path": path }), - f, - ); - } - - pub fn update(&self, buffer_id: BufferId, delta: &RopeDelta, rev: u64) { - self.rpc.send_rpc_notification( - "update", - &json!({ - "buffer_id": buffer_id, - "delta": delta, - "rev": rev, - }), - ) - } - - pub fn save(&self, rev: u64, buffer_id: BufferId, f: Box) { - self.rpc.send_rpc_request_async( - "save", - &json!({ - "rev": rev, - "buffer_id": buffer_id, - }), - f, - ); - } - - pub fn get_completion( - &self, - request_id: usize, - buffer_id: BufferId, - position: Position, - f: Box, - ) { - self.rpc.send_rpc_request_async( - "get_completion", - &json!({ - "request_id": request_id, - "buffer_id": buffer_id, - "position": position, - }), - f, - ); - } - - pub fn completion_resolve( - &self, - buffer_id: BufferId, - completion_item: CompletionItem, - f: Box, - ) { - self.rpc.send_rpc_request_async( - "completion_resolve", - &json!({ - "buffer_id": buffer_id, - "completion_item": completion_item, - }), - f, - ); - } - - pub fn get_signature( - &self, - buffer_id: BufferId, - position: Position, - f: Box, - ) { - self.rpc.send_rpc_request_async( - "get_signature", - &json!({ - "buffer_id": buffer_id, - "position": position, - }), - f, - ); - } - - pub fn get_references( - &self, - buffer_id: BufferId, - position: Position, - f: Box, - ) { - self.rpc.send_rpc_request_async( - "get_references", - &json!({ - "buffer_id": buffer_id, - "position": position, - }), - f, - ); - } - - pub fn get_files(&self, f: Box) { - self.rpc.send_rpc_request_async( - "get_files", - &json!({ - "path": "path", - }), - f, - ); - } - - pub fn read_dir(&self, path: &Path, f: Box) { - self.rpc.send_rpc_request_async( - "read_dir", - &json!({ - "path": path, - }), - f, - ); - } - - pub fn get_definition( - &self, - request_id: usize, - buffer_id: BufferId, - position: Position, - f: Box, - ) { - self.rpc.send_rpc_request_async( - "get_definition", - &json!({ - "request_id": request_id, - "buffer_id": buffer_id, - "position": position, - }), - f, - ); - } - - pub fn get_document_symbols(&self, buffer_id: BufferId, f: Box) { - self.rpc.send_rpc_request_async( - "get_document_symbols", - &json!({ - "buffer_id": buffer_id, - }), - f, - ); - } - - pub fn get_code_actions( - &self, - buffer_id: BufferId, - position: Position, - f: Box, - ) { - self.rpc.send_rpc_request_async( - "get_code_actions", - &json!({ - "buffer_id": buffer_id, - "position": position, - }), - f, - ); - } - - pub fn get_document_formatting( - &self, - buffer_id: BufferId, - f: Box, - ) { - self.rpc.send_rpc_request_async( - "get_document_formatting", - &json!({ - "buffer_id": buffer_id, - }), - f, - ); - } - - pub fn stop(&self) { - self.rpc.send_rpc_notification("shutdown", &json!({})); - // self.core_sender.send(json!({ - // "method": "shutdown", - // "params": {}, - // })); - } -} - -#[derive(Debug, Clone, Serialize, Deserialize)] -pub enum CursorShape { - /// Cursor is a block like `▒`. - Block, - - /// Cursor is an underscore like `_`. - Underline, - - /// Cursor is a vertical bar `⎸`. - Beam, - - /// Cursor is a box like `☐`. - HollowBlock, - - /// Invisible cursor. - Hidden, -} - -#[derive(Debug, Clone, Serialize, Deserialize)] -#[serde(rename_all = "snake_case")] -#[serde(tag = "method", content = "params")] -pub enum Notification { - ProxyConnected {}, - SemanticTokens { - rev: u64, - buffer_id: BufferId, - path: PathBuf, - tokens: Vec<(usize, usize, String)>, - }, - 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)) -// } -// } diff --git a/lapce-ui/src/settings.rs b/lapce-ui/src/settings.rs index 3337b1bf..e24d1b34 100644 --- a/lapce-ui/src/settings.rs +++ b/lapce-ui/src/settings.rs @@ -16,6 +16,7 @@ config::{EditorConfig, LapceConfig, LapceTheme}, data::LapceTabData, keypress::KeyPressFocus, + proxy::VERSION, state::Mode, }; @@ -355,13 +356,24 @@ fn paint(&mut self, ctx: &mut PaintCtx, data: &LapceTabData, env: &Env) { .build() .unwrap(); let text_size = text_layout.size(); + let x = self.header_rect.height() / 2.0 - text_size.height / 2.0; + let y = self.header_rect.height() / 2.0 - text_size.height / 2.0; + ctx.draw_text(&text_layout, self.header_rect.origin() + (x, y)); + + let version_text_layout = ctx + .text() + .new_text_layout(format!("v{VERSION}")) + .font(FontFamily::SYSTEM_UI, 10.0) + .text_color( + data.config + .get_color_unchecked(LapceTheme::EDITOR_FOREGROUND) + .clone(), + ) + .build() + .unwrap(); ctx.draw_text( - &text_layout, - self.header_rect.origin() - + ( - self.header_rect.height() / 2.0 - text_size.height / 2.0, - self.header_rect.height() / 2.0 - text_size.height / 2.0, - ), + &version_text_layout, + self.header_rect.origin() + (x + text_size.width + 10.0, y + 5.0), ); let svg = get_svg("close.svg").unwrap();