diff --git a/src/completionItemBuilder.ts b/src/completionItemBuilder.ts index e917b38..efbae91 100644 --- a/src/completionItemBuilder.ts +++ b/src/completionItemBuilder.ts @@ -3,8 +3,9 @@ import ts = require('typescript') import { adjustMultilineIndentation } from './utils/multiline-expressions' import { SnippetParser } from 'vscode-snippet-parser' import { getConfigValue } from './utils' +import { getLastExpressionName, getLastExpressionNode, } from './utils/infer-names' -const RegexExpression = '{{expr(?::(upper|lower|capitalize))?}}' +const RegexExpression = '{{(expr|exprLast|exprRest)(?::(upper|lower|capitalize))?}}' export class CompletionItemBuilder { private item: vsc.CompletionItem @@ -95,12 +96,22 @@ export class CompletionItemBuilder { private replaceExpression = (replacement: string, code: string, customRegex?: string) => { const re = new RegExp(customRegex || RegexExpression, 'g') - return replacement.replace(re, (_match, p1) => { - if (p1 && this.filters[p1]) { - return this.filters[p1](code) + return replacement.replace(re, (_match, type, variant) => { + let codeToInsert: string; + if (type === 'expr') { + codeToInsert = code; + } else if (type === 'exprLast') { + codeToInsert = getLastExpressionName(this.node); + } else { + const lastExpr = getLastExpressionNode(this.node) + codeToInsert = lastExpr ? code.slice(0, lastExpr.getStart() - this.node.getStart() - 1) /* -1 for dot */ : '' } - return code; - }) + + if (variant && this.filters[variant]) { + return this.filters[variant](codeToInsert) + } + return codeToInsert; + }); } private filters: {[key: string]: (x: string) => string} = { diff --git a/src/utils/infer-names.ts b/src/utils/infer-names.ts index ad28ed3..e192640 100644 --- a/src/utils/infer-names.ts +++ b/src/utils/infer-names.ts @@ -22,7 +22,7 @@ export const inferVarTemplateName = (node: ts.Node): string[] => { } export const inferForVarTemplate = (node: ts.Node): string[] => { - const subjectName = getForExpressionName(node) + const subjectName = getLastExpressionName(node) if (!subjectName) { return } @@ -47,28 +47,36 @@ function beautifyMethodName(name: string) { return MethodCallRegex.exec(name)?.groups?.name } -function getForExpressionName(node: ts.Node) { +export function getLastExpressionNode(node: ts.Node) { if (ts.isIdentifier(node)) { - return node.text + return node } else if (ts.isPropertyAccessExpression(node)) { - return node.name.text + return node.name } else if (ts.isCallExpression(node)) { - return getMethodName(node) + return getMethodNode(node) } } -function getMethodName(node: ts.CallExpression) { +export function getLastExpressionName(node: ts.Node) { + return getLastExpressionNode(node)?.text +} + +function getMethodNode(node: ts.CallExpression) { if (ts.isIdentifier(node.expression)) { - return node.expression.text + return node.expression } else if (ts.isPropertyAccessExpression(node.expression)) { - return node.expression.name.text + return node.expression.name } } +function getMethodName(node: ts.CallExpression) { + return getMethodNode(node)?.text +} + function inferNewExpressionVar(node: ts.NewExpression) { if (ts.isIdentifier(node.expression)) { return node.expression.text } else if (ts.isPropertyAccessExpression(node.expression)) { return node.expression.name.text } -} \ No newline at end of file +}