1
+ use std:: fmt:: Write ;
1
2
use std:: str:: FromStr ;
2
3
3
4
use crate :: edit:: WorkspaceEditTracker ;
4
5
use crate :: server:: api:: LSPResult ;
5
6
use crate :: server:: schedule:: Task ;
6
7
use crate :: server:: { client, SupportedCommand } ;
7
8
use crate :: session:: Session ;
8
- use crate :: DIAGNOSTIC_NAME ;
9
9
use crate :: { edit:: DocumentVersion , server} ;
10
+ use crate :: { DocumentKey , DIAGNOSTIC_NAME } ;
10
11
use lsp_server:: ErrorCode ;
11
- use lsp_types:: { self as types, request as req} ;
12
+ use lsp_types:: { self as types, request as req, TextDocumentIdentifier } ;
12
13
use serde:: Deserialize ;
13
14
14
15
pub ( crate ) struct ExecuteCommand ;
@@ -19,6 +20,17 @@ struct Argument {
19
20
version : DocumentVersion ,
20
21
}
21
22
23
+ /// The argument schema for the `ruff.printDebugInformation` command.
24
+ #[ derive( Default , Deserialize ) ]
25
+ #[ serde( rename_all = "camelCase" ) ]
26
+ struct DebugCommandArgument {
27
+ /// The URI of the document to print debug information for.
28
+ ///
29
+ /// When provided, both document-specific debug information and global information are printed.
30
+ /// If not provided ([None]), only global debug information is printed.
31
+ text_document : Option < TextDocumentIdentifier > ,
32
+ }
33
+
22
34
impl super :: RequestHandler for ExecuteCommand {
23
35
type RequestType = req:: ExecuteCommand ;
24
36
}
@@ -34,7 +46,12 @@ impl super::SyncRequestHandler for ExecuteCommand {
34
46
. with_failure_code ( ErrorCode :: InvalidParams ) ?;
35
47
36
48
if command == SupportedCommand :: Debug {
37
- let output = debug_information ( session) ;
49
+ let argument: DebugCommandArgument = params. arguments . into_iter ( ) . next ( ) . map_or_else (
50
+ || Ok ( DebugCommandArgument :: default ( ) ) ,
51
+ |value| serde_json:: from_value ( value) . with_failure_code ( ErrorCode :: InvalidParams ) ,
52
+ ) ?;
53
+ let output = debug_information ( session, argument. text_document )
54
+ . with_failure_code ( ErrorCode :: InternalError ) ?;
38
55
notifier
39
56
. notify :: < types:: notification:: LogMessage > ( types:: LogMessageParams {
40
57
message : output. clone ( ) ,
@@ -134,23 +151,71 @@ fn apply_edit(
134
151
)
135
152
}
136
153
137
- fn debug_information ( session : & Session ) -> String {
154
+ /// Returns a string with debug information about the session and the document at the given URI.
155
+ fn debug_information (
156
+ session : & Session ,
157
+ text_document : Option < TextDocumentIdentifier > ,
158
+ ) -> crate :: Result < String > {
138
159
let executable = std:: env:: current_exe ( )
139
160
. map ( |path| format ! ( "{}" , path. display( ) ) )
140
161
. unwrap_or_else ( |_| "<unavailable>" . to_string ( ) ) ;
141
- format ! (
142
- "executable = {executable}
162
+
163
+ let mut buffer = String :: new ( ) ;
164
+
165
+ writeln ! (
166
+ buffer,
167
+ "Global:
168
+ executable = {executable}
143
169
version = {version}
144
- encoding = {encoding:?}
145
- open_document_count = {doc_count}
146
- active_workspace_count = {workspace_count}
147
- configuration_files = {config_files:?}
148
- {client_capabilities}" ,
170
+ position_encoding = {encoding:?}
171
+ workspace_root_folders = {workspace_folders:#?}
172
+ indexed_configuration_files = {config_files:#?}
173
+ open_documents_len = {open_documents_len}
174
+ client_capabilities = {client_capabilities:#?}
175
+ " ,
149
176
version = crate :: version( ) ,
150
177
encoding = session. encoding( ) ,
178
+ workspace_folders = session. workspace_root_folders( ) . collect:: <Vec <_>>( ) ,
179
+ config_files = session. config_file_paths( ) . collect:: <Vec <_>>( ) ,
180
+ open_documents_len = session. open_documents_len( ) ,
151
181
client_capabilities = session. resolved_client_capabilities( ) ,
152
- doc_count = session. num_documents( ) ,
153
- workspace_count = session. num_workspaces( ) ,
154
- config_files = session. list_config_files( )
155
- )
182
+ ) ?;
183
+
184
+ if let Some ( TextDocumentIdentifier { uri } ) = text_document {
185
+ let Some ( snapshot) = session. take_snapshot ( uri. clone ( ) ) else {
186
+ writeln ! ( buffer, "Unable to take a snapshot of the document at {uri}" ) ?;
187
+ return Ok ( buffer) ;
188
+ } ;
189
+ let query = snapshot. query ( ) ;
190
+
191
+ writeln ! (
192
+ buffer,
193
+ "Open document:
194
+ uri = {uri}
195
+ kind = {kind}
196
+ version = {version}
197
+ client_settings = {client_settings:#?}
198
+ config_path = {config_path:?}
199
+ {settings}
200
+ " ,
201
+ uri = uri. clone( ) ,
202
+ kind = match session. key_from_url( uri) {
203
+ DocumentKey :: Notebook ( _) => "Notebook" ,
204
+ DocumentKey :: NotebookCell ( _) => "NotebookCell" ,
205
+ DocumentKey :: Text ( _) => "Text" ,
206
+ } ,
207
+ version = query. version( ) ,
208
+ client_settings = snapshot. client_settings( ) ,
209
+ config_path = query. settings( ) . path( ) ,
210
+ settings = query. settings( ) ,
211
+ ) ?;
212
+ } else {
213
+ writeln ! (
214
+ buffer,
215
+ "global_client_settings = {:#?}" ,
216
+ session. global_client_settings( )
217
+ ) ?;
218
+ }
219
+
220
+ Ok ( buffer)
156
221
}
0 commit comments