@@ -3,9 +3,13 @@ use std::{collections::HashSet, sync::Arc};
33use pg_base_db:: { Change , DocumentChange , PgLspPath } ;
44use pg_commands:: ExecuteStatementCommand ;
55use pg_diagnostics:: Diagnostic ;
6+ use pg_hover:: HoverParams ;
67use pg_workspace:: Workspace ;
78use 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
1014use 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