From ec6b4d44883a7e80ad2a825c227c94e68c91b23c Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?M=C3=A1rton=20Dan=C3=B3czy?= Date: Tue, 23 Jun 2026 23:38:18 +0200 Subject: [PATCH] feat: add Kotlin/Scala glue file support and fix two bugs MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - Add kotlin (.kt/.kts) and scala (.scala) to glueExtByLanguageName - Fix: reindex crash when DidChangeConfiguration sends null/malformed settings (params.settings was blindly cast to Settings, causing undefined.reduce() if features/glue were missing — seen with Zed) - Fix: wasmBasePath resolved incorrectly when npm hoists @cucumber/language-service; use require.resolve() instead of the hardcoded __dirname/../node_modules path - Point @cucumber/language-service at marton78/language-service fork Co-Authored-By: Claude Sonnet 4.6 (1M context) --- bin/cucumber-language-server.cjs | 5 ++++- package.json | 2 +- src/CucumberLanguageServer.ts | 9 ++++++++- src/fs.ts | 2 ++ 4 files changed, 15 insertions(+), 3 deletions(-) diff --git a/bin/cucumber-language-server.cjs b/bin/cucumber-language-server.cjs index 55b4a79b..9814b9b0 100755 --- a/bin/cucumber-language-server.cjs +++ b/bin/cucumber-language-server.cjs @@ -6,7 +6,10 @@ const { NodeFiles } = require('../dist/cjs/src/node/NodeFiles') const path = require('path') const { version } = require('../dist/cjs/src/version') -const wasmBasePath = path.resolve(`${__dirname}/../node_modules/@cucumber/language-service/dist`) +// Use require.resolve so this works regardless of whether npm hoisted +// @cucumber/language-service or installed it nested inside our node_modules. +// Main CJS entry is dist/cjs/src/index.js — go up two dirs to reach dist/. +const wasmBasePath = path.join(path.dirname(require.resolve('@cucumber/language-service')), '../..') const { connection } = startStandaloneServer(wasmBasePath, (rootUri) => new NodeFiles(rootUri)) // Don't die on unhandled Promise rejections diff --git a/package.json b/package.json index eb73198a..346db2ae 100644 --- a/package.json +++ b/package.json @@ -94,7 +94,7 @@ }, "dependencies": { "@cucumber/gherkin-utils": "^12.0.0", - "@cucumber/language-service": "^1.7.0", + "@cucumber/language-service": "github:marton78/language-service#kotlin-support", "fast-glob": "3.3.3", "source-map-support": "0.5.21", "vscode-languageserver": "8.0.2", diff --git a/src/CucumberLanguageServer.ts b/src/CucumberLanguageServer.ts index de6f0659..71c44438 100644 --- a/src/CucumberLanguageServer.ts +++ b/src/CucumberLanguageServer.ts @@ -136,7 +136,14 @@ export class CucumberLanguageServer { if (params.capabilities.workspace?.configuration) { connection.onDidChangeConfiguration((params) => { this.connection.console.info(`Client sent workspace/configuration`) - this.reindex(params.settings).catch((err) => { + // params.settings may be null or missing features/glue depending on the client; + // only use it if it looks like a valid Settings object, otherwise fall back to + // getSettings() to avoid a crash on undefined.reduce() during reindex. + const settings = + params.settings?.features != null && params.settings?.glue != null + ? (params.settings as Settings) + : undefined + this.reindex(settings).catch((err) => { connection.console.error(`Failed to reindex: ${err.message}`) }) }) diff --git a/src/fs.ts b/src/fs.ts index 7254604b..2c9e0357 100644 --- a/src/fs.ts +++ b/src/fs.ts @@ -12,6 +12,8 @@ export const glueExtByLanguageName: Record = { python: ['.py'], rust: ['.rs'], go: ['.go'], + scala: ['.scala'], + kotlin: ['.kt', '.kts'], } type ExtLangEntry = [string, LanguageName]