Skip to content

Commit d6085f7

Browse files
author
Kanchalai Tanglertsampan
committed
Return completions for JsDoc tagname even when there are no "@' sign prefix
1 parent fc9bcc1 commit d6085f7

File tree

2 files changed

+52
-19
lines changed

2 files changed

+52
-19
lines changed

src/services/completions.ts

Lines changed: 29 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -16,11 +16,11 @@ namespace ts.Completions {
1616
return undefined;
1717
}
1818

19-
const { symbols, isGlobalCompletion, isMemberCompletion, isNewIdentifierLocation, location, isJsDocTagName } = completionData;
19+
const { symbols, isGlobalCompletion, isMemberCompletion, isNewIdentifierLocation, location, isJsDocTagName, shouldAppendAtSignBeforeJsDocTagName } = completionData;
2020

2121
if (isJsDocTagName) {
2222
// If the current position is a jsDoc tag name, only tag names should be provided for completion
23-
return { isGlobalCompletion: false, isMemberCompletion: false, isNewIdentifierLocation: false, entries: JsDoc.getAllJsDocCompletionEntries() };
23+
return { isGlobalCompletion: false, isMemberCompletion: false, isNewIdentifierLocation: false, entries: JsDoc.getAllJsDocCompletionEntries(shouldAppendAtSignBeforeJsDocTagName) };
2424
}
2525

2626
const entries: CompletionEntry[] = [];
@@ -815,6 +815,12 @@ namespace ts.Completions {
815815
const isJavaScriptFile = isSourceFileJavaScript(sourceFile);
816816

817817
let isJsDocTagName = false;
818+
// This is for the case when users request completion in JsDoc without "@"
819+
// i.e.
820+
// /**
821+
// * |completion here|
822+
// **/
823+
let shouldAppendAtSignBeforeJsDocTagName = false;
818824

819825
let start = timestamp();
820826
const currentToken = getTokenAtPosition(sourceFile, position);
@@ -826,10 +832,24 @@ namespace ts.Completions {
826832
log("getCompletionData: Is inside comment: " + (timestamp() - start));
827833

828834
if (insideComment) {
829-
// The current position is next to the '@' sign, when no tag name being provided yet.
830-
// Provide a full list of tag names
831-
if (hasDocComment(sourceFile, position) && sourceFile.text.charCodeAt(position - 1) === CharacterCodes.at) {
832-
isJsDocTagName = true;
835+
if (hasDocComment(sourceFile, position)) {
836+
// The current position is next to the '@' sign, when no tag name being provided yet.
837+
// Provide a full list of tag names
838+
if (sourceFile.text.charCodeAt(position - 1) === CharacterCodes.at) {
839+
isJsDocTagName = true;
840+
}
841+
else {
842+
const lineStart = getLineStartPositionForPosition(position, sourceFile);
843+
shouldAppendAtSignBeforeJsDocTagName = sourceFile.text.substr(lineStart, position).indexOf("@") === -1;
844+
845+
// This is for the case
846+
// /**
847+
// * |completion here|
848+
// **/
849+
if (shouldAppendAtSignBeforeJsDocTagName) {
850+
isJsDocTagName = true;
851+
}
852+
}
833853
}
834854

835855
// Completion should work inside certain JsDoc tags. For example:
@@ -854,8 +874,8 @@ namespace ts.Completions {
854874
}
855875
}
856876

857-
if (isJsDocTagName) {
858-
return { symbols: undefined, isGlobalCompletion: false, isMemberCompletion: false, isNewIdentifierLocation: false, location: undefined, isRightOfDot: false, isJsDocTagName };
877+
if (isJsDocTagName || shouldAppendAtSignBeforeJsDocTagName) {
878+
return { symbols: undefined, isGlobalCompletion: false, isMemberCompletion: false, isNewIdentifierLocation: false, location: undefined, isRightOfDot: false, isJsDocTagName, shouldAppendAtSignBeforeJsDocTagName };
859879
}
860880

861881
if (!insideJsDocTagExpression) {
@@ -983,7 +1003,7 @@ namespace ts.Completions {
9831003

9841004
log("getCompletionData: Semantic work: " + (timestamp() - semanticStart));
9851005

986-
return { symbols, isGlobalCompletion, isMemberCompletion, isNewIdentifierLocation, location, isRightOfDot: (isRightOfDot || isRightOfOpenTag), isJsDocTagName };
1006+
return { symbols, isGlobalCompletion, isMemberCompletion, isNewIdentifierLocation, location, isRightOfDot: (isRightOfDot || isRightOfOpenTag), isJsDocTagName, shouldAppendAtSignBeforeJsDocTagName };
9871007

9881008
function getTypeScriptMemberSymbols(): void {
9891009
// Right of dot member completion list

src/services/jsDoc.ts

Lines changed: 23 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -42,7 +42,8 @@ namespace ts.JsDoc {
4242
"prop",
4343
"version"
4444
];
45-
let jsDocCompletionEntries: CompletionEntry[];
45+
let jsDocTagNameCompletionEntries: CompletionEntry[];
46+
let jsDocTagNameWithAtSignCompletionEntries: CompletionEntry[];
4647

4748
export function getJsDocCommentsFromDeclarations(declarations: Declaration[]) {
4849
// Only collect doc comments from duplicate declarations once:
@@ -88,15 +89,27 @@ namespace ts.JsDoc {
8889
return undefined;
8990
}
9091

91-
export function getAllJsDocCompletionEntries(): CompletionEntry[] {
92-
return jsDocCompletionEntries || (jsDocCompletionEntries = ts.map(jsDocTagNames, tagName => {
93-
return {
94-
name: tagName,
95-
kind: ScriptElementKind.keyword,
96-
kindModifiers: "",
97-
sortText: "0",
98-
};
99-
}));
92+
export function getAllJsDocCompletionEntries(shouldAppendAtSign: boolean): CompletionEntry[] {
93+
if (!shouldAppendAtSign) {
94+
return jsDocTagNameCompletionEntries || (jsDocTagNameCompletionEntries = ts.map(jsDocTagNames, tagName => {
95+
return {
96+
name: tagName,
97+
kind: ScriptElementKind.keyword,
98+
kindModifiers: "",
99+
sortText: "0",
100+
};
101+
}));
102+
}
103+
else {
104+
return jsDocTagNameWithAtSignCompletionEntries || (jsDocTagNameWithAtSignCompletionEntries = ts.map(jsDocTagNames, tagName => {
105+
return {
106+
name: `@${tagName}`,
107+
kind: ScriptElementKind.keyword,
108+
kindModifiers: "",
109+
sortText: "0"
110+
}
111+
}));
112+
}
100113
}
101114

102115
/**

0 commit comments

Comments
 (0)