fix snippet generate
This commit is contained in:
parent
0473880f30
commit
8febbe9418
3 changed files with 103 additions and 20 deletions
|
@ -15,6 +15,7 @@ import * as Previewer from '../utils/previewer'
|
||||||
import * as typeConverters from '../utils/typeConverters'
|
import * as typeConverters from '../utils/typeConverters'
|
||||||
import TypingsStatus from '../utils/typingsStatus'
|
import TypingsStatus from '../utils/typingsStatus'
|
||||||
import FileConfigurationManager, { SuggestOptions } from './fileConfigurationManager'
|
import FileConfigurationManager, { SuggestOptions } from './fileConfigurationManager'
|
||||||
|
import SnippetString from '../utils/SnippetString'
|
||||||
|
|
||||||
// command center
|
// command center
|
||||||
export interface CommandItem {
|
export interface CommandItem {
|
||||||
|
@ -352,26 +353,16 @@ export default class TypeScriptCompletionItemProvider implements CompletionItemP
|
||||||
detail: Proto.CompletionEntryDetails
|
detail: Proto.CompletionEntryDetails
|
||||||
): void {
|
): void {
|
||||||
let { displayParts } = detail
|
let { displayParts } = detail
|
||||||
let snippet = (item.insertText || item.label) + '(' // tslint:disable-line
|
|
||||||
const parameterListParts = getParameterListParts(displayParts)
|
const parameterListParts = getParameterListParts(displayParts)
|
||||||
let { parts, hasOptionalParameters } = parameterListParts
|
const snippet = new SnippetString()
|
||||||
let idx = 1
|
snippet.appendText(`${item.insertText || item.label}(`)
|
||||||
if (parts.length == 0 && hasOptionalParameters) {
|
appendJoinedPlaceholders(snippet, parameterListParts.parts, ', ')
|
||||||
item.insertText = snippet + '${1})$0'
|
if (parameterListParts.hasOptionalParameters) {
|
||||||
return
|
snippet.appendTabstop()
|
||||||
}
|
}
|
||||||
for (let part of parts) {
|
snippet.appendText(')')
|
||||||
snippet += '${' + idx + ':' + part.text + '}' // tslint:disable-line
|
snippet.appendTabstop(0)
|
||||||
if (idx == parts.length) {
|
item.insertText = snippet.value
|
||||||
if (hasOptionalParameters) snippet += '${' + (idx + 1) + '}' // tslint:disable-line
|
|
||||||
} else {
|
|
||||||
snippet += ', '
|
|
||||||
}
|
|
||||||
idx = idx + 1
|
|
||||||
}
|
|
||||||
snippet += ')$0'
|
|
||||||
// tslint:disable-next-line:deprecation
|
|
||||||
item.insertText = snippet
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private async isValidFunctionCompletionContext(
|
private async isValidFunctionCompletionContext(
|
||||||
|
@ -415,3 +406,17 @@ function shouldExcludeCompletionEntry(
|
||||||
|| (!completionConfiguration.autoImports && element.hasAction)
|
|| (!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)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
79
src/server/utils/SnippetString.ts
Normal file
79
src/server/utils/SnippetString.ts
Normal 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
|
||||||
|
}
|
||||||
|
}
|
|
@ -178,7 +178,7 @@ export function getParameterListParts(
|
||||||
break
|
break
|
||||||
|
|
||||||
case PConst.DisplayPartKind.parameterName:
|
case PConst.DisplayPartKind.parameterName:
|
||||||
if (parenCount === 1 && isInMethod) {
|
if (parenCount === 1 && braceCount === 0 && isInMethod) {
|
||||||
// Only take top level paren names
|
// Only take top level paren names
|
||||||
const next = displayParts[i + 1]
|
const next = displayParts[i + 1]
|
||||||
// Skip optional parameters
|
// Skip optional parameters
|
||||||
|
@ -210,6 +210,5 @@ export function getParameterListParts(
|
||||||
break
|
break
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return { hasOptionalParameters, parts }
|
return { hasOptionalParameters, parts }
|
||||||
}
|
}
|
||||||
|
|
Loading…
Add table
Reference in a new issue