fix type issues with previewer and completion
This commit is contained in:
parent
05c2a824a0
commit
e99f1c8079
9 changed files with 144 additions and 29 deletions
|
@ -675,7 +675,7 @@
|
|||
"license": "MIT",
|
||||
"devDependencies": {
|
||||
"@types/node": "^10.12.0",
|
||||
"coc.nvim": "^0.0.80",
|
||||
"coc.nvim": "^0.0.81-next.4",
|
||||
"esbuild": "^0.8.29",
|
||||
"semver": "^7.3.2",
|
||||
"vscode-languageserver-protocol": "^3.16.0",
|
||||
|
|
|
@ -93,7 +93,7 @@ function fromProtocolCallHierarchyItem(item: Proto.CallHierarchyItem): CallHiera
|
|||
}
|
||||
|
||||
const kindModifiers = item.kindModifiers ? parseKindModifier(item.kindModifiers) : undefined
|
||||
if (kindModifiers?.has(PConst.KindModifiers.depreacted)) {
|
||||
if (kindModifiers?.has(PConst.KindModifiers.deprecated)) {
|
||||
result.tags = [SymbolTag.Deprecated]
|
||||
}
|
||||
return result
|
||||
|
|
|
@ -1,9 +1,9 @@
|
|||
import { commands, CompletionItemProvider, TextDocument, window, workspace } from 'coc.nvim'
|
||||
import { commands, CompletionItemProvider, TextDocument, CompletionList, CompletionItem, window, workspace } from 'coc.nvim'
|
||||
/*---------------------------------------------------------------------------------------------
|
||||
* Copyright (c) Microsoft Corporation. All rights reserved.
|
||||
* Licensed under the MIT License. See License.txt in the project root for license information.
|
||||
*--------------------------------------------------------------------------------------------*/
|
||||
import { CancellationToken, Command, CompletionContext, CompletionItem, CompletionList, InsertTextFormat, MarkupContent, MarkupKind, Position, Range, TextEdit } from 'vscode-languageserver-protocol'
|
||||
import { CancellationToken, Command, CompletionContext, InsertTextFormat, MarkupContent, MarkupKind, Position, Range, TextEdit } from 'vscode-languageserver-protocol'
|
||||
import Proto from '../protocol'
|
||||
import * as PConst from '../protocol.const'
|
||||
import { ITypeScriptServiceClient, ServerResponse } from '../typescriptService'
|
||||
|
|
|
@ -2,8 +2,7 @@
|
|||
* Copyright (c) Microsoft Corporation. All rights reserved.
|
||||
* Licensed under the MIT License. See License.txt in the project root for license information.
|
||||
*--------------------------------------------------------------------------------------------*/
|
||||
import { CancellationToken, CompletionContext, CompletionItem, CompletionItemKind, CompletionList, Position, Range } from 'vscode-languageserver-protocol'
|
||||
import { TextDocument } from 'coc.nvim'
|
||||
import { CancellationToken, CompletionContext, CompletionItem, CompletionItemKind, CompletionList, Position, Range, TextDocument } from 'coc.nvim'
|
||||
import { workspace } from 'coc.nvim'
|
||||
import { ITypeScriptServiceClient } from '../typescriptService'
|
||||
import API from '../utils/api'
|
||||
|
@ -37,7 +36,7 @@ const tsDirectives390: Directive[] = [
|
|||
]
|
||||
|
||||
export default class DirectiveCommentCompletionProvider {
|
||||
constructor(private readonly client: ITypeScriptServiceClient) { }
|
||||
constructor(private readonly client: ITypeScriptServiceClient) {}
|
||||
|
||||
public provideCompletionItems(
|
||||
document: TextDocument,
|
||||
|
@ -62,7 +61,7 @@ export default class DirectiveCommentCompletionProvider {
|
|||
? tsDirectives390
|
||||
: tsDirectives
|
||||
let items = directives.map(directive => {
|
||||
const item = CompletionItem.create(directive.value)
|
||||
const item: CompletionItem = { label: directive.value }
|
||||
item.kind = CompletionItemKind.Snippet
|
||||
item.detail = directive.description
|
||||
item.textEdit = {
|
||||
|
|
|
@ -86,7 +86,7 @@ export default class LanguageProvider {
|
|||
if (this.client.apiVersion.gte(API.v230)) {
|
||||
this._register(languages.registerCompletionItemProvider(
|
||||
`${this.description.id}-directive`,
|
||||
'TSC', languageIds, new DirectiveCommentCompletionProvider(client,), ['@']
|
||||
'TSC', languageIds, new DirectiveCommentCompletionProvider(client), ['@']
|
||||
))
|
||||
}
|
||||
|
||||
|
|
|
@ -44,7 +44,7 @@ export class DiagnosticCategory {
|
|||
|
||||
export class KindModifiers {
|
||||
public static readonly optional = 'optional'
|
||||
public static readonly depreacted = 'deprecated'
|
||||
public static readonly deprecated = 'deprecated'
|
||||
public static readonly color = 'color'
|
||||
|
||||
public static readonly dtsFile = '.d.ts'
|
||||
|
|
|
@ -2,7 +2,7 @@
|
|||
* Copyright (c) Microsoft Corporation. All rights reserved.
|
||||
* Licensed under the MIT License. See License.txt in the project root for license information.
|
||||
*--------------------------------------------------------------------------------------------*/
|
||||
import { Range, CompletionItem, CompletionItemKind, InsertTextFormat, Position, TextEdit } from 'vscode-languageserver-protocol'
|
||||
import { Range, CompletionItem, CompletionItemKind, InsertTextFormat, Position, TextEdit } from 'coc.nvim'
|
||||
import * as Proto from '../protocol'
|
||||
import * as PConst from '../protocol.const'
|
||||
|
||||
|
|
|
@ -5,37 +5,83 @@
|
|||
|
||||
import { MarkupContent, MarkupKind } from 'vscode-languageserver-protocol'
|
||||
import * as Proto from '../protocol'
|
||||
import { Uri } from 'coc.nvim'
|
||||
|
||||
function toResource(filepath: string): Uri {
|
||||
return Uri.file(filepath)
|
||||
}
|
||||
|
||||
function replaceLinks(text: string): string {
|
||||
return text
|
||||
// Http(s) links
|
||||
.replace(/\{@(link|linkplain|linkcode) (https?:\/\/[^ |}]+?)(?:[| ]([^{}\n]+?))?\}/gi, (_, tag: string, link: string, text?: string) => {
|
||||
switch (tag) {
|
||||
case 'linkcode':
|
||||
return `[\`${text ? text.trim() : link}\`](${link})`
|
||||
|
||||
default:
|
||||
return `[${text ? text.trim() : link}](${link})`
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
function processInlineTags(text: string): string {
|
||||
return replaceLinks(text)
|
||||
}
|
||||
|
||||
function getTagBodyText(tag: Proto.JSDocTagInfo): string | undefined {
|
||||
if (!tag.text) {
|
||||
return undefined
|
||||
}
|
||||
|
||||
switch (tag.name) {
|
||||
case 'example':
|
||||
case 'default':
|
||||
// Convert to markdown code block if it not already one
|
||||
if (tag.text.match(/^\s*[~`]{3}/g)) {
|
||||
return tag.text
|
||||
}
|
||||
return '```\n' + tag.text + '\n```'
|
||||
// Convert to markdown code block if it is not already one
|
||||
function makeCodeblock(text: string): string {
|
||||
if (text.match(/^\s*[~`]{3}/g)) {
|
||||
return text
|
||||
}
|
||||
return '```\n' + text + '\n```'
|
||||
}
|
||||
|
||||
return tag.text
|
||||
const text = convertLinkTags(tag.text)
|
||||
switch (tag.name) {
|
||||
case 'example':
|
||||
// check for caption tags, fix for #79704
|
||||
const captionTagMatches = text.match(/<caption>(.*?)<\/caption>\s*(\r\n|\n)/)
|
||||
if (captionTagMatches && captionTagMatches.index === 0) {
|
||||
return captionTagMatches[1] + '\n\n' + makeCodeblock(text.substr(captionTagMatches[0].length))
|
||||
} else {
|
||||
return makeCodeblock(text)
|
||||
}
|
||||
case 'author':
|
||||
// fix obsucated email address, #80898
|
||||
const emailMatch = text.match(/(.+)\s<([-.\w]+@[-.\w]+)>/)
|
||||
|
||||
if (emailMatch === null) {
|
||||
return text
|
||||
} else {
|
||||
return `${emailMatch[1]} ${emailMatch[2]}`
|
||||
}
|
||||
case 'default':
|
||||
return makeCodeblock(text)
|
||||
}
|
||||
|
||||
return processInlineTags(text)
|
||||
}
|
||||
|
||||
function getTagDocumentation(tag: Proto.JSDocTagInfo): string | undefined {
|
||||
switch (tag.name) {
|
||||
case 'augments':
|
||||
case 'extends':
|
||||
case 'param':
|
||||
const body = (tag.text || '').split(/^([\w\.]+)\s*/)
|
||||
if (body && body.length === 3) {
|
||||
case 'template':
|
||||
const body = (convertLinkTags(tag.text)).split(/^(\S+)\s*-?\s*/)
|
||||
if (body?.length === 3) {
|
||||
const param = body[1]
|
||||
const doc = body[2]
|
||||
const label = `*@${tag.name}* \`${param}\``
|
||||
if (!doc) {
|
||||
return label
|
||||
}
|
||||
return label + (doc.match(/\r\n|\n/g) ? '\n' + doc : ` — ${doc}`)
|
||||
return label + (doc.match(/\r\n|\n/g) ? ' \n' + processInlineTags(doc) : ` — ${processInlineTags(doc)}`)
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -45,7 +91,7 @@ function getTagDocumentation(tag: Proto.JSDocTagInfo): string | undefined {
|
|||
if (!text) {
|
||||
return label
|
||||
}
|
||||
return label + (text.match(/\r\n|\n/g) ? '\n' + text : ` — ${text}`)
|
||||
return label + (text.match(/\r\n|\n/g) ? ' \n' + text : ` — ${text}`)
|
||||
}
|
||||
|
||||
export function plain(parts: Proto.SymbolDisplayPart[]): string {
|
||||
|
@ -71,3 +117,73 @@ export function markdownDocumentation(
|
|||
value: out
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Convert `@link` inline tags to markdown links
|
||||
*/
|
||||
function convertLinkTags(
|
||||
parts: readonly Proto.SymbolDisplayPart[] | string | undefined
|
||||
): string {
|
||||
if (!parts) {
|
||||
return ''
|
||||
}
|
||||
|
||||
if (typeof parts === 'string') {
|
||||
return parts
|
||||
}
|
||||
|
||||
const out: string[] = []
|
||||
let currentLink: { name?: string, target?: Proto.FileSpan, text?: string } | undefined
|
||||
for (const part of parts) {
|
||||
switch (part.kind) {
|
||||
case 'link':
|
||||
if (currentLink) {
|
||||
const text = currentLink.text ?? currentLink.name
|
||||
if (currentLink.target) {
|
||||
const link = toResource(currentLink.target.file)
|
||||
.with({
|
||||
fragment: `L${currentLink.target.start.line},${currentLink.target.start.offset}`
|
||||
})
|
||||
|
||||
out.push(`[${text}](${link.toString()})`)
|
||||
} else {
|
||||
if (text) {
|
||||
if (/^https?:/.test(text)) {
|
||||
const parts = text.split(' ')
|
||||
if (parts.length === 1) {
|
||||
out.push(parts[0])
|
||||
} else if (parts.length > 1) {
|
||||
out.push(`[${parts.slice(1).join(' ')}](${parts[0]})`)
|
||||
}
|
||||
} else {
|
||||
out.push(text)
|
||||
}
|
||||
}
|
||||
}
|
||||
currentLink = undefined
|
||||
} else {
|
||||
currentLink = {}
|
||||
}
|
||||
break
|
||||
|
||||
case 'linkName':
|
||||
if (currentLink) {
|
||||
currentLink.name = part.text
|
||||
// TODO: remove cast once we pick up TS 4.3
|
||||
currentLink.target = (part as any as Proto.JSDocLinkDisplayPart).target
|
||||
}
|
||||
break
|
||||
|
||||
case 'linkText':
|
||||
if (currentLink) {
|
||||
currentLink.text = part.text
|
||||
}
|
||||
break
|
||||
|
||||
default:
|
||||
out.push(part.text)
|
||||
break
|
||||
}
|
||||
}
|
||||
return processInlineTags(out.join(''))
|
||||
}
|
||||
|
|
|
@ -7,10 +7,10 @@
|
|||
resolved "https://registry.yarnpkg.com/@types/node/-/node-10.17.44.tgz#3945e6b702cb6403f22b779c8ea9e5c3f44ead40"
|
||||
integrity sha512-vHPAyBX1ffLcy4fQHmDyIUMUb42gHZjPHU66nhvbMzAWJqHnySGZ6STwN3rwrnSd1FHB0DI/RWgGELgKSYRDmw==
|
||||
|
||||
coc.nvim@^0.0.80:
|
||||
version "0.0.80"
|
||||
resolved "https://registry.yarnpkg.com/coc.nvim/-/coc.nvim-0.0.80.tgz#785145c382660db03f517f9b497900d95cbd0e4f"
|
||||
integrity sha512-/3vTcnofoAYMrdENrlQmADTzfXX4+PZ0fiM10a39UA37dTR2dpIGi9O469kcIksuunLjToqWG8S45AGx/9wV7g==
|
||||
coc.nvim@^0.0.81-next.4:
|
||||
version "0.0.81-next.4"
|
||||
resolved "https://registry.yarnpkg.com/coc.nvim/-/coc.nvim-0.0.81-next.4.tgz#06d808ceca76a250041f3f3dbf33ed9c221eb19b"
|
||||
integrity sha512-zAgDe8o0mMvmsz7lM3Y/TiDc/+ZQIp05Z21tp1+WnLpNlNjbrqp6xpdcgDutjJWS04nzPNRRJA/btCGpMg7+/Q==
|
||||
|
||||
esbuild@^0.8.29:
|
||||
version "0.8.29"
|
||||
|
|
Loading…
Reference in a new issue