提交 e8b01da7 编写于 作者: M Matt Bierner 提交者: GitHub

Clean Up JSDoc Completion Provider Implementation (#25981)

* Fix JSDoc Completion Provider

**Bug**
89da6ab8 fixed #11944 by changing how enter works in completion providers. Now if the completion exactly matches the current text, pressing `enter` is not captured by the the suggestion widget. Instead it inserts a new line into the editor. This broke the jsdoc completion provider which uses `''` as a placeholder insertion before calculating the actual insertion upon being accepted. This weird behavior is because of a of the current tsserver api

**Fix**
Change the insert text to a single space instead. This seems to fix this issue in my testing.

* Slightly more elegant fix
上级 7d2dea4e
......@@ -26,7 +26,7 @@ namespace Configuration {
class JsDocCompletionItem extends CompletionItem {
constructor(
file: Uri,
document: TextDocument,
position: Position,
shouldGetJSDocFromTSServer: boolean,
) {
......@@ -34,10 +34,19 @@ class JsDocCompletionItem extends CompletionItem {
this.detail = localize('typescript.jsDocCompletionItem.documentation', 'JSDoc comment');
this.insertText = '';
this.sortText = '\0';
const line = document.lineAt(position.line).text;
const prefix = line.slice(0, position.character).match(/\/\**\s*$/);
const suffix = line.slice(position.character).match(/^\s*\**\//);
const start = position.translate(0, prefix ? -prefix[0].length : 0);
this.range = new Range(
start,
position.translate(0, suffix ? suffix[0].length : 0));
this.command = {
title: 'Try Complete JSDoc',
command: TryCompleteJsDocCommand.COMMAND_NAME,
arguments: [file, position, shouldGetJSDocFromTSServer]
arguments: [document.uri, start, shouldGetJSDocFromTSServer]
};
}
}
......@@ -67,7 +76,7 @@ export class JsDocCompletionProvider implements CompletionItemProvider {
const line = document.lineAt(position.line).text;
const prefix = line.slice(0, position.character);
if (prefix.match(/^\s*$|\/\*\*\s*$|^\s*\/\*\*+\s*$/)) {
return [new JsDocCompletionItem(document.uri, position, this.config.enabled)];
return [new JsDocCompletionItem(document, position, this.config.enabled)];
}
return [];
}
......@@ -80,15 +89,15 @@ export class JsDocCompletionProvider implements CompletionItemProvider {
export class TryCompleteJsDocCommand {
static COMMAND_NAME = '_typeScript.tryCompleteJsDoc';
constructor(private client: ITypescriptServiceClient) {
}
constructor(
private client: ITypescriptServiceClient
) { }
/**
* Try to insert a jsdoc comment, using a template provide by typescript
* if possible, otherwise falling back to a default comment format.
*/
public tryCompleteJsDoc(resource: Uri, position: Position, shouldGetJSDocFromTSServer: boolean): Thenable<boolean> {
public tryCompleteJsDoc(resource: Uri, start: Position, shouldGetJSDocFromTSServer: boolean): Thenable<boolean> {
const file = this.client.normalizePath(resource);
if (!file) {
return Promise.resolve(false);
......@@ -99,44 +108,17 @@ export class TryCompleteJsDocCommand {
return Promise.resolve(false);
}
return this.prepForDocCompletion(editor, position)
.then((start: Position) => {
if (!shouldGetJSDocFromTSServer) {
return this.tryInsertDefaultDoc(editor, start);
}
return this.tryInsertJsDocFromTemplate(editor, file, start)
.then((didInsertFromTemplate: boolean) => {
if (didInsertFromTemplate) {
return true;
}
return this.tryInsertDefaultDoc(editor, start);
});
});
}
/**
* Prepare the area around the position for insertion of the jsdoc.
*
* Removes any the prefix and suffix of a possible jsdoc
*/
private prepForDocCompletion(editor: TextEditor, position: Position): Thenable<Position> {
const line = editor.document.lineAt(position.line).text;
const prefix = line.slice(0, position.character).match(/\/\**\s*$/);
const suffix = line.slice(position.character).match(/^\s*\**\//);
if (!prefix && !suffix) {
// Nothing to remove
return Promise.resolve(position);
if (!shouldGetJSDocFromTSServer) {
return this.tryInsertDefaultDoc(editor, start);
}
const start = position.translate(0, prefix ? -prefix[0].length : 0);
return editor.edit(
edits => {
edits.delete(new Range(start, position.translate(0, suffix ? suffix[0].length : 0)));
}, {
undoStopBefore: true,
undoStopAfter: false
}).then(() => start);
return this.tryInsertJsDocFromTemplate(editor, file, start)
.then((didInsertFromTemplate: boolean) => {
if (didInsertFromTemplate) {
return true;
}
return this.tryInsertDefaultDoc(editor, start);
});
}
private tryInsertJsDocFromTemplate(editor: TextEditor, file: string, position: Position): Promise<boolean> {
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册