|
| 1 | +# FsAutoComplete Copilot Instructions |
| 2 | + |
| 3 | +## Project Overview |
| 4 | + |
| 5 | +FsAutoComplete (FSAC) is a Language Server Protocol (LSP) backend service that provides rich editing and intellisense features for F# development. It serves as the core engine behind F# support in various editors including Visual Studio Code (Ionide), Emacs, Neovim, Vim, Sublime Text, and Zed. |
| 6 | + |
| 7 | +## Supported Editors |
| 8 | + |
| 9 | +FsAutoComplete currently provides F# support for: |
| 10 | +- **Visual Studio Code** (via [Ionide](https://github.com/ionide/ionide-vscode-fsharp)) |
| 11 | +- **Emacs** (via [emacs-fsharp-mode](https://github.com/fsharp/emacs-fsharp-mode)) |
| 12 | +- **Neovim** (via [nvim-lspconfig](https://github.com/neovim/nvim-lspconfig/blob/master/doc/server_configurations.md#fsautocomplete)) |
| 13 | +- **Vim** (via [vim-fsharp](https://github.com/fsharp/vim-fsharp)) |
| 14 | +- **Sublime Text** (via [LSP package](https://lsp.sublimetext.io/language_servers/#f)) |
| 15 | +- **Zed** (via [zed-fsharp](https://github.com/nathanjcollins/zed-fsharp)) |
| 16 | + |
| 17 | +## Architecture |
| 18 | + |
| 19 | +### Core Components |
| 20 | + |
| 21 | +- **FsAutoComplete.Core**: Contains the core functionality, including: |
| 22 | + - F# compiler service interfaces |
| 23 | + - Code generation and refactoring utilities |
| 24 | + - Symbol resolution and type checking |
| 25 | + - Signature formatting and documentation |
| 26 | + - File system abstractions |
| 27 | + |
| 28 | +- **FsAutoComplete**: Main LSP server implementation with: |
| 29 | + - LSP protocol handlers and endpoints |
| 30 | + - Code fixes and quick actions |
| 31 | + - Parser for LSP requests/responses |
| 32 | + - Program entry point |
| 33 | + |
| 34 | +- **FsAutoComplete.Logging**: Centralized logging infrastructure |
| 35 | + |
| 36 | +### Key Dependencies |
| 37 | + |
| 38 | +- **FSharp.Compiler.Service** (>= 43.9.300): Core F# compiler APIs for language analysis |
| 39 | +- **Ionide.ProjInfo** (>= 0.71.2): Project and solution file parsing, with separate packages for FCS integration and project system |
| 40 | +- **FSharpLint.Core**: Code linting and static analysis |
| 41 | +- **Fantomas.Client** (>= 0.9): F# code formatting |
| 42 | +- **Microsoft.Build** (>= 17.2): MSBuild integration for project loading |
| 43 | +- **Serilog** (>= 2.10.0): Structured logging infrastructure |
| 44 | +- **Language Server Protocol**: Communication with editors |
| 45 | + |
| 46 | +#### Target Frameworks |
| 47 | +- **netstandard2.0 & netstandard2.1**: For broader compatibility |
| 48 | +- **net8.0 & net9.0**: For latest .NET features and performance |
| 49 | + |
| 50 | +## Development Workflow |
| 51 | + |
| 52 | +### Building the Project |
| 53 | + |
| 54 | +Requirements: |
| 55 | +- .NET SDK (see `global.json` for exact version - minimum >= 6.0, recommended >= 7.0) |
| 56 | + |
| 57 | +```bash |
| 58 | +# Restore .NET tools (including Paket) |
| 59 | +dotnet tool restore |
| 60 | + |
| 61 | +# Build the entire solution |
| 62 | +dotnet build |
| 63 | + |
| 64 | +# Run tests |
| 65 | +dotnet test |
| 66 | + |
| 67 | +# Run specific test project |
| 68 | +dotnet test -f net8.0 ./test/FsAutoComplete.Tests.Lsp/FsAutoComplete.Tests.Lsp.fsproj |
| 69 | + |
| 70 | +# Format code |
| 71 | +dotnet fantomas src/ test/ |
| 72 | +``` |
| 73 | + |
| 74 | +#### Development Environment Options |
| 75 | +- **DevContainer**: Use with VSCode's Remote Containers extension for stable development environment |
| 76 | +- **Gitpod**: Web-based VSCode IDE available at https://gitpod.io/#https://github.com/fsharp/fsautocomplete |
| 77 | + |
| 78 | +### Project Dependencies |
| 79 | + |
| 80 | +This project uses **Paket** for dependency management instead of NuGet directly: |
| 81 | +- Dependencies are declared in `paket.dependencies` |
| 82 | +- Lock file is `paket.lock` |
| 83 | +- Each project has its own `paket.references` file |
| 84 | + |
| 85 | +### Code Organization |
| 86 | + |
| 87 | +#### Code Fixes |
| 88 | +- Located in `src/FsAutoComplete/CodeFixes/` |
| 89 | +- Each code fix is typically a separate F# module |
| 90 | +- Follow the pattern: analyze issue → generate fix → apply transformation |
| 91 | +- **Scaffolding**: Use `dotnet fsi build.fsx -- -p ScaffoldCodeFix YourCodeFixName` to create new code fixes |
| 92 | +- This generates implementation file, signature file, and unit test, plus updates registration files |
| 93 | +- Examples include: `ImplementInterface.fs`, `GenerateUnionCases.fs`, `AddMissingEqualsToTypeDefinition.fs` |
| 94 | + |
| 95 | +#### LSP Endpoints |
| 96 | +- Standard LSP endpoints in `src/FsAutoComplete/LspServers/` |
| 97 | +- Key server files: `AdaptiveFSharpLspServer.fs`, `AdaptiveServerState.fs`, `ProjectWorkspace.fs` |
| 98 | +- Custom F#-specific endpoints prefixed with `fsharp/` |
| 99 | +- Request/response types in `CommandResponse.fs` |
| 100 | +- Interface definitions in `IFSharpLspServer.fs` |
| 101 | + |
| 102 | +#### Testing |
| 103 | +- Main test suite in `test/FsAutoComplete.Tests.Lsp/` |
| 104 | +- Tests organized by feature area (CompletionTests, CodeFixTests, etc.) |
| 105 | +- Uses F# testing frameworks with custom helpers in `Helpers.fs` |
| 106 | +- Test cases often in `TestCases/` subdirectories |
| 107 | + |
| 108 | +## F# Language Conventions |
| 109 | + |
| 110 | +### Coding Style |
| 111 | +- Follow F# community conventions |
| 112 | +- Use `fantomas` for code formatting (configured in the project) |
| 113 | +- Prefer immutable data structures and functional programming patterns |
| 114 | +- Use explicit type annotations where they improve clarity |
| 115 | + |
| 116 | +### Module Organization |
| 117 | +- One primary type/feature per file |
| 118 | +- Use `.fs` and `.fsi` pairs for public APIs |
| 119 | +- Organize related functionality into modules |
| 120 | +- Follow naming conventions: `CamelCase` for types, `camelCase` for values |
| 121 | + |
| 122 | +### Error Handling |
| 123 | +- Use F# Result types for error handling where appropriate |
| 124 | +- Use FsToolkit.ErrorHandling for railway-oriented programming |
| 125 | +- Prefer explicit error types over generic exceptions |
| 126 | + |
| 127 | +## LSP Implementation Details |
| 128 | + |
| 129 | +### Supported Standard LSP Features |
| 130 | +- `textDocument/completion` with `completionItem/resolve` |
| 131 | +- `textDocument/hover`, `textDocument/definition`, `textDocument/references` |
| 132 | +- `textDocument/codeAction`, `textDocument/codeLens` |
| 133 | +- `textDocument/formatting` (via Fantomas) |
| 134 | +- `textDocument/rename`, `textDocument/signatureHelp` |
| 135 | +- Workspace management and file watching |
| 136 | + |
| 137 | +### Custom F# Extensions |
| 138 | +- `fsharp/signature`: Get formatted signature at position |
| 139 | +- `fsharp/compile`: Compile project and return diagnostics |
| 140 | +- `fsharp/workspacePeek`: Discover available projects/solutions |
| 141 | +- `fsharp/workspaceLoad`: Load specific projects |
| 142 | +- `fsproj/addFile`, `fsproj/removeFile`: Project file manipulation |
| 143 | +- `fsharp/documentationForSymbol`: Get documentation for symbols |
| 144 | +- `fsharp/f1Help`: F1 help functionality |
| 145 | +- `fsharp/fsi`: F# Interactive integration |
| 146 | + |
| 147 | +## Testing Guidelines |
| 148 | + |
| 149 | +### Test Structure |
| 150 | +- Tests are organized by feature area |
| 151 | +- Use descriptive test names that explain the scenario |
| 152 | +- Include both positive and negative test cases |
| 153 | +- Test with realistic F# code examples |
| 154 | + |
| 155 | +### Adding New Tests |
| 156 | +1. Identify the appropriate test file (e.g., `CompletionTests.fs` for completion features) |
| 157 | +2. Follow existing patterns for test setup and assertions |
| 158 | +3. Use the helpers in `Helpers.fs` for common operations |
| 159 | +4. Include edge cases and error conditions |
| 160 | +5. For code fixes: Run focused tests with `dotnet run -f net8.0 --project ./test/FsAutoComplete.Tests.Lsp/FsAutoComplete.Tests.Lsp.fsproj` |
| 161 | +6. Remove focused test markers before submitting PRs (they cause CI failures) |
| 162 | + |
| 163 | +### Test Data |
| 164 | +- Sample F# projects in `TestCases/` directories |
| 165 | +- Use minimal, focused examples that demonstrate specific features |
| 166 | +- Avoid overly complex test scenarios that are hard to debug |
| 167 | + |
| 168 | +## Performance Considerations |
| 169 | + |
| 170 | +### Memory Management |
| 171 | +- Be mindful of memory usage in long-running language server scenarios |
| 172 | +- Dispose of compiler service resources appropriately |
| 173 | +- Use caching judiciously to balance performance and memory |
| 174 | + |
| 175 | +### Responsiveness |
| 176 | +- LSP operations should be fast and non-blocking |
| 177 | +- Use async/await patterns for I/O operations |
| 178 | +- Consider cancellation tokens for long-running operations |
| 179 | + |
| 180 | +## Debugging and Telemetry |
| 181 | + |
| 182 | +### OpenTelemetry Integration |
| 183 | +- Tracing is available with `--otel-exporter-enabled` flag |
| 184 | +- Use Jaeger for trace visualization during development |
| 185 | +- Activity tracing helps debug performance issues |
| 186 | + |
| 187 | +### Logging |
| 188 | +- Structured logging via Serilog |
| 189 | +- Use appropriate log levels (Debug, Info, Warning, Error) |
| 190 | +- Include relevant context in log messages |
| 191 | + |
| 192 | +## Common Patterns |
| 193 | + |
| 194 | +### Working with FCS (F# Compiler Service) |
| 195 | +- Always work with `FSharpCheckFileResults` and `FSharpParseFileResults` |
| 196 | +- Handle both parsed and typed ASTs appropriately |
| 197 | +- Be aware of file dependencies and project context |
| 198 | + |
| 199 | +### LSP Request Handling |
| 200 | +- Validate input parameters |
| 201 | +- Handle exceptions gracefully |
| 202 | +- Return appropriate error responses for invalid requests |
| 203 | +- Use proper JSON serialization |
| 204 | + |
| 205 | +### Code Generation |
| 206 | +- Use the F# AST utilities in `TypedAstUtils.fs` and `UntypedAstUtils.fs` |
| 207 | +- Consider both syntactic and semantic correctness |
| 208 | +- Test generated code compiles and has expected behavior |
| 209 | + |
| 210 | +## Contributing Guidelines |
| 211 | + |
| 212 | +### Before Submitting Changes |
| 213 | +1. Ensure all tests pass: `dotnet test` |
| 214 | +2. Run code formatting: `dotnet fantomas src/ test/` |
| 215 | +3. Verify the solution builds cleanly |
| 216 | +4. Test your changes with a real F# project if possible |
| 217 | + |
| 218 | +### Code Review Focus Areas |
| 219 | +- Correctness of F# language analysis |
| 220 | +- Performance impact on language server operations |
| 221 | +- Compatibility with different F# project types |
| 222 | +- LSP protocol compliance |
| 223 | +- Test coverage for new features |
| 224 | + |
| 225 | +## Resources |
| 226 | + |
| 227 | +### Core Documentation |
| 228 | +- [FsAutoComplete GitHub Repository](https://github.com/ionide/FsAutoComplete) |
| 229 | +- [LSP Specification](https://microsoft.github.io/language-server-protocol/) |
| 230 | +- [F# Compiler Service Documentation](https://fsharp.github.io/FSharp.Compiler.Service/) |
| 231 | + |
| 232 | +### F# Development Guidelines |
| 233 | +- [F# Style Guide](https://docs.microsoft.com/en-us/dotnet/fsharp/style-guide/) |
| 234 | +- [F# Formatting Guidelines](https://docs.microsoft.com/en-us/dotnet/fsharp/style-guide/formatting) |
| 235 | +- [F# Component Design Guidelines](https://docs.microsoft.com/en-us/dotnet/fsharp/style-guide/component-design-guidelines) |
| 236 | + |
| 237 | +### Project-Specific Guides |
| 238 | +- [Creating a New Code Fix Guide](./docs/Creating%20a%20new%20code%20fix.md) |
| 239 | +- [Ionide.ProjInfo Documentation](https://github.com/ionide/proj-info) |
| 240 | +- [Fantomas Configuration](https://fsprojects.github.io/fantomas/) |
| 241 | + |
| 242 | +### Related Tools |
| 243 | +- [FSharpLint](https://github.com/fsprojects/FSharpLint/) - Static analysis tool |
| 244 | +- [Paket](https://fsprojects.github.io/Paket/) - Dependency management |
| 245 | +- [FAKE](https://fake.build/) - Build automation (used for scaffolding) |
0 commit comments