|
| 1 | +open Import |
| 2 | + |
| 3 | +let action_kind = "refactor-extract (extract an area into a fresh let binding)" |
| 4 | + |
| 5 | +let make_edit params doc { Query_protocol.loc; content; selection_range = _ } = |
| 6 | + let uri = params.CodeActionParams.textDocument.uri in |
| 7 | + let textDocument = |
| 8 | + OptionalVersionedTextDocumentIdentifier.create ~uri ~version:(Document.version doc) () |
| 9 | + in |
| 10 | + let textedit = TextEdit.create ~newText:content ~range:(Range.of_loc loc) in |
| 11 | + let edit = TextDocumentEdit.create ~textDocument ~edits:[ `TextEdit textedit ] in |
| 12 | + WorkspaceEdit.create ~documentChanges:[ `TextDocumentEdit edit ] () |
| 13 | +;; |
| 14 | + |
| 15 | +let dispatch_command pipeline doc ~start ~stop = |
| 16 | + let buffer = Document.source doc in |
| 17 | + let command = Query_protocol.Refactor_extract_region (start, stop, None, buffer) in |
| 18 | + Query_commands.dispatch pipeline command |
| 19 | +;; |
| 20 | + |
| 21 | +let code_action doc (params : CodeActionParams.t) = |
| 22 | + match Document.kind doc with |
| 23 | + | `Other -> Fiber.return None |
| 24 | + | `Merlin m when Document.Merlin.kind m = Intf -> Fiber.return None |
| 25 | + | `Merlin merlin -> |
| 26 | + let start = Position.logical params.range.Range.start in |
| 27 | + let stop = Position.logical params.range.Range.end_ in |
| 28 | + Document.Merlin.with_pipeline_exn ~name:"refactor" merlin (fun pipeline -> |
| 29 | + let typer = Mpipeline.typer_result pipeline in |
| 30 | + let typedtree = Mtyper.get_typedtree typer in |
| 31 | + match typedtree with |
| 32 | + | `Interface _ -> None |
| 33 | + | `Implementation structure -> |
| 34 | + let enclosing = |
| 35 | + Mbrowse.enclosing |
| 36 | + (Mpipeline.get_lexing_pos pipeline start) |
| 37 | + [ Mbrowse.of_typedtree typedtree ] |
| 38 | + in |
| 39 | + if |
| 40 | + Merlin_analysis.Refactor_extract_region.is_region_extractable |
| 41 | + ~start:(Mpipeline.get_lexing_pos pipeline start) |
| 42 | + ~stop:(Mpipeline.get_lexing_pos pipeline stop) |
| 43 | + enclosing |
| 44 | + structure |
| 45 | + then ( |
| 46 | + let substitution = dispatch_command pipeline doc ~start ~stop in |
| 47 | + let edit = make_edit params doc substitution in |
| 48 | + let code_action = |
| 49 | + CodeAction.create |
| 50 | + ~title:"Extract expression" |
| 51 | + ~kind:(CodeActionKind.Other action_kind) |
| 52 | + ~edit |
| 53 | + () |
| 54 | + in |
| 55 | + Some code_action) |
| 56 | + else None) |
| 57 | +;; |
| 58 | + |
| 59 | +let t = Code_action.non_batchable (Other action_kind) code_action |
0 commit comments