Skip to content

Commit f896f67

Browse files
authored
Merge pull request #35 from sass/docs
docs: document public API, how to add new features
2 parents 1dd4921 + 41233e1 commit f896f67

37 files changed

+720
-411
lines changed

CONTRIBUTING.md

+6-2
Original file line numberDiff line numberDiff line change
@@ -4,9 +4,13 @@ Thank you for showing an interest in contributing.
44

55
This project is an early proof of concept of a language server for Sass written in Dart to make use of [sass_api](https://pub.dev/packages/sass_api).
66

7-
Check the documentation to get started:
7+
Note that the Sass parser currently requires a valid document to generate an AST ([sass/dart-sass#2476](https://github.com/sass/dart-sass/issues/2476)),
8+
making it impossible to implement certain features such as completions/IntelliSense.
9+
10+
You are still welcome to test and contribute where you can. Check the documentation and list of open issues to get started:
811

912
- [Development environment](./docs/contributing/development-environment.md)
10-
- [Debugging](./docs/contributing/debugging.md)
13+
- [Testing and debugging](./docs/contributing/testing-and-debugging.md)
1114
- [Building](./docs/contributing/building.md)
1215
- [Architecture](./docs/contributing/architecture.md)
16+
- [Adding new language- or workspace features](./docs/contributing/adding-new-features.md)

README.md

+24-5
Original file line numberDiff line numberDiff line change
@@ -2,10 +2,29 @@
22

33
This is a work-in-progress language server for Sass written in Dart to
44
use [sass_api](https://pub.dev/packages/sass_api).
5+
It uses [the language server protocol](https://microsoft.github.io/language-server-protocol/specifications/lsp/3.18/specification/#languageFeatures) (LSP).
56

6-
See the [initial version roadmap](https://github.com/sass/dart-sass-language-server/issues/2) for the state of different features or check the documentation to get started:
7+
## Status
78

8-
- [Development environment](./docs/contributing/development-environment.md)
9-
- [Testing and debugging](./docs/contributing/testing-and-debugging.md)
10-
- [Building](./docs/contributing/building.md)
11-
- [Architecture](./docs/contributing/architecture.md)
9+
[Development of new features is paused](https://github.com/sass/dart-sass/issues/2476). See the Issues and Pull request tabs for planned and partially implemented features.
10+
11+
The [Testing and debugging](docs/contributing/testing-and-debugging.md) docs explain how to run the language server from source code.
12+
13+
These features are implemented:
14+
15+
| Feature | Specification |
16+
| ---------------------------------------------------------------------------------------- | -------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
17+
| [Document highlights](pkgs/sass_language_services/lib/src/features/document_highlights/) | [textDocument/documentHighlight](https://microsoft.github.io/language-server-protocol/specifications/lsp/3.18/specification/#textDocument_documentHighlight) |
18+
| [Document links](pkgs/sass_language_services/lib/src/features/document_links/) | [textDocument/documentLink](https://microsoft.github.io/language-server-protocol/specifications/lsp/3.18/specification/#textDocument_documentLink) |
19+
| [Document symbols](pkgs/sass_language_services/lib/src/features/document_symbols/) | [textDocument/documentSymbol](https://microsoft.github.io/language-server-protocol/specifications/lsp/3.18/specification/#textDocument_documentSymbol) |
20+
| [Find references](pkgs/sass_language_services/lib/src/features/find_references/) | [textDocument/references](https://microsoft.github.io/language-server-protocol/specifications/lsp/3.18/specification/#textDocument_references) |
21+
| [Folding ranges](pkgs/sass_language_services/lib/src/features/folding_ranges/) | [textDocument/foldingRange](https://microsoft.github.io/language-server-protocol/specifications/lsp/3.18/specification/#textDocument_foldingRange) |
22+
| [Go to definition](pkgs/sass_language_services/lib/src/features/go_to_definition/) | [textDocument/definition](https://microsoft.github.io/language-server-protocol/specifications/lsp/3.18/specification/#textDocument_definition) |
23+
| [Hover](pkgs/sass_language_services/lib/src/features/hover/) | [textDocument/hover](https://microsoft.github.io/language-server-protocol/specifications/lsp/3.18/specification/#textDocument_hover) |
24+
| [Rename](pkgs/sass_language_services/lib/src/features/rename/) | [textDocument/prepareRename](https://microsoft.github.io/language-server-protocol/specifications/lsp/3.18/specification/#textDocument_prepareRename), [textDocument/rename](https://microsoft.github.io/language-server-protocol/specifications/lsp/3.18/specification/#textDocument_rename) |
25+
| [Selection ranges](pkgs/sass_language_services/lib/src/features/selection_ranges/) | [textDocument/selectionRange](https://microsoft.github.io/language-server-protocol/specifications/lsp/3.18/specification/#textDocument_selectionRange) |
26+
| [Workspace symbol](pkgs/sass_language_services/lib/src/features/workspace_symbols/) | [workspace/symbol](https://microsoft.github.io/language-server-protocol/specifications/lsp/3.18/specification/#workspace_symbol) |
27+
28+
## How to contribute
29+
30+
See [Contributing](./CONTRIBUTING.md), but note that the parser currently requires a valid Sass document to generate an AST ([sass/dart-sass#2476](https://github.com/sass/dart-sass/issues/2476)).
+22
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,22 @@
1+
# How to add new features
2+
3+
This document explains some of the steps involved in adding a new language- or workspace feature.
4+
5+
For some complete examples, see:
6+
7+
- [Folding ranges (#32)](https://github.com/sass/dart-sass-language-server/pull/32/files)
8+
- [Workspace symbols (#26)](https://github.com/sass/dart-sass-language-server/pull/26/files)
9+
10+
A summary of what you need:
11+
12+
1. Extend [language_configuration.dart](../../pkgs/sass_language_services/lib/src/configuration/language_configuration.dart) to parse the user's configuration for the feature.
13+
2. Set defaults for the same user configuration in [the extension's package.json](../../extension/package.json) (look for the `"configuration"` key, and check for existing options).
14+
3. Declare that the language server has the new capability in [language_server.dart](../../pkgs/sass_language_server/lib/src/language_server.dart) (look for `ServerCapabilities`).
15+
4. Add a request handler for the feature in `language_server.dart` using `_connection.on<FeatureName>`. If a method doesn't exist for the feature, use the generic `_connection.peer.registerMethod()`.
16+
5. Create a folder for the feature in [sass_language_services](../../pkgs/sass_language_services/lib/src/features/).
17+
6. Implement the feature in a class that extends `LanguageFeature`.
18+
- Look at existing features for some common patterns, such as how to parse a `TextDocument` to get the AST.
19+
- You may want to know what AST node is at a given `Position`. See `node_at_offset_visitor.dart`.
20+
- Use `findInWorkspace` to run a callback on each linked document, recursively (with a `lazy` option).
21+
7. Add the feature to the public API in [language_services.dart](../../pkgs/sass_language_services/lib/src/language_services.dart).
22+
8. Use the feature in the request handler in `language_server.dart`.

docs/contributing/architecture.md

+10-2
Original file line numberDiff line numberDiff line change
@@ -15,11 +15,19 @@ We have this split so the language server features are reusable [for embedded la
1515

1616
This is the language server executable. Users will install this package, and the language client will run the server when needed.
1717

18+
This executable listens for incoming [JSON-RPC messages](https://microsoft.github.io/language-server-protocol/specifications/lsp/3.18/specification/#languageServerProtocol). It handles [lifecycle messages](https://microsoft.github.io/language-server-protocol/specifications/lsp/3.18/specification/#lifeCycleMessages) and [document synchronization](https://microsoft.github.io/language-server-protocol/specifications/lsp/3.18/specification/#textDocument_synchronization) so the language server can keep track of the document and workspace state.
19+
20+
It has handlers for the different [language features](https://microsoft.github.io/language-server-protocol/specifications/lsp/3.18/specification/#languageFeatures) and [workspace features](https://microsoft.github.io/language-server-protocol/specifications/lsp/3.18/specification/#workspaceFeatures), but the implementation of those features are in [sass_language_services](#sass_language_services).
21+
1822
## sass_language_services
1923

20-
This is where you find the core functionality of the language server. Individual features are in the `lib/src/features/` directory. Each feature extends a base `LanguageFeature` class.
24+
This is where you find the core functionality of the language server. Individual features are in the [lib/src/features/](../../pkgs/sass_language_services/lib/src/features/) directory. Each feature extends a base `LanguageFeature` class.
25+
26+
When used, all features parse a given `TextDocument` using [`sass_api`](https://pub.dev/packages/sass_api) to get the [`Stylesheet` node](https://pub.dev/documentation/sass_api/latest/sass/Stylesheet-class.html). Parses are cached, along with other often-used information such as resolved links.
27+
28+
A feature typically returns a `Future` of some kind so it can traverse linked documents in order to be workspace-aware for features like Go to definition and Hover.
2129

22-
When used, all features parse the given `TextDocument` using [`sass_api`](https://pub.dev/packages/sass_api) to get the [`Stylesheet` node](https://pub.dev/documentation/sass_api/latest/sass/Stylesheet-class.html). Parses are cached, along with other often-used information such as resolved links.
30+
A feature also typically returns a language server protocol response type, such as [Hover](https://microsoft.github.io/language-server-protocol/specifications/lsp/3.18/specification/#hover).
2331

2432
## extension
2533

docs/contributing/building.md

+4-2
Original file line numberDiff line numberDiff line change
@@ -9,13 +9,15 @@ Here we assume you have set up a [development environment](./development-environ
99

1010
## Building the language server
1111

12-
In `pkgs/sass_language_server`:
12+
In `pkgs/sass_language_server`, run this command:
1313

1414
```sh
1515
dart compile exe bin/sass_language_server.dart -o bin/sass-language-server
1616
```
1717

18-
This builds an executable for your current operating system named `sass-language-server`.
18+
This builds an executable for your current operating system named `sass-language-server`. You can add this to your `PATH` and use it with any editor that has an LSP client.
19+
20+
Run `sass-language-server --help` to see available options.
1921

2022
## Building the language extension
2123

docs/contributing/development-environment.md

-3
Original file line numberDiff line numberDiff line change
@@ -16,9 +16,6 @@ To work on the language extension, or test your changes in Visual Studio Code:
1616

1717
- [Node.js v20 or higher](https://nodejs.org/en)
1818
- [Visual Studio Code](https://code.visualstudio.com/) or [VSCodium](https://github.com/VSCodium/vscodium) (we'll refer to Visual Studio Code, VS Code for short, in the documentation)
19-
20-
### Recommended software
21-
2219
- [Dart extension for VS Code](https://github.com/Dart-Code/Dart-Code)
2320

2421
## Install dependencies

docs/contributing/testing-and-debugging.md

+13-26
Original file line numberDiff line numberDiff line change
@@ -4,19 +4,23 @@ Here we assume you have set up a [development environment](./development-environ
44

55
## Run the language extension and server
66

7-
The quickest way to test the language server is to debug the language extension in Visual Studio Code. A debugging launch configuration is included in the repository. To use it:
7+
The quickest way to test the language server is to debug the language extension in [Visual Studio Code](https://code.visualstudio.com). A debugging launch configuration is included in the repository. To use it:
88

99
1. Open this repository in VS Code.
10-
2. Go to the Run and Debug view.
10+
2. Go to the [Run and Debug view](https://code.visualstudio.com/docs/editor/debugging).
1111
3. Pick Debug extension and language server from the menu.
1212
4. Click Start debugging.
1313

1414
This will open another window of Visual Studio Code, this one running as an `[Extension Development Host]`.
1515

16-
### Find the link to Dart DevTools or VM service
16+
### Attach the debugger
1717

1818
When debugging, the client runs [`dart run --enable-vm-service`](https://github.com/sass/dart-sass-language-server/blob/main/extension/src/server.ts#L49)
19-
in the local `sass_language_server` package.
19+
in the local `sass_language_server` package. This lets us attach a debugger to set breakpoints.
20+
21+
The video below demonstrates how to attach a debugger.
22+
23+
https://github.com/user-attachments/assets/d5143197-e092-483d-9d66-f1c9c52a075b
2024

2125
Use the `[Extension Development Host]` window to find the link to open Dart DevTools or to [attach the debugger](#attach-to-language-server).
2226

@@ -32,37 +36,20 @@ The Dart VM service is listening on http://127.0.0.1:8181/SMIxtkPzlAY=/
3236
The Dart DevTools debugger and profiler is available at: http://127.0.0.1:8181/SMIxtkPzlAY=/devtools/?uri=ws://127.0.0.1:8181/SMIxtkPzlAY=/ws
3337
```
3438

35-
Click the second link to open Dart DevTools, or copy the first link to [attach a debugger](#attach-to-language-server).
36-
37-
![screenshot showing the output pane and the dropdown with sass selected](https://github.com/user-attachments/assets/85839d2f-4305-4fb9-aeb0-d78f435e8b7d)
38-
39-
### Attach to language server
40-
41-
The debugger in Dart DevTools is deprecated in favor the debugger that ships with [Dart for Visual Studio Code][vscodedart].
42-
43-
To start debugging in VS Code (provided you have the Dart extension):
44-
45-
1. [Run the language server and extension](#run-the-language-extension-and-server) in debug mode.
46-
2. [Find the link to the Dart VM](#find-the-link-to-dart-devtools-or-vm-service).
47-
48-
You should see output similar to this in the `[Extension Development Host]`.
49-
50-
```
51-
The Dart VM service is listening on http://127.0.0.1:8181/SMIxtkPzlAY=/
52-
The Dart DevTools debugger and profiler is available at: http://127.0.0.1:8181/SMIxtkPzlAY=/devtools/?uri=ws://127.0.0.1:8181/SMIxtkPzlAY=/ws
53-
```
54-
5539
Copy the first link, then go back to the Run and debug window where you started the language server and extension.
5640

5741
1. Click the Run and debug drop-down and run `Attach to language server`.
5842
2. Paste the link you copied and hit Enter.
5943

6044
Your debugger should be attached, allowing you to place breakpoints and step through code.
6145

62-
_The video below demonstrates how to attach a debugger._
46+
### Dart DevTools
6347

64-
https://github.com/user-attachments/assets/d5143197-e092-483d-9d66-f1c9c52a075b
48+
The second link in the Output pane is to the [Dart DevTools](https://dart.dev/tools/dart-devtools).
6549

50+
The debugger in Dart DevTools is deprecated in favor the debugger that ships with [Dart for Visual Studio Code][vscodedart], but the DevTools have other usefool tools such as a memory and CPU profiler.
51+
52+
![screenshot showing the output pane and the dropdown with sass selected](https://github.com/user-attachments/assets/85839d2f-4305-4fb9-aeb0-d78f435e8b7d)
6653

6754
### Test in VS Code without built-in SCSS features
6855

pkgs/sass_language_server/README.md

+6-2
Original file line numberDiff line numberDiff line change
@@ -4,12 +4,16 @@ A Dart implementation of a language server for Sass. The language server uses th
44

55
## Installing the Sass language server
66

7-
### From Pub
7+
See the contributing documentation for [how to build the language server](../../docs/contributing/building.md) so you can add it to your `PATH`.
8+
9+
<!--
810
9-
<!-- Assuming this is how it will be -->
11+
### From Pub
1012
1113
If you're a [Dart](https://dart.dev/get-dart) user, you can install the Sass language server globally using `pub global activate sass_language_server`, which will provide a `sass-language-server` executable.
1214
15+
-->
16+
1317
## Using the Sass language server
1418

1519
To use `sass-language-server` your editor needs a language client.
Original file line numberDiff line numberDiff line change
@@ -1,2 +1,11 @@
1+
/// The Sass language server.
2+
///
3+
/// Includes an executable `sass-language-server`. Run `sass-language-server --help` to see available options.
4+
///
5+
/// The server listens for incoming [JSON-RPC messages](https://microsoft.github.io/language-server-protocol/specifications/lsp/3.18/specification/#languageServerProtocol). It handles [lifecycle messages](https://microsoft.github.io/language-server-protocol/specifications/lsp/3.18/specification/#lifeCycleMessages) and [document synchronization](https://microsoft.github.io/language-server-protocol/specifications/lsp/3.18/specification/#textDocument_synchronization) so the language server can keep track of the document and workspace state.
6+
///
7+
/// It has handlers for the different [language features](https://microsoft.github.io/language-server-protocol/specifications/lsp/3.18/specification/#languageFeatures) and [workspace features](https://microsoft.github.io/language-server-protocol/specifications/lsp/3.18/specification/#workspaceFeatures), but the implementation of those features are in `sass_language_services`.
8+
library;
9+
110
export 'src/local_file_system.dart' show LocalFileSystem;
211
export 'src/language_server.dart' show LanguageServer, Transport;

pkgs/sass_language_server/lib/src/logger.dart

+5
Original file line numberDiff line numberDiff line change
@@ -25,6 +25,11 @@ int levelToRank(String level) {
2525
}
2626
}
2727

28+
/// An interface so send log messages to the client.
29+
///
30+
/// It's up to each individual editor how to display these log messages.
31+
/// They may get shown in a status bar, in a dedicated output pane, or
32+
/// not shown at all.
2833
class Logger {
2934
late RemoteConsole _console;
3035
late int _level;

pkgs/sass_language_services/lib/sass_language_services.dart

+3
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,8 @@
44
/// if your language server is also written in Dart. Otherwise you may
55
/// want to use [the request forwarding pattern](https://code.visualstudio.com/api/language-extensions/embedded-languages#request-forwarding)
66
/// in your languages' client.
7+
///
8+
/// [LanguageServices] is the main public API.
79
library;
810

911
export 'src/configuration/configuration.dart' show LanguageServerConfiguration;
@@ -21,4 +23,5 @@ export 'src/file_system_provider.dart'
2123
export 'src/language_services.dart' show LanguageServices;
2224

2325
export 'src/features/document_links/stylesheet_document_link.dart';
26+
export 'src/features/document_symbols/scoped_symbols.dart';
2427
export 'src/features/document_symbols/stylesheet_document_symbol.dart';

pkgs/sass_language_services/lib/src/configuration/configuration.dart

+1
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,7 @@ import 'editor_configuration.dart';
22
import 'language_configuration.dart';
33
import 'workspace_configuration.dart';
44

5+
/// User configuration for the different language server features.
56
class LanguageServerConfiguration {
67
late LanguageConfiguration css;
78
late LanguageConfiguration scss;

pkgs/sass_language_services/lib/src/configuration/editor_configuration.dart

+1-1
Original file line numberDiff line numberDiff line change
@@ -12,7 +12,7 @@ class EditorConfiguration {
1212
colorDecoratorsLimit = config?['colorDecoratorsLimit'] as int? ?? 500;
1313
insertSpaces = config?['insertSpaces'] as bool? ?? false;
1414

15-
// legacy reasons in VS Code
15+
// legacy options in VS Code
1616
var maybeIndentSize = config?['indentSize'];
1717
if (maybeIndentSize is int) {
1818
indentSize = maybeIndentSize;

0 commit comments

Comments
 (0)