@@ -35,10 +35,7 @@ pub struct Session {
3535 /// but not the database (which is owned directly by Session).
3636 workspace : Workspace ,
3737
38- client_capabilities : lsp_types:: ClientCapabilities ,
39-
40- /// Position encoding negotiated with client
41- position_encoding : PositionEncoding ,
38+ client_capabilities : ClientCapabilities ,
4239
4340 /// The Salsa database for incremental computation
4441 db : DjangoDatabase ,
@@ -68,12 +65,16 @@ impl Session {
6865
6966 Self {
7067 workspace,
71- client_capabilities : params. capabilities . clone ( ) ,
72- position_encoding : negotiate_position_encoding ( & params. capabilities ) ,
68+ client_capabilities : ClientCapabilities :: negotiate ( & params. capabilities ) ,
7369 db,
7470 }
7571 }
7672
73+ #[ must_use]
74+ pub fn client_capabilities ( & self ) -> ClientCapabilities {
75+ self . client_capabilities
76+ }
77+
7778 #[ must_use]
7879 pub fn db ( & self ) -> & DjangoDatabase {
7980 & self . db
@@ -83,11 +84,6 @@ impl Session {
8384 self . db . set_settings ( settings) ;
8485 }
8586
86- #[ must_use]
87- pub fn position_encoding ( & self ) -> PositionEncoding {
88- self . position_encoding
89- }
90-
9187 /// Execute a read-only operation with access to the database.
9288 pub fn with_db < F , R > ( & self , f : F ) -> R
9389 where
@@ -104,11 +100,6 @@ impl Session {
104100 f ( & mut self . db )
105101 }
106102
107- /// Get a reference to the database for project operations.
108- pub fn database ( & self ) -> & DjangoDatabase {
109- & self . db
110- }
111-
112103 /// Get the current project for this session
113104 pub fn project ( & self ) -> Option < djls_project:: Project > {
114105 self . db . project ( )
@@ -180,7 +171,7 @@ impl Session {
180171 & path,
181172 doc_changes,
182173 text_document. version ,
183- self . position_encoding ,
174+ self . client_capabilities . position_encoding ( ) ,
184175 ) ?;
185176
186177 self . handle_file ( document. file ( ) ) ;
@@ -219,60 +210,77 @@ impl Session {
219210 }
220211 }
221212 }
213+ }
222214
223- /// Check if the client supports pull diagnostics.
224- ///
225- /// Returns true if the client has indicated support for textDocument/diagnostic requests.
226- /// When true, the server should not push diagnostics and instead wait for pull requests.
227- #[ must_use]
228- pub fn supports_pull_diagnostics ( & self ) -> bool {
229- self . client_capabilities
215+ impl Default for Session {
216+ fn default ( ) -> Self {
217+ Self :: new ( & lsp_types:: InitializeParams :: default ( ) )
218+ }
219+ }
220+
221+ #[ derive( Debug , Clone , Copy ) ]
222+ pub struct ClientCapabilities {
223+ pull_diagnostics : bool ,
224+ snippets : bool ,
225+ position_encoding : PositionEncoding ,
226+ }
227+
228+ impl ClientCapabilities {
229+ fn negotiate ( capabilities : & lsp_types:: ClientCapabilities ) -> Self {
230+ let pull_diagnostics = capabilities
230231 . text_document
231232 . as_ref ( )
232- . and_then ( |td| td. diagnostic . as_ref ( ) )
233- . is_some ( )
234- }
233+ . and_then ( |text_doc| text_doc. diagnostic . as_ref ( ) )
234+ . is_some ( ) ;
235235
236- /// Check if the client supports snippet completions
237- #[ must_use]
238- pub fn supports_snippets ( & self ) -> bool {
239- self . client_capabilities
236+ let snippets = capabilities
240237 . text_document
241238 . as_ref ( )
242- . and_then ( |td| td. completion . as_ref ( ) )
243- . and_then ( |c| c. completion_item . as_ref ( ) )
244- . and_then ( |ci| ci. snippet_support )
245- . unwrap_or ( false )
239+ . and_then ( |text_document| text_document. completion . as_ref ( ) )
240+ . and_then ( |completion| completion. completion_item . as_ref ( ) )
241+ . and_then ( |completion_item| completion_item. snippet_support )
242+ . unwrap_or ( false ) ;
243+
244+ let client_encodings = capabilities
245+ . general
246+ . as_ref ( )
247+ . and_then ( |general| general. position_encodings . as_ref ( ) )
248+ . map_or ( & [ ] [ ..] , |kinds| kinds. as_slice ( ) ) ;
249+
250+ let position_encoding = [
251+ PositionEncoding :: Utf8 ,
252+ PositionEncoding :: Utf32 ,
253+ PositionEncoding :: Utf16 ,
254+ ]
255+ . into_iter ( )
256+ . find ( |& preferred| {
257+ client_encodings
258+ . iter ( )
259+ . any ( |kind| kind. to_position_encoding ( ) == Some ( preferred) )
260+ } )
261+ . unwrap_or ( PositionEncoding :: Utf16 ) ;
262+
263+ Self {
264+ pull_diagnostics,
265+ snippets,
266+ position_encoding,
267+ }
246268 }
247- }
248269
249- impl Default for Session {
250- fn default ( ) -> Self {
251- Self :: new ( & lsp_types :: InitializeParams :: default ( ) )
270+ # [ must_use ]
271+ pub fn supports_pull_diagnostics ( & self ) -> bool {
272+ self . pull_diagnostics
252273 }
253- }
254274
255- fn negotiate_position_encoding ( capabilities : & lsp_types:: ClientCapabilities ) -> PositionEncoding {
256- let client_encodings = capabilities
257- . general
258- . as_ref ( )
259- . and_then ( |general| general. position_encodings . as_ref ( ) )
260- . map_or ( & [ ] [ ..] , |encodings| encodings. as_slice ( ) ) ;
261-
262- for preferred in [
263- PositionEncoding :: Utf8 ,
264- PositionEncoding :: Utf32 ,
265- PositionEncoding :: Utf16 ,
266- ] {
267- if client_encodings
268- . iter ( )
269- . any ( |kind| kind. to_position_encoding ( ) == Some ( preferred) )
270- {
271- return preferred;
272- }
275+ #[ must_use]
276+ pub fn supports_snippets ( & self ) -> bool {
277+ self . snippets
273278 }
274279
275- PositionEncoding :: Utf16
280+ #[ must_use]
281+ pub fn position_encoding ( & self ) -> PositionEncoding {
282+ self . position_encoding
283+ }
276284}
277285
278286#[ cfg( test) ]
@@ -367,7 +375,7 @@ mod tests {
367375 ..Default :: default ( )
368376 } ;
369377 assert_eq ! (
370- negotiate_position_encoding ( & capabilities) ,
378+ ClientCapabilities :: negotiate ( & capabilities) . position_encoding ( ) ,
371379 PositionEncoding :: Utf8
372380 ) ;
373381 }
@@ -385,7 +393,7 @@ mod tests {
385393 ..Default :: default ( )
386394 } ;
387395 assert_eq ! (
388- negotiate_position_encoding ( & capabilities) ,
396+ ClientCapabilities :: negotiate ( & capabilities) . position_encoding ( ) ,
389397 PositionEncoding :: Utf32
390398 ) ;
391399 }
@@ -403,7 +411,7 @@ mod tests {
403411 ..Default :: default ( )
404412 } ;
405413 assert_eq ! (
406- negotiate_position_encoding ( & capabilities) ,
414+ ClientCapabilities :: negotiate ( & capabilities) . position_encoding ( ) ,
407415 PositionEncoding :: Utf16
408416 ) ;
409417 }
@@ -412,7 +420,7 @@ mod tests {
412420 fn test_negotiate_fallback_with_no_capabilities ( ) {
413421 let capabilities = lsp_types:: ClientCapabilities :: default ( ) ;
414422 assert_eq ! (
415- negotiate_position_encoding ( & capabilities) ,
423+ ClientCapabilities :: negotiate ( & capabilities) . position_encoding ( ) ,
416424 PositionEncoding :: Utf16
417425 ) ;
418426 }
0 commit comments