diff --git a/.gitignore b/.gitignore
index abab0fa64..af3907006 100644
--- a/.gitignore
+++ b/.gitignore
@@ -52,4 +52,3 @@ site/
biome-main/
.review/
pglinter_repo/
-.review/
diff --git a/crates/pgls_lsp/src/capabilities.rs b/crates/pgls_lsp/src/capabilities.rs
index 38d66d876..87aaf96f4 100644
--- a/crates/pgls_lsp/src/capabilities.rs
+++ b/crates/pgls_lsp/src/capabilities.rs
@@ -1,10 +1,13 @@
use crate::adapters::{PositionEncoding, WideEncoding, negotiated_encoding};
use crate::handlers::code_actions::command_id;
use pgls_workspace::features::code_actions::CommandActionCategory;
+use pgls_workspace::features::semantic_tokens::{TokenModifier, TokenType};
use strum::IntoEnumIterator;
use tower_lsp::lsp_types::{
ClientCapabilities, CompletionOptions, ExecuteCommandOptions, HoverProviderCapability, OneOf,
- PositionEncodingKind, SaveOptions, ServerCapabilities, TextDocumentSyncCapability,
+ PositionEncodingKind, SaveOptions, SemanticTokenModifier, SemanticTokenType,
+ SemanticTokensFullOptions, SemanticTokensLegend, SemanticTokensOptions,
+ SemanticTokensServerCapabilities, ServerCapabilities, TextDocumentSyncCapability,
TextDocumentSyncKind, TextDocumentSyncOptions, TextDocumentSyncSaveOptions,
WorkDoneProgressOptions,
};
@@ -69,6 +72,25 @@ pub(crate) fn server_capabilities(capabilities: &ClientCapabilities) -> ServerCa
)),
rename_provider: None,
hover_provider: Some(HoverProviderCapability::Simple(true)),
+ semantic_tokens_provider: Some(SemanticTokensServerCapabilities::SemanticTokensOptions(
+ SemanticTokensOptions {
+ work_done_progress_options: WorkDoneProgressOptions {
+ work_done_progress: None,
+ },
+ legend: SemanticTokensLegend {
+ token_types: TokenType::legend()
+ .into_iter()
+ .map(SemanticTokenType::new)
+ .collect(),
+ token_modifiers: TokenModifier::legend()
+ .into_iter()
+ .map(SemanticTokenModifier::new)
+ .collect(),
+ },
+ range: Some(true),
+ full: Some(SemanticTokensFullOptions::Bool(true)),
+ },
+ )),
..Default::default()
}
}
diff --git a/crates/pgls_lsp/src/handlers.rs b/crates/pgls_lsp/src/handlers.rs
index 42ac16963..afb1c2627 100644
--- a/crates/pgls_lsp/src/handlers.rs
+++ b/crates/pgls_lsp/src/handlers.rs
@@ -2,4 +2,5 @@ pub(crate) mod code_actions;
pub(crate) mod completions;
pub(crate) mod formatting;
pub(crate) mod hover;
+pub(crate) mod semantic_tokens;
pub(crate) mod text_document;
diff --git a/crates/pgls_lsp/src/handlers/semantic_tokens.rs b/crates/pgls_lsp/src/handlers/semantic_tokens.rs
new file mode 100644
index 000000000..4022d54ee
--- /dev/null
+++ b/crates/pgls_lsp/src/handlers/semantic_tokens.rs
@@ -0,0 +1,189 @@
+use crate::{adapters, diagnostics::LspError, session::Session};
+use pgls_text_size::TextRange;
+use pgls_workspace::features::semantic_tokens::SemanticTokensParams;
+use tower_lsp::lsp_types::{self, SemanticToken, SemanticTokens, SemanticTokensRangeResult};
+
+/// Handles a full semantic tokens request.
+#[tracing::instrument(level = "debug", skip(session), err)]
+pub fn semantic_tokens_full(
+ session: &Session,
+ params: lsp_types::SemanticTokensParams,
+) -> Result