mirror of
https://github.com/arduino/arduino-ide.git
synced 2025-07-24 11:46:32 +00:00
ATL-222: Moved the language feature to a VS Code extension.
Updated to next Theia: 1.6.0-next.b43a1623. Signed-off-by: Akos Kitta <kittaakos@typefox.io>
This commit is contained in:
parent
fbebfc7cca
commit
f26dae185b
4
.github/workflows/build.yml
vendored
4
.github/workflows/build.yml
vendored
@ -32,10 +32,10 @@ jobs:
|
||||
- name: Checkout
|
||||
uses: actions/checkout@v2
|
||||
|
||||
- name: Install Node.js 10.x
|
||||
- name: Install Node.js 12.x
|
||||
uses: actions/setup-node@v1
|
||||
with:
|
||||
node-version: '10.x'
|
||||
node-version: '12.14.1'
|
||||
registry-url: 'https://registry.npmjs.org'
|
||||
|
||||
- name: Install Python 2.7
|
||||
|
11
.vscode/tasks.json
vendored
11
.vscode/tasks.json
vendored
@ -3,6 +3,17 @@
|
||||
// for the documentation about the tasks.json format
|
||||
"version": "2.0.0",
|
||||
"tasks": [
|
||||
{
|
||||
"label": "Arduino Pro IDE - Rebuild Electron App",
|
||||
"type": "shell",
|
||||
"command": "yarn rebuild:browser && yarn rebuild:electron",
|
||||
"group": "build",
|
||||
"presentation": {
|
||||
"reveal": "always",
|
||||
"panel": "new",
|
||||
"clear": false
|
||||
}
|
||||
},
|
||||
{
|
||||
"label": "Arduino Pro IDE - Start Browser App",
|
||||
"type": "shell",
|
||||
|
@ -1,5 +1,5 @@
|
||||
import { injectable, inject } from 'inversify';
|
||||
import { MenuModelRegistry, Path, MessageService, Command, CommandRegistry } from '@theia/core';
|
||||
import { MenuModelRegistry, MessageService, Command, CommandRegistry } from '@theia/core';
|
||||
import { KeybindingRegistry } from '@theia/core/lib/browser';
|
||||
import { TabBarToolbarRegistry } from '@theia/core/lib/browser/shell/tab-bar-toolbar';
|
||||
import { DebugFrontendApplicationContribution, DebugCommands } from '@theia/debug/lib/browser/debug-frontend-application-contribution';
|
||||
@ -62,8 +62,8 @@ export class ArduinoDebugFrontendApplicationContribution extends DebugFrontendAp
|
||||
if (current.configuration.type === 'arduino') {
|
||||
const wsStat = this.workspaceService.workspace;
|
||||
let sketchFileURI: URI | undefined;
|
||||
if (wsStat && await this.sketchesService.isSketchFolder(wsStat.uri)) {
|
||||
const wsPath = new Path(wsStat.uri);
|
||||
if (wsStat && await this.sketchesService.isSketchFolder(wsStat.resource.toString())) {
|
||||
const wsPath = wsStat.resource.path;
|
||||
const sketchFilePath = wsPath.join(wsPath.name + '.ino').toString();
|
||||
sketchFileURI = new URI(sketchFilePath);
|
||||
} else if (this.editorManager.currentEditor) {
|
||||
|
@ -30,6 +30,7 @@ export class ArduinoGDBBackend extends GDBBackend {
|
||||
'--interpreter', 'mi2',
|
||||
sketchDir
|
||||
];
|
||||
console.log('Starting debugger:', command, JSON.stringify(args));
|
||||
const proc = spawn(command, args);
|
||||
this.proc = proc;
|
||||
this.out = proc.stdin;
|
||||
|
File diff suppressed because it is too large
Load Diff
@ -23,7 +23,6 @@
|
||||
"@theia/editor": "next",
|
||||
"@theia/filesystem": "next",
|
||||
"@theia/git": "next",
|
||||
"@theia/languages": "next",
|
||||
"@theia/markers": "next",
|
||||
"@theia/monaco": "next",
|
||||
"@theia/navigator": "next",
|
||||
|
@ -1,4 +1,4 @@
|
||||
import { MAIN_MENU_BAR, MenuContribution, MenuModelRegistry, SelectionService } from '@theia/core';
|
||||
import { MAIN_MENU_BAR, MenuContribution, MenuModelRegistry, SelectionService, ILogger } from '@theia/core';
|
||||
import {
|
||||
ContextMenuRenderer,
|
||||
FrontendApplication, FrontendApplicationContribution,
|
||||
@ -13,7 +13,6 @@ import { MessageService } from '@theia/core/lib/common/message-service';
|
||||
import URI from '@theia/core/lib/common/uri';
|
||||
import { EditorMainMenu, EditorManager } from '@theia/editor/lib/browser';
|
||||
import { FileDialogService } from '@theia/filesystem/lib/browser/file-dialog';
|
||||
import { FileSystem } from '@theia/filesystem/lib/common';
|
||||
import { ProblemContribution } from '@theia/markers/lib/browser/problem/problem-contribution';
|
||||
import { MonacoMenus } from '@theia/monaco/lib/browser/monaco-menu';
|
||||
import { FileNavigatorContribution } from '@theia/navigator/lib/browser/navigator-contribution';
|
||||
@ -25,7 +24,7 @@ import { TerminalMenus } from '@theia/terminal/lib/browser/terminal-frontend-con
|
||||
import { inject, injectable, postConstruct } from 'inversify';
|
||||
import * as React from 'react';
|
||||
import { MainMenuManager } from '../common/main-menu-manager';
|
||||
import { BoardsService, BoardsServiceClient, CoreService, Port, SketchesService, ToolOutputServiceClient } from '../common/protocol';
|
||||
import { BoardsService, BoardsServiceClient, CoreService, Port, SketchesService, ToolOutputServiceClient, ExecutableService } from '../common/protocol';
|
||||
import { ArduinoDaemon } from '../common/protocol/arduino-daemon';
|
||||
import { ConfigService } from '../common/protocol/config-service';
|
||||
import { FileSystemExt } from '../common/protocol/filesystem-ext';
|
||||
@ -41,11 +40,18 @@ import { MonitorConnection } from './monitor/monitor-connection';
|
||||
import { MonitorViewContribution } from './monitor/monitor-view-contribution';
|
||||
import { WorkspaceService } from './theia/workspace/workspace-service';
|
||||
import { ArduinoToolbar } from './toolbar/arduino-toolbar';
|
||||
import { HostedPluginSupport } from '@theia/plugin-ext/lib/hosted/browser/hosted-plugin';
|
||||
import { FileService } from '@theia/filesystem/lib/browser/file-service';
|
||||
|
||||
const debounce = require('lodash.debounce');
|
||||
|
||||
@injectable()
|
||||
export class ArduinoFrontendContribution implements FrontendApplicationContribution,
|
||||
TabBarToolbarContribution, CommandContribution, MenuContribution, ColorContribution {
|
||||
|
||||
@inject(ILogger)
|
||||
protected logger: ILogger;
|
||||
|
||||
@inject(MessageService)
|
||||
protected readonly messageService: MessageService;
|
||||
|
||||
@ -77,8 +83,8 @@ export class ArduinoFrontendContribution implements FrontendApplicationContribut
|
||||
@inject(FileDialogService)
|
||||
protected readonly fileDialogService: FileDialogService;
|
||||
|
||||
@inject(FileSystem)
|
||||
protected readonly fileSystem: FileSystem;
|
||||
@inject(FileService)
|
||||
protected readonly fileSystem: FileService;
|
||||
|
||||
@inject(SketchesService)
|
||||
protected readonly sketchService: SketchesService;
|
||||
@ -140,6 +146,12 @@ export class ArduinoFrontendContribution implements FrontendApplicationContribut
|
||||
@inject(FileSystemExt)
|
||||
protected readonly fileSystemExt: FileSystemExt;
|
||||
|
||||
@inject(HostedPluginSupport)
|
||||
protected hostedPluginSupport: HostedPluginSupport;
|
||||
|
||||
@inject(ExecutableService)
|
||||
protected executableService: ExecutableService;
|
||||
|
||||
@postConstruct()
|
||||
protected async init(): Promise<void> {
|
||||
if (!window.navigator.onLine) {
|
||||
@ -177,6 +189,35 @@ export class ArduinoFrontendContribution implements FrontendApplicationContribut
|
||||
viewContribution.initializeLayout(app);
|
||||
}
|
||||
}
|
||||
this.boardsServiceClientImpl.onBoardsConfigChanged(async ({ selectedBoard }) => {
|
||||
if (selectedBoard) {
|
||||
const { name, fqbn } = selectedBoard;
|
||||
if (fqbn) {
|
||||
await this.hostedPluginSupport.didStart;
|
||||
this.startLanguageServer(fqbn, name);
|
||||
}
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
protected startLanguageServer = debounce((fqbn: string, name: string | undefined) => this.doStartLanguageServer(fqbn, name));
|
||||
protected async doStartLanguageServer(fqbn: string, name: string | undefined): Promise<void> {
|
||||
this.logger.info(`Starting language server: ${fqbn}`);
|
||||
const { clangdUri, cliUri, lsUri } = await this.executableService.list();
|
||||
const [clangdPath, cliPath, lsPath] = await Promise.all([
|
||||
this.fileSystem.fsPath(new URI(clangdUri)),
|
||||
this.fileSystem.fsPath(new URI(cliUri)),
|
||||
this.fileSystem.fsPath(new URI(lsUri)),
|
||||
]);
|
||||
this.commandRegistry.executeCommand('arduino.languageserver.start', {
|
||||
lsPath,
|
||||
cliPath,
|
||||
clangdPath,
|
||||
board: {
|
||||
fqbn,
|
||||
name: name ? `"${name}"` : undefined
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
registerToolbarItems(registry: TabBarToolbarRegistry): void {
|
||||
@ -208,7 +249,7 @@ export class ArduinoFrontendContribution implements FrontendApplicationContribut
|
||||
isToggled: () => this.editorMode.compileForDebug
|
||||
});
|
||||
registry.registerCommand(ArduinoCommands.OPEN_SKETCH_FILES, {
|
||||
execute: async (uri: string) => {
|
||||
execute: async (uri: URI) => {
|
||||
this.openSketchFiles(uri);
|
||||
}
|
||||
});
|
||||
@ -256,9 +297,9 @@ export class ArduinoFrontendContribution implements FrontendApplicationContribut
|
||||
});
|
||||
}
|
||||
|
||||
protected async openSketchFiles(uri: string): Promise<void> {
|
||||
protected async openSketchFiles(uri: URI): Promise<void> {
|
||||
try {
|
||||
const sketch = await this.sketchService.loadSketch(uri);
|
||||
const sketch = await this.sketchService.loadSketch(uri.toString());
|
||||
const { mainFileUri, otherSketchFileUris, additionalFileUris } = sketch;
|
||||
for (const uri of [mainFileUri, ...otherSketchFileUris, ...additionalFileUris]) {
|
||||
await this.ensureOpened(uri);
|
||||
|
@ -6,12 +6,8 @@ import { bindViewContribution } from '@theia/core/lib/browser/shell/view-contrib
|
||||
import { TabBarToolbarContribution, TabBarToolbarFactory } from '@theia/core/lib/browser/shell/tab-bar-toolbar';
|
||||
import { WebSocketConnectionProvider } from '@theia/core/lib/browser/messaging/ws-connection-provider';
|
||||
import { FrontendApplicationContribution, FrontendApplication as TheiaFrontendApplication } from '@theia/core/lib/browser/frontend-application'
|
||||
import { LanguageGrammarDefinitionContribution } from '@theia/monaco/lib/browser/textmate';
|
||||
import { LanguageClientContribution } from '@theia/languages/lib/browser';
|
||||
import { ArduinoLanguageClientContribution } from './language/arduino-language-client-contribution';
|
||||
import { LibraryListWidget } from './library/library-list-widget';
|
||||
import { ArduinoFrontendContribution } from './arduino-frontend-contribution';
|
||||
import { ArduinoLanguageGrammarContribution } from './language/arduino-language-grammar-contribution';
|
||||
import { LibraryServiceServer, LibraryServiceServerPath } from '../common/protocol/library-service';
|
||||
import { BoardsService, BoardsServicePath, BoardsServiceClient } from '../common/protocol/boards-service';
|
||||
import { SketchesService, SketchesServicePath } from '../common/protocol/sketches-service';
|
||||
@ -125,6 +121,9 @@ import { IncludeLibrary } from './contributions/include-library';
|
||||
import { OutputChannelManager as TheiaOutputChannelManager } from '@theia/output/lib/common/output-channel';
|
||||
import { OutputChannelManager } from './theia/output/output-channel';
|
||||
import { OutputChannelRegistryMainImpl as TheiaOutputChannelRegistryMainImpl, OutputChannelRegistryMainImpl } from './theia/plugin-ext/output-channel-registry-main';
|
||||
import { ExecutableService, ExecutableServicePath } from '../common/protocol';
|
||||
import { MonacoTextModelService as TheiaMonacoTextModelService } from '@theia/monaco/lib/browser/monaco-text-model-service';
|
||||
import { MonacoTextModelService } from './theia/monaco/monaco-text-model-service';
|
||||
|
||||
const ElementQueries = require('css-element-queries/src/ElementQueries');
|
||||
|
||||
@ -150,10 +149,6 @@ export default new ContainerModule((bind, unbind, isBound, rebind) => {
|
||||
bind(ArduinoToolbarContribution).toSelf().inSingletonScope();
|
||||
bind(FrontendApplicationContribution).toService(ArduinoToolbarContribution);
|
||||
|
||||
// `ino` TextMate grammar and language client
|
||||
bind(LanguageGrammarDefinitionContribution).to(ArduinoLanguageGrammarContribution).inSingletonScope();
|
||||
bind(LanguageClientContribution).to(ArduinoLanguageClientContribution).inSingletonScope();
|
||||
|
||||
// Renderer for both the library and the core widgets.
|
||||
bind(ListItemRenderer).toSelf().inSingletonScope();
|
||||
|
||||
@ -317,6 +312,8 @@ export default new ContainerModule((bind, unbind, isBound, rebind) => {
|
||||
rebind(TheiaOutputChannelManager).toService(OutputChannelManager);
|
||||
bind(OutputChannelRegistryMainImpl).toSelf().inTransientScope();
|
||||
rebind(TheiaOutputChannelRegistryMainImpl).toService(OutputChannelRegistryMainImpl);
|
||||
bind(MonacoTextModelService).toSelf().inSingletonScope();
|
||||
rebind(TheiaMonacoTextModelService).toService(MonacoTextModelService);
|
||||
|
||||
// Show a disconnected status bar, when the daemon is not available
|
||||
bind(ApplicationConnectionStatusContribution).toSelf().inSingletonScope();
|
||||
@ -360,9 +357,12 @@ export default new ContainerModule((bind, unbind, isBound, rebind) => {
|
||||
// File-system extension
|
||||
bind(FileSystemExt).toDynamicValue(context => WebSocketConnectionProvider.createProxy(context.container, FileSystemExtPath)).inSingletonScope();
|
||||
|
||||
// Examples service
|
||||
// Examples service@
|
||||
bind(ExamplesService).toDynamicValue(context => WebSocketConnectionProvider.createProxy(context.container, ExamplesServicePath)).inSingletonScope();
|
||||
|
||||
// Executable URIs known by the backend
|
||||
bind(ExecutableService).toDynamicValue(context => WebSocketConnectionProvider.createProxy(context.container, ExecutableServicePath)).inSingletonScope();
|
||||
|
||||
Contribution.configure(bind, NewSketch);
|
||||
Contribution.configure(bind, OpenSketch);
|
||||
Contribution.configure(bind, CloseSketch);
|
||||
|
@ -1,40 +0,0 @@
|
||||
import { injectable, inject, postConstruct } from 'inversify';
|
||||
import { BaseLanguageClientContribution } from '@theia/languages/lib/browser';
|
||||
import { BoardsServiceClientImpl } from '../boards/boards-service-client-impl';
|
||||
import { BoardsConfig } from '../boards/boards-config';
|
||||
|
||||
@injectable()
|
||||
export class ArduinoLanguageClientContribution extends BaseLanguageClientContribution {
|
||||
|
||||
readonly id = 'ino';
|
||||
readonly name = 'Arduino';
|
||||
|
||||
protected get documentSelector(): string[] {
|
||||
return ['ino'];
|
||||
}
|
||||
|
||||
protected get globPatterns() {
|
||||
return ['**/*.ino'];
|
||||
}
|
||||
|
||||
@inject(BoardsServiceClientImpl)
|
||||
protected readonly boardsServiceClient: BoardsServiceClientImpl;
|
||||
|
||||
protected boardConfig?: BoardsConfig.Config;
|
||||
|
||||
@postConstruct()
|
||||
protected init() {
|
||||
this.boardsServiceClient.onBoardsConfigChanged(this.selectBoard.bind(this));
|
||||
}
|
||||
|
||||
selectBoard(config: BoardsConfig.Config): void {
|
||||
this.boardConfig = config;
|
||||
// Force a restart to send the new board config to the language server
|
||||
this.restart();
|
||||
}
|
||||
|
||||
protected getStartParameters(): BoardsConfig.Config | undefined {
|
||||
return this.boardConfig;
|
||||
}
|
||||
|
||||
}
|
@ -1,63 +0,0 @@
|
||||
import { injectable } from 'inversify';
|
||||
import { LanguageGrammarDefinitionContribution, TextmateRegistry } from '@theia/monaco/lib/browser/textmate';
|
||||
|
||||
@injectable()
|
||||
export class ArduinoLanguageGrammarContribution implements LanguageGrammarDefinitionContribution {
|
||||
|
||||
static INO_LANGUAGE_ID = 'ino';
|
||||
|
||||
registerTextmateLanguage(registry: TextmateRegistry) {
|
||||
monaco.languages.register({
|
||||
id: ArduinoLanguageGrammarContribution.INO_LANGUAGE_ID,
|
||||
extensions: ['.ino'],
|
||||
aliases: ['INO', 'Ino', 'ino'],
|
||||
});
|
||||
|
||||
monaco.languages.setLanguageConfiguration(ArduinoLanguageGrammarContribution.INO_LANGUAGE_ID, this.configuration);
|
||||
|
||||
const inoGrammar = require('../../../data/ino.tmLanguage.json');
|
||||
registry.registerTextmateGrammarScope('source.ino', {
|
||||
async getGrammarDefinition() {
|
||||
return {
|
||||
format: 'json',
|
||||
content: inoGrammar
|
||||
};
|
||||
}
|
||||
});
|
||||
registry.mapLanguageIdToTextmateGrammar(ArduinoLanguageGrammarContribution.INO_LANGUAGE_ID, 'source.ino');
|
||||
}
|
||||
|
||||
private readonly configuration: monaco.languages.LanguageConfiguration = {
|
||||
comments: {
|
||||
lineComment: '//',
|
||||
blockComment: ['/*', '*/'],
|
||||
},
|
||||
brackets: [
|
||||
['{', '}'],
|
||||
['[', ']'],
|
||||
['(', ')']
|
||||
],
|
||||
autoClosingPairs: [
|
||||
{ open: '[', close: ']' },
|
||||
{ open: '{', close: '}' },
|
||||
{ open: '(', close: ')' },
|
||||
{ open: '\'', close: '\'', notIn: ['string', 'comment'] },
|
||||
{ open: '"', close: '"', notIn: ['string'] },
|
||||
{ open: '/*', close: ' */', notIn: ['string'] }
|
||||
],
|
||||
surroundingPairs: [
|
||||
{ open: '{', close: '}' },
|
||||
{ open: '[', close: ']' },
|
||||
{ open: '(', close: ')' },
|
||||
{ open: '"', close: '"' },
|
||||
{ open: '\'', close: '\'' },
|
||||
],
|
||||
folding: {
|
||||
markers: {
|
||||
start: new RegExp('^\\s*#pragma\\s+region\\b'),
|
||||
end: new RegExp('^\\s*#pragma\\s+endregion\\b')
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
}
|
@ -1,5 +1,5 @@
|
||||
import { injectable, inject } from 'inversify';
|
||||
import { FileSystem } from '@theia/filesystem/lib/common/filesystem';
|
||||
import { FileService } from '@theia/filesystem/lib/browser/file-service';
|
||||
import { CommandService } from '@theia/core/lib/common/command';
|
||||
import { WorkspaceService } from '@theia/workspace/lib/browser/workspace-service';
|
||||
import { FrontendApplication as TheiaFrontendApplication } from '@theia/core/lib/browser/frontend-application';
|
||||
@ -8,8 +8,8 @@ import { ArduinoCommands } from '../../arduino-commands';
|
||||
@injectable()
|
||||
export class FrontendApplication extends TheiaFrontendApplication {
|
||||
|
||||
@inject(FileSystem)
|
||||
protected readonly fileSystem: FileSystem;
|
||||
@inject(FileService)
|
||||
protected readonly fileService: FileService;
|
||||
|
||||
@inject(WorkspaceService)
|
||||
protected readonly workspaceService: WorkspaceService;
|
||||
@ -21,9 +21,9 @@ export class FrontendApplication extends TheiaFrontendApplication {
|
||||
await super.initializeLayout();
|
||||
const roots = await this.workspaceService.roots;
|
||||
for (const root of roots) {
|
||||
const exists = await this.fileSystem.exists(root.uri);
|
||||
const exists = await this.fileService.exists(root.resource);
|
||||
if (exists) {
|
||||
await this.commandService.executeCommand(ArduinoCommands.OPEN_SKETCH_FILES.id, root.uri);
|
||||
await this.commandService.executeCommand(ArduinoCommands.OPEN_SKETCH_FILES.id, root.resource);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -1,11 +1,11 @@
|
||||
import { inject, injectable, postConstruct } from 'inversify';
|
||||
import URI from '@theia/core/lib/common/uri';
|
||||
import { Title, Widget } from '@phosphor/widgets';
|
||||
import { ILogger } from '@theia/core';
|
||||
import { ILogger } from '@theia/core/lib/common/logger';
|
||||
import { EditorWidget } from '@theia/editor/lib/browser';
|
||||
import { WidgetDecoration } from '@theia/core/lib/browser/widget-decoration';
|
||||
import { TabBarDecoratorService as TheiaTabBarDecoratorService } from '@theia/core/lib/browser/shell/tab-bar-decorator';
|
||||
import { ConfigService } from '../../../common/protocol/config-service';
|
||||
import { EditorWidget } from '@theia/editor/lib/browser';
|
||||
|
||||
@injectable()
|
||||
export class TabBarDecoratorService extends TheiaTabBarDecoratorService {
|
||||
@ -20,7 +20,6 @@ export class TabBarDecoratorService extends TheiaTabBarDecoratorService {
|
||||
|
||||
@postConstruct()
|
||||
protected init(): void {
|
||||
super.init();
|
||||
this.configService.getConfiguration()
|
||||
.then(({ dataDirUri }) => this.dataDirUri = new URI(dataDirUri))
|
||||
.catch(err => this.logger.error(`Failed to determine the data directory: ${err}`));
|
||||
|
@ -0,0 +1,29 @@
|
||||
import { injectable } from 'inversify';
|
||||
import { Resource } from '@theia/core/lib/common/resource';
|
||||
import { MaybePromise } from '@theia/core/lib/common/types';
|
||||
import { Log, Loggable } from '@theia/core/lib/common/logger';
|
||||
import { MonacoEditorModel } from '@theia/monaco/lib/browser/monaco-editor-model';
|
||||
import { MonacoTextModelService as TheiaMonacoTextModelService } from '@theia/monaco/lib/browser/monaco-text-model-service';
|
||||
|
||||
@injectable()
|
||||
export class MonacoTextModelService extends TheiaMonacoTextModelService {
|
||||
|
||||
protected createModel(resource: Resource): MaybePromise<MonacoEditorModel> {
|
||||
const factory = this.factories.getContributions().find(({ scheme }) => resource.uri.scheme === scheme);
|
||||
return factory ? factory.createModel(resource) : new SilentMonacoEditorModel(resource, this.m2p, this.p2m, this.logger);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
// https://github.com/eclipse-theia/theia/pull/8491
|
||||
export class SilentMonacoEditorModel extends MonacoEditorModel {
|
||||
|
||||
protected trace(loggable: Loggable): void {
|
||||
if (this.logger) {
|
||||
this.logger.trace((log: Log) =>
|
||||
loggable((message, ...params) => log(message, ...params, this.resource.uri.toString(true)))
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
}
|
@ -1,7 +1,7 @@
|
||||
import { inject, injectable } from 'inversify';
|
||||
import URI from '@theia/core/lib/common/uri';
|
||||
import { open } from '@theia/core/lib/browser/opener-service';
|
||||
import { FileStat } from '@theia/filesystem/lib/common';
|
||||
import { FileStat } from '@theia/filesystem/lib/common/files';
|
||||
import { CommandRegistry, CommandService } from '@theia/core/lib/common/command';
|
||||
import { WorkspaceCommandContribution as TheiaWorkspaceCommandContribution, WorkspaceCommands } from '@theia/workspace/lib/browser/workspace-commands';
|
||||
import { Sketch } from '../../../common/protocol';
|
||||
@ -40,7 +40,7 @@ export class WorkspaceCommandContribution extends TheiaWorkspaceCommandContribut
|
||||
return;
|
||||
}
|
||||
|
||||
const parentUri = new URI(parent.uri);
|
||||
const parentUri = parent.resource;
|
||||
const dialog = new WorkspaceInputDialog({
|
||||
title: 'Name for new file',
|
||||
parentUri,
|
||||
@ -51,7 +51,7 @@ export class WorkspaceCommandContribution extends TheiaWorkspaceCommandContribut
|
||||
const nameWithExt = this.maybeAppendInoExt(name);
|
||||
if (nameWithExt) {
|
||||
const fileUri = parentUri.resolve(nameWithExt);
|
||||
await this.fileSystem.createFile(fileUri.toString());
|
||||
await this.fileService.createFile(fileUri);
|
||||
this.fireCreateNewFile({ parent: parentUri, uri: fileUri });
|
||||
open(this.openerService, fileUri);
|
||||
}
|
||||
@ -132,7 +132,7 @@ export class WorkspaceCommandContribution extends TheiaWorkspaceCommandContribut
|
||||
if (newNameWithExt) {
|
||||
const oldUri = uri;
|
||||
const newUri = uri.parent.resolve(newNameWithExt);
|
||||
this.fileSystem.move(oldUri.toString(), newUri.toString());
|
||||
this.fileService.move(oldUri, newUri);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -25,7 +25,7 @@ export class WorkspaceDeleteHandler extends TheiaWorkspaceDeleteHandler {
|
||||
});
|
||||
if (response === 1) { // OK
|
||||
await Promise.all([...sketch.additionalFileUris, ...sketch.otherSketchFileUris, sketch.mainFileUri].map(uri => this.closeWithoutSaving(new URI(uri))));
|
||||
await this.fileSystem.delete(sketch.uri);
|
||||
await this.fileService.delete(new URI(sketch.uri));
|
||||
window.close();
|
||||
}
|
||||
return;
|
||||
|
@ -74,7 +74,7 @@ export class WorkspaceService extends TheiaWorkspaceService {
|
||||
}
|
||||
|
||||
private async isValid(uri: string): Promise<boolean> {
|
||||
const exists = await this.fileSystem.exists(uri);
|
||||
const exists = await this.fileService.exists(new URI(uri));
|
||||
if (!exists) {
|
||||
return false;
|
||||
}
|
||||
@ -104,8 +104,7 @@ export class WorkspaceService extends TheiaWorkspaceService {
|
||||
|
||||
protected get workspaceTitle(): string | undefined {
|
||||
if (this.workspace) {
|
||||
const uri = new URI(this.workspace.uri);
|
||||
return this.labelProvider.getName(uri);
|
||||
return this.labelProvider.getName(this.workspace.resource);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -0,0 +1,5 @@
|
||||
export const ExecutableServicePath = '/services/executable-service';
|
||||
export const ExecutableService = Symbol('ExecutableService');
|
||||
export interface ExecutableService {
|
||||
list(): Promise<{ clangdUri: string, cliUri: string, lsUri: string }>;
|
||||
}
|
@ -10,3 +10,5 @@ export * from './monitor-service';
|
||||
export * from './searchable';
|
||||
export * from './sketches-service';
|
||||
export * from './tool-output-service';
|
||||
export * from './examples-service';
|
||||
export * from './executable-service';
|
||||
|
@ -1,6 +1,7 @@
|
||||
import { inject, injectable } from 'inversify';
|
||||
import URI from '@theia/core/lib/common/uri';
|
||||
import { notEmpty } from '@theia/core/lib/common/objects';
|
||||
import { FileSystem } from '@theia/filesystem/lib/common';
|
||||
import { FileService } from '@theia/filesystem/lib/browser/file-service';
|
||||
import { MessageService } from '@theia/core/lib/common/message-service';
|
||||
import { WorkspaceService } from '@theia/workspace/lib/browser/workspace-service';
|
||||
import { Sketch, SketchesService } from '../../common/protocol';
|
||||
@ -8,8 +9,8 @@ import { Sketch, SketchesService } from '../../common/protocol';
|
||||
@injectable()
|
||||
export class SketchesServiceClientImpl {
|
||||
|
||||
@inject(FileSystem)
|
||||
protected readonly fileSystem: FileSystem;
|
||||
@inject(FileService)
|
||||
protected readonly fileService: FileService;
|
||||
|
||||
@inject(MessageService)
|
||||
protected readonly messageService: MessageService;
|
||||
@ -21,7 +22,7 @@ export class SketchesServiceClientImpl {
|
||||
protected readonly workspaceService: WorkspaceService;
|
||||
|
||||
async currentSketch(): Promise<Sketch | undefined> {
|
||||
const sketches = (await Promise.all(this.workspaceService.tryGetRoots().map(({ uri }) => this.sketchService.getSketchFolder(uri)))).filter(notEmpty);
|
||||
const sketches = (await Promise.all(this.workspaceService.tryGetRoots().map(({ resource }) => this.sketchService.getSketchFolder(resource.toString())))).filter(notEmpty);
|
||||
if (!sketches.length) {
|
||||
return undefined;
|
||||
}
|
||||
@ -35,7 +36,7 @@ export class SketchesServiceClientImpl {
|
||||
const sketch = await this.currentSketch();
|
||||
if (sketch) {
|
||||
const uri = sketch.mainFileUri;
|
||||
const exists = await this.fileSystem.exists(uri);
|
||||
const exists = await this.fileService.exists(new URI(uri));
|
||||
if (!exists) {
|
||||
this.messageService.warn(`Could not find sketch file: ${uri}`);
|
||||
return undefined;
|
||||
|
@ -5,8 +5,6 @@ import { ContainerModule } from 'inversify';
|
||||
import { ArduinoDaemonImpl } from './arduino-daemon-impl';
|
||||
import { ILogger } from '@theia/core/lib/common/logger';
|
||||
import { BackendApplicationContribution } from '@theia/core/lib/node/backend-application';
|
||||
import { LanguageServerContribution } from '@theia/languages/lib/node';
|
||||
import { ArduinoLanguageServerContribution } from './language/arduino-language-server-contribution';
|
||||
import { LibraryServiceServerPath, LibraryServiceServer, LibraryServiceClient } from '../common/protocol/library-service';
|
||||
import { BoardsService, BoardsServicePath, BoardsServiceClient } from '../common/protocol/boards-service';
|
||||
import { LibraryServiceServerImpl } from './library-service-server-impl';
|
||||
@ -37,6 +35,8 @@ import { NodeFileSystemExt } from './node-filesystem-ext';
|
||||
import { FileSystemExt, FileSystemExtPath } from '../common/protocol/filesystem-ext';
|
||||
import { ExamplesServiceImpl } from './examples-service-impl';
|
||||
import { ExamplesService, ExamplesServicePath } from '../common/protocol/examples-service';
|
||||
import { ExecutableService, ExecutableServicePath } from '../common/protocol/executable-service';
|
||||
import { ExecutableServiceImpl } from './executable-service-impl';
|
||||
|
||||
export default new ContainerModule((bind, unbind, isBound, rebind) => {
|
||||
rebind(EnvVariablesServer).to(ArduinoEnvVariablesServer).inSingletonScope();
|
||||
@ -73,9 +73,10 @@ export default new ContainerModule((bind, unbind, isBound, rebind) => {
|
||||
bind(ExamplesService).toService(ExamplesServiceImpl);
|
||||
bind(ConnectionHandler).toDynamicValue(context => new JsonRpcConnectionHandler(ExamplesServicePath, () => context.container.get(ExamplesService))).inSingletonScope();
|
||||
|
||||
// Language server
|
||||
bind(ArduinoLanguageServerContribution).toSelf().inSingletonScope();
|
||||
bind(LanguageServerContribution).toService(ArduinoLanguageServerContribution);
|
||||
// Exposes the executable paths/URIs to the frontend
|
||||
bind(ExecutableServiceImpl).toSelf().inSingletonScope();
|
||||
bind(ExecutableService).toService(ExecutableServiceImpl);
|
||||
bind(ConnectionHandler).toDynamicValue(context => new JsonRpcConnectionHandler(ExecutableServicePath, () => context.container.get(ExecutableService))).inSingletonScope();
|
||||
|
||||
// Library service
|
||||
bind(LibraryServiceServerImpl).toSelf().inSingletonScope();
|
||||
|
@ -1,5 +1,5 @@
|
||||
import { inject, injectable, postConstruct } from 'inversify';
|
||||
import { FileSystem } from '@theia/filesystem/lib/common/filesystem';
|
||||
import { FileUri } from '@theia/core/lib/node/file-uri';
|
||||
import { CoreService, CoreServiceClient } from '../common/protocol/core-service';
|
||||
import { CompileReq, CompileResp } from './cli-protocol/commands/compile_pb';
|
||||
import { BoardsService } from '../common/protocol/boards-service';
|
||||
@ -14,8 +14,6 @@ export class CoreServiceImpl implements CoreService {
|
||||
@inject(CoreClientProvider)
|
||||
protected readonly coreClientProvider: CoreClientProvider;
|
||||
|
||||
@inject(FileSystem)
|
||||
protected readonly fileSystem: FileSystem;
|
||||
|
||||
@inject(BoardsService)
|
||||
protected readonly boardsService: BoardsService;
|
||||
@ -37,10 +35,7 @@ export class CoreServiceImpl implements CoreService {
|
||||
async compile(options: CoreService.Compile.Options): Promise<void> {
|
||||
this.toolOutputService.append({ tool: 'compile', chunk: 'Compiling...\n' + JSON.stringify(options, null, 2) + '\n--------------------------\n' });
|
||||
const { sketchUri, fqbn } = options;
|
||||
const sketchFilePath = await this.fileSystem.getFsPath(sketchUri);
|
||||
if (!sketchFilePath) {
|
||||
throw new Error(`Cannot resolve filesystem path for URI: ${sketchUri}.`);
|
||||
}
|
||||
const sketchFilePath = FileUri.fsPath(sketchUri);
|
||||
const sketchpath = path.dirname(sketchFilePath);
|
||||
|
||||
const coreClient = await this.coreClientProvider.client();
|
||||
@ -83,10 +78,7 @@ export class CoreServiceImpl implements CoreService {
|
||||
await this.compile(options);
|
||||
this.toolOutputService.append({ tool: 'upload', chunk: 'Uploading...\n' + JSON.stringify(options, null, 2) + '\n--------------------------\n' });
|
||||
const { sketchUri, fqbn } = options;
|
||||
const sketchFilePath = await this.fileSystem.getFsPath(sketchUri);
|
||||
if (!sketchFilePath) {
|
||||
throw new Error(`Cannot resolve filesystem path for URI: ${sketchUri}.`);
|
||||
}
|
||||
const sketchFilePath = FileUri.fsPath(sketchUri);
|
||||
const sketchpath = path.dirname(sketchFilePath);
|
||||
|
||||
const coreClient = await this.coreClientProvider.client();
|
||||
|
31
arduino-ide-extension/src/node/executable-service-impl.ts
Normal file
31
arduino-ide-extension/src/node/executable-service-impl.ts
Normal file
@ -0,0 +1,31 @@
|
||||
import * as os from 'os';
|
||||
import { injectable, inject } from 'inversify';
|
||||
import { ILogger } from '@theia/core/lib/common/logger';
|
||||
import { FileUri } from '@theia/core/lib/node/file-uri';
|
||||
import { getExecPath } from './exec-util';
|
||||
import { ExecutableService } from '../common/protocol/executable-service';
|
||||
|
||||
@injectable()
|
||||
export class ExecutableServiceImpl implements ExecutableService {
|
||||
|
||||
@inject(ILogger)
|
||||
protected logger: ILogger;
|
||||
|
||||
async list(): Promise<{ clangdUri: string, cliUri: string, lsUri: string }> {
|
||||
const [ls, clangd, cli] = await Promise.all([
|
||||
getExecPath('arduino-language-server', this.onError.bind(this)),
|
||||
getExecPath('clangd', this.onError.bind(this), '--version', os.platform() !== 'win32'),
|
||||
getExecPath('arduino-cli', this.onError.bind(this))
|
||||
]);
|
||||
return {
|
||||
clangdUri: FileUri.create(clangd).toString(),
|
||||
cliUri: FileUri.create(cli).toString(),
|
||||
lsUri: FileUri.create(ls).toString()
|
||||
};
|
||||
}
|
||||
|
||||
protected onError(error: Error): void {
|
||||
this.logger.error(error);
|
||||
}
|
||||
|
||||
}
|
@ -1,55 +0,0 @@
|
||||
import * as os from 'os';
|
||||
import { injectable, inject } from 'inversify';
|
||||
import { ILogger } from '@theia/core';
|
||||
import { BaseLanguageServerContribution, IConnection, LanguageServerStartOptions } from '@theia/languages/lib/node';
|
||||
import { Board } from '../../common/protocol/boards-service';
|
||||
import { getExecPath } from '../exec-util';
|
||||
|
||||
@injectable()
|
||||
export class ArduinoLanguageServerContribution extends BaseLanguageServerContribution {
|
||||
|
||||
readonly description = {
|
||||
id: 'ino',
|
||||
name: 'Arduino',
|
||||
documentSelector: ['ino'],
|
||||
fileEvents: ['**/*.ino']
|
||||
}
|
||||
|
||||
get id() {
|
||||
return this.description.id;
|
||||
}
|
||||
|
||||
get name() {
|
||||
return this.description.name;
|
||||
}
|
||||
|
||||
@inject(ILogger)
|
||||
protected logger: ILogger;
|
||||
|
||||
async start(clientConnection: IConnection, options: LanguageServerStartOptions): Promise<void> {
|
||||
const [languageServer, clangd, cli] = await Promise.all([
|
||||
getExecPath('arduino-language-server', this.onError.bind(this)),
|
||||
getExecPath('clangd', this.onError.bind(this), '--version', os.platform() !== 'win32'),
|
||||
getExecPath('arduino-cli', this.onError.bind(this))
|
||||
]);
|
||||
// Add '-log' argument to enable logging to files
|
||||
const args: string[] = ['-clangd', clangd, '-cli', cli];
|
||||
if (options.parameters && options.parameters.selectedBoard) {
|
||||
const board = options.parameters.selectedBoard as Board;
|
||||
if (board.fqbn) {
|
||||
args.push('-fqbn', board.fqbn);
|
||||
}
|
||||
if (board.name) {
|
||||
args.push('-board-name', `"${board.name}"`);
|
||||
}
|
||||
}
|
||||
console.log(`Starting language server ${languageServer} ${args.join(' ')}`);
|
||||
const serverConnection = await this.createProcessStreamConnectionAsync(languageServer, args);
|
||||
this.forward(clientConnection, serverConnection);
|
||||
}
|
||||
|
||||
protected onError(error: Error): void {
|
||||
this.logger.error(error);
|
||||
}
|
||||
|
||||
}
|
@ -9,7 +9,6 @@
|
||||
"@theia/editor": "next",
|
||||
"@theia/file-search": "next",
|
||||
"@theia/filesystem": "next",
|
||||
"@theia/languages": "next",
|
||||
"@theia/messages": "next",
|
||||
"@theia/monaco": "next",
|
||||
"@theia/navigator": "next",
|
||||
|
@ -8,13 +8,13 @@ Building the Pro IDE on Linux `armv7l` (aka `armhf`) and `aarch64` (aka `arm64`)
|
||||
```
|
||||
Restart your shell then:
|
||||
```
|
||||
nvm install 10.15.3
|
||||
nvm use 10.15.3
|
||||
nvm install 12.14.1
|
||||
nvm use 12.14.1
|
||||
```
|
||||
Verify:
|
||||
```
|
||||
node -v
|
||||
v10.15.3
|
||||
v12.14.1
|
||||
```
|
||||
|
||||
2. Install [Yarn](https://classic.yarnpkg.com/en/docs/install/#debian-stable):
|
||||
|
@ -11,7 +11,6 @@
|
||||
"@theia/electron": "next",
|
||||
"@theia/file-search": "next",
|
||||
"@theia/filesystem": "next",
|
||||
"@theia/languages": "next",
|
||||
"@theia/messages": "next",
|
||||
"@theia/monaco": "next",
|
||||
"@theia/navigator": "next",
|
||||
|
@ -25,7 +25,7 @@
|
||||
"patch": "ncp ./patch/electron-main.js ./src-gen/frontend/electron-main.js && ncp ./patch/main.js ./src-gen/backend/main.js"
|
||||
},
|
||||
"engines": {
|
||||
"node": ">=10.11.0 <13"
|
||||
"node": ">=12.14.1 <13"
|
||||
},
|
||||
"repository": {
|
||||
"type": "git",
|
||||
@ -127,6 +127,7 @@
|
||||
},
|
||||
"theiaPluginsDir": "plugins",
|
||||
"theiaPlugins": {
|
||||
"vscode-builtin-cpp": "http://open-vsx.org/api/vscode/cpp/1.44.2/file/vscode.cpp-1.44.2.vsix"
|
||||
"vscode-builtin-cpp": "http://open-vsx.org/api/vscode/cpp/1.44.2/file/vscode.cpp-1.44.2.vsix",
|
||||
"vscode-arduino-language-server": "https://downloads.arduino.cc/vscode-arduino-language-server/nightly/vscode-arduino-language-server-0.0.1.vsix"
|
||||
}
|
||||
}
|
||||
|
@ -31,7 +31,7 @@
|
||||
"yargs": "^12.0.5"
|
||||
},
|
||||
"engines": {
|
||||
"node": ">=10.11.0 <13"
|
||||
"node": ">=12.14.1 <13"
|
||||
},
|
||||
"mocha": {
|
||||
"reporter": "spec",
|
||||
|
@ -7,7 +7,7 @@
|
||||
"license": "MIT",
|
||||
"private": true,
|
||||
"engines": {
|
||||
"node": ">=10.11.0 <13"
|
||||
"node": ">=12.14.1 <13"
|
||||
},
|
||||
"devDependencies": {
|
||||
"@theia/cli": "next",
|
||||
@ -34,6 +34,7 @@
|
||||
],
|
||||
"theiaPluginsDir": "plugins",
|
||||
"theiaPlugins": {
|
||||
"vscode-builtin-cpp": "http://open-vsx.org/api/vscode/cpp/1.44.2/file/vscode.cpp-1.44.2.vsix"
|
||||
"vscode-builtin-cpp": "http://open-vsx.org/api/vscode/cpp/1.44.2/file/vscode.cpp-1.44.2.vsix",
|
||||
"vscode-arduino-language-server": "https://downloads.arduino.cc/vscode-arduino-language-server/nightly/vscode-arduino-language-server-0.0.1.vsix"
|
||||
}
|
||||
}
|
||||
|
Loading…
x
Reference in New Issue
Block a user