@@ -4,7 +4,7 @@ use log::info;
44use lsp_server:: { Connection , Message , Notification , Response } ;
55use lsp_types:: {
66 CodeAction , CodeActionKind , CodeActionOptions , CodeActionOrCommand , CodeActionParams ,
7- CodeActionProviderCapability , CodeActionResponse , CodeDescription , Diagnostic ,
7+ CodeActionProviderCapability , CodeActionResponse , CodeDescription , Command , Diagnostic ,
88 DiagnosticSeverity , DidChangeTextDocumentParams , DidCloseTextDocumentParams ,
99 DidOpenTextDocumentParams , GotoDefinitionParams , GotoDefinitionResponse , InitializeParams ,
1010 Location , Position , PublishDiagnosticsParams , Range , ServerCapabilities ,
@@ -142,6 +142,8 @@ fn handle_goto_definition(connection: &Connection, req: lsp_server::Request) ->
142142 Ok ( ( ) )
143143}
144144
145+ const DIAGNOSTIC_NAME : & str = "squawk" ;
146+
145147fn handle_code_action (
146148 connection : & Connection ,
147149 req : lsp_server:: Request ,
@@ -152,7 +154,41 @@ fn handle_code_action(
152154
153155 let mut actions = Vec :: new ( ) ;
154156
155- for mut diagnostic in params. context . diagnostics {
157+ for mut diagnostic in params
158+ . context
159+ . diagnostics
160+ . into_iter ( )
161+ . filter ( |diagnostic| diagnostic. source . as_deref ( ) == Some ( DIAGNOSTIC_NAME ) )
162+ {
163+ if let Some ( code) = diagnostic. code . as_ref ( ) {
164+ let rule_name = match code {
165+ lsp_types:: NumberOrString :: String ( s) => s. clone ( ) ,
166+ lsp_types:: NumberOrString :: Number ( n) => n. to_string ( ) ,
167+ } ;
168+
169+ let title = format ! ( "Show documentation for {}" , rule_name) ;
170+
171+ let documentation_action = CodeAction {
172+ title : title. clone ( ) ,
173+ kind : Some ( CodeActionKind :: QUICKFIX ) ,
174+ diagnostics : Some ( vec ! [ diagnostic. clone( ) ] ) ,
175+ edit : None ,
176+ command : Some ( Command {
177+ title,
178+ command : "vscode.open" . to_string ( ) ,
179+ arguments : Some ( vec ! [ serde_json:: to_value( format!(
180+ "https://squawkhq.com/docs/{}" ,
181+ rule_name
182+ ) ) ?] ) ,
183+ } ) ,
184+ is_preferred : Some ( false ) ,
185+ disabled : None ,
186+ data : None ,
187+ } ;
188+
189+ actions. push ( CodeActionOrCommand :: CodeAction ( documentation_action) ) ;
190+ }
191+
156192 if let Some ( data) = diagnostic. data . take ( ) {
157193 let associated_data: AssociatedDiagnosticData =
158194 serde_json:: from_value ( data) . context ( "deserializing diagnostic data" ) ?;
@@ -328,7 +364,7 @@ fn lint(content: &str) -> Vec<Diagnostic> {
328364 code_description : Some ( CodeDescription {
329365 href : Url :: parse ( "https://squawkhq.com/docs/syntax-error" ) . unwrap ( ) ,
330366 } ) ,
331- source : Some ( "squawk" . to_string ( ) ) ,
367+ source : Some ( DIAGNOSTIC_NAME . to_string ( ) ) ,
332368 message : error. message ( ) . to_string ( ) ,
333369 ..Default :: default ( )
334370 } ;
@@ -378,7 +414,7 @@ fn lint(content: &str) -> Vec<Diagnostic> {
378414 code_description : Some ( CodeDescription {
379415 href : Url :: parse ( & format ! ( "https://squawkhq.com/docs/{}" , violation. code) ) . unwrap ( ) ,
380416 } ) ,
381- source : Some ( "squawk" . to_string ( ) ) ,
417+ source : Some ( DIAGNOSTIC_NAME . to_string ( ) ) ,
382418 message : violation. message ,
383419 data : data. map ( |d| serde_json:: to_value ( d) . unwrap ( ) ) ,
384420 ..Default :: default ( )
0 commit comments