@theia/cpp
Version:
Theia - Cpp Extension
113 lines (101 loc) • 4.33 kB
text/typescript
/********************************************************************************
* Copyright (C) 2017 TypeFox and others.
*
* This program and the accompanying materials are made available under the
* terms of the Eclipse Public License v. 2.0 which is available at
* http://www.eclipse.org/legal/epl-2.0.
*
* This Source Code may also be made available under the following Secondary
* Licenses when the conditions for such availability set forth in the Eclipse
* Public License v. 2.0 are satisfied: GNU General Public License, version 2
* with the GNU Classpath Exception which is available at
* https://www.gnu.org/software/classpath/license.html.
*
* SPDX-License-Identifier: EPL-2.0 OR GPL-2.0 WITH Classpath-exception-2.0
********************************************************************************/
import { inject, injectable } from 'inversify';
import { SelectionService, UriSelection } from '@theia/core/lib/common';
import { CommandContribution, CommandRegistry, Command } from '@theia/core/lib/common';
import URI from '@theia/core/lib/common/uri';
import { open, OpenerService } from '@theia/core/lib/browser';
import { CppLanguageClientContribution } from './cpp-language-client-contribution';
import { SwitchSourceHeaderRequest } from './cpp-protocol';
import { TextDocumentIdentifier } from '@theia/languages/lib/browser';
import { EditorCommands, EditorManager } from '@theia/editor/lib/browser';
import { HEADER_AND_SOURCE_FILE_EXTENSIONS } from '../common';
/**
* The C/C++ command category.
*/
const CPP_CATEGORY = 'C/C++';
/**
* Command to switch between source/header files.
*/
export const SWITCH_SOURCE_HEADER: Command = {
id: 'switch_source_header',
category: CPP_CATEGORY,
label: 'Switch Between Source/Header File',
};
/**
* Command that is used to show the references from a CodeLens.
*/
export const SHOW_CLANGD_REFERENCES: Command = {
id: 'clangd.references'
};
/**
* Command to open the file path.
* @param path the file path.
*/
export const FILE_OPEN_PATH = (path: string): Command => <Command>{
id: 'file:openPath'
};
/**
* Determine if a C/C++ file is currently active (opened).
* @param editorManager the editor manager if it is defined.
*
* @returns `true` if the current active editor is a C/C++ file.
*/
export function editorContainsCppFiles(editorManager: EditorManager | undefined): boolean {
if (editorManager && editorManager.activeEditor) {
const uri = editorManager.activeEditor.editor.document.uri;
return HEADER_AND_SOURCE_FILE_EXTENSIONS.some(value => uri.endsWith('.' + value));
}
return false;
}
()
export class CppCommandContribution implements CommandContribution {
constructor(
(CppLanguageClientContribution) protected readonly clientContribution: CppLanguageClientContribution,
(OpenerService) protected readonly openerService: OpenerService,
(EditorManager) private editorService: EditorManager,
protected readonly selectionService: SelectionService
) { }
/**
* Register commands for C/C++.
* @param commands the command registry.
*/
registerCommands(commands: CommandRegistry): void {
commands.registerCommand(SWITCH_SOURCE_HEADER, {
isEnabled: () => editorContainsCppFiles(this.editorService),
execute: () => this.switchSourceHeader()
});
commands.registerCommand(SHOW_CLANGD_REFERENCES, {
execute: (doc: TextDocumentIdentifier, pos: Position, locs: Location[]) =>
commands.executeCommand(EditorCommands.SHOW_REFERENCES.id, doc.uri, pos, locs)
});
}
/**
* Actually switch the source header.
*/
protected async switchSourceHeader(): Promise<void> {
const uri = UriSelection.getUri(this.selectionService.selection);
if (!uri) {
return;
}
const docIdentifier = TextDocumentIdentifier.create(uri.toString());
const languageClient = await this.clientContribution.languageClient;
const sourceUri: string | undefined = await languageClient.sendRequest(SwitchSourceHeaderRequest.type, docIdentifier);
if (sourceUri !== undefined) {
open(this.openerService, new URI(sourceUri.toString()));
}
}
}