Language Server Protocol (LSP) support is available in the Dart analysis server from version 2.2.0 of the SDK (which was included in version 1.2.1 of Flutter). The supported messages are detailed below (for the version of the SDK that matches this README).
Start the language server using the dart language-server
command. Pass the --client-id
and --client-version
flags to identify your editor/plugin and version:
dart language-server --client-id my-editor.my-plugin --client-version 1.2
Note: In LSP the client makes the first request so there is no obvious confirmation that the server is working correctly until the client sends an initialize
request. Unlike standard JSON RPC, LSP requires that headers are sent.
When there are no open workspace folders (or if the initialization option onlyAnalyzeProjectsWithOpenFiles
is set to true
), analysis will be performed based on project folders located by the open files. For each open file, the project root will be located, and that whole project analyzed. If the file does not have a project (eg. there is no pubspec.yaml in its ancestor folders) then the file will be analyzed in isolation.
onlyAnalyzeProjectsWithOpenFiles
(bool?
): When set totrue
, workspace folders will be ignored and analysis will be performed based on the open files, as if no workspace was open at all. This allows opening large folders without causing them to be completely analyzed. Defaults tofalse
.suggestFromUnimportedLibraries
(bool?
): When set tofalse
, completion will not include symbols that are not already imported into the current file. Defaults totrue
, though the client must additionally supportworkspace/applyEdit
for these completions to be included.closingLabels
(bool?
): When set totrue
,dart/textDocument/publishClosingLabels
notifications will be sent with information to render editor closing labels.outline
(bool?
): When set totrue
,dart/textDocument/publishOutline
notifications will be sent with outline information for open files.flutterOutline
(bool?
): When set totrue
,dart/textDocument/publishFlutterOutline
notifications will be sent with Flutter outline information for open files.allowOpenUri
: When set totrue
, indicates that the client will handledart/openUri
notifications by opening a browser for the supplied URI.
Client workspace settings are requested with workspace/configuration
during initialization and re-requested whenever the client notifies the server with workspace/didChangeConfiguration
. This allows the settings to take effect without restarting the server.
dart.analysisExcludedFolders
(List<String>?
): An array of paths (absolute or relative to each workspace folder) that should be excluded from analysis.dart.enableSdkFormatter
(bool?
): When set tofalse
, prevents registration (or unregisters) the SDK formatter. When set totrue
or not supplied, will register/reregister the SDK formatter.dart.lineLength
(int?
): Sets a default value for the formatter to wrap code at if no value is specified informatter.page_width
inanalysis_options.yaml
. If unspecified by both, code will be wrapped at80
characters.dart.completeFunctionCalls
(bool?
): When set to true, completes functions/methods with their required parameters.dart.showTodos
(bool?
): Whether to generate diagnostics for TODO comments. If unspecified, diagnostics will not be generated.dart.renameFilesWithClasses
(String
): When set to"always"
, will include edits to rename files when classes are renamed if the filename matches the class name (but in snake_form). When set to"prompt"
, a prompt will be shown on each class rename asking to confirm the file rename. Otherwise, files will not be renamed. Renames are performed using LSP's ResourceOperation edits - that means the rename is simply included in the resultingWorkspaceEdit
and must be handled by the client.dart.enableSnippets
(bool?
): Whether to include code snippets (such asclass
,stful
,switch
) in code completion. When unspecified, snippets will be included.dart.updateImportsOnRename
(bool?
): Whether to update imports and other directives when files are renamed. When unspecified, imports will be updated if the client supportswillRenameFiles
requests.dart.documentation
(none
,summary
orfull
): The typekind of dartdocs to include in Hovers, Code Completion, Signature Help and other similar requests. If not set, defaults tofull
.dart.includeDependenciesInWorkspaceSymbols
(bool?
): Whether to include symbols from dependencies and Dart/Flutter SDKs in Workspace Symbol results. If not set, defaults totrue
.
Below is a list of LSP methods and their implementation status.
- Method: The LSP method name
- Basic Impl: This method has an implementation but may assume some client capabilities
- Capabilities: Only types from the original spec or as advertised in client capabilities are returned
- Plugins: This functionality works with server plugins
- Tests: Has automated tests
- Tested Client: Has been manually tested in at least one LSP client editor
Method | Server | Plugins | Notes |
---|---|---|---|
initialize | ✅ | N/A | trace and other options NYI |
initialized | ✅ | N/A | |
shutdown | ✅ | N/A | supported but does nothing |
exit | ✅ | N/A | |
$/cancelRequest | ✅ | ||
$/logTrace | |||
$/progress | |||
$/setTrace | |||
client/registerCapability | ✅ | ✅ | |
client/unregisterCapability | ✅ | ✅ | |
notebookDocument/* | |||
telemetry/event | |||
textDocument/codeAction (assists) | ✅ | ✅ | Only if the client advertises codeActionLiteralSupport with Refactor |
textDocument/codeAction (fixAll) | ✅ | ||
textDocument/codeAction (fixes) | ✅ | ✅ | Only if the client advertises codeActionLiteralSupport with QuickFix |
textDocument/codeAction (organiseImports) | ✅ | ||
textDocument/codeAction (refactors) | ✅ | ||
textDocument/codeAction (sortMembers) | ✅ | ||
codeAction/resolve | |||
textDocument/codeLens | ✅ | ||
codeLens/resolve | |||
textDocument/completion | ✅ | ✅ | |
completionItem/resolve | ✅ | ||
textDocument/declaration | |||
textDocument/definition | ✅ | ✅ | |
textDocument/diagnostic | |||
textDocument/didChange | ✅ | ✅ | |
textDocument/didClose | ✅ | ✅ | |
textDocument/didOpen | ✅ | ✅ | |
textDocument/didSave | |||
textDocument/documentColor | ✅ | ||
textDocument/colorPresentation | ✅ | ||
textDocument/documentHighlight | ✅ | ||
textDocument/documentLink | ✅ | ||
documentLink/resolve | |||
textDocument/documentSymbol | ✅ | ||
textDocument/foldingRange | ✅ | ✅ | |
textDocument/formatting | ✅ | ||
textDocument/onTypeFormatting | ✅ | ||
textDocument/rangeFormatting | ✅ | ||
textDocument/hover | ✅ | ||
textDocument/implementation | ✅ | ||
textDocument/inlayHint | ✅ | ||
inlayHint/resolve | |||
textDocument/inlineValue | |||
textDocument/linkedEditingRange | |||
textDocument/moniker | |||
textDocument/prepareCallHierarchy | ✅ | ||
callHierarchy/incomingCalls | ✅ | ||
callHierarchy/outgoingCalls | ✅ | ||
textDocument/prepareRename | ✅ | ||
textDocument/rename | ✅ | ||
textDocument/prepareTypeHierarchy | ✅ | ||
typeHierarchy/subtypes | ✅ | ||
typeHierarchy/supertypes | ✅ | ||
textDocument/publishDiagnostics | ✅ | ✅ | |
textDocument/references | ✅ | ||
textDocument/selectionRange | ✅ | ||
textDocument/semanticTokens/full | ✅ | ✅ | |
textDocument/semanticTokens/full/delta | |||
textDocument/semanticTokens/range | ✅ | ✅ | |
workspace/semanticTokens/refresh | |||
textDocument/signatureHelp | ✅ | ||
textDocument/typeDefinition | ✅ | ||
textDocument/willSave | |||
textDocument/willSaveWaitUntil | |||
window/logMessage | ✅ | ||
window/showDocument | |||
window/showMessage | ✅ | ||
window/showMessageRequest | |||
window/workDoneProgress/cancel | |||
window/workDoneProgress/create | ✅ | ||
workspace/applyEdit | ✅ | ||
workspace/codeLens/refresh | |||
workspace/configuration | ✅ | ||
workspace/diagnostic | |||
workspace/diagnostic/refresh | |||
workspace/didChangeConfiguration | ✅ | ||
workspace/didChangeWatchedFiles | unused, server does own watching | ||
workspace/didChangeWorkspaceFolders | ✅ | ✅ | |
workspace/didCreateFiles | |||
workspace/didDeleteFiles | |||
workspace/didRenameFiles | |||
workspace/executeCommand | ✅ | ||
workspace/inlayHint/refresh | |||
workspace/inlineValue/refresh | |||
workspace/symbol | ✅ | ||
workspaceSymbol/resolve | |||
workspace/willCreateFiles | |||
workspace/willDeleteFiles | |||
workspace/willRenameFiles | |||
workspace/willRenameFiles | ✅ | ||
workspace/workspaceFolders |
The following custom fields/methods/notifications are also provided by the Dart LSP server:
The server accepts an optional int?
on all incoming messages named clientRequestTime
(alongside id
, method
, params
) containing a timestamp (milliseconds since epoch) of when the client made that request. Providing clientRequestTime helps track how responsive analysis server is to client requests and better address any issues that occur.
Direction: Client -> Server
Params: None
Returns: { port: number }
Starts the analyzer diagnostics server (if not already running) and returns the port number it's listening on.
Direction: Client -> Server Params: None Returns: None
Forces re-reading of all potentially changed files, re-resolving of all referenced URIs, and corresponding re-analysis of everything affected in the current analysis roots. Clients should not usually need to call this method - needing to do so may indicate a bug in the server.
Direction: Client -> Server
Params: TextDocumentPositionParams
Returns: Location | null
Returns the location of the super definition of the class or method at the provided position or null
if there isn't one.
Direction: Client -> Server
Params: TextDocumentPositionParams
Returns: Location[] | null
Returns the location(s) of the import directive(s) that expose the element at the provided position or null
if there isn't one.
Direction: Client -> Server
Params: TextDocumentPositionParams
Returns: Location | null
Returns the location of the declaration that is augmented at the provided position or null
if the position is not an augmentation.
Direction: Client -> Server
Params: TextDocumentPositionParams
Returns: Location | null
Returns the location of the augmentation for the declaration at the provided position or null
if declaration is not augmented.
Direction: Server -> Client
Params: { isAnalyzing: boolean }
Notifies the client when analysis starts/completes.
This notification is not sent if the client capabilities include window.workDoneProgress == true
because analyzing status events will be sent using $/progress
.
This notification may be removed in a future Dart SDK release and should not be depended on.
Direction: Server -> Client
Params: { uri: string, labels: { label: string, range: Range }[] }
Notifies the client when closing label information is available (or updated) for a file.
Direction: Server -> Client
Params: { uri: string, outline: Outline }
Outline: { element: Element, range: Range, codeRange: Range, children: Outline[] }
Element: { name: string, range: Range, kind: string, parameters: string | undefined, typeParameters: string | undefined, returnType: string | undefined }
Notifies the client when outline information is available (or updated) for a file.
Nodes contains multiple ranges:
element.range
- the range of the name in the declaration of the elementrange
- the entire range of the declaration including dartdocscodeRange
- the range of code part of the declaration (excluding dartdocs and annotations) - typically used when navigating to the declaration
Direction: Server -> Client
Params: { uri: string, outline: FlutterOutline }
FlutterOutline: { dartElement: Element | undefined, range: Range, codeRange: Range, children: Outline[], kind: string, label: string | undefined, className: string | undefined, variableName: string | undefined, attributes: FlutterOutlineAttribute[] | undefined }
FlutterOutlineAttribute: { name: string, label: string }
Element: as defined for the dart/textDocument/publishOutline
notification.
Notifies the client when Flutter outline information is available (or updated) for a file.
Nodes contains multiple ranges as described for the dart/textDocument/publishOutline
notification.
Direction: Server -> Client
Params: { uri: Uri }
Notifies the client that the server would like to open a given URI. This event is only sent in response to direct user actions (such as if the user clicks a "Learn More" button in a window/showMessageRequest
). URIs could be either external web pages (http/https) to be opened in the browser or documents (file:///) to be opened in the editor.
This notification (and functionality that relies on it) will only be sent if the client passes allowOpenUri: true
in initializationOptions
.
Direction: Client -> Server
Params: { uri: Uri }
Returns: { content: string | undefined }
Returns the content of the the virtual document with uri
. This is intended for generated files (such as those generated by macros) and is not supported for 'file' URIs.
Direction: Server -> Client
Params: { uri: Uri }
Notifies the client that the content in the virtual file with uri
may have changed (for example because a macro executed and regenerated its content).
Direction: Client -> Server
Params: { uri: Uri }
Returns: null
Provides the URI of a Dart Tooling Daemon server to allow the LSP server to connect and provide access to a subset of LSP functionality to DTD clients. This support is still a work in progress and should not be used outside of development (yet).
Some server functionality relies on well-known commands being available on the client. For example some CodeLenses like "Go to Augmented" required that the server can tell the client to navigate to a specific Location
. To enable this functionality, the client must inform the server which commands it supports from the set below during initialization in the experimental.commands
field of the client capabilities.
{
// ... other client capabilities
"experimental": {
"commands": [
"dart.goToLocation",
]
}
}
Arguments: Location
This command takes a single Location
argument and should navigate to that location in the editor. The server may use this command in CodeLenses or other places where a Command
can be returned. For example:
// Response to textDocument/codeLens
[
// CodeLens
{
"range": {
"end": { "character": 0, "line": 2 },
"start": { "character": 0, "line": 2 }
},
// Command
"command": {
"title": "Go to Augmented",
"command": "dart.goToLocation",
"arguments": [
// Location
{
"uri": "file:///C:/Projects/my_app/lib/main.dart",
"range": {
"end": { "character": 7, "line": 2 },
"start": { "character": 6, "line": 2 }
}
}
]
}
}
]