diff --git a/crates/pgt_completions/src/builder.rs b/crates/pgt_completions/src/builder.rs index cad446e4..39439afb 100644 --- a/crates/pgt_completions/src/builder.rs +++ b/crates/pgt_completions/src/builder.rs @@ -1,4 +1,4 @@ -use crate::{CompletionResult, item::CompletionItem}; +use crate::item::CompletionItem; pub(crate) struct CompletionBuilder { items: Vec, @@ -13,7 +13,7 @@ impl CompletionBuilder { self.items.push(item); } - pub fn finish(mut self) -> CompletionResult { + pub fn finish(mut self) -> Vec { self.items .sort_by(|a, b| b.score.cmp(&a.score).then_with(|| a.label.cmp(&b.label))); @@ -22,8 +22,7 @@ impl CompletionBuilder { let should_preselect_first_item = self.should_preselect_first_item(); - let items: Vec = self - .items + self.items .into_iter() .enumerate() .map(|(idx, mut item)| { @@ -32,9 +31,7 @@ impl CompletionBuilder { } item }) - .collect(); - - CompletionResult { items } + .collect() } fn should_preselect_first_item(&mut self) -> bool { diff --git a/crates/pgt_completions/src/complete.rs b/crates/pgt_completions/src/complete.rs index 4acc1a24..fb00aeaf 100644 --- a/crates/pgt_completions/src/complete.rs +++ b/crates/pgt_completions/src/complete.rs @@ -1,5 +1,4 @@ use pgt_text_size::TextSize; -use serde::{Deserialize, Serialize}; use crate::{ builder::CompletionBuilder, @@ -18,21 +17,7 @@ pub struct CompletionParams<'a> { pub tree: Option<&'a tree_sitter::Tree>, } -#[derive(Debug, Default, Serialize, Deserialize)] -#[cfg_attr(feature = "schema", derive(schemars::JsonSchema))] -pub struct CompletionResult { - pub(crate) items: Vec, -} - -impl IntoIterator for CompletionResult { - type Item = CompletionItem; - type IntoIter = as IntoIterator>::IntoIter; - fn into_iter(self) -> Self::IntoIter { - self.items.into_iter() - } -} - -pub fn complete(params: CompletionParams) -> CompletionResult { +pub fn complete(params: CompletionParams) -> Vec { let ctx = CompletionContext::new(¶ms); let mut builder = CompletionBuilder::new(); diff --git a/crates/pgt_completions/src/providers/columns.rs b/crates/pgt_completions/src/providers/columns.rs index 71aa923b..3f1c5bb9 100644 --- a/crates/pgt_completions/src/providers/columns.rs +++ b/crates/pgt_completions/src/providers/columns.rs @@ -141,13 +141,13 @@ mod tests { let (tree, cache) = get_test_deps(setup, case.get_input_query()).await; let params = get_test_params(&tree, &cache, case.get_input_query()); - let mut results = complete(params); + let mut items = complete(params); - let _ = results.items.split_off(3); + let _ = items.split_off(3); - results.items.sort_by(|a, b| a.label.cmp(&b.label)); + items.sort_by(|a, b| a.label.cmp(&b.label)); - let labels: Vec = results.items.into_iter().map(|c| c.label).collect(); + let labels: Vec = items.into_iter().map(|c| c.label).collect(); assert_eq!(labels, vec!["name", "narrator", "narrator_id"]); } diff --git a/crates/pgt_completions/src/providers/tables.rs b/crates/pgt_completions/src/providers/tables.rs index c2fa753d..6a1e00c9 100644 --- a/crates/pgt_completions/src/providers/tables.rs +++ b/crates/pgt_completions/src/providers/tables.rs @@ -43,11 +43,11 @@ mod tests { let (tree, cache) = get_test_deps(setup, query.as_str().into()).await; let params = get_test_params(&tree, &cache, query.as_str().into()); - let results = complete(params); + let items = complete(params); - assert!(!results.items.is_empty()); + assert!(!items.is_empty()); - let best_match = &results.items[0]; + let best_match = &items[0]; assert_eq!( best_match.label, "users", @@ -81,11 +81,11 @@ mod tests { for (query, expected_label) in test_cases { let (tree, cache) = get_test_deps(setup, query.as_str().into()).await; let params = get_test_params(&tree, &cache, query.as_str().into()); - let results = complete(params); + let items = complete(params); - assert!(!results.items.is_empty()); + assert!(!items.is_empty()); - let best_match = &results.items[0]; + let best_match = &items[0]; assert_eq!( best_match.label, expected_label, @@ -126,11 +126,11 @@ mod tests { for (query, expected_label) in test_cases { let (tree, cache) = get_test_deps(setup, query.as_str().into()).await; let params = get_test_params(&tree, &cache, query.as_str().into()); - let results = complete(params); + let items = complete(params); - assert!(!results.items.is_empty()); + assert!(!items.is_empty()); - let best_match = &results.items[0]; + let best_match = &items[0]; assert_eq!( best_match.label, expected_label, @@ -163,9 +163,9 @@ mod tests { let (tree, cache) = get_test_deps(setup, query.as_str().into()).await; let params = get_test_params(&tree, &cache, query.as_str().into()); - let results = complete(params); + let items = complete(params); - let CompletionItem { label, kind, .. } = results + let CompletionItem { label, kind, .. } = items .into_iter() .next() .expect("Should return at least one completion item"); diff --git a/crates/pgt_lsp/src/capabilities.rs b/crates/pgt_lsp/src/capabilities.rs index 0b64788e..a801dd5e 100644 --- a/crates/pgt_lsp/src/capabilities.rs +++ b/crates/pgt_lsp/src/capabilities.rs @@ -1,6 +1,6 @@ use crate::adapters::{PositionEncoding, WideEncoding, negotiated_encoding}; -use pgt_workspace::code_actions::{CommandActionCategory, CommandActionCategoryIter}; -use strum::{EnumIter, IntoEnumIterator}; +use pgt_workspace::features::code_actions::CommandActionCategory; +use strum::IntoEnumIterator; use tower_lsp::lsp_types::{ ClientCapabilities, CompletionOptions, ExecuteCommandOptions, PositionEncodingKind, SaveOptions, ServerCapabilities, TextDocumentSyncCapability, TextDocumentSyncKind, diff --git a/crates/pgt_lsp/src/handlers/code_actions.rs b/crates/pgt_lsp/src/handlers/code_actions.rs index 140eb8a3..4e118c2b 100644 --- a/crates/pgt_lsp/src/handlers/code_actions.rs +++ b/crates/pgt_lsp/src/handlers/code_actions.rs @@ -5,7 +5,7 @@ use tower_lsp::lsp_types::{ MessageType, }; -use pgt_workspace::code_actions::{ +use pgt_workspace::features::code_actions::{ CodeActionKind, CodeActionsParams, CommandActionCategory, ExecuteStatementParams, }; diff --git a/crates/pgt_lsp/src/handlers/completions.rs b/crates/pgt_lsp/src/handlers/completions.rs index 2abb63bd..34f08bdd 100644 --- a/crates/pgt_lsp/src/handlers/completions.rs +++ b/crates/pgt_lsp/src/handlers/completions.rs @@ -1,6 +1,6 @@ use crate::session::Session; use anyhow::Result; -use pgt_workspace::{WorkspaceError, workspace}; +use pgt_workspace::{WorkspaceError, features::completions::GetCompletionsParams}; use tower_lsp::lsp_types::{self, CompletionItem, CompletionItemLabelDetails}; use super::helper; @@ -13,27 +13,24 @@ pub fn get_completions( let url = params.text_document_position.text_document.uri; let path = session.file_path(&url)?; - let completion_result = - match session - .workspace - .get_completions(workspace::GetCompletionsParams { - path, - position: helper::get_cursor_position( - session, - &url, - params.text_document_position.position, - )?, - }) { - Ok(result) => result, - Err(e) => match e { - WorkspaceError::DatabaseConnectionError(_) => { - return Ok(lsp_types::CompletionResponse::Array(vec![])); - } - _ => { - return Err(e.into()); - } - }, - }; + let completion_result = match session.workspace.get_completions(GetCompletionsParams { + path, + position: helper::get_cursor_position( + session, + &url, + params.text_document_position.position, + )?, + }) { + Ok(result) => result, + Err(e) => match e { + WorkspaceError::DatabaseConnectionError(_) => { + return Ok(lsp_types::CompletionResponse::Array(vec![])); + } + _ => { + return Err(e.into()); + } + }, + }; let items: Vec = completion_result .into_iter() diff --git a/crates/pgt_lsp/src/session.rs b/crates/pgt_lsp/src/session.rs index add71c92..5c10b980 100644 --- a/crates/pgt_lsp/src/session.rs +++ b/crates/pgt_lsp/src/session.rs @@ -11,8 +11,9 @@ use pgt_diagnostics::{DiagnosticExt, Error}; use pgt_fs::{FileSystem, PgTPath}; use pgt_workspace::Workspace; use pgt_workspace::configuration::{LoadedConfiguration, load_configuration}; +use pgt_workspace::features; use pgt_workspace::settings::PartialConfigurationExt; -use pgt_workspace::workspace::{PullDiagnosticsParams, UpdateSettingsParams}; +use pgt_workspace::workspace::UpdateSettingsParams; use pgt_workspace::{DynRef, WorkspaceError}; use rustc_hash::FxHashMap; use serde_json::Value; @@ -265,13 +266,15 @@ impl Session { let categories = RuleCategoriesBuilder::default().all(); let diagnostics: Vec = { - let result = self.workspace.pull_diagnostics(PullDiagnosticsParams { - path: pgt_path.clone(), - max_diagnostics: u64::MAX, - categories: categories.build(), - only: Vec::new(), - skip: Vec::new(), - })?; + let result = + self.workspace + .pull_diagnostics(features::diagnostics::PullDiagnosticsParams { + path: pgt_path.clone(), + max_diagnostics: u64::MAX, + categories: categories.build(), + only: Vec::new(), + skip: Vec::new(), + })?; result .diagnostics diff --git a/crates/pgt_workspace/src/code_actions.rs b/crates/pgt_workspace/src/features/code_actions.rs similarity index 100% rename from crates/pgt_workspace/src/code_actions.rs rename to crates/pgt_workspace/src/features/code_actions.rs diff --git a/crates/pgt_workspace/src/features/completions.rs b/crates/pgt_workspace/src/features/completions.rs new file mode 100644 index 00000000..8fb13313 --- /dev/null +++ b/crates/pgt_workspace/src/features/completions.rs @@ -0,0 +1,26 @@ +use pgt_completions::CompletionItem; +use pgt_fs::PgTPath; +use pgt_text_size::TextSize; + +#[derive(Debug, serde::Serialize, serde::Deserialize)] +#[cfg_attr(feature = "schema", derive(schemars::JsonSchema))] +pub struct GetCompletionsParams { + /// The File for which a completion is requested. + pub path: PgTPath, + /// The Cursor position in the file for which a completion is requested. + pub position: TextSize, +} + +#[derive(Debug, serde::Serialize, serde::Deserialize, Default)] +#[cfg_attr(feature = "schema", derive(schemars::JsonSchema))] +pub struct CompletionsResult { + pub(crate) items: Vec, +} + +impl IntoIterator for CompletionsResult { + type Item = CompletionItem; + type IntoIter = as IntoIterator>::IntoIter; + fn into_iter(self) -> Self::IntoIter { + self.items.into_iter() + } +} diff --git a/crates/pgt_workspace/src/features/diagnostics.rs b/crates/pgt_workspace/src/features/diagnostics.rs new file mode 100644 index 00000000..ff60e142 --- /dev/null +++ b/crates/pgt_workspace/src/features/diagnostics.rs @@ -0,0 +1,21 @@ +use pgt_analyse::RuleCategories; +use pgt_configuration::RuleSelector; +use pgt_fs::PgTPath; + +#[derive(Debug, serde::Serialize, serde::Deserialize)] +#[cfg_attr(feature = "schema", derive(schemars::JsonSchema))] +pub struct PullDiagnosticsParams { + pub path: PgTPath, + pub categories: RuleCategories, + pub max_diagnostics: u64, + pub only: Vec, + pub skip: Vec, +} + +#[derive(Debug, serde::Serialize, serde::Deserialize)] +#[cfg_attr(feature = "schema", derive(schemars::JsonSchema))] +pub struct PullDiagnosticsResult { + pub diagnostics: Vec, + pub errors: usize, + pub skipped_diagnostics: u64, +} diff --git a/crates/pgt_workspace/src/features/mod.rs b/crates/pgt_workspace/src/features/mod.rs new file mode 100644 index 00000000..31013f36 --- /dev/null +++ b/crates/pgt_workspace/src/features/mod.rs @@ -0,0 +1,3 @@ +pub mod code_actions; +pub mod completions; +pub mod diagnostics; diff --git a/crates/pgt_workspace/src/lib.rs b/crates/pgt_workspace/src/lib.rs index a631853e..99fe063f 100644 --- a/crates/pgt_workspace/src/lib.rs +++ b/crates/pgt_workspace/src/lib.rs @@ -3,10 +3,10 @@ use std::ops::{Deref, DerefMut}; use pgt_console::Console; use pgt_fs::{FileSystem, OsFileSystem}; -pub mod code_actions; pub mod configuration; pub mod diagnostics; pub mod dome; +pub mod features; pub mod matcher; pub mod settings; pub mod workspace; diff --git a/crates/pgt_workspace/src/workspace.rs b/crates/pgt_workspace/src/workspace.rs index 13750b94..4a503d5d 100644 --- a/crates/pgt_workspace/src/workspace.rs +++ b/crates/pgt_workspace/src/workspace.rs @@ -4,13 +4,17 @@ pub use self::client::{TransportRequest, WorkspaceClient, WorkspaceTransport}; use pgt_analyse::RuleCategories; use pgt_configuration::{PartialConfiguration, RuleSelector}; use pgt_fs::PgTPath; -use pgt_text_size::{TextRange, TextSize}; +use pgt_text_size::TextRange; use serde::{Deserialize, Serialize}; use crate::{ WorkspaceError, - code_actions::{ - CodeActionsParams, CodeActionsResult, ExecuteStatementParams, ExecuteStatementResult, + features::{ + code_actions::{ + CodeActionsParams, CodeActionsResult, ExecuteStatementParams, ExecuteStatementResult, + }, + completions::{CompletionsResult, GetCompletionsParams}, + diagnostics::{PullDiagnosticsParams, PullDiagnosticsResult}, }, }; @@ -41,33 +45,6 @@ pub struct ChangeFileParams { pub changes: Vec, } -#[derive(Debug, serde::Serialize, serde::Deserialize)] -#[cfg_attr(feature = "schema", derive(schemars::JsonSchema))] -pub struct PullDiagnosticsParams { - pub path: PgTPath, - pub categories: RuleCategories, - pub max_diagnostics: u64, - pub only: Vec, - pub skip: Vec, -} - -#[derive(Debug, serde::Serialize, serde::Deserialize)] -#[cfg_attr(feature = "schema", derive(schemars::JsonSchema))] -pub struct GetCompletionsParams { - /// The File for which a completion is requested. - pub path: PgTPath, - /// The Cursor position in the file for which a completion is requested. - pub position: TextSize, -} - -#[derive(Debug, serde::Serialize, serde::Deserialize)] -#[cfg_attr(feature = "schema", derive(schemars::JsonSchema))] -pub struct PullDiagnosticsResult { - pub diagnostics: Vec, - pub errors: usize, - pub skipped_diagnostics: u64, -} - #[derive(Debug, serde::Serialize, serde::Deserialize)] #[cfg_attr(feature = "schema", derive(schemars::JsonSchema))] pub struct ChangeParams { @@ -131,7 +108,7 @@ pub trait Workspace: Send + Sync + RefUnwindSafe { fn get_completions( &self, params: GetCompletionsParams, - ) -> Result; + ) -> Result; /// Update the global settings for this workspace fn update_settings(&self, params: UpdateSettingsParams) -> Result<(), WorkspaceError>; diff --git a/crates/pgt_workspace/src/workspace/client.rs b/crates/pgt_workspace/src/workspace/client.rs index beb97b7c..d727fff6 100644 --- a/crates/pgt_workspace/src/workspace/client.rs +++ b/crates/pgt_workspace/src/workspace/client.rs @@ -91,15 +91,15 @@ where { fn pull_code_actions( &self, - params: crate::code_actions::CodeActionsParams, - ) -> Result { + params: crate::features::code_actions::CodeActionsParams, + ) -> Result { self.request("pgt/code_actions", params) } fn execute_statement( &self, - params: crate::code_actions::ExecuteStatementParams, - ) -> Result { + params: crate::features::code_actions::ExecuteStatementParams, + ) -> Result { self.request("pgt/execute_statement", params) } @@ -133,15 +133,15 @@ where fn pull_diagnostics( &self, - params: super::PullDiagnosticsParams, - ) -> Result { + params: crate::features::diagnostics::PullDiagnosticsParams, + ) -> Result { self.request("pgt/pull_diagnostics", params) } fn get_completions( &self, params: super::GetCompletionsParams, - ) -> Result { + ) -> Result { self.request("pgt/get_completions", params) } } diff --git a/crates/pgt_workspace/src/workspace/server.rs b/crates/pgt_workspace/src/workspace/server.rs index 39155e94..c37c5bb6 100644 --- a/crates/pgt_workspace/src/workspace/server.rs +++ b/crates/pgt_workspace/src/workspace/server.rs @@ -21,13 +21,16 @@ use tree_sitter::TreeSitterStore; use crate::{ WorkspaceError, - code_actions::{ - self, CodeAction, CodeActionKind, CodeActionsResult, CommandAction, CommandActionCategory, - ExecuteStatementResult, - }, configuration::to_analyser_rules, + features::{ + code_actions::{ + self, CodeAction, CodeActionKind, CodeActionsResult, CommandAction, + CommandActionCategory, ExecuteStatementParams, ExecuteStatementResult, + }, + completions::{CompletionsResult, GetCompletionsParams}, + diagnostics::{PullDiagnosticsParams, PullDiagnosticsResult}, + }, settings::{Settings, SettingsHandle, SettingsHandleMut}, - workspace::PullDiagnosticsResult, }; use super::{ @@ -193,7 +196,7 @@ impl Workspace for WorkspaceServer { } /// Remove a file from the workspace - fn close_file(&self, params: super::CloseFileParams) -> Result<(), crate::WorkspaceError> { + fn close_file(&self, params: super::CloseFileParams) -> Result<(), WorkspaceError> { let (_, doc) = self .documents .remove(¶ms.path) @@ -272,7 +275,7 @@ impl Workspace for WorkspaceServer { .iter_statements_with_text_and_range() .filter(|(_, range, _)| range.contains(params.cursor_position)); - let mut actions: Vec = vec![]; + let mut actions: Vec = vec![]; let settings = self .settings @@ -305,8 +308,8 @@ impl Workspace for WorkspaceServer { fn execute_statement( &self, - params: code_actions::ExecuteStatementParams, - ) -> Result { + params: ExecuteStatementParams, + ) -> Result { let doc = self .documents .get(¶ms.path) @@ -356,8 +359,8 @@ impl Workspace for WorkspaceServer { fn pull_diagnostics( &self, - params: super::PullDiagnosticsParams, - ) -> Result { + params: PullDiagnosticsParams, + ) -> Result { // get all statements form the requested document and pull diagnostics out of every // source let doc = self @@ -498,8 +501,8 @@ impl Workspace for WorkspaceServer { #[tracing::instrument(level = "debug", skip(self))] fn get_completions( &self, - params: super::GetCompletionsParams, - ) -> Result { + params: GetCompletionsParams, + ) -> Result { tracing::debug!( "Getting completions for file {:?} at position {:?}", ¶ms.path, @@ -508,7 +511,7 @@ impl Workspace for WorkspaceServer { let pool = match self.connection.read().unwrap().get_pool() { Some(pool) => pool, - None => return Ok(pgt_completions::CompletionResult::default()), + None => return Ok(CompletionsResult::default()), }; let doc = self @@ -527,7 +530,7 @@ impl Workspace for WorkspaceServer { .find(|(_, r, _)| r.contains(params.position)) { Some(s) => s, - None => return Ok(pgt_completions::CompletionResult::default()), + None => return Ok(CompletionsResult::default()), }; // `offset` is the position in the document, @@ -548,14 +551,14 @@ impl Workspace for WorkspaceServer { tracing::debug!("Loaded schema cache for completions"); - let result = pgt_completions::complete(pgt_completions::CompletionParams { + let items = pgt_completions::complete(pgt_completions::CompletionParams { position, schema: schema_cache.as_ref(), tree: tree.as_deref(), text: text.to_string(), }); - Ok(result) + Ok(CompletionsResult { items }) } }