Skip to content

Commit 3312dc5

Browse files
committed
Fixes #376
1 parent afe825b commit 3312dc5

File tree

2 files changed

+16
-8
lines changed

2 files changed

+16
-8
lines changed

CHANGELOG.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,7 @@
33
## [2.7.4] - 2025-XX-XX
44
- Fix issue [#373](https://github.com/intersystems/language-server/issues/373): Add go to definition and hover support for `UrlMap` Call and Forward attribute values
55
- Fix issue [#374](https://github.com/intersystems/language-server/issues/374): `undefined` items appearing in completion lists for XML XData
6+
- Fix issue [#376](https://github.com/intersystems/language-server/issues/376): Completion inside `$TEXT()` should always return routines
67

78
## [2.7.3] - 2025-05-05
89
- Fix issue [#366](https://github.com/intersystems/language-server/issues/366): Language Server can return invalid DocumentSymbols in some rare circumstances

server/src/providers/completion.ts

Lines changed: 15 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -654,20 +654,27 @@ async function globalsOrRoutines(
654654
settings: LanguageServerConfiguration, server: ServerSpec, lineText: string, prefix: string = ""
655655
): Promise<CompletionItem[]> {
656656
// Determine if this is a routine or global, and return null if we're in $BITLOGIC
657-
let brk = false, parenLevel = 0, isBitlogic = false, lastCmd = "";
657+
let brk = false, parenLevel = 0, isBitlogic = false, lastCmd = "", isRoutine = false;
658658
for (let ln = line; ln >= 0; ln--) {
659659
if (!parsed[ln]?.length) continue;
660660
for (let tkn = (ln == line ? token : parsed[ln].length - 1); tkn >= 0; tkn--) {
661661
if (parsed[ln][tkn].l == ld.cos_langindex && parsed[ln][tkn].s == ld.cos_delim_attrindex) {
662662
const delimtext = doc.getText(Range.create(ln,parsed[ln][tkn].p,ln,parsed[ln][tkn].p+parsed[ln][tkn].c));
663663
if (delimtext == "(") {
664664
parenLevel++;
665-
if (parenLevel > 0 && tkn > 0 && parsed[ln][tkn-1].l == ld.cos_langindex && parsed[ln][tkn-1].s == ld.cos_sysf_attrindex &&
666-
doc.getText(Range.create(ln,parsed[ln][tkn-1].p,ln,parsed[ln][tkn-1].p+parsed[ln][tkn-1].c)).toLowerCase() == "$bitlogic"
667-
) {
668-
isBitlogic = true;
669-
brk = true;
670-
break;
665+
if (parenLevel > 0 && tkn > 0 && parsed[ln][tkn-1].l == ld.cos_langindex && parsed[ln][tkn-1].s == ld.cos_sysf_attrindex) {
666+
const sysf = doc.getText(Range.create(ln,parsed[ln][tkn-1].p,ln,parsed[ln][tkn-1].p+parsed[ln][tkn-1].c)).toLowerCase();
667+
if (sysf == "$bitlogic") {
668+
// Caret inside $BITLOGIC is neither a routine nor global prefix
669+
isBitlogic = true;
670+
brk = true;
671+
break;
672+
} else if (["$text","$t"].includes(sysf)) {
673+
// Caret inside $TEXT is always a routine prefix
674+
isRoutine = true;
675+
brk = true;
676+
break;
677+
}
671678
}
672679
}
673680
else if (delimtext == ")") {
@@ -682,7 +689,7 @@ async function globalsOrRoutines(
682689
if (brk) break;
683690
}
684691
if (isBitlogic) return null;
685-
const isRoutine =
692+
isRoutine = isRoutine ||
686693
// The character before the caret is part of a label or extrinsic function syntax
687694
/[%$\d\p{L}]/u.test(lineText.slice(-2,-1)) ||
688695
// Routine syntax without a label or extrinsic function syntax can only appear as an argument for a DO or JOB command

0 commit comments

Comments
 (0)