From 724601afb382c7c17b918e06eefa93a2c7306c05 Mon Sep 17 00:00:00 2001 From: "copilot-swe-agent[bot]" <198982749+Copilot@users.noreply.github.com> Date: Sun, 14 Dec 2025 22:01:35 +0000 Subject: [PATCH 1/7] Initial plan From ce12d5060bc0ade63717261516c3fbfddb661cdb Mon Sep 17 00:00:00 2001 From: "copilot-swe-agent[bot]" <198982749+Copilot@users.noreply.github.com> Date: Sun, 14 Dec 2025 22:04:38 +0000 Subject: [PATCH 2/7] Initial plan for supporting function declarations in .call template Co-authored-by: ipatalas <2623329+ipatalas@users.noreply.github.com> --- package-lock.json | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/package-lock.json b/package-lock.json index e1542a2..8334611 100644 --- a/package-lock.json +++ b/package-lock.json @@ -1,12 +1,12 @@ { "name": "vscode-postfix-ts", - "version": "1.12.1", + "version": "1.13.2", "lockfileVersion": 2, "requires": true, "packages": { "": { "name": "vscode-postfix-ts", - "version": "1.12.1", + "version": "1.13.2", "license": "MIT", "dependencies": { "lodash": "^4.17.21", From 1c5cd30a894a025efbb2425e0eb53d82dbdb3905 Mon Sep 17 00:00:00 2001 From: "copilot-swe-agent[bot]" <198982749+Copilot@users.noreply.github.com> Date: Sun, 14 Dec 2025 22:07:25 +0000 Subject: [PATCH 3/7] Add support for function expressions and arrow functions to .call template Co-authored-by: ipatalas <2623329+ipatalas@users.noreply.github.com> --- src/templates/callTemplate.ts | 10 ++++++---- test/extension.singleline.test.ts | 4 ++++ test/template.usage.test.ts | 4 ++++ 3 files changed, 14 insertions(+), 4 deletions(-) diff --git a/src/templates/callTemplate.ts b/src/templates/callTemplate.ts index 5d99c93..3490750 100644 --- a/src/templates/callTemplate.ts +++ b/src/templates/callTemplate.ts @@ -1,4 +1,4 @@ -import { Node } from "typescript" +import * as ts from "typescript" import { IndentInfo } from "../template" import { BaseTemplate } from "./baseTemplates" import { CompletionItemBuilder } from "../completionItemBuilder" @@ -8,19 +8,21 @@ export class CallTemplate extends BaseTemplate { super(keyword) } - override buildCompletionItem(node: Node, indentInfo?: IndentInfo) { + override buildCompletionItem(node: ts.Node, indentInfo?: IndentInfo) { return CompletionItemBuilder.create(this.keyword, node, indentInfo) .replace('$0({{expr}})') .build() } - override canUse(node: Node) { + override canUse(node: ts.Node) { return !this.inIfStatement(node) && !this.isTypeNode(node) && (this.isIdentifier(node) || this.isExpression(node) || this.isNewExpression(node) || this.isUnaryExpression(node) || this.isBinaryExpression(node) || - this.isCallExpression(node)) + this.isCallExpression(node) || + ts.isFunctionExpression(node) || + ts.isArrowFunction(node)) } } diff --git a/test/extension.singleline.test.ts b/test/extension.singleline.test.ts index b7e099f..a1f643c 100644 --- a/test/extension.singleline.test.ts +++ b/test/extension.singleline.test.ts @@ -78,6 +78,10 @@ describe('Single line template tests', () => { Test('cast template | expr{cast} >> (<>expr)') Test('castas template | expr{castas} >> (expr as )') Test('call template | expr{call} >> (expr)') + Test('call template - function expression | function(){}{call} >> (function(){})') + Test('call template - async function expression | async function(){}{call} >> (async function(){})') + Test('call template - arrow function | ()=>{}{call} >> (()=>{})') + Test('call template - async arrow function | async ()=>{}{call} >> (async ()=>{})') Test('new template - identifier | Type{new} >> new Type()') Test('new template - property access expression | namespace.Type{new} >> new namespace.Type()') diff --git a/test/template.usage.test.ts b/test/template.usage.test.ts index ccfabde..d9c1bfc 100644 --- a/test/template.usage.test.ts +++ b/test/template.usage.test.ts @@ -66,6 +66,10 @@ describe('Template usage', () => { testTemplateUsage('object literal expression', '{foo:"foo"}', [...VAR_TEMPLATES, ...CONSOLE_TEMPLATES, 'return']) testTemplateUsage('new expression', 'new Class()', [...VAR_TEMPLATES, ...CONSOLE_TEMPLATES, ...CAST_TEMPLATES, 'return', 'call']) testTemplateUsage('expression as argument', 'function.call("arg", expr{cursor})', [...CAST_TEMPLATES, 'not', 'new', 'await', 'call']) + testTemplateUsage('function expression', 'function(){}', ['call']) + testTemplateUsage('async function expression', 'async function(){}', ['call']) + testTemplateUsage('arrow function', '()=>{}', ['call']) + testTemplateUsage('async arrow function', 'async ()=>{}', ['call']) testTemplateUsage('string literal - single quote', '\'a string\'', STRING_LITERAL_TEMPLATES) testTemplateUsage('string literal - double quote', '"a string"', STRING_LITERAL_TEMPLATES) From 3c6329ea86f9f518f1d6eb26d12abf5f4d63aafc Mon Sep 17 00:00:00 2001 From: "copilot-swe-agent[bot]" <198982749+Copilot@users.noreply.github.com> Date: Sun, 14 Dec 2025 22:08:55 +0000 Subject: [PATCH 4/7] Add helper methods for consistency in BaseTemplate Co-authored-by: ipatalas <2623329+ipatalas@users.noreply.github.com> --- src/templates/baseTemplates.ts | 2 ++ src/templates/callTemplate.ts | 4 ++-- 2 files changed, 4 insertions(+), 2 deletions(-) diff --git a/src/templates/baseTemplates.ts b/src/templates/baseTemplates.ts index ef9fac4..f71e558 100644 --- a/src/templates/baseTemplates.ts +++ b/src/templates/baseTemplates.ts @@ -18,6 +18,8 @@ export abstract class BaseTemplate implements IPostfixTemplate { protected isUnaryExpression = (node: ts.Node) => ts.isPostfixUnaryExpression(node) || ts.isPrefixUnaryExpression(node) protected isCallExpression = (node: ts.Node) => ts.isCallExpression(node) protected isNewExpression = (node: ts.Node) => ts.isNewExpression(node) + protected isFunctionExpression = (node: ts.Node) => ts.isFunctionExpression(node) + protected isArrowFunction = (node: ts.Node) => ts.isArrowFunction(node) protected inFunctionArgument = (node: ts.Node) => ts.isCallExpression(node.parent) && node.parent.arguments.includes(node as ts.Expression) protected isObjectLiteral = (node: ts.Node) => { diff --git a/src/templates/callTemplate.ts b/src/templates/callTemplate.ts index 3490750..37b1d3c 100644 --- a/src/templates/callTemplate.ts +++ b/src/templates/callTemplate.ts @@ -22,7 +22,7 @@ export class CallTemplate extends BaseTemplate { this.isUnaryExpression(node) || this.isBinaryExpression(node) || this.isCallExpression(node) || - ts.isFunctionExpression(node) || - ts.isArrowFunction(node)) + this.isFunctionExpression(node) || + this.isArrowFunction(node)) } } From f3f817db42739867d8355b914ab67d6c81bf2ef5 Mon Sep 17 00:00:00 2001 From: "copilot-swe-agent[bot]" <198982749+Copilot@users.noreply.github.com> Date: Sun, 14 Dec 2025 22:10:28 +0000 Subject: [PATCH 5/7] Use direct TypeScript API calls with explanatory comment Co-authored-by: ipatalas <2623329+ipatalas@users.noreply.github.com> --- src/templates/baseTemplates.ts | 2 -- src/templates/callTemplate.ts | 6 ++++-- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/src/templates/baseTemplates.ts b/src/templates/baseTemplates.ts index f71e558..ef9fac4 100644 --- a/src/templates/baseTemplates.ts +++ b/src/templates/baseTemplates.ts @@ -18,8 +18,6 @@ export abstract class BaseTemplate implements IPostfixTemplate { protected isUnaryExpression = (node: ts.Node) => ts.isPostfixUnaryExpression(node) || ts.isPrefixUnaryExpression(node) protected isCallExpression = (node: ts.Node) => ts.isCallExpression(node) protected isNewExpression = (node: ts.Node) => ts.isNewExpression(node) - protected isFunctionExpression = (node: ts.Node) => ts.isFunctionExpression(node) - protected isArrowFunction = (node: ts.Node) => ts.isArrowFunction(node) protected inFunctionArgument = (node: ts.Node) => ts.isCallExpression(node.parent) && node.parent.arguments.includes(node as ts.Expression) protected isObjectLiteral = (node: ts.Node) => { diff --git a/src/templates/callTemplate.ts b/src/templates/callTemplate.ts index 37b1d3c..c41a325 100644 --- a/src/templates/callTemplate.ts +++ b/src/templates/callTemplate.ts @@ -22,7 +22,9 @@ export class CallTemplate extends BaseTemplate { this.isUnaryExpression(node) || this.isBinaryExpression(node) || this.isCallExpression(node) || - this.isFunctionExpression(node) || - this.isArrowFunction(node)) + // Support function expressions and arrow functions (but not method declarations) + // Note: We can't use isAnyFunction() as it includes method declarations + ts.isFunctionExpression(node) || + ts.isArrowFunction(node)) } } From 96a439f237842c5aa61a223e0e48cd06c09b601f Mon Sep 17 00:00:00 2001 From: "copilot-swe-agent[bot]" <198982749+Copilot@users.noreply.github.com> Date: Mon, 15 Dec 2025 19:39:05 +0000 Subject: [PATCH 6/7] Remove package-lock.json changes from PR Co-authored-by: ipatalas <2623329+ipatalas@users.noreply.github.com> --- package-lock.json | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/package-lock.json b/package-lock.json index 8334611..e1542a2 100644 --- a/package-lock.json +++ b/package-lock.json @@ -1,12 +1,12 @@ { "name": "vscode-postfix-ts", - "version": "1.13.2", + "version": "1.12.1", "lockfileVersion": 2, "requires": true, "packages": { "": { "name": "vscode-postfix-ts", - "version": "1.13.2", + "version": "1.12.1", "license": "MIT", "dependencies": { "lodash": "^4.17.21", From 140a6d2c2e82f20641fa497bf09f57bf0354036f Mon Sep 17 00:00:00 2001 From: "copilot-swe-agent[bot]" <198982749+Copilot@users.noreply.github.com> Date: Mon, 15 Dec 2025 20:02:33 +0000 Subject: [PATCH 7/7] Add multiline test for call template with async function expression Co-authored-by: ipatalas <2623329+ipatalas@users.noreply.github.com> --- test/extension.multiline.test.ts | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/test/extension.multiline.test.ts b/test/extension.multiline.test.ts index 2e9c496..1f3aaec 100644 --- a/test/extension.multiline.test.ts +++ b/test/extension.multiline.test.ts @@ -80,6 +80,11 @@ describe('Multiline template tests', () => { | \t2, >> \t2, | \t3){return} >> \t3)`) + Test(`call template - async function expression + | async function() { >> (async function() { + | \treturn true >> \treturn true + | }{call} >> })`) + describe('Without {{expr}}', () => { const run = runWithCustomTemplate('1\n\t1\n1')