OLD | NEW |
(Empty) | |
| 1 # Providing Code Completions |
| 2 |
| 3 A code completion is used by clients to provide a set of possible completions to |
| 4 partially entered code. Completions are intended to address two use cases: to |
| 5 help users enter code with less effort and to help users discover the behavior |
| 6 of an object. |
| 7 |
| 8 For example, if the user has typed `o.toSt` and then requested completions, one |
| 9 suggestion might be `toString`. |
| 10 |
| 11 That said, the completion suggestions that your plugin returns should include |
| 12 all of the options that would be valid if the partial identifier did not exist. |
| 13 The reason is that most clients are implemented such that they send a single |
| 14 request for completions when the dialog with the user begins and cannot send any |
| 15 subsequent requests. If the user presses the backspace key during the dialog the |
| 16 client needs to have already received the expanded list of options that now |
| 17 match the prefix (or all options if the prefix has completely been deleted). |
| 18 Clients will filter the list of suggestions displayed as appropriate. |
| 19 |
| 20 Hence, in the example above, plugins should return suggestions as if the user |
| 21 had requested completions after typing `o.`; |
| 22 |
| 23 ## Implementation details |
| 24 |
| 25 When appropriate, the analysis server will send your plugin a |
| 26 `completion.getSuggestions` request. The request includes the `file` and |
| 27 `offset` at which completions are being requested. |
| 28 |
| 29 When a `completion.getSuggestions` request is received, the method |
| 30 `handleCompletionGetSuggestions` will be invoked. This method is responsible for |
| 31 returning a response that contains the available suggestions. |
| 32 |
| 33 The easiest way to implement this method is by adding the classes |
| 34 `CompletionMixin` and `DartCompletionMixin` (from |
| 35 `package:analyzer_plugin/plugin/completion_mixin.dart`) to the list of mixins |
| 36 for your subclass of `ServerPlugin`. This will leave you with one abstract |
| 37 method that you need to implement: `getCompletionContributors`. That method is |
| 38 responsible for returning a list of `CompletionContributor`s. It is the |
| 39 completion contributors that produce the actual completion suggestions. (Most |
| 40 plugins will only need a single completion contributor.) |
| 41 |
| 42 To write a completion contributor, create a class that implements |
| 43 `CompletionContributor`. The interface defines a single method named |
| 44 `computeSuggestions`. The method has two arguments: a `CompletionRequest` that |
| 45 describes the where completions are being requested and a `CompletionCollector` |
| 46 through which suggestions are to be added. |
| 47 |
| 48 ## Example |
| 49 |
| 50 Start by creating a class that implements `CompletionContributor`, then |
| 51 implement the method `computeSuggestions`. Your contributor should invoke the |
| 52 method `checkAborted`, defined on the `CompletionRequest` object, before |
| 53 starting any slow work. This allows the computation of completion suggestions |
| 54 to be preempted if the client no longer needs the results. |
| 55 |
| 56 For example, your contributor might look something like the following: |
| 57 |
| 58 ```dart |
| 59 class MyCompletionContributor implements CompletionContributor { |
| 60 @override |
| 61 Future<Null> computeSuggestions(covariant DartCompletionRequest request, |
| 62 CompletionCollector collector) async { |
| 63 // ... |
| 64 } |
| 65 } |
| 66 ``` |
| 67 |
| 68 Given a contributor like the one above, you can implement your plugin similar to |
| 69 the following: |
| 70 |
| 71 ```dart |
| 72 class MyPlugin extends ServerPlugin with CompletionMixin, DartCompletionMixin { |
| 73 // ... |
| 74 |
| 75 @override |
| 76 List<CompletionContributor> getCompletionContributors( |
| 77 covariant AnalysisDriverGeneric driver) { |
| 78 return <CompletionContributor>[new MyCompletionContributor()]; |
| 79 } |
| 80 } |
| 81 ``` |
OLD | NEW |