diff --git a/Cargo.lock b/Cargo.lock index dd8eb7f..4ea2907 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -119,6 +119,7 @@ version = "0.2.1" dependencies = [ "discord-rich-presence", "git2", + "serde_json", "tokio", "tower-lsp", ] @@ -618,11 +619,12 @@ dependencies = [ [[package]] name = "serde_json" -version = "1.0.120" +version = "1.0.122" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4e0d21c9a8cae1235ad58a00c11cb40d4b1e5c784f1ef2c537876ed6ffd8b7c5" +checksum = "784b6203951c57ff748476b126ccb5e8e2959a5c19e5c617ab1956be3dbc68da" dependencies = [ "itoa", + "memchr", "ryu", "serde", ] diff --git a/README.md b/README.md index 8b0f9b0..180a6ac 100644 --- a/README.md +++ b/README.md @@ -13,3 +13,21 @@ The easiest way to get [rust](https://rust-lang.org) is by using [rustup](https: 2. CTRL + SHIFT + P and select zed: install dev extension 3. Choose the directory where you cloned this repository 4. Enjoy :) + +## How to configure? + +You can configure state, details and git integration by changing Discord Presence LSP settings. This can be done in zed: open settings with following configuration: + +```json +{ + "lsp": { + "discord_presence": { + "initialization_options": { + "state": "Working on {filename}", + "details": "In {workspace}", + "git_integration": true + } + } + } +} +``` diff --git a/lsp/Cargo.toml b/lsp/Cargo.toml index 1d737fd..25175b7 100644 --- a/lsp/Cargo.toml +++ b/lsp/Cargo.toml @@ -8,3 +8,4 @@ discord-rich-presence = "0.2.4" tokio = { version = "1.37.0", features = ["full"] } tower-lsp = "0.20.0" git2 = "0.19.0" +serde_json = "1.0.122" diff --git a/lsp/src/configuration.rs b/lsp/src/configuration.rs new file mode 100644 index 0000000..e470a03 --- /dev/null +++ b/lsp/src/configuration.rs @@ -0,0 +1,57 @@ +/* + * This file is part of discord-presence. Extension for Zed that adds support for Discord Rich Presence using LSP. + * + * Copyright (c) 2024 Steinhübl + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see + */ + +use serde_json::Value; + +#[derive(Debug)] +pub struct Configuration { + pub state: String, + pub details: String, + pub git_integration: bool, +} + +impl Configuration { + pub fn new() -> Self { + Self { + state: String::from("Working on {filename}"), + details: String::from("In {workspace}"), + git_integration: true, + } + } + + pub fn set(&mut self, initialization_options: Option) { + if initialization_options.is_none() { + return; + } + + let initialization_options = initialization_options.unwrap(); + + if let Some(state) = initialization_options.get("state") { + self.state = state.as_str().unwrap().to_string(); + } + + if let Some(details) = initialization_options.get("details") { + self.details = details.as_str().unwrap().to_string(); + } + + if let Some(git_integration) = initialization_options.get("git_integration") { + self.git_integration = git_integration.as_bool().unwrap_or(true); + } + } +} diff --git a/lsp/src/discord.rs b/lsp/src/discord.rs index 6f8719f..64d301f 100644 --- a/lsp/src/discord.rs +++ b/lsp/src/discord.rs @@ -60,19 +60,11 @@ impl Discord { result.unwrap(); } - pub fn change_file(&self, filename: &str, workspace: &str, git_remote_url: Option) { - self.change_activity( - format!("Working on {}", filename), - format!("In {}", workspace), - git_remote_url, - ) - } - pub fn get_client(&self) -> MutexGuard { return self.client.lock().expect("Failed to lock discord client"); } - fn change_activity(&self, state: String, details: String, git_remote_url: Option) { + pub fn change_activity(&self, state: String, details: String, git_remote_url: Option) { let mut client = self.get_client(); let timestamp: i64 = self.start_timestamp.as_millis() as i64; diff --git a/lsp/src/main.rs b/lsp/src/main.rs index 4984874..0fa0cb4 100644 --- a/lsp/src/main.rs +++ b/lsp/src/main.rs @@ -21,12 +21,14 @@ use std::fmt::Debug; use std::path::{Path, PathBuf}; use std::sync::{Mutex, MutexGuard}; +use configuration::Configuration; use discord::Discord; use git::get_repository_and_remote; use tower_lsp::jsonrpc::Result; use tower_lsp::lsp_types::*; use tower_lsp::{Client, LanguageServer, LspService, Server}; +mod configuration; mod discord; mod git; @@ -41,6 +43,7 @@ struct Backend { client: Client, workspace_file_name: Mutex, git_remote_url: Mutex>, + config: Mutex, } impl Document { @@ -65,15 +68,27 @@ impl Backend { discord: Discord::new(), workspace_file_name: Mutex::new(String::new()), git_remote_url: Mutex::new(None), + config: Mutex::new(Configuration::new()), } } async fn on_change(&self, doc: Document) { - self.discord.change_file( - doc.get_filename(), - self.get_workspace_file_name().as_str(), - self.get_git_remote_url(), - ) + let config = self.get_config(); + + let state = config.state.replace("{filename}", doc.get_filename()); + let details = config + .details + .replace("{workspace}", &self.get_workspace_file_name()); + + self.discord.change_activity( + state, + details, + if config.git_integration { + self.get_git_remote_url() + } else { + None + }, + ); } fn get_workspace_file_name(&self) -> MutexGuard<'_, String> { @@ -91,6 +106,10 @@ impl Backend { guard.clone() } + + fn get_config(&self) -> MutexGuard { + return self.config.lock().expect("Failed to lock config"); + } } #[tower_lsp::async_trait] @@ -116,6 +135,9 @@ impl LanguageServer for Backend { let mut git_remote_url = self.git_remote_url.lock().unwrap(); *git_remote_url = get_repository_and_remote(workspace_path.to_str().unwrap()); + let mut config = self.config.lock().unwrap(); + config.set(params.initialization_options); + Ok(InitializeResult { server_info: Some(ServerInfo { name: env!("CARGO_PKG_NAME").into(),