diff --git a/src/server/features/completionItemProvider.ts b/src/server/features/completionItemProvider.ts
index bc1c2ce..a78c36d 100644
--- a/src/server/features/completionItemProvider.ts
+++ b/src/server/features/completionItemProvider.ts
@@ -10,7 +10,7 @@ import * as PConst from '../protocol.const'
 import { ITypeScriptServiceClient } from '../typescriptService'
 import API from '../utils/api'
 import { applyCodeAction } from '../utils/codeAction'
-import { convertCompletionEntry } from '../utils/completionItem'
+import { convertCompletionEntry, getParameterListParts } from '../utils/completionItem'
 import * as Previewer from '../utils/previewer'
 import * as typeConverters from '../utils/typeConverters'
 import TypingsStatus from '../utils/typingsStatus'
@@ -337,52 +337,21 @@ export default class TypeScriptCompletionItemProvider implements CompletionItemP
     item: CompletionItem,
     detail: Proto.CompletionEntryDetails
   ): void {
-    let hasOptionalParameters = false
-    let hasAddedParameters = false
-
-    let snippet = ''
-    const methodName = detail.displayParts.find(
-      part => part.kind === 'methodName'
-    )
-    snippet += item.insertText || (methodName && methodName.text) || item.label // tslint:disable-line
-    snippet += '('
-    let holderIndex = 1
-    let parenCount = 0
-    let i = 0
-    for (; i < detail.displayParts.length; ++i) {
-      const part = detail.displayParts[i]
-      // Only take top level paren names
-      if (part.kind === 'parameterName' && parenCount === 1) {
-        const next = detail.displayParts[i + 1]
-        // Skip optional parameters
-        const nameIsFollowedByOptionalIndicator = next && next.text === '?'
-        if (!nameIsFollowedByOptionalIndicator) {
-          if (hasAddedParameters) snippet += ', '
-          hasAddedParameters = true
-          // tslint:disable-next-line:no-invalid-template-strings
-          snippet += '${' + holderIndex + ':' + part.text + '}'
-          holderIndex = holderIndex + 1
-        }
-        hasOptionalParameters =
-          hasOptionalParameters || nameIsFollowedByOptionalIndicator
-      } else if (part.kind === 'punctuation') {
-        if (part.text === '(') {
-          ++parenCount
-        } else if (part.text === ')') {
-          --parenCount
-        } else if (part.text === '...' && parenCount === 1) {
-          // Found rest parmeter. Do not fill in any further arguments
-          hasOptionalParameters = true
-          break
-        }
+    let { displayParts } = detail
+    let snippet = (item.insertText || item.label) + '(' // tslint:disable-line
+    const parameterListParts = getParameterListParts(displayParts)
+    let { parts, hasOptionalParameters } = parameterListParts
+    let idx = 1
+    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
     }
-    if (hasOptionalParameters) {
-      // tslint:disable-next-line:no-invalid-template-strings
-      snippet += '${' + holderIndex + '}'
-    }
-    snippet += ')'
-    snippet += '$0'
+    snippet += ')$0'
     // tslint:disable-next-line:deprecation
     item.insertText = snippet
   }
diff --git a/src/server/protocol.const.ts b/src/server/protocol.const.ts
index 54010a6..7d047e4 100644
--- a/src/server/protocol.const.ts
+++ b/src/server/protocol.const.ts
@@ -2,6 +2,7 @@
  *  Copyright (c) Microsoft Corporation. All rights reserved.
  *  Licensed under the MIT License. See License.txt in the project root for license information.
  *--------------------------------------------------------------------------------------------*/
+
 export class Kind {
   public static readonly alias = 'alias'
   public static readonly callSignature = 'call'
@@ -12,7 +13,6 @@ export class Kind {
   public static readonly directory = 'directory'
   public static readonly enum = 'enum'
   public static readonly externalModuleName = 'external module name'
-  public static readonly file = 'file'
   public static readonly function = 'function'
   public static readonly indexSignature = 'index'
   public static readonly interface = 'interface'
@@ -30,10 +30,43 @@ export class Kind {
   public static readonly type = 'type'
   public static readonly variable = 'var'
   public static readonly warning = 'warning'
+  public static readonly string = 'string'
+  public static readonly parameter = 'parameter'
 }
 
+
 export class DiagnosticCategory {
   public static readonly error = 'error'
   public static readonly warning = 'warning'
   public static readonly suggestion = 'suggestion'
 }
+
+export class KindModifiers {
+  public static readonly optional = 'optional'
+  public static readonly color = 'color'
+
+  public static readonly dtsFile = '.d.ts'
+  public static readonly tsFile = '.ts'
+  public static readonly tsxFile = '.tsx'
+  public static readonly jsFile = '.js'
+  public static readonly jsxFile = '.jsx'
+  public static readonly jsonFile = '.json'
+
+  public static readonly fileExtensionKindModifiers = [
+    KindModifiers.dtsFile,
+    KindModifiers.tsFile,
+    KindModifiers.tsxFile,
+    KindModifiers.jsFile,
+    KindModifiers.jsxFile,
+    KindModifiers.jsonFile,
+  ]
+}
+
+export class DisplayPartKind {
+  public static readonly functionName = 'functionName'
+  public static readonly methodName = 'methodName'
+  public static readonly parameterName = 'parameterName'
+  public static readonly propertyName = 'propertyName'
+  public static readonly punctuation = 'punctuation'
+  public static readonly text = 'text'
+}
diff --git a/src/server/utils/completionItem.ts b/src/server/utils/completionItem.ts
index 70f3d64..02f8cc1 100644
--- a/src/server/utils/completionItem.ts
+++ b/src/server/utils/completionItem.ts
@@ -3,7 +3,7 @@
  *  Licensed under the MIT License. See License.txt in the project root for license information.
  *--------------------------------------------------------------------------------------------*/
 import { workspace } from 'coc.nvim'
-import { CompletionItem, CompletionItemKind, InsertTextFormat, Position, TextEdit } from 'vscode-languageserver-protocol'
+import { CompletionItem, CompletionItemKind, InsertTextFormat, Position } from 'vscode-languageserver-protocol'
 import * as Proto from '../protocol'
 import * as PConst from '../protocol.const'
 
@@ -13,6 +13,11 @@ interface CommitCharactersSettings {
   readonly useCodeSnippetsOnMethodSuggest: boolean
 }
 
+interface ParamterListParts {
+  readonly parts: ReadonlyArray<Proto.SymbolDisplayPart>
+  readonly hasOptionalParameters: boolean
+}
+
 export function convertCompletionEntry(
   tsEntry: Proto.CompletionEntry,
   uri: string,
@@ -97,7 +102,6 @@ function convertKind(kind: string): CompletionItemKind {
     case PConst.Kind.interface:
       return CompletionItemKind.Interface
     case PConst.Kind.warning:
-    case PConst.Kind.file:
     case PConst.Kind.script:
       return CompletionItemKind.File
     case PConst.Kind.directory:
@@ -140,3 +144,61 @@ function getCommitCharacters(tsEntry: Proto.CompletionEntry, settings: CommitCha
   }
   return commitCharacters.length === 0 ? undefined : commitCharacters
 }
+
+export function getParameterListParts(
+  displayParts: ReadonlyArray<Proto.SymbolDisplayPart>
+): ParamterListParts {
+  const parts: Proto.SymbolDisplayPart[] = []
+  let isInMethod = false
+  let hasOptionalParameters = false
+  let parenCount = 0
+  let braceCount = 0
+
+  outer: for (let i = 0; i < displayParts.length; ++i) {
+    const part = displayParts[i]
+    switch (part.kind) {
+      case PConst.DisplayPartKind.methodName:
+      case PConst.DisplayPartKind.functionName:
+      case PConst.DisplayPartKind.text:
+      case PConst.DisplayPartKind.propertyName:
+        if (parenCount === 0 && braceCount === 0) {
+          isInMethod = true
+        }
+        break
+
+      case PConst.DisplayPartKind.parameterName:
+        if (parenCount === 1 && isInMethod) {
+          // Only take top level paren names
+          const next = displayParts[i + 1]
+          // Skip optional parameters
+          const nameIsFollowedByOptionalIndicator = next && next.text === '?'
+          if (!nameIsFollowedByOptionalIndicator) {
+            parts.push(part)
+          }
+          hasOptionalParameters = hasOptionalParameters || nameIsFollowedByOptionalIndicator
+        }
+        break
+
+      case PConst.DisplayPartKind.punctuation:
+        if (part.text === '(') {
+          ++parenCount
+        } else if (part.text === ')') {
+          --parenCount
+          if (parenCount <= 0 && isInMethod) {
+            break outer
+          }
+        } else if (part.text === '...' && parenCount === 1) {
+          // Found rest parmeter. Do not fill in any further arguments
+          hasOptionalParameters = true
+          break outer
+        } else if (part.text === '{') {
+          ++braceCount
+        } else if (part.text === '}') {
+          --braceCount
+        }
+        break
+    }
+  }
+
+  return { hasOptionalParameters, parts }
+}