Skip to content

Commit

Permalink
feat: add {module} as a magic string for the afterModule setting (#229)
Browse files Browse the repository at this point in the history
This should fix an issue seen in SublimeText where the editor would
replace the module itself (eg module.$variable, module would disappear).
  • Loading branch information
wkillerud authored Sep 12, 2024
1 parent d7523d3 commit 07953dc
Show file tree
Hide file tree
Showing 7 changed files with 89 additions and 7 deletions.
9 changes: 9 additions & 0 deletions .vscode/launch.json
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,15 @@
{
"version": "0.2.0",
"configurations": [
{
"name": "Attach to language server running with --inspect",
"port": 9229,
"request": "attach",
"skipFiles": [
"<node_internals>/**"
],
"type": "node"
},
{
"type": "extensionHost",
"request": "launch",
Expand Down
22 changes: 22 additions & 0 deletions docs/src/contributing/debugging.md
Original file line number Diff line number Diff line change
Expand Up @@ -42,5 +42,27 @@ Find `browser-server.js` in the `vscode-extension/dist/` folder to set breakpoin

Restart the debugger after building to see any changes you make in the code.

## Attach to a running language server

If you need to debug an interaction in an editor other than Visual Studio Code,
you can run the language server using Node [with the `--inspect` flag](https://nodejs.org/en/learn/getting-started/debugging).

For example, in Sublime Text, this should be the command:

```json
{
"command": ["${node_bin}", "--inspect", "${server_path}", "--stdio", "--debug"]
}
```

Note that we also use the `--debug` flag in order to run the language server's non-minified bundle.

You can then [attach an inspector client](https://nodejs.org/en/learn/getting-started/debugging#inspector-clients).

In VS Code, once the debugger is attached, you should be able to find the language server's script in the Loaded scripts section.
There you can place breakpoints to step through the code you want to inspect.

![](../images/debugging/attach-to-server.png)

[exthost]: https://code.visualstudio.com/api/advanced-topics/extension-host
[vsdebug]: https://code.visualstudio.com/docs/editor/debugging
Binary file added docs/src/images/debugging/attach-to-server.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
22 changes: 18 additions & 4 deletions docs/src/language-server/configure-a-client.md
Original file line number Diff line number Diff line change
Expand Up @@ -28,10 +28,24 @@ For example, while we may document `"somesass.loadPaths": []` (and write it this

In addition to [the user settings](../user-guide/settings.md), language clients may want to configure these server-only settings to tweak how certain features interact with your specific editor.

| Key | Description |
| ------------------------------------ | ----------------------------------------------------------------------------------------------------------- |
| `somesass.completion.afterModule` | Set this to the empty string if you end up with `module..$variable` after accepting a code suggestion item. |
| `somesass.completion.beforeVariable` | Set this to the empty string if you end up with `$$variable` after accepting a code suggestion item. |
| Key | Description |
| ------------------------------------ | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------ |
| `somesass.completion.afterModule` | Set this to the empty string if you end up with `module..$variable` after accepting a code suggestion item. If `module.` or `module` disappears, you can set it to `"{module}."` or `"{module}"` respectively. That is a "magic string" that will be replaced with the actual module name. |
| `somesass.completion.beforeVariable` | Set this to the empty string if you end up with `$$variable` after accepting a code suggestion item. |

For example:

```json
{
"settings": {
"somesass": {
"completion": {
"afterModule": "{module}"
}
}
}
}
```

## Existing clients

Expand Down
38 changes: 35 additions & 3 deletions packages/language-services/src/features/do-complete.ts
Original file line number Diff line number Diff line change
Expand Up @@ -861,6 +861,13 @@ export class DoComplete extends LanguageFeature {
? asDollarlessVariable(label)
: label;

if (
this.configuration.completionSettings?.afterModule &&
this.configuration.completionSettings.afterModule.startsWith("{module}")
) {
insertText = `${namespace}${insertText}`;
}

filterText = currentWord.endsWith(".") ? `${namespace}.${label}` : label;
} else if (
dotExt === ".vue" ||
Expand Down Expand Up @@ -926,12 +933,21 @@ export class DoComplete extends LanguageFeature {
initialDocument.languageId === "sass" ||
this.configuration.completionSettings?.afterModule === "";

const insertText = namespace
let insertText = namespace
? noDot
? `${prefix}${symbol.name}`
: `.${prefix}${symbol.name}`
: symbol.name;

if (
namespace &&
namespace !== "*" &&
this.configuration.completionSettings?.afterModule &&
this.configuration.completionSettings.afterModule.startsWith("{module}")
) {
insertText = `${namespace}${insertText}`;
}

const sortText = isPrivate ? label.replace(/^$[_]/, "") : undefined;

const documentation = {
Expand Down Expand Up @@ -1059,12 +1075,21 @@ export class DoComplete extends LanguageFeature {
initialDocument.languageId === "sass" ||
this.configuration.completionSettings?.afterModule === "";

const insertText = namespace
let insertText = namespace
? noDot
? `${prefix}${symbol.name}`
: `.${prefix}${symbol.name}`
: symbol.name;

if (
namespace &&
namespace !== "*" &&
this.configuration.completionSettings?.afterModule &&
this.configuration.completionSettings.afterModule.startsWith("{module}")
) {
insertText = `${namespace}${insertText}`;
}

const sortText = isPrivate ? label.replace(/^$[_]/, "") : undefined;

const documentation = {
Expand Down Expand Up @@ -1158,12 +1183,19 @@ export class DoComplete extends LanguageFeature {
document.languageId === "sass" ||
this.configuration.completionSettings?.afterModule === "";

const insertText = context.currentWord.includes(".")
let insertText = context.currentWord.includes(".")
? `${noDot ? "" : "."}${label}${
signature ? `(${parameterSnippet})` : ""
}`
: label;

if (
this.configuration.completionSettings?.afterModule &&
this.configuration.completionSettings.afterModule.startsWith("{module}")
) {
insertText = `${context.namespace}${insertText}`;
}

items.push({
documentation: {
kind: MarkupKind.Markdown,
Expand Down
4 changes: 4 additions & 0 deletions packages/language-services/src/language-feature.ts
Original file line number Diff line number Diff line change
Expand Up @@ -79,6 +79,10 @@ export abstract class LanguageFeature {
this.configuration = {
...defaultConfiguration,
...configuration,
completionSettings: {
...defaultConfiguration.completionSettings,
...(configuration.completionSettings || {}),
},
};
this._internal.sassLs.configure(configuration);
}
Expand Down
1 change: 1 addition & 0 deletions packages/language-services/src/language-services-types.ts
Original file line number Diff line number Diff line change
Expand Up @@ -227,6 +227,7 @@ export interface LanguageServiceConfiguration {
includePrefixDot?: boolean;
/**
* If you end up with an extra `.` after accepting a suggestion, set this to the empty string.
* If your module disappears, set it to "{module}" or "{module}." depending on your situation.
*
* @example
* ```scss
Expand Down

0 comments on commit 07953dc

Please sign in to comment.