fix snippet generate

This commit is contained in:
chemzqm 2019-02-20 02:39:22 +08:00
parent 0473880f30
commit 8febbe9418
3 changed files with 103 additions and 20 deletions

View file

@ -15,6 +15,7 @@ import * as Previewer from '../utils/previewer'
import * as typeConverters from '../utils/typeConverters'
import TypingsStatus from '../utils/typingsStatus'
import FileConfigurationManager, { SuggestOptions } from './fileConfigurationManager'
import SnippetString from '../utils/SnippetString'
// command center
export interface CommandItem {
@ -352,26 +353,16 @@ export default class TypeScriptCompletionItemProvider implements CompletionItemP
detail: Proto.CompletionEntryDetails
): void {
let { displayParts } = detail
let snippet = (item.insertText || item.label) + '(' // tslint:disable-line
const parameterListParts = getParameterListParts(displayParts)
let { parts, hasOptionalParameters } = parameterListParts
let idx = 1
if (parts.length == 0 && hasOptionalParameters) {
item.insertText = snippet + '${1})$0'
return
const snippet = new SnippetString()
snippet.appendText(`${item.insertText || item.label}(`)
appendJoinedPlaceholders(snippet, parameterListParts.parts, ', ')
if (parameterListParts.hasOptionalParameters) {
snippet.appendTabstop()
}
for (let part of parts) {
snippet += '${' + idx + ':' + part.text + '}' // tslint:disable-line
if (idx == parts.length) {
if (hasOptionalParameters) snippet += '${' + (idx + 1) + '}' // tslint:disable-line
} else {
snippet += ', '
}
idx = idx + 1
}
snippet += ')$0'
// tslint:disable-next-line:deprecation
item.insertText = snippet
snippet.appendText(')')
snippet.appendTabstop(0)
item.insertText = snippet.value
}
private async isValidFunctionCompletionContext(
@ -415,3 +406,17 @@ function shouldExcludeCompletionEntry(
|| (!completionConfiguration.autoImports && element.hasAction)
)
}
function appendJoinedPlaceholders(
snippet: SnippetString,
parts: ReadonlyArray<Proto.SymbolDisplayPart>,
joiner: string
) {
for (let i = 0; i < parts.length; ++i) {
const paramterPart = parts[i]
snippet.appendPlaceholder(paramterPart.text)
if (i !== parts.length - 1) {
snippet.appendText(joiner)
}
}
}

View file

@ -0,0 +1,79 @@
export default class SnippetString {
static isSnippetString(thing: any): thing is SnippetString {
if (thing instanceof SnippetString) {
return true
}
if (!thing) {
return false
}
return typeof (<SnippetString>thing).value === 'string'
}
private static _escape(value: string): string {
return value.replace(/\$|}|\\/g, '\\$&')
}
private _tabstop: number = 1
value: string
constructor(value?: string) {
this.value = value || ''
}
appendText(string: string): SnippetString {
this.value += SnippetString._escape(string)
return this
}
appendTabstop(number: number = this._tabstop++): SnippetString {
this.value += '$'
this.value += number
return this
}
appendPlaceholder(value: string | ((snippet: SnippetString) => any), number: number = this._tabstop++): SnippetString {
if (typeof value === 'function') {
const nested = new SnippetString()
nested._tabstop = this._tabstop
value(nested)
this._tabstop = nested._tabstop
value = nested.value
} else {
value = SnippetString._escape(value)
}
this.value += '${'
this.value += number
this.value += ':'
this.value += value
this.value += '}'
return this
}
appendVariable(name: string, defaultValue?: string | ((snippet: SnippetString) => any)): SnippetString {
if (typeof defaultValue === 'function') {
const nested = new SnippetString()
nested._tabstop = this._tabstop
defaultValue(nested)
this._tabstop = nested._tabstop
defaultValue = nested.value
} else if (typeof defaultValue === 'string') {
defaultValue = defaultValue.replace(/\$|}/g, '\\$&')
}
this.value += '${'
this.value += name
if (defaultValue) {
this.value += ':'
this.value += defaultValue
}
this.value += '}'
return this
}
}

View file

@ -178,7 +178,7 @@ export function getParameterListParts(
break
case PConst.DisplayPartKind.parameterName:
if (parenCount === 1 && isInMethod) {
if (parenCount === 1 && braceCount === 0 && isInMethod) {
// Only take top level paren names
const next = displayParts[i + 1]
// Skip optional parameters
@ -210,6 +210,5 @@ export function getParameterListParts(
break
}
}
return { hasOptionalParameters, parts }
}