# FsAutoComplete
[![NuGet version (FsAutoComplete)](https://img.shields.io/nuget/v/FsAutoComplete.svg?style=flat-square)](https://www.nuget.org/packages/FsAutoComplete/)
The `FsAutoComplete` project (`FSAC`) provides a backend service for rich editing or intellisense features for editors.
It can be hosted using the Language Server Protocol.
Currently it is used by:
* [Emacs](https://github.com/fsharp/emacs-fsharp-mode)
* [Neovim](https://github.com/neovim/nvim-lspconfig/blob/master/doc/server_configurations.md#fsautocomplete)
* [Vim](https://github.com/fsharp/vim-fsharp)
* [Visual Studio Code](https://github.com/ionide/ionide-vscode-fsharp)
* [Sublime Text](https://lsp.sublimetext.io/language_servers/#f)
It's based on:
* [FSharp.Compiler.Service](https://github.com/fsharp/FSharp.Compiler.Service/) for F# language info.
* [Ionide.ProjInfo](https://github.com/ionide/proj-info) for project/solution management.
* [FSharpLint](https://github.com/fsprojects/FSharpLint/) for the linter feature.
* [Fantomas](https://github.com/fsprojects/fantomas) for F# code formatting.
## Building and testing
Requirements:
* .NET SDK, see [global.json](global.json) for the exact version.
Minimum: >= 6.0, Recommended: >= 7.0
1. Restore dotnet tools to install local Paket `dotnet tool restore`
2. Build FSAC with `dotnet run --project build`
3. Optionally specify a target with the `-t` parameter: `dotnet run --project build -t ....`
* To build release fsautocomplete binaries in `~/bin` directory, use the `LocalRelease` target
* To build, run all tests and create packages, use the `All` target
### DevContainer
The repository additionally provides DevContainer definition that can be used with VSCode's Remote Containers extension - use it to get stable development environment
### Gitpod.io
This repository is prepared to use Gitpod for a web-based VSCode-style IDE. Click the button below to begin!
[![Gitpod Ready-to-Code](https://img.shields.io/badge/Gitpod-ready--to--code-blue?logo=gitpod)](https://gitpod.io/#https://github.com/fsharp/fsautocomplete)
## Releasing
* Update CHANGELOG.md with the release notes from the current release in the `Unreleased` section. Use section headings like `Added`, `Fixed`, etc from keepachangelog.com.
* For individual section items in the Changelog, use headings like `BUGFIX`, `FEATURE`, and `ENHANCEMENT` followed by a link to the PR with the PR title.
* Run the `Promote` FAKE target via the `Promote` target to create the appropriate release version from the current `Unreleased` section and stamp the date, as well as create a commit and tag for this promotion
* push this commit and tag to main
* the CI pipeline will publish a release from the tag.
## OpenTelemetry
FsAutocomplete is using [System.Diagnostics.Activity](https://learn.microsoft.com/en-us/dotnet/core/diagnostics/distributed-tracing-instrumentation-walkthroughs) to create traces.
To export traces, run [Jaeger](https://www.jaegertracing.io/)
```bash
docker run -d --name jaeger \
-e COLLECTOR_ZIPKIN_HOST_PORT=:9411 \
-e COLLECTOR_OTLP_ENABLED=true \
-p 6831:6831/udp \
-p 6832:6832/udp \
-p 5778:5778 \
-p 16686:16686 \
-p 4317:4317 \
-p 4318:4318 \
-p 14250:14250 \
-p 14268:14268 \
-p 14269:14269 \
-p 9411:9411 \
jaegertracing/all-in-one:latest
```
Then configure your [environment](https://opentelemetry.io/docs/concepts/sdk-configuration/otlp-exporter-configuration/)
```bash
OTEL_EXPORTER_OTLP_ENDPOINT = "http://localhost:4317"
```
Start FsAutocomplete (either by `code .` or `dotnet fsautocomplete`)
Do some actions like opening documents, saving, getting tooltips, etc.
Then open `http://localhost:16686/` to inspect traces.
## Communication protocol
FsAutoComplete supports [LSP](https://microsoft.github.io/language-server-protocol/) as a communication protocol.
### Supported LSP endpoints
* `initialize`
* `textDocument/didOpen`
* `textDocument/didChange`
* `textDocument/didSave`
* `textDocument/hover`
* `textDocument/completion` & `completionItem/resolve`
* `textDocument/rename`
* `textDocument/definition`
* `textDocument/typeDefinition`
* `textDocument/implementation`
* `textDocument/codeAction`:
* Remove unused `open`
* Resolve namespace/module
* Replace unused symbol with `_`
* Fix typo based on error message
* Remove redundant qualifier
* Add missing `new` keyword for `IDisposable`
* Generate cases for all DU case in pattern matching
* Generate empty interface implementation
* Fixes suggested by [FSharpLint](https://github.com/fsprojects/FSharpLint)
* `textDocument/codeLens` & `codeLens/resolve`:
* signature Code Lenses
* reference number Code Lenses
* `textDocument/formatting` - powered by [fantomas](https://github.com/fsprojects/fantomas)
* `textDocument/references`
* `textDocument/documentHighlight`
* `textDocument/signatureHelp`
* `textDocument/documentSymbol`
* `textDocument/inlayHint`
* `textDocument/inlineValue`
* `workspace/didChangeWatchedFiles`
* `workspace/didChangeConfiguration`
* `workspace/symbol`
### Custom endpoints
Custom endpoints are using (for messages body) `PlainNotification` type and string format serialized with exactly same serialization format as old JSON protocol
* `fsharp/signature` - accepts `TextDocumentPositionParams`, returns signature of symbol at given position as a formatted string
* `fsharp/signatureData` - accepts `TextDocumentPositionParams`, returns signature of symbol at given position as DTO
* `fsharp/lineLens` - accepts `ProjectParms` (`Project` filed contain F# file path), returns locations where LineLenses should be displayed
* `fsharp/compilerLocation` - no input, returns paths to FCS, FSI and MsBuild
* `fsharp/compile` - accepts `ProjectParms`, tries to compile project, returns list of errors and exit status code
* `fsharp/workspacePeek` - accepts `WorkspacePeekRequest`, returns list of possible workspaces (resolved solution files, or list of projects if there are no solution files)
* `fsharp/workspaceLoad` - accepts `WorkspaceLoadParms`, loads given list of projects in the background, partial result notified by `fsharp/notifyWorkspace` notification
* `fsharp/project` - accepts `ProjectParms`, loads given project
* `fsharp/fsdn` - accepts `ProjectParms` (`Project` filed contain query string), query FSDN and returns list of functions
* `fsharp/f1Help` - accepts `TextDocumentPositionParams`, returns URL to MSDN documentation for symbol at given position
* `fsharp/documentation` - accepts `TextDocumentPositionParams`, returns documentation data about symbol at given position, used for InfoPanel
* `fsharp/documentationSymbol` - accepts `DocumentationForSymbolReuqest`, returns documentation data about given symbol from given assembly, used for InfoPanel
* `fsproj/moveFileUp` - accepts `DotnetFileRequest`, move the file down of 1 line in the project file
* `fsproj/moveFileDown` - accepts `DotnetFileRequest`, move the file up of 1 line in the project file
* `fsproj/addFileAbove` - accepts `DotnetFile2Request`, create the file if needed and add it above the reference file in the project if not already present
* `fsproj/addFileBelow` - accepts `DotnetFile2Request`, create the file if needed and add it below the reference file in the project if not already present
* `fsproj/addFile` - accepts `DotnetFileRequest`, create the file if needed and add it to the project if not already present
* `fsproj/addExistingFile` - accepts `DotnetFileRequest`, add existing file to a project if not already present
* `fsproj/removeFile` - accepts `DotnetFileRequest`, remove the file from the project
* `fsproj/renameFile` - accepts `DotnetRenameFileRequest`, rename the file from the project
### Supported LSP notifications
* `window/showMessage`
* `window/logMessage`
* `textDocument/publishDiagnostics`
### Custom notifications
* `fsharp/notifyWorkspace` - notification for workspace/solution/project loading events
* `fsharp/notifyWorkspacePeek` - notification for initial workspace p