# Providing Code Completions

A code completion is used by clients to provide a set of possible completions to
partially entered code. Completions are intended to address two use cases: to
help users enter code with less effort and to help users discover the behavior
of an object.

For example, if the user has typed `o.toSt` and then requested completions, one
suggestion might be `toString`.

That said, the completion suggestions that your plugin returns should include
all of the options that would be valid if the partial identifier did not exist.
The reason is that most clients are implemented such that they send a single
request for completions when the dialog with the user begins and cannot send any
subsequent requests. If the user presses the backspace key during the dialog the
client needs to have already received the expanded list of options that now
match the prefix (or all options if the prefix has completely been deleted).
Clients will filter the list of suggestions displayed as appropriate.

Hence, in the example above, plugins should return suggestions as if the user
had requested completions after typing `o.`;

## Implementation details

When appropriate, the analysis server will send your plugin a
`completion.getSuggestions` request. The request includes the `file` and
`offset` at which completions are being requested.

When a `completion.getSuggestions` request is received, the method
`handleCompletionGetSuggestions` will be invoked. This method is responsible for
returning a response that contains the available suggestions.

The easiest way to implement this method is by adding the classes
`CompletionMixin` and `DartCompletionMixin` (from
`package:analyzer_plugin/plugin/completion_mixin.dart`) to the list of mixins
for your subclass of `ServerPlugin`. This will leave you with one abstract
method that you need to implement: `getCompletionContributors`. That method is
responsible for returning a list of `CompletionContributor`s. It is the
completion contributors that produce the actual completion suggestions. (Most
plugins will only need a single completion contributor.)

To write a completion contributor, create a class that implements
`CompletionContributor`. The interface defines a single method named
`computeSuggestions`. The method has two arguments: a `CompletionRequest` that
describes the where completions are being requested and a `CompletionCollector`
through which suggestions are to be added.

If you mix in the class `DartCompletionMixin`, then the request will be an
instance of `DartCompletionRequest`, which also has analysis results.

## Example

Start by creating a class that implements `CompletionContributor`, then
implement the method `computeSuggestions`. Your contributor should invoke the
method `checkAborted`, defined on the `CompletionRequest` object, before
starting any slow work. This allows the computation of completion suggestions
to be preempted if the client no longer needs the results.

For example, your contributor might look something like the following:

```dart
class MyCompletionContributor implements CompletionContributor {
  @override
  Future<void> computeSuggestions(DartCompletionRequest request,
      CompletionCollector collector) async {
    // ...
  }
}
```

Given a contributor like the one above, you can implement your plugin similar to
the following:

```dart
class MyPlugin extends ServerPlugin with CompletionMixin, DartCompletionMixin {
  // ...

  @override
  List<CompletionContributor> getCompletionContributors(
      AnalysisDriverGeneric driver) {
    return <CompletionContributor>[new MyCompletionContributor()];
  }
}
```
