diff --git a/src/dockerSemanticTokens.ts b/src/dockerSemanticTokens.ts index fd065d7..bd70a59 100644 --- a/src/dockerSemanticTokens.ts +++ b/src/dockerSemanticTokens.ts @@ -519,7 +519,11 @@ export class DockerSemanticTokens { let lastVariableRange = null; for (const variable of instruction.getVariables()) { const variableRange = variable.getRange(); - if (Util.isInsideRange(variableRange.start, range)) { + if (Util.isInsideRange(range.start, variableRange) && Util.isInsideRange(range.end, variableRange)) { + // the token is completely inside the variable's range, render it as a variable + this.createToken(instruction, range, SemanticTokenTypes.variable, [], false); + return; + } else if (Util.isInsideRange(variableRange.start, range)) { if (Util.positionBefore(startPosition, variableRange.start)) { // create a parameter token for the characters // before the variable diff --git a/test/dockerSemanticTokens.test.ts b/test/dockerSemanticTokens.test.ts index 343bd53..da54e20 100644 --- a/test/dockerSemanticTokens.test.ts +++ b/test/dockerSemanticTokens.test.ts @@ -606,6 +606,15 @@ describe("Dockerfile Semantic Token tests", () => { assertEdit(tokens.data, SemanticTokenTypes.variable, 10, 0, 5, 4); }); + it("RUN $var\\\\niable", () => { + const tokens = computeSemanticTokens("RUN $var\\\niable"); + assert.strictEqual(20, tokens.data.length); + assertEdit(tokens.data, SemanticTokenTypes.keyword, 0, 0, 0, 3); + assertEdit(tokens.data, SemanticTokenTypes.variable, 5, 0, 4, 4); + assertEdit(tokens.data, SemanticTokenTypes.macro, 10, 0, 4, 1); + assertEdit(tokens.data, SemanticTokenTypes.variable, 15, 1, 0, 5); + }); + it("FROM golang:$GO_VERSION AS", () => { const tokens = computeSemanticTokens("FROM golang:$GO_VERSION AS"); assert.strictEqual(20, tokens.data.length); @@ -660,6 +669,15 @@ describe("Dockerfile Semantic Token tests", () => { assertEdit(tokens.data, SemanticTokenTypes.variable, 10, 0, 7, 6); }); + it("RUN ${var}\\\\niable", () => { + const tokens = computeSemanticTokens("RUN ${var}\\\niable"); + assert.strictEqual(20, tokens.data.length); + assertEdit(tokens.data, SemanticTokenTypes.keyword, 0, 0, 0, 3); + assertEdit(tokens.data, SemanticTokenTypes.variable, 5, 0, 4, 6); + assertEdit(tokens.data, SemanticTokenTypes.macro, 10, 0, 6, 1); + assertEdit(tokens.data, SemanticTokenTypes.parameter, 15, 1, 0, 5); + }); + it("HEALTHCHECK --timeout=${a} CMD ls", () => { const tokens = computeSemanticTokens("HEALTHCHECK --timeout=${a} CMD ls"); assert.strictEqual(30, tokens.data.length);