feat(commands): Go to Source Definition (#384)

This commit is contained in:
Heyward Fann 2022-07-30 00:43:59 +08:00 committed by GitHub
parent 74103e5e35
commit 84309083d1
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
4 changed files with 62 additions and 6 deletions

View file

@ -30,11 +30,10 @@
"onLanguage:jsx-tags", "onLanguage:jsx-tags",
"onLanguage:jsonc", "onLanguage:jsonc",
"onCommand:_typescript.configurePlugin", "onCommand:_typescript.configurePlugin",
"onCommand:typescript.reloadProjects", "onCommand:tsserver.reloadProjects",
"onCommand:javascript.reloadProjects", "onCommand:tsserver.goToProjectConfig",
"onCommand:javascript.goToProjectConfig", "onCommand:tsserver.openTsServerLog",
"onCommand:typescript.goToProjectConfig", "onCommand:tsserver.goToSourceDefinition",
"onCommand:typescript.openTsServerLog",
"onCommand:tsserver.watchBuild" "onCommand:tsserver.watchBuild"
], ],
"contributes": { "contributes": {
@ -94,6 +93,11 @@
"category": "TSServer", "category": "TSServer",
"command": "tsserver.findAllFileReferences" "command": "tsserver.findAllFileReferences"
}, },
{
"command": "tsserver.goToSourceDefinition",
"title": "Go to Source Definition",
"category": "TSServer"
},
{ {
"title": "Run `tsc --watch` for current project by use vim's job feature.", "title": "Run `tsc --watch` for current project by use vim's job feature.",
"category": "TSServer", "category": "TSServer",

View file

@ -218,6 +218,56 @@ export class FileReferencesCommand implements Command {
} }
} }
export class SourceDefinitionCommand implements Command {
public static readonly context = 'tsSupportsSourceDefinition'
public static readonly minVersion = API.v470
public readonly id = 'tsserver.goToSourceDefinition'
public constructor(private readonly service: TsserverService) {}
public async execute() {
const client = await this.service.getClientHost()
if (client.serviceClient.apiVersion.lt(SourceDefinitionCommand.minVersion)) {
window.showErrorMessage('Go to Source Definition failed. Requires TypeScript 4.7+.')
return
}
const { document, position } = await workspace.getCurrentState()
if (client.serviceClient.modeIds.indexOf(document.languageId) == -1) {
window.showErrorMessage('Go to Source Definition failed. Unsupported file type.')
return
}
const openedFiledPath = client.serviceClient.toOpenedFilePath(document.uri)
if (!openedFiledPath) {
window.showErrorMessage('Go to Source Definition failed. Unknown file type.')
return
}
await window.withProgress({ title: 'Finding source definitions' }, async (_progress, token) => {
const args = typeConverters.Position.toFileLocationRequestArgs(openedFiledPath, position)
const response = await client.serviceClient.execute('findSourceDefinition', args, token)
if (response.type === 'response' && response.body) {
const locations: Location[] = (response as Proto.DefinitionResponse).body.map(reference =>
typeConverters.Location.fromTextSpan(client.serviceClient.toResource(reference.file), reference))
if (locations.length) {
commands.executeCommand('editor.action.showReferences', document.uri, position, locations)
// if (locations.length === 1) {
// commands.executeCommand('vscode.open', locations[0].uri)
// } else {
// commands.executeCommand('editor.action.showReferences', document.uri, position, locations)
// }
return
}
}
window.showErrorMessage('No source definitions found.')
})
}
}
export function registCommand(cmd: Command): Disposable { export function registCommand(cmd: Command): Disposable {
let { id, execute } = cmd let { id, execute } = cmd
return commands.registerCommand(id as string, execute, cmd) return commands.registerCommand(id as string, execute, cmd)

View file

@ -1,7 +1,7 @@
import { commands, disposeAll, IServiceProvider, ServiceStat, workspace, WorkspaceConfiguration } from 'coc.nvim' import { commands, disposeAll, IServiceProvider, ServiceStat, workspace, WorkspaceConfiguration } from 'coc.nvim'
import { Disposable, DocumentSelector, Emitter, Event } from 'vscode-languageserver-protocol' import { Disposable, DocumentSelector, Emitter, Event } from 'vscode-languageserver-protocol'
import { PluginManager } from '../utils/plugins' import { PluginManager } from '../utils/plugins'
import { AutoFixCommand, Command, ConfigurePluginCommand, FileReferencesCommand, OpenTsServerLogCommand, ReloadProjectsCommand, TypeScriptGoToProjectConfigCommand } from './commands' import { AutoFixCommand, Command, ConfigurePluginCommand, FileReferencesCommand, OpenTsServerLogCommand, ReloadProjectsCommand, SourceDefinitionCommand, TypeScriptGoToProjectConfigCommand } from './commands'
import { OrganizeImportsCommand, SourceImportsCommand } from './organizeImports' import { OrganizeImportsCommand, SourceImportsCommand } from './organizeImports'
import TypeScriptServiceClientHost from './typescriptServiceClientHost' import TypeScriptServiceClientHost from './typescriptServiceClientHost'
import { LanguageDescription, standardLanguageDescriptions } from './utils/languageDescription' import { LanguageDescription, standardLanguageDescriptions } from './utils/languageDescription'
@ -69,6 +69,7 @@ export default class TsserverService implements IServiceProvider {
registCommand(new TypeScriptGoToProjectConfigCommand(this)) registCommand(new TypeScriptGoToProjectConfigCommand(this))
registCommand(new OrganizeImportsCommand(this)) registCommand(new OrganizeImportsCommand(this))
registCommand(new SourceImportsCommand(this)) registCommand(new SourceImportsCommand(this))
registCommand(new SourceDefinitionCommand(this))
registCommand({ registCommand({
id: 'tsserver.restart', id: 'tsserver.restart',
execute: (): void => { execute: (): void => {

View file

@ -44,6 +44,7 @@ export default class API {
public static readonly v420 = API.fromSimpleString('4.2.0') public static readonly v420 = API.fromSimpleString('4.2.0')
public static readonly v430 = API.fromSimpleString('4.3.0') public static readonly v430 = API.fromSimpleString('4.3.0')
public static readonly v440 = API.fromSimpleString('4.4.0') public static readonly v440 = API.fromSimpleString('4.4.0')
public static readonly v470 = API.fromSimpleString('4.7.0')
public static fromVersionString(versionString: string): API { public static fromVersionString(versionString: string): API {
let version = semver.valid(versionString) let version = semver.valid(versionString)