Skip to content

Commit ee96db1

Browse files
hover
1 parent 1bc33d0 commit ee96db1

File tree

2 files changed

+130
-32
lines changed

2 files changed

+130
-32
lines changed

crates/pg_lsp/src/b_server.rs

Lines changed: 31 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -243,7 +243,10 @@ impl LanguageServer for Server {
243243
let path = file_path(&uri);
244244
let range = params.range;
245245

246-
let actions = self.session.get_available_code_actions(path, range);
246+
let actions = self
247+
.session
248+
.get_available_code_actions_or_commands(path, range)
249+
.await;
247250

248251
Ok(actions)
249252
}
@@ -260,6 +263,33 @@ impl LanguageServer for Server {
260263
Ok(hints)
261264
}
262265

266+
async fn completion(&self, params: CompletionParams) -> Result<Option<CompletionResponse>> {
267+
let mut uri = params.text_document_position.text_document.uri;
268+
normalize_uri(&mut uri);
269+
270+
let path = file_path(&uri);
271+
let position = params.text_document_position.position;
272+
273+
let completions = self.session.get_available_completions(path, position).await;
274+
275+
Ok(completions.map(|c| CompletionResponse::List(c)))
276+
}
277+
278+
async fn hover(&self, params: HoverParams) -> Result<Option<Hover>> {
279+
let mut uri = params.text_document_position_params.text_document.uri;
280+
normalize_uri(&mut uri);
281+
282+
let path = file_path(&uri);
283+
let position = params.text_document_position_params.position;
284+
285+
let hover_diagnostics = self
286+
.session
287+
.get_available_hover_diagnostics(path, position)
288+
.await;
289+
290+
Ok(hover_diagnostics)
291+
}
292+
263293
async fn execute_command(
264294
&self,
265295
params: ExecuteCommandParams,

crates/pg_lsp/src/session.rs

Lines changed: 99 additions & 31 deletions
Original file line numberDiff line numberDiff line change
@@ -3,9 +3,13 @@ use std::{collections::HashSet, sync::Arc};
33
use pg_base_db::{Change, DocumentChange, PgLspPath};
44
use pg_commands::ExecuteStatementCommand;
55
use pg_diagnostics::Diagnostic;
6+
use pg_hover::HoverParams;
67
use pg_workspace::Workspace;
78
use tokio::sync::RwLock;
8-
use tower_lsp::lsp_types::{CodeAction, InlayHint, Range};
9+
use tower_lsp::lsp_types::{
10+
CodeAction, CodeActionOrCommand, CompletionItem, CompletionItemKind, CompletionList, Hover,
11+
HoverContents, InlayHint, MarkedString, Position, Range,
12+
};
913

1014
use crate::{db_connection::DbConnection, utils::line_index_ext::LineIndexExt};
1115

@@ -133,21 +137,15 @@ impl Session {
133137
.collect()
134138
}
135139

136-
pub async fn get_available_code_actions(
140+
pub async fn get_available_code_actions_or_commands(
137141
&self,
138142
path: PgLspPath,
139143
range: Range,
140-
) -> Option<Vec<CodeAction>> {
144+
) -> Option<Vec<CodeActionOrCommand>> {
141145
let ide = self.ide.read().await;
142-
let doc = ide.documents.get(&path);
143-
if doc.is_none() {
144-
return None;
145-
}
146+
let doc = ide.documents.get(&path)?;
146147

147-
let db = self.db.read().await;
148-
if db.is_none() {
149-
return None;
150-
}
148+
let db = self.db.read().await?;
151149

152150
let doc = doc.unwrap();
153151
let range = doc.line_index.offset_lsp_range(range).unwrap();
@@ -162,20 +160,11 @@ impl Session {
162160
"Execute '{}'",
163161
ExecuteStatementCommand::trim_statement(stmt.text.clone(), 50)
164162
);
165-
CodeAction {
166-
title: title.clone(),
167-
kind: None,
168-
edit: None,
169-
command: Some(Command {
170-
title,
171-
command: format!("pglsp.{}", cmd.id()),
172-
arguments: Some(vec![serde_json::to_value(stmt.text.clone()).unwrap()]),
173-
}),
174-
diagnostics: None,
175-
is_preferred: None,
176-
disabled: None,
177-
data: None,
178-
}
163+
CodeActionOrCommand::Command(Command {
164+
title,
165+
command: format!("pglsp.{}", cmd.id()),
166+
arguments: Some(vec![serde_json::to_value(stmt.text.clone()).unwrap()]),
167+
})
179168
})
180169
.collect();
181170

@@ -184,13 +173,9 @@ impl Session {
184173

185174
pub async fn get_inlay_hints(&self, path: PgLspPath, range: Range) -> Option<Vec<InlayHint>> {
186175
let ide = self.ide.read().await;
187-
let doc = ide.documents.get(&path);
188-
if doc.is_none() {
189-
return None;
190-
}
176+
let doc = ide.documents.get(&path)?;
191177

192-
let doc = doc.unwrap();
193-
let range = doc.line_index.offset_lsp_range(range).unwrap();
178+
let range = doc.line_index.offset_lsp_range(range)?;
194179

195180
let schema_cache = ide.schema_cache.read().expect("Unable to get Schema Cache");
196181

@@ -235,4 +220,87 @@ impl Session {
235220

236221
Some(hints)
237222
}
223+
224+
pub async fn get_available_completions(
225+
&self,
226+
path: PgLspPath,
227+
position: Position,
228+
) -> Option<CompletionList> {
229+
let ide = self.ide.read().await;
230+
231+
let doc = ide.documents.get(&path)?;
232+
let offset = doc.line_index.offset_lsp(position)?;
233+
let (range, stmt) = doc.statement_at_offset_with_range(&offset)?;
234+
235+
let schema_cache = ide.schema_cache.read().expect("No Schema Cache");
236+
237+
let completion_items = pg_completions::complete(&CompletionParams {
238+
position: pos - range.start() - TextSize::from(1),
239+
text: stmt.text.as_str(),
240+
tree: ide.tree_sitter.tree(&stmt).as_ref().map(|x| x.as_ref()),
241+
schema: &schema,
242+
})
243+
.items
244+
.into_iter()
245+
.map(|i| CompletionItem {
246+
// TODO: add more data
247+
label: i.data.label().to_string(),
248+
label_details: None,
249+
kind: Some(CompletionItemKind::CLASS),
250+
detail: None,
251+
documentation: None,
252+
deprecated: None,
253+
preselect: None,
254+
sort_text: None,
255+
filter_text: None,
256+
insert_text: None,
257+
insert_text_format: None,
258+
insert_text_mode: None,
259+
text_edit: None,
260+
additional_text_edits: None,
261+
commit_characters: None,
262+
data: None,
263+
tags: None,
264+
command: None,
265+
})
266+
.collect();
267+
268+
Some(CompletionList {
269+
is_incomplete: false,
270+
items: completion_items,
271+
})
272+
}
273+
274+
pub async fn get_available_hover_diagnostics(
275+
&self,
276+
path: PgLspPath,
277+
position: Position,
278+
) -> Option<Hover> {
279+
let ide = self.ide.read().await;
280+
let doc = ide.documents.get(&path)?;
281+
282+
let offset = doc.line_index.offset_lsp(position)?;
283+
284+
let (range, stmt) = doc.statement_at_offset_with_range(&offset)?;
285+
let range_start = range.start();
286+
let hover_range = doc.line_index.line_col_lsp_range(range);
287+
288+
let schema_cache = ide.schema_cache.read().expect("No Schema Cache");
289+
290+
::pg_hover::hover(HoverParams {
291+
position: offset - range_start,
292+
source: stmt.text.as_str(),
293+
enriched_ast: ide
294+
.pg_query
295+
.enriched_ast(&stmt)
296+
.as_ref()
297+
.map(|x| x.as_ref()),
298+
tree: ide.tree_sitter.tree(&stmt).as_ref().map(|x| x.as_ref()),
299+
schema_cache: schema_cache.clone(),
300+
})
301+
.map(|hover| Hover {
302+
contents: HoverContents::Scalar(MarkedString::String(hover.content)),
303+
range: hover_range,
304+
})
305+
}
238306
}

0 commit comments

Comments
 (0)