From affb5df12b53143cb42bd995d5bb2e8065b24aa4 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jozef=20Steinh=C3=BCbl?= Date: Sun, 18 Aug 2024 20:26:57 +0200 Subject: [PATCH] feat: introduce rules (#10) * feat: introduce rules * docs: rules example --- README.md | 11 +++++++- lsp/src/configuration.rs | 58 ++++++++++++++++++++++++++++++++++++++++ lsp/src/main.rs | 16 ++++++++--- 3 files changed, 81 insertions(+), 4 deletions(-) diff --git a/README.md b/README.md index 5670072..c1ab4f4 100644 --- a/README.md +++ b/README.md @@ -34,6 +34,15 @@ You can configure state, details and git integration by changing Discord Presenc // URL for small image "small_image": "{base_icons_url}/zed.png", "small_text": "Zed", + + // Rules - disable presence in some workspaces + "rules": { + "mode": "blacklist" // or whitelist + "paths": [ + "absolute path" + ] + }, + "git_integration": true } } @@ -41,4 +50,4 @@ You can configure state, details and git integration by changing Discord Presenc } ``` -You can also use `null` to unset the option. Possible for everything except `base_icons_url` and `git_integration` +You can also use `null` to unset the option. Possible for everything except `base_icons_url`, `rules` and `git_integration` diff --git a/lsp/src/configuration.rs b/lsp/src/configuration.rs index e159cd8..dccd5b9 100644 --- a/lsp/src/configuration.rs +++ b/lsp/src/configuration.rs @@ -19,6 +19,39 @@ use serde_json::Value; +#[derive(Debug, PartialEq)] +pub enum RulesMode { + Whitelist, + Blacklist, +} + +#[derive(Debug)] +pub struct Rules { + pub mode: RulesMode, + pub paths: Vec, +} + +impl Default for Rules { + fn default() -> Self { + Rules { + mode: RulesMode::Blacklist, + paths: Vec::new(), + } + } +} + +impl Rules { + pub fn suitable(&self, path: &str) -> bool { + let contains = self.paths.contains(&path.to_string()); + + if self.mode == RulesMode::Blacklist { + !contains + } else { + contains + } + } +} + #[derive(Debug)] pub struct Configuration { pub base_icons_url: String, @@ -31,6 +64,8 @@ pub struct Configuration { pub small_image: Option, pub small_text: Option, + pub rules: Rules, + pub git_integration: bool, } @@ -66,6 +101,7 @@ impl Configuration { large_text: Some(String::from("{language:u}")), small_image: Some(String::from("{base_icons_url}/zed.png")), small_text: Some(String::from("Zed")), + rules: Rules::default(), git_integration: true, } } @@ -80,6 +116,28 @@ impl Configuration { set_option!(self, options, small_image, "small_image"); set_option!(self, options, small_text, "small_text"); + if let Some(rules) = options.get("rules") { + self.rules.mode = rules.get("mode").and_then(|m| m.as_str()).map_or( + RulesMode::Blacklist, + |mode| match mode { + "whitelist" => RulesMode::Whitelist, + "blacklist" => RulesMode::Blacklist, + _ => RulesMode::Blacklist, + }, + ); + + self.rules.paths = + rules + .get("paths") + .and_then(|p| p.as_array()) + .map_or(Vec::new(), |paths| { + paths + .iter() + .filter_map(|p| p.as_str().map(|s| s.to_string())) + .collect() + }); + } + if let Some(git_integration) = options.get("git_integration") { self.git_integration = git_integration.as_bool().unwrap_or(true); } diff --git a/lsp/src/main.rs b/lsp/src/main.rs index 7f811a2..71c6ade 100644 --- a/lsp/src/main.rs +++ b/lsp/src/main.rs @@ -21,6 +21,7 @@ use std::ffi::OsStr; use std::fmt::Debug; use std::ops::Deref; use std::path::{Path, PathBuf}; +use std::process::exit; use std::sync::{Mutex, MutexGuard}; use configuration::Configuration; @@ -155,9 +156,6 @@ impl Backend { #[tower_lsp::async_trait] impl LanguageServer for Backend { async fn initialize(&self, params: InitializeParams) -> Result { - // Connect discord client - self.discord.connect(); - // Set workspace name let root_uri = params.root_uri.expect("Failed to get root uri"); let workspace_path = Path::new(root_uri.path()); @@ -178,6 +176,18 @@ impl LanguageServer for Backend { let mut config = self.config.lock().unwrap(); config.set(params.initialization_options); + if config.rules.suitable( + workspace_path + .to_str() + .expect("Failed to transform workspace path to str"), + ) { + // Connect discord client + self.discord.connect(); + } else { + // Exit LSP + exit(0); + } + Ok(InitializeResult { server_info: Some(ServerInfo { name: env!("CARGO_PKG_NAME").into(),