diff --git a/.changeset/fix-extra-hyphens.md b/.changeset/fix-extra-hyphens.md new file mode 100644 index 0000000..1c114d8 --- /dev/null +++ b/.changeset/fix-extra-hyphens.md @@ -0,0 +1,6 @@ +--- +"css-variables-language-server": patch +"vscode-css-variables": patch +--- + +Fix issue where extra hyphens are added when completing a variable starting with hyphens. diff --git a/package-lock.json b/package-lock.json index a39c4c1..1f05d34 100644 --- a/package-lock.json +++ b/package-lock.json @@ -11771,7 +11771,7 @@ } }, "packages/css-variables-language-server": { - "version": "2.7.2", + "version": "2.8.2", "license": "MIT", "dependencies": { "axios": "^1.13.2", @@ -13643,7 +13643,7 @@ } }, "packages/vscode-css-variables": { - "version": "2.7.1", + "version": "2.8.2", "dependencies": { "axios": "^1.13.2", "culori": "^4.0.2", diff --git a/packages/css-variables-language-server/src/index.ts b/packages/css-variables-language-server/src/index.ts index 0f398c4..a169e02 100644 --- a/packages/css-variables-language-server/src/index.ts +++ b/packages/css-variables-language-server/src/index.ts @@ -12,6 +12,7 @@ import { ColorInformation, FileChangeType, Hover, + TextEdit, } from 'vscode-languageserver/node'; import * as fs from 'fs'; import { Position, TextDocument } from 'vscode-languageserver-textdocument'; @@ -19,7 +20,7 @@ import isColor from './utils/isColor'; import { uriToPath } from './utils/protocol'; import { findAll } from './utils/findAll'; import { indexToPosition } from './utils/indexToPosition'; -import { getCurrentWord } from './utils/getCurrentWord'; +import { getCurrentWord, getCurrentWordInfo } from './utils/getCurrentWord'; import { isInFunctionExpression } from './utils/isInFunctionExpression'; import CSSVariableManager, { CSSVariablesSettings, defaultSettings } from './CSSVariableManager'; import { formatHex } from 'culori'; @@ -184,7 +185,8 @@ connection.onCompletion( } const offset = doc.offsetAt(_textDocumentPosition.position); - const currentWord = getCurrentWord(doc, offset); + const wordInfo = getCurrentWordInfo(doc, offset); + const currentWord = wordInfo.word; const isFunctionCall = isInFunctionExpression(currentWord); @@ -194,11 +196,17 @@ connection.onCompletion( const insertText = isFunctionCall ? varSymbol.name : `var(${varSymbol.name})`; + + const start = doc.positionAt(wordInfo.left + 1); + const end = doc.positionAt(wordInfo.right); + const range = { start, end }; + const completion: CompletionItem = { label: varSymbol.name, detail: varSymbol.value, documentation: varSymbol.value, insertText, + textEdit: TextEdit.replace(range, insertText), kind: isColor(varSymbol.value) ? CompletionItemKind.Color : CompletionItemKind.Variable, diff --git a/packages/css-variables-language-server/src/tests/unit-tests/getCurrentWord.test.ts b/packages/css-variables-language-server/src/tests/unit-tests/getCurrentWord.test.ts new file mode 100644 index 0000000..04afdc6 --- /dev/null +++ b/packages/css-variables-language-server/src/tests/unit-tests/getCurrentWord.test.ts @@ -0,0 +1,24 @@ + +import { TextDocument } from 'vscode-languageserver-textdocument'; +import { getCurrentWord } from '../../utils/getCurrentWord'; + +describe('getCurrentWord', () => { + it('should return word including delimiter at start', () => { + const text = 'var(--color)'; + const document = TextDocument.create('test.css', 'css', 1, text); + // offset at end of --color + // v:0, a:1, r:2, (:3, -:4, -:5, c:6, ... r:10, ):11 + // offset 11 (before )) + const word = getCurrentWord(document, 11); + expect(word).toBe('(--color'); + }); + + it('should handle cursor at delimiter', () => { + const text = 'var(--)'; + const document = TextDocument.create('test.css', 'css', 1, text); + // v:0, a:1, r:2, (:3, -:4, -:5, ):6 + // offset 6 (at )) + const word = getCurrentWord(document, 6); + expect(word).toBe('(--'); + }); +}); diff --git a/packages/css-variables-language-server/src/utils/getCurrentWord.ts b/packages/css-variables-language-server/src/utils/getCurrentWord.ts index b91b0fb..dd9ef17 100644 --- a/packages/css-variables-language-server/src/utils/getCurrentWord.ts +++ b/packages/css-variables-language-server/src/utils/getCurrentWord.ts @@ -1,8 +1,14 @@ import { TextDocument } from 'vscode-languageserver-textdocument'; -export function getCurrentWord(document: TextDocument, offset: number): string { +export interface WordInfo { + word: string; + left: number; + right: number; +} + +export function getCurrentWordInfo(document: TextDocument, offset: number): WordInfo { let left = offset - 1; - let right = offset + 1; + let right = offset; const text = document.getText(); while (left >= 0 && ' \t\n\r":{[()]},*>+'.indexOf(text.charAt(left)) === -1) { @@ -16,5 +22,13 @@ export function getCurrentWord(document: TextDocument, offset: number): string { right++; } - return text.substring(left, right); + return { + word: text.substring(left, right), + left, + right + }; +} + +export function getCurrentWord(document: TextDocument, offset: number): string { + return getCurrentWordInfo(document, offset).word; }