Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
8 changes: 8 additions & 0 deletions vscode/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -551,6 +551,14 @@
"type": "boolean",
"default": true
},
"rubyLsp.addonLanguageIds": {
"description": "Language IDs of other files to send to the server, for languages that an installed add-on supports (for example, `slim`). Without such an add-on, the server treats these files as Ruby",
"type": "array",
"items": {
"type": "string"
},
"default": []
},
"rubyLsp.featureFlags": {
"description": "Allows opting in or out of feature flags",
"type": "object",
Expand Down
7 changes: 4 additions & 3 deletions vscode/src/client.ts
Original file line number Diff line number Diff line change
Expand Up @@ -30,7 +30,7 @@ import {
ErrorCodes,
} from "vscode-languageclient/node";

import { LSP_NAME, ClientInterface, Addon, SUPPORTED_LANGUAGE_IDS, FEATURE_FLAGS, featureEnabled } from "./common";
import { LSP_NAME, ClientInterface, Addon, supportedLanguageIds, FEATURE_FLAGS, featureEnabled } from "./common";
import { Ruby } from "./ruby";
import { WorkspaceChannel } from "./workspaceChannel";

Expand Down Expand Up @@ -169,14 +169,15 @@ function collectClientOptions(
// 1. Files inside of the workspace itself
// 2. Bundled gems
// 3. Default gems
let documentSelector: DocumentSelector = SUPPORTED_LANGUAGE_IDS.flatMap((language) => {
const languageIds = supportedLanguageIds();
let documentSelector: DocumentSelector = languageIds.flatMap((language) => {
return { scheme: "file", language, pattern: `${fsPath}/**/*` };
});

// Only the first language server we spawn should handle unsaved files, otherwise requests will be duplicated across
// all workspaces
if (isMainWorkspace) {
SUPPORTED_LANGUAGE_IDS.forEach((language) => {
languageIds.forEach((language) => {
documentSelector.push({
language,
scheme: "untitled",
Expand Down
7 changes: 7 additions & 0 deletions vscode/src/common.ts
Original file line number Diff line number Diff line change
Expand Up @@ -75,6 +75,13 @@ export const LOG_CHANNEL = vscode.window.createOutputChannel(LSP_NAME, {
});
export const SUPPORTED_LANGUAGE_IDS = ["ruby", "erb"];

// Add-ons can make the server understand other languages, such as Slim templates. Users opt into sending those files to
// the server, since without a matching add-on it would treat them as Ruby
export function supportedLanguageIds(): string[] {
const addonLanguageIds = vscode.workspace.getConfiguration("rubyLsp").get<string[]>("addonLanguageIds") ?? [];
return [...SUPPORTED_LANGUAGE_IDS, ...addonLanguageIds];
}

// A list of feature flags where the key is the name and the value is the rollout percentage.
//
// Note: names added here should also be added to the `rubyLsp.optedOutFeatureFlags` enum in the `package.json` file
Expand Down
6 changes: 3 additions & 3 deletions vscode/src/rubyLsp.ts
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@ import { Range } from "vscode-languageclient/node";

import DocumentProvider from "./documentProvider";
import { Workspace } from "./workspace";
import { Command, featureEnabled, LOG_CHANNEL, STATUS_EMITTER, SUPPORTED_LANGUAGE_IDS } from "./common";
import { Command, featureEnabled, LOG_CHANNEL, STATUS_EMITTER, supportedLanguageIds } from "./common";
import { ManagerIdentifier, ManagerConfiguration } from "./ruby";
import { StatusItems } from "./status";
import { TestController } from "./testController";
Expand Down Expand Up @@ -72,7 +72,7 @@ export class RubyLsp {
}),
// Lazily activate workspaces that do not contain a lockfile
vscode.workspace.onDidOpenTextDocument(async (document) => {
if (!SUPPORTED_LANGUAGE_IDS.includes(document.languageId)) {
if (!supportedLanguageIds().includes(document.languageId)) {
return;
}

Expand Down Expand Up @@ -127,7 +127,7 @@ export class RubyLsp {
// eagerly activate the workspace for that file too
const activeDocument = vscode.window.activeTextEditor?.document;

if (activeDocument && SUPPORTED_LANGUAGE_IDS.includes(activeDocument.languageId)) {
if (activeDocument && supportedLanguageIds().includes(activeDocument.languageId)) {
const workspaceFolder = vscode.workspace.getWorkspaceFolder(activeDocument.uri);

if (workspaceFolder) {
Expand Down
4 changes: 2 additions & 2 deletions vscode/src/status.ts
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
import * as vscode from "vscode";
import { State } from "vscode-languageclient";

import { Command, STATUS_EMITTER, WorkspaceInterface, SUPPORTED_LANGUAGE_IDS } from "./common";
import { Command, STATUS_EMITTER, WorkspaceInterface, supportedLanguageIds } from "./common";

const STOPPED_SERVER_OPTIONS = [
{ label: "Ruby LSP: Start", description: Command.Start },
Expand All @@ -21,7 +21,7 @@ export abstract class StatusItem {
public item: vscode.LanguageStatusItem;

constructor(id: string) {
const documentSelector = SUPPORTED_LANGUAGE_IDS.map((language) => ({
const documentSelector = supportedLanguageIds().map((language) => ({
language,
}));

Expand Down
30 changes: 29 additions & 1 deletion vscode/src/test/suite/common.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@ import * as assert from "assert";
import * as vscode from "vscode";
import sinon from "sinon";

import { featureEnabled, FEATURE_FLAGS } from "../../common";
import { featureEnabled, FEATURE_FLAGS, supportedLanguageIds } from "../../common";

suite("featureEnabled", () => {
let sandbox: sinon.SinonSandbox;
Expand Down Expand Up @@ -131,3 +131,31 @@ suite("featureEnabled", () => {
secondStub.restore();
});
});

suite("supportedLanguageIds", () => {
let sandbox: sinon.SinonSandbox;

setup(() => {
sandbox = sinon.createSandbox();
});

teardown(() => {
sandbox.restore();
});

test("returns Ruby and ERB by default", () => {
sandbox.stub(vscode.workspace, "getConfiguration").returns({
get: () => undefined,
} as any);

assert.deepStrictEqual(supportedLanguageIds(), ["ruby", "erb"]);
});

test("includes the language IDs configured for add-ons", () => {
sandbox.stub(vscode.workspace, "getConfiguration").returns({
get: (key: string) => (key === "addonLanguageIds" ? ["slim"] : undefined),
} as any);

assert.deepStrictEqual(supportedLanguageIds(), ["ruby", "erb", "slim"]);
});
});
Loading