From ed62c237ed2c3c710850c0740113ad09a99fd7da Mon Sep 17 00:00:00 2001 From: Lukas Scheller <45085299+Schottkyc137@users.noreply.github.com> Date: Sat, 27 Apr 2024 17:41:27 +0200 Subject: [PATCH] Enable ignoring files that are not part of the project (#297) --- vhdl_ls/src/main.rs | 1 + vhdl_ls/src/vhdl_server.rs | 63 +++++++++++++++++++++++++++++++++----- 2 files changed, 56 insertions(+), 8 deletions(-) diff --git a/vhdl_ls/src/main.rs b/vhdl_ls/src/main.rs index 2ed3d3e7..29dd5c8e 100644 --- a/vhdl_ls/src/main.rs +++ b/vhdl_ls/src/main.rs @@ -28,5 +28,6 @@ fn main() { vhdl_ls::start(VHDLServerSettings { no_lint: args.no_lint, silent: args.silent, + ..Default::default() }); } diff --git a/vhdl_ls/src/vhdl_server.rs b/vhdl_ls/src/vhdl_server.rs index 9e1ed2ca..29bfc84a 100644 --- a/vhdl_ls/src/vhdl_server.rs +++ b/vhdl_ls/src/vhdl_server.rs @@ -12,6 +12,7 @@ use std::collections::HashMap; use vhdl_lang::ast::{Designator, ObjectClass}; use crate::rpc_channel::SharedRpcChannel; +use serde_json::Value; use std::io; use std::io::ErrorKind; use std::path::{Path, PathBuf}; @@ -21,10 +22,33 @@ use vhdl_lang::{ Source, SrcPos, Token, Type, VHDLStandard, }; +/// Defines how the language server handles files +/// that are not part of the `vhdl_ls.toml` project settings file. +#[derive(Default, Clone, Eq, PartialEq)] +pub enum NonProjectFileHandling { + /// Ignore any non-project files + Ignore, + /// Add non-project files to an anonymous library and analyze them + #[default] + Analyze, +} + +impl NonProjectFileHandling { + pub fn from_string(value: &str) -> Option { + use NonProjectFileHandling::*; + Some(match value { + "ignore" => Ignore, + "analyze" => Analyze, + _ => return None, + }) + } +} + #[derive(Default, Clone)] pub struct VHDLServerSettings { pub no_lint: bool, pub silent: bool, + pub non_project_file_handling: NonProjectFileHandling, } pub struct VHDLServer { @@ -116,12 +140,30 @@ impl VHDLServer { config } + fn apply_initial_options(&mut self, options: &Value) { + let Some(non_project_file_handling) = options.get("nonProjectFiles") else { + return; + }; + match non_project_file_handling { + Value::String(handling) => match NonProjectFileHandling::from_string(handling) { + None => self.message(Message::error(format!( + "Illegal setting {handling} for nonProjectFiles setting" + ))), + Some(handling) => self.settings.non_project_file_handling = handling, + }, + _ => self.message(Message::error("nonProjectFiles must be a string")), + } + } + pub fn initialize_request(&mut self, init_params: InitializeParams) -> InitializeResult { self.config_file = self.root_uri_config_file(&init_params); let config = self.load_config(); self.severity_map = *config.severities(); self.project = Project::from_config(config, &mut self.message_filter()); self.project.enable_unused_declaration_detection(); + if let Some(options) = &init_params.initialization_options { + self.apply_initial_options(options) + } self.init_params = Some(init_params); let trigger_chars: Vec = r".".chars().map(|ch| ch.to_string()).collect(); @@ -228,7 +270,7 @@ impl VHDLServer { } self.project.update_source(&source); self.publish_diagnostics(); - } else { + } else if self.settings.non_project_file_handling != NonProjectFileHandling::Ignore { self.message(Message::error(format!( "Changing file {} that is not part of the project", file_name.to_string_lossy() @@ -244,13 +286,18 @@ impl VHDLServer { self.project.update_source(&source); self.publish_diagnostics(); } else { - self.message(Message::warning(format!( - "Opening file {} that is not part of the project", - file_name.to_string_lossy() - ))); - self.project - .update_source(&Source::inline(&file_name, text)); - self.publish_diagnostics(); + match self.settings.non_project_file_handling { + NonProjectFileHandling::Ignore => {} + NonProjectFileHandling::Analyze => { + self.message(Message::warning(format!( + "Opening file {} that is not part of the project", + file_name.to_string_lossy() + ))); + self.project + .update_source(&Source::inline(&file_name, text)); + self.publish_diagnostics(); + } + } } }