coc-tsserver/src/server/features/folding.ts

74 lines
2.4 KiB
TypeScript

/*---------------------------------------------------------------------------------------------
* Copyright (c) Microsoft Corporation. All rights reserved.
* Licensed under the MIT License. See License.txt in the project root for license information.
*--------------------------------------------------------------------------------------------*/
import { CancellationToken } from 'vscode-jsonrpc'
import { FoldingRange, TextDocument } from 'vscode-languageserver-types'
import { FoldingContext, FoldingRangeProvider } from 'coc.nvim/lib/provider'
import { workspace } from 'coc.nvim'
import Proto from '../protocol'
import { ITypeScriptServiceClient } from '../typescriptService'
import * as typeConverters from '../utils/typeConverters'
export default class TypeScriptFoldingProvider implements FoldingRangeProvider {
public constructor(private readonly client: ITypeScriptServiceClient) { }
public async provideFoldingRanges(
document: TextDocument,
_context: FoldingContext,
token: CancellationToken
): Promise<FoldingRange[] | undefined> {
const file = this.client.toPath(document.uri)
if (!file) {
return
}
const args: Proto.FileRequestArgs = { file }
const res = await this.client.execute('getOutliningSpans', args, token)
if (res.type != 'response') {
return
}
const { body } = res
if (!body) {
return
}
return body
.map(span => this.convertOutliningSpan(span, document))
.filter(foldingRange => !!foldingRange) as FoldingRange[]
}
private convertOutliningSpan(
span: Proto.OutliningSpan,
document: TextDocument
): FoldingRange | undefined {
const range = typeConverters.Range.fromTextSpan(span.textSpan)
const kind = TypeScriptFoldingProvider.getFoldingRangeKind(span)
// Workaround for #49904
if (span.kind === 'comment') {
let doc = workspace.getDocument(document.uri)
const line = doc.getline(range.start.line)
if (line.match(/\/\/\s*#endregion/gi)) {
return undefined
}
}
let { start, end } = range
return FoldingRange.create(start.line, end.line, start.character, end.character, kind)
}
private static getFoldingRangeKind(
span: Proto.OutliningSpan
): string {
switch (span.kind) {
case 'comment':
case 'region':
case 'imports':
case 'code':
return span.kind
default:
return undefined
}
}
}