fix startcol & textEdit, fix #7

This commit is contained in:
chemzqm 2018-12-25 15:23:57 +08:00
parent c123b19762
commit c324456e5d
4 changed files with 44 additions and 2492 deletions

View file

@ -415,18 +415,18 @@
"@chemzqm/tslint-config": "^1.0.17", "@chemzqm/tslint-config": "^1.0.17",
"@types/fast-diff": "^1.2.0", "@types/fast-diff": "^1.2.0",
"@types/find-up": "^2.1.1", "@types/find-up": "^2.1.1",
"@types/node": "^10.12.7", "@types/node": "^10.12.18",
"coc.nvim": "0.0.29", "coc.nvim": "0.0.39",
"rimraf": "^2.6.2", "rimraf": "^2.6.2",
"tslint": "^5.11.0" "tslint": "^5.12.0"
}, },
"dependencies": { "dependencies": {
"fast-diff": "^1.2.0", "fast-diff": "^1.2.0",
"find-up": "^3.0.0", "find-up": "^3.0.0",
"semver": "^5.6.0", "semver": "^5.6.0",
"tslib": "^1.9.3", "tslib": "^1.9.3",
"typescript": "^3.1.6", "typescript": "^3.2.2",
"vscode-languageserver-protocol": "^3.13.0", "vscode-languageserver-protocol": "^3.14.1",
"vscode-uri": "^1.0.6", "vscode-uri": "^1.0.6",
"which": "^1.3.1" "which": "^1.3.1"
} }

View file

@ -2,7 +2,7 @@
* Copyright (c) Microsoft Corporation. All rights reserved. * Copyright (c) Microsoft Corporation. All rights reserved.
* Licensed under the MIT License. See License.txt in the project root for license information. * Licensed under the MIT License. See License.txt in the project root for license information.
*--------------------------------------------------------------------------------------------*/ *--------------------------------------------------------------------------------------------*/
import { CancellationToken, Command, CompletionContext, CompletionItem, InsertTextFormat, MarkupContent, MarkupKind, Position, TextDocument, TextEdit } from 'vscode-languageserver-protocol' import { CancellationToken, Command, CompletionContext, CompletionItem, InsertTextFormat, MarkupContent, MarkupKind, Position, TextDocument, TextEdit, CompletionList } from 'vscode-languageserver-protocol'
import { commands, workspace } from 'coc.nvim' import { commands, workspace } from 'coc.nvim'
import { CompletionItemProvider } from 'coc.nvim/lib/provider' import { CompletionItemProvider } from 'coc.nvim/lib/provider'
import Proto from '../protocol' import Proto from '../protocol'
@ -49,7 +49,7 @@ class ApplyCompletionCodeActionCommand implements CommandItem {
export default class TypeScriptCompletionItemProvider implements CompletionItemProvider { export default class TypeScriptCompletionItemProvider implements CompletionItemProvider {
public static readonly triggerCharacters = ['.', '@', '<'] public static readonly triggerCharacters = ['.', '"', '\'', '/', '@', '<']
private completeOption: SuggestOptions private completeOption: SuggestOptions
private noSemicolons = false private noSemicolons = false
@ -87,25 +87,26 @@ export default class TypeScriptCompletionItemProvider implements CompletionItemP
position: Position, position: Position,
token: CancellationToken, token: CancellationToken,
context: CompletionContext, context: CompletionContext,
): Promise<CompletionItem[]> { ): Promise<CompletionList | null> {
if (this.typingsStatus.isAcquiringTypings) { if (this.typingsStatus.isAcquiringTypings) {
workspace.showMessage('Acquiring typings...', 'warning') workspace.showMessage('Acquiring typings...', 'warning')
return [] return null
} }
let { uri } = document let { uri } = document
const file = this.client.toPath(document.uri) const file = this.client.toPath(document.uri)
if (!file) return [] if (!file) return null
let preText = document.getText({ let preText = document.getText({
start: { line: position.line, character: 0 }, start: { line: position.line, character: 0 },
end: position end: position
}) })
let { triggerCharacter } = context let { triggerCharacter, option } = context as any
if (!this.shouldTrigger(triggerCharacter, preText)) { if (!this.shouldTrigger(triggerCharacter, preText, option)) {
return [] return null
} }
const { completeOption } = this const { completeOption } = this
const doc = workspace.getDocument(uri)
const args: Proto.CompletionsRequestArgs = { const args: Proto.CompletionsRequestArgs = {
...typeConverters.Position.toFileLocationRequestArgs(file, position), ...typeConverters.Position.toFileLocationRequestArgs(file, position),
@ -134,7 +135,7 @@ export default class TypeScriptCompletionItemProvider implements CompletionItemP
} else { } else {
const response = await this.client.execute('completions', args, token) const response = await this.client.execute('completions', args, token)
msg = response.body msg = response.body
if (!msg) return [] if (!msg) return null
} }
const completionItems: CompletionItem[] = [] const completionItems: CompletionItem[] = []
@ -151,8 +152,16 @@ export default class TypeScriptCompletionItemProvider implements CompletionItemP
) )
completionItems.push(item) completionItems.push(item)
} }
let startcol: number | null = null
return completionItems if (triggerCharacter == '@' && !doc.isWord('@')) {
startcol = option.col - 1
}
let res: any = {
startcol,
isIncomplete: false,
items: completionItems
}
return res
} }
private getTsTriggerCharacter(context: CompletionContext): Proto.CompletionsTriggerCharacter | undefined { private getTsTriggerCharacter(context: CompletionContext): Proto.CompletionsTriggerCharacter | undefined {
@ -293,12 +302,17 @@ export default class TypeScriptCompletionItemProvider implements CompletionItemP
private shouldTrigger( private shouldTrigger(
triggerCharacter: string, triggerCharacter: string,
pre: string, pre: string,
option: any
): boolean { ): boolean {
if (triggerCharacter === '.') { if (triggerCharacter === '.') {
if (pre.match(/[\s\.'"]\.$/)) { if (pre.match(/[\s\.'"]\.$/)) {
return false return false
} }
} else if (triggerCharacter === '@') { } else if (triggerCharacter === '@') {
// trigger in string
if (option.synname && /string/i.test(option.synname)) {
return true
}
// make sure we are in something that looks like the start of a jsdoc comment // make sure we are in something that looks like the start of a jsdoc comment
if (!pre.match(/^\s*\*[ ]?@/) && !pre.match(/\/\*\*+[ ]?@/)) { if (!pre.match(/^\s*\*[ ]?@/) && !pre.match(/\/\*\*+[ ]?@/)) {
return false return false

2477
src/server/protocol.d.ts vendored

File diff suppressed because it is too large Load diff

View file

@ -3,7 +3,7 @@
* Licensed under the MIT License. See License.txt in the project root for license information. * Licensed under the MIT License. See License.txt in the project root for license information.
*--------------------------------------------------------------------------------------------*/ *--------------------------------------------------------------------------------------------*/
import { workspace } from 'coc.nvim' import { workspace } from 'coc.nvim'
import { CompletionItem, CompletionItemKind, InsertTextFormat, Position } from 'vscode-languageserver-protocol' import { Range, CompletionItem, CompletionItemKind, InsertTextFormat, Position, TextEdit } from 'vscode-languageserver-protocol'
import * as Proto from '../protocol' import * as Proto from '../protocol'
import * as PConst from '../protocol.const' import * as PConst from '../protocol.const'
@ -52,9 +52,20 @@ export function convertCompletionEntry(
let commitCharacters = getCommitCharacters(tsEntry, { isNewIdentifierLocation, isInValidCommitCharacterContext, useCodeSnippetsOnMethodSuggest }) let commitCharacters = getCommitCharacters(tsEntry, { isNewIdentifierLocation, isInValidCommitCharacterContext, useCodeSnippetsOnMethodSuggest })
let optional = tsEntry.kindModifiers && tsEntry.kindModifiers.match(/\boptional\b/) let optional = tsEntry.kindModifiers && tsEntry.kindModifiers.match(/\boptional\b/)
let textEdit: TextEdit | null = null
if (tsEntry.replacementSpan) {
let { start, end } = tsEntry.replacementSpan
if (start.line == end.line) {
textEdit = {
range: Range.create(start.line - 1, start.offset - 1, end.line - 1, end.offset - 1),
newText: insertText || label
}
}
}
return { return {
label, label,
insertText, insertText,
textEdit,
kind, kind,
insertTextFormat, insertTextFormat,
sortText, sortText,