Skip to content
Merged
Show file tree
Hide file tree
Changes from 9 commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 2 additions & 1 deletion .claude/settings.local.json
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,8 @@
"Bash(cargo test:*)",
"Bash(cargo run:*)",
"Bash(cargo check:*)",
"Bash(cargo fmt:*)"
"Bash(cargo fmt:*)",
"Bash(cargo doc:*)"
],
"deny": []
}
Expand Down
126 changes: 120 additions & 6 deletions Cargo.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

18 changes: 2 additions & 16 deletions crates/pgt_cli/src/execute/process_file/workspace_file.rs
Original file line number Diff line number Diff line change
Expand Up @@ -2,13 +2,14 @@ use crate::execute::diagnostics::{ResultExt, ResultIoExt};
use crate::execute::process_file::SharedTraversalOptions;
use pgt_diagnostics::{Error, category};
use pgt_fs::{File, OpenOptions, PgTPath};
use pgt_workspace::workspace::{ChangeParams, FileGuard, OpenFileParams};
use pgt_workspace::workspace::{FileGuard, OpenFileParams};
use pgt_workspace::{Workspace, WorkspaceError};
use std::path::{Path, PathBuf};

/// Small wrapper that holds information and operations around the current processed file
pub(crate) struct WorkspaceFile<'ctx, 'app> {
guard: FileGuard<'app, dyn Workspace + 'ctx>,
#[allow(dead_code)]
file: Box<dyn File>,
pub(crate) path: PathBuf,
}
Expand Down Expand Up @@ -57,19 +58,4 @@ impl<'ctx, 'app> WorkspaceFile<'ctx, 'app> {
pub(crate) fn input(&self) -> Result<String, WorkspaceError> {
self.guard().get_file_content()
}

/// It updates the workspace file with `new_content`
#[allow(dead_code)]
pub(crate) fn update_file(&mut self, new_content: impl Into<String>) -> Result<(), Error> {
let new_content = new_content.into();

self.file
.set_content(new_content.as_bytes())
.with_file_path(self.path.display().to_string())?;
self.guard.change_file(
self.file.file_version(),
vec![ChangeParams::overwrite(new_content)],
)?;
Ok(())
}
}
18 changes: 11 additions & 7 deletions crates/pgt_lsp/src/capabilities.rs
Original file line number Diff line number Diff line change
@@ -1,14 +1,10 @@
use crate::adapters::{PositionEncoding, WideEncoding, negotiated_encoding};
use pgt_workspace::features::code_actions::CommandActionCategory;
use strum::IntoEnumIterator;
use tower_lsp::lsp_types::{
ClientCapabilities, CompletionOptions, ExecuteCommandOptions, PositionEncodingKind,
SaveOptions, ServerCapabilities, TextDocumentSyncCapability, TextDocumentSyncKind,
TextDocumentSyncOptions, TextDocumentSyncSaveOptions, WorkDoneProgressOptions,
};

use crate::handlers::code_actions::command_id;

/// The capabilities to send from server as part of [`InitializeResult`]
///
/// [`InitializeResult`]: lspower::lsp::InitializeResult
Expand Down Expand Up @@ -51,9 +47,7 @@ pub(crate) fn server_capabilities(capabilities: &ClientCapabilities) -> ServerCa
},
}),
execute_command_provider: Some(ExecuteCommandOptions {
commands: CommandActionCategory::iter()
.map(|c| command_id(&c))
.collect::<Vec<String>>(),
commands: available_command_ids(),

..Default::default()
}),
Expand All @@ -67,3 +61,13 @@ pub(crate) fn server_capabilities(capabilities: &ClientCapabilities) -> ServerCa
..Default::default()
}
}

/// Returns all available command IDs for capability registration.
/// Since CommandActionCategory has variants with data, we can't use strum::IntoEnumIterator.
/// Instead, we manually list the command IDs we want to register.
fn available_command_ids() -> Vec<String> {
vec![
"postgres-tools.executeStatement".to_string(),
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The ID in pgt_lsp/src/handlers/code_actions.rs also needs to be adjusted 👍

Copy link
Collaborator

@juleswritescode juleswritescode Jul 12, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Also, we're now just sending the full statement over to the client anyway, so we might as well change the CommandActionCategory::ExecuteStatement(_) to hold a String instead of a StatementId – I think you can then use strum again :)

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

ah good point!

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

reverted my changes. I think its simpler to just add a comment to the default implementation

// Add other command IDs here as needed
]
}
31 changes: 9 additions & 22 deletions crates/pgt_lsp/src/handlers/text_document.rs
Original file line number Diff line number Diff line change
@@ -1,10 +1,9 @@
use crate::adapters::from_lsp;
use crate::{
diagnostics::LspError, documents::Document, session::Session, utils::apply_document_changes,
};
use anyhow::Result;
use pgt_workspace::workspace::{
ChangeFileParams, ChangeParams, CloseFileParams, GetFileContentParams, OpenFileParams,
ChangeFileParams, CloseFileParams, GetFileContentParams, OpenFileParams,
};
use tower_lsp::lsp_types;
use tracing::error;
Expand Down Expand Up @@ -48,40 +47,28 @@ pub(crate) async fn did_change(

let pgt_path = session.file_path(&url)?;

let old_doc = session.document(&url)?;
let old_text = session.workspace.get_file_content(GetFileContentParams {
path: pgt_path.clone(),
})?;

let start = params
.content_changes
.iter()
.rev()
.position(|change| change.range.is_none())
.map_or(0, |idx| params.content_changes.len() - idx - 1);
tracing::trace!("old document: {:?}", old_text);
tracing::trace!("content changes: {:?}", params.content_changes);

let text = apply_document_changes(
session.position_encoding(),
old_text,
&params.content_changes[start..],
&params.content_changes,
);

tracing::trace!("new document: {:?}", text);

session.insert_document(url.clone(), Document::new(version, &text));

session.workspace.change_file(ChangeFileParams {
path: pgt_path,
version,
changes: params.content_changes[start..]
.iter()
.map(|c| ChangeParams {
range: c.range.and_then(|r| {
from_lsp::text_range(&old_doc.line_index, r, session.position_encoding()).ok()
}),
text: c.text.clone(),
})
.collect(),
content: text,
})?;

session.insert_document(url.clone(), Document::new(version, &text));

if let Err(err) = session.update_diagnostics(url).await {
error!("Failed to update diagnostics: {}", err);
}
Expand Down
7 changes: 6 additions & 1 deletion crates/pgt_statement_splitter/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -19,4 +19,9 @@ pgt_text_size.workspace = true
regex.workspace = true

[dev-dependencies]
ntest = "0.9.3"
criterion = "0.3"
ntest = "0.9.3"

[[bench]]
harness = false
name = "splitter"
Loading