Skip to content

Commit a09643f

Browse files
add capabilities, normalize offset
1 parent 7bd82cf commit a09643f

File tree

7 files changed

+89
-49
lines changed

7 files changed

+89
-49
lines changed

crates/pg_lsp_new/src/capabilities.rs

Lines changed: 20 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,8 @@
11
use pg_lsp_converters::{negotiated_encoding, PositionEncoding, WideEncoding};
22
use tower_lsp::lsp_types::{
3-
ClientCapabilities, PositionEncodingKind, SaveOptions, ServerCapabilities,
3+
ClientCapabilities, CompletionOptions, PositionEncodingKind, SaveOptions, ServerCapabilities,
44
TextDocumentSyncCapability, TextDocumentSyncKind, TextDocumentSyncOptions,
5-
TextDocumentSyncSaveOptions,
5+
TextDocumentSyncSaveOptions, WorkDoneProgressOptions,
66
};
77

88
/// The capabilities to send from server as part of [`InitializeResult`]
@@ -28,6 +28,24 @@ pub(crate) fn server_capabilities(capabilities: &ClientCapabilities) -> ServerCa
2828
})),
2929
},
3030
)),
31+
completion_provider: Some(CompletionOptions {
32+
// currently not supporting the completionItem/resolve request.
33+
// The request is used to get more information about a simple CompletionItem.
34+
resolve_provider: None,
35+
36+
trigger_characters: Some(vec![".".to_owned(), ",".to_owned(), " ".to_owned()]),
37+
38+
// No character will lead to automatically inserting the selected completion-item
39+
all_commit_characters: None,
40+
41+
// No special support for completionItem/resolve requests
42+
completion_item: None,
43+
44+
// We do not report the progress of the completion process
45+
work_done_progress_options: WorkDoneProgressOptions {
46+
work_done_progress: None,
47+
},
48+
}),
3149
document_formatting_provider: None,
3250
document_range_formatting_provider: None,
3351
document_on_type_formatting_provider: None,

crates/pg_lsp_new/src/handlers/completions.rs

Lines changed: 7 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -1,22 +1,22 @@
11
use crate::session::Session;
22
use anyhow::Result;
33
use pg_workspace_new::workspace::CompletionParams;
4-
use text_size::TextSize;
54
use tower_lsp::lsp_types::{self, CompletionItem, CompletionItemLabelDetails};
65

6+
#[tracing::instrument(level = "debug", skip_all)]
77
pub fn get_completions(
88
session: &Session,
99
params: lsp_types::CompletionParams,
1010
) -> Result<lsp_types::CompletionResponse> {
11-
let pos = params.text_document_position.position;
1211
let url = params.text_document_position.text_document.uri;
13-
1412
let path = session.file_path(&url)?;
13+
let column = params.text_document_position.position.character;
14+
let line = params.text_document_position.position.line;
1515

16-
let completion_result = session.workspace.get_completions(CompletionParams {
17-
path,
18-
position: TextSize::from(pos.character),
19-
})?;
16+
let completion_result =
17+
session
18+
.workspace
19+
.get_completions(CompletionParams { path, line, column })?;
2020

2121
let items: Vec<CompletionItem> = completion_result
2222
.into_iter()

crates/pg_lsp_new/src/handlers/text_document.rs

Lines changed: 1 addition & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -43,48 +43,36 @@ pub(crate) async fn did_open(
4343
}
4444

4545
// Handler for `textDocument/didChange` LSP notification
46-
#[tracing::instrument(level = "info", skip_all, fields(url = field::display(&params.text_document.uri), version = params.text_document.version), err)]
46+
#[tracing::instrument(level = "debug", skip_all, fields(url = field::display(&params.text_document.uri), version = params.text_document.version), err)]
4747
pub(crate) async fn did_change(
4848
session: &Session,
4949
params: lsp_types::DidChangeTextDocumentParams,
5050
) -> Result<()> {
5151
let url = params.text_document.uri;
5252
let version = params.text_document.version;
5353

54-
info!("Reading LSP Path...");
55-
5654
let pglsp_path = session.file_path(&url)?;
5755

58-
info!("Getting file content...");
59-
6056
// we need to keep the documents here too for the line index
6157
let old_text = session.workspace.get_file_content(GetFileContentParams {
6258
path: pglsp_path.clone(),
6359
})?;
6460

65-
info!("Finding start…");
66-
6761
let start = params
6862
.content_changes
6963
.iter()
7064
.rev()
7165
.position(|change| change.range.is_none())
7266
.map_or(0, |idx| params.content_changes.len() - idx - 1);
7367

74-
info!("Getting finalized text...");
75-
7668
let text = apply_document_changes(
7769
session.position_encoding(),
7870
old_text,
7971
&params.content_changes[start..],
8072
);
8173

82-
info!("Creating new doc…");
83-
8474
let new_doc = Document::new(version, &text);
8575

86-
info!("Changing File in Workspace...");
87-
8876
session.workspace.change_file(ChangeFileParams {
8977
path: pglsp_path,
9078
version,
@@ -99,12 +87,8 @@ pub(crate) async fn did_change(
9987
.collect(),
10088
})?;
10189

102-
info!("Inserting document...");
103-
10490
session.insert_document(url.clone(), new_doc);
10591

106-
info!("Updating diagnostics...");
107-
10892
if let Err(err) = session.update_diagnostics(url).await {
10993
error!("Failed to update diagnostics: {}", err);
11094
}

crates/pg_lsp_new/src/server.rs

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -210,35 +210,35 @@ impl LanguageServer for LSPServer {
210210
}
211211
}
212212

213-
#[tracing::instrument(level = "info", skip(self))]
213+
#[tracing::instrument(level = "trace", skip(self))]
214214
async fn did_open(&self, params: DidOpenTextDocumentParams) {
215215
handlers::text_document::did_open(&self.session, params)
216216
.await
217217
.ok();
218218
}
219219

220-
#[tracing::instrument(level = "info", skip(self, params))]
220+
#[tracing::instrument(level = "trace", skip(self, params))]
221221
async fn did_change(&self, params: DidChangeTextDocumentParams) {
222222
if let Err(e) = handlers::text_document::did_change(&self.session, params).await {
223223
error!("{}", e);
224224
};
225225
}
226226

227-
#[tracing::instrument(level = "info", skip(self))]
227+
#[tracing::instrument(level = "trace", skip(self))]
228228
async fn did_save(&self, params: DidSaveTextDocumentParams) {
229229
// handlers::text_document::did_save(&self.session, params)
230230
// .await
231231
// .ok();
232232
}
233233

234-
#[tracing::instrument(level = "info", skip(self))]
234+
#[tracing::instrument(level = "trace", skip(self))]
235235
async fn did_close(&self, params: DidCloseTextDocumentParams) {
236236
handlers::text_document::did_close(&self.session, params)
237237
.await
238238
.ok();
239239
}
240240

241-
#[tracing::instrument(level = "info", skip(self))]
241+
#[tracing::instrument(level = "trace", skip(self))]
242242
async fn completion(&self, params: CompletionParams) -> LspResult<Option<CompletionResponse>> {
243243
match handlers::completions::get_completions(&self.session, params) {
244244
Ok(result) => LspResult::Ok(Some(result)),

crates/pg_workspace_new/src/workspace.rs

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -44,7 +44,8 @@ pub struct CompletionParams {
4444
/// The File for which a completion is requested.
4545
pub path: PgLspPath,
4646
/// The Cursor position in the file for which a completion is requested.
47-
pub position: TextSize,
47+
pub column: u32,
48+
pub line: u32,
4849
}
4950

5051
#[derive(Debug, serde::Serialize, serde::Deserialize)]

crates/pg_workspace_new/src/workspace/server.rs

Lines changed: 22 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -343,7 +343,7 @@ impl Workspace for WorkspaceServer {
343343
})
344344
}
345345

346-
#[tracing::instrument(level = "info", skip(self))]
346+
#[tracing::instrument(level = "debug", skip(self))]
347347
fn get_completions(
348348
&self,
349349
params: super::CompletionParams,
@@ -353,27 +353,39 @@ impl Workspace for WorkspaceServer {
353353
.get(&params.path)
354354
.ok_or(WorkspaceError::not_found())?;
355355

356-
tracing::info!("Found the document.");
357-
tracing::info!("Looking for statement at position: {:?}", &params.position);
356+
let offset = doc.line_and_col_to_offset(params.line, params.column);
358357

359-
let statement_ref = match doc.statement_ref_at_offset(&params.position) {
358+
tracing::info!(
359+
"Found the document. Looking for statement in file {:?} at position: {:?}",
360+
&params.path,
361+
&offset
362+
);
363+
364+
let statement = match doc.statement_at_offset(&offset) {
360365
Some(s) => s,
361366
None => return Ok(pg_completions::CompletionResult::default()),
362367
};
368+
let statement_ref = &statement.ref_;
369+
370+
// `offset` is the position in the document,
371+
// but we need the position within the *statement*.
372+
let stmt_range = doc
373+
.statement_range(statement_ref)
374+
.expect("Range of statement should be defined.");
375+
let position = offset - stmt_range.start();
376+
377+
let tree = self.tree_sitter.fetch(statement_ref);
378+
let text = statement.text;
363379

364-
let tree = self.tree_sitter.fetch(&statement_ref);
365-
let text = doc
366-
.statement_by_id(statement_ref.id)
367-
.expect("Found statement_ref but no matching statement")
368-
.text;
380+
tracing::info!("Found the statement. We're looking for position {:?}. Statement Range {:?} to {:?}. Statement: {}", position, stmt_range.start(), stmt_range.end(), text);
369381

370382
let schema_cache = self
371383
.schema_cache
372384
.read()
373385
.map_err(|_| WorkspaceError::runtime("Unable to load SchemaCache"))?;
374386

375387
let result = pg_completions::complete(pg_completions::CompletionParams {
376-
position: params.position,
388+
position,
377389
schema: &schema_cache,
378390
tree: tree.as_deref(),
379391
text,

crates/pg_workspace_new/src/workspace/server/document.rs

Lines changed: 32 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -81,6 +81,31 @@ impl Document {
8181
.collect()
8282
}
8383

84+
pub fn line_and_col_to_offset(&self, line: u32, col: u32) -> TextSize {
85+
let line = line as usize;
86+
let pos = col as usize;
87+
88+
let mut offset: usize = 0;
89+
90+
for (current_line_num, current_line) in self.content.lines().enumerate() {
91+
let current_line_num = current_line_num + 1;
92+
if current_line_num < line {
93+
offset += current_line.len();
94+
} else if current_line_num == line {
95+
offset += pos;
96+
};
97+
}
98+
99+
// Normalize in case we exceed the length of the content
100+
if offset > self.content.len() {
101+
offset = self.content.len()
102+
}
103+
104+
let offset = u32::try_from(offset).expect("Offset should be within u32 bounds");
105+
106+
TextSize::from(offset)
107+
}
108+
84109
#[allow(dead_code)]
85110
/// Returns the statement ref at the given offset
86111
pub fn statement_ref_at_offset(&self, offset: &TextSize) -> Option<StatementRef> {
@@ -129,20 +154,20 @@ impl Document {
129154
.collect()
130155
}
131156

132-
pub(super) fn statement_by_id(&self, id: StatementId) -> Option<Statement> {
133-
self.statements
134-
.iter()
135-
.find(|s| s.0 == id)
136-
.map(|pos| self.statement(pos))
137-
}
138-
139157
pub(super) fn statement_ref(&self, inner_ref: &StatementPosition) -> StatementRef {
140158
StatementRef {
141159
id: inner_ref.0,
142160
path: self.path.clone(),
143161
}
144162
}
145163

164+
pub(super) fn statement_range(&self, sref: &StatementRef) -> Option<TextRange> {
165+
self.statements
166+
.iter()
167+
.find(|s| s.0 == sref.id)
168+
.map(|it| it.1)
169+
}
170+
146171
pub(super) fn statement(&self, inner_ref: &StatementPosition) -> Statement {
147172
Statement {
148173
ref_: self.statement_ref(inner_ref),

0 commit comments

Comments
 (0)