Skip to content

Commit b8786e1

Browse files
committed
feat: linkedEditing support
closes #423
1 parent d8a2f44 commit b8786e1

File tree

7 files changed

+72
-9
lines changed

7 files changed

+72
-9
lines changed

package.json

+2-2
Original file line numberDiff line numberDiff line change
@@ -1172,11 +1172,11 @@
11721172
"coc.nvim": "^0.0.83-next.11",
11731173
"esbuild": "^0.15.13",
11741174
"semver": "^7.3.7",
1175-
"vscode-languageserver-protocol": "^3.17.2",
11761175
"strip-ansi": "^7.0.1",
1176+
"vscode-languageserver-protocol": "^3.17.2",
11771177
"which": "^2.0.2"
11781178
},
11791179
"dependencies": {
1180-
"typescript": "^4.9.3"
1180+
"typescript": "^5.1.0-dev.20230509"
11811181
}
11821182
}

src/server/features/linkedEditing.ts

+32
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,32 @@
1+
/*---------------------------------------------------------------------------------------------
2+
* Copyright (c) Microsoft Corporation. All rights reserved.
3+
* Licensed under the MIT License. See License.txt in the project root for license information.
4+
*--------------------------------------------------------------------------------------------*/
5+
6+
import { CancellationToken, LinkedEditingRangeProvider, LinkedEditingRanges, Position, TextDocument } from 'coc.nvim';
7+
import { ITypeScriptServiceClient } from '../typescriptService';
8+
import API from '../utils/api';
9+
import * as typeConverters from '../utils/typeConverters';
10+
11+
export default class TypeScriptLinkedEditingRangeProvider implements LinkedEditingRangeProvider {
12+
13+
public static readonly minVersion = API.v510;
14+
15+
public constructor(private readonly client: ITypeScriptServiceClient) {}
16+
17+
async provideLinkedEditingRanges(document: TextDocument, position: Position, token: CancellationToken): Promise<LinkedEditingRanges | undefined> {
18+
const filepath = this.client.toOpenedFilePath(document.uri);
19+
if (!filepath) {
20+
return undefined;
21+
}
22+
23+
const args = typeConverters.Position.toFileLocationRequestArgs(filepath, position);
24+
const response = await this.client.execute('linkedEditingRange', args, token);
25+
if (response.type !== 'response' || !response.body) {
26+
return undefined;
27+
}
28+
29+
const ranges = response.body.ranges.map(range => typeConverters.Range.fromTextSpan(range));
30+
return { ranges, wordPattern: response.body.wordPattern }
31+
}
32+
}

src/server/languageProvider.ts

+5
Original file line numberDiff line numberDiff line change
@@ -22,6 +22,7 @@ import ImportfixProvider from './features/importFix'
2222
import TypeScriptInlayHintsProvider from './features/inlayHints'
2323
import { JsDocCompletionProvider } from './features/jsDocCompletion'
2424
import InstallModuleProvider from './features/moduleInstall'
25+
import LinkedEditingRangeProvider from './features/linkedEditing'
2526
import QuickfixProvider from './features/quickfix'
2627
import RefactorProvider from './features/refactor'
2728
import ReferenceProvider from './features/references'
@@ -230,6 +231,10 @@ export default class LanguageProvider {
230231
this.client.logger.error(`languages.registerInlayHintsProvider is not a function, inlay hints won't work`)
231232
}
232233
}
234+
if (this.client.apiVersion.gte(API.v510)) {
235+
const provider = new LinkedEditingRangeProvider(this.client)
236+
this._register(languages.registerLinkedEditingRangeProvider(documentSelector.semantic, provider))
237+
}
233238
}
234239

235240
public handles(resource: string, doc: TextDocument): boolean {

src/server/protocol.d.ts

+27-2
Original file line numberDiff line numberDiff line change
@@ -1,2 +1,27 @@
1-
import * as Proto from 'typescript/lib/protocol';
2-
export = Proto;
1+
import ts from 'typescript/lib/tsserverlibrary';
2+
export = ts.server.protocol;
3+
4+
declare enum ServerType {
5+
Syntax = 'syntax',
6+
Semantic = 'semantic',
7+
}
8+
9+
declare module 'typescript/lib/tsserverlibrary' {
10+
namespace server.protocol {
11+
type TextInsertion = ts.TextInsertion;
12+
type ScriptElementKind = ts.ScriptElementKind;
13+
14+
interface Response {
15+
readonly _serverType?: ServerType;
16+
}
17+
18+
interface LinkedEditingRangesBody {
19+
ranges: TextSpan[];
20+
wordPattern?: string;
21+
}
22+
23+
interface LinkedEditingRangeResponse extends Response {
24+
readonly body: LinkedEditingRangesBody;
25+
}
26+
}
27+
}

src/server/typescriptService.ts

+1
Original file line numberDiff line numberDiff line change
@@ -57,6 +57,7 @@ interface StandardTsServerRequests {
5757
'getSupportedCodeFixes': [null, Proto.GetSupportedCodeFixesResponse]
5858
'implementation': [Proto.FileLocationRequestArgs, Proto.ImplementationResponse]
5959
'jsxClosingTag': [Proto.JsxClosingTagRequestArgs, Proto.JsxClosingTagResponse]
60+
'linkedEditingRange': [Proto.FileLocationRequestArgs, Proto.LinkedEditingRangeResponse];
6061
'navto': [Proto.NavtoRequestArgs, Proto.NavtoResponse]
6162
'navtree': [Proto.FileRequestArgs, Proto.NavTreeResponse]
6263
'organizeImports': [Proto.OrganizeImportsRequestArgs, Proto.OrganizeImportsResponse]

src/server/utils/api.ts

+1-1
Original file line numberDiff line numberDiff line change
@@ -48,7 +48,7 @@ export default class API {
4848
public static readonly v460 = API.fromSimpleString('4.6.0');
4949
public static readonly v480 = API.fromSimpleString('4.8.0');
5050
public static readonly v490 = API.fromSimpleString('4.9.0');
51-
51+
public static readonly v510 = API.fromSimpleString('5.1.0');
5252

5353
public static fromVersionString(versionString: string): API {
5454
let version = semver.valid(versionString)

yarn.lock

+4-4
Original file line numberDiff line numberDiff line change
@@ -181,10 +181,10 @@ strip-ansi@^7.0.1:
181181
dependencies:
182182
ansi-regex "^6.0.1"
183183

184-
typescript@^4.9.3:
185-
version "4.9.3"
186-
resolved "https://registry.yarnpkg.com/typescript/-/typescript-4.9.3.tgz#3aea307c1746b8c384435d8ac36b8a2e580d85db"
187-
integrity sha512-CIfGzTelbKNEnLpLdGFgdyKhG23CKdKgQPOBc+OUNrkJ2vr+KSzsSV5kq5iWhEQbok+quxgGzrAtGWCyU7tHnA==
184+
typescript@^5.1.0-dev.20230509:
185+
version "5.1.0-dev.20230509"
186+
resolved "https://registry.yarnpkg.com/typescript/-/typescript-5.1.0-dev.20230509.tgz#20024bfeb6d0c7bfa4026d614d35fea53a40de94"
187+
integrity sha512-ZOIqXGpzmqUPr0Mgi5dP1NMTH6AcbKqojL7ChJk1AyE3I0zfce04xH5vpjtNOl4UcGWyZoz1xI7HOvmJhy/yng==
188188

189189
190190
version "8.0.2"

0 commit comments

Comments
 (0)