mirror of
https://github.com/arduino/arduino-ide.git
synced 2025-10-13 05:18:33 +00:00
Compare commits
35 Commits
2.0.0-rc8
...
pluggable-
Author | SHA1 | Date | |
---|---|---|---|
![]() |
9a16cf9e02 | ||
![]() |
a4ff05a82b | ||
![]() |
0427759fdb | ||
![]() |
80ade4c37e | ||
![]() |
355dec8aaa | ||
![]() |
7bf4ea0637 | ||
![]() |
1982609c87 | ||
![]() |
62eaeb1c74 | ||
![]() |
9b58c9d0c8 | ||
![]() |
eff960bb7f | ||
![]() |
fbe8fb421a | ||
![]() |
a8d803e7c3 | ||
![]() |
397ca5665f | ||
![]() |
f9da9fc24b | ||
![]() |
b97af32bb8 | ||
![]() |
ce2f1c227a | ||
![]() |
7889f40834 | ||
![]() |
6b7b33356d | ||
![]() |
ad781f0bfc | ||
![]() |
6cf61c498a | ||
![]() |
50239c5756 | ||
![]() |
cbd5b4de1b | ||
![]() |
bf958fd8cf | ||
![]() |
ee265aec90 | ||
![]() |
9058abb015 | ||
![]() |
31b704cdb9 | ||
![]() |
61b8bdeec9 | ||
![]() |
c5695d3a76 | ||
![]() |
480492a7c8 | ||
![]() |
2c95e7f033 | ||
![]() |
116b3d5984 | ||
![]() |
750796d3a0 | ||
![]() |
3133b01c4a | ||
![]() |
ebab0b226f | ||
![]() |
2b2ea72643 |
1
.github/workflows/build.yml
vendored
1
.github/workflows/build.yml
vendored
@@ -78,7 +78,6 @@ jobs:
|
|||||||
fi
|
fi
|
||||||
fi
|
fi
|
||||||
|
|
||||||
npx node-gyp install
|
|
||||||
yarn --cwd ./electron/packager/
|
yarn --cwd ./electron/packager/
|
||||||
yarn --cwd ./electron/packager/ package
|
yarn --cwd ./electron/packager/ package
|
||||||
|
|
||||||
|
49
.github/workflows/themes-weekly-pull.yml
vendored
49
.github/workflows/themes-weekly-pull.yml
vendored
@@ -1,49 +0,0 @@
|
|||||||
name: themes-weekly-pull
|
|
||||||
|
|
||||||
on:
|
|
||||||
schedule:
|
|
||||||
# run every friday at 5AM
|
|
||||||
- cron: '0 5 * * 5'
|
|
||||||
workflow_dispatch:
|
|
||||||
|
|
||||||
env:
|
|
||||||
NODE_VERSION: 14.x
|
|
||||||
|
|
||||||
jobs:
|
|
||||||
pull-from-jsonbin:
|
|
||||||
runs-on: ubuntu-latest
|
|
||||||
steps:
|
|
||||||
- name: Checkout
|
|
||||||
uses: actions/checkout@v3
|
|
||||||
|
|
||||||
- name: Install Node.js
|
|
||||||
uses: actions/setup-node@v3
|
|
||||||
with:
|
|
||||||
node-version: ${{ env.NODE_VERSION }}
|
|
||||||
registry-url: 'https://registry.npmjs.org'
|
|
||||||
|
|
||||||
- name: Install dependencies
|
|
||||||
run: yarn
|
|
||||||
|
|
||||||
- name: Run themes:pull script
|
|
||||||
run: yarn run themes:pull
|
|
||||||
env:
|
|
||||||
JSONBIN_MASTER_KEY: ${{ secrets.JSONBIN_MASTER_KEY }}
|
|
||||||
JSONBIN_ID: ${{ secrets.JSONBIN_ID }}
|
|
||||||
|
|
||||||
- name: Generate dark tokens
|
|
||||||
run: npx token-transformer scripts/themes/tokens/arduino-tokens.json scripts/themes/tokens/dark.json core,ide-default,ide-dark,theia core,ide-default,ide-dark
|
|
||||||
|
|
||||||
- name: Generate default tokens
|
|
||||||
run: npx token-transformer scripts/themes/tokens/arduino-tokens.json scripts/themes/tokens/default.json core,ide-default,theia core,ide-default
|
|
||||||
|
|
||||||
- name: Run themes:generate script
|
|
||||||
run: yarn run themes:generate
|
|
||||||
|
|
||||||
- name: Create Pull Request
|
|
||||||
uses: peter-evans/create-pull-request@v4
|
|
||||||
with:
|
|
||||||
commit-message: Updated themes
|
|
||||||
title: Update themes
|
|
||||||
branch: themes/themes-update
|
|
||||||
author: github-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com>
|
|
6
.gitignore
vendored
6
.gitignore
vendored
@@ -17,9 +17,3 @@ yarn*.log
|
|||||||
plugins
|
plugins
|
||||||
# the config files for the CLI
|
# the config files for the CLI
|
||||||
arduino-ide-extension/data/cli/config
|
arduino-ide-extension/data/cli/config
|
||||||
# the tokens folder for the themes
|
|
||||||
scripts/themes/tokens
|
|
||||||
# environment variables
|
|
||||||
.env
|
|
||||||
# content trace files for electron
|
|
||||||
electron-app/traces
|
|
||||||
|
@@ -2,6 +2,5 @@
|
|||||||
"singleQuote": true,
|
"singleQuote": true,
|
||||||
"tabWidth": 2,
|
"tabWidth": 2,
|
||||||
"useTabs": false,
|
"useTabs": false,
|
||||||
"printWidth": 80,
|
"printWidth": 80
|
||||||
"endOfLine": "auto"
|
|
||||||
}
|
}
|
||||||
|
40
.vscode/launch.json
vendored
40
.vscode/launch.json
vendored
@@ -1,44 +1,6 @@
|
|||||||
{
|
{
|
||||||
"version": "0.2.0",
|
"version": "0.2.0",
|
||||||
"configurations": [
|
"configurations": [
|
||||||
{
|
|
||||||
"type": "node",
|
|
||||||
"request": "launch",
|
|
||||||
"name": "App (Electron) [Dev]",
|
|
||||||
"runtimeExecutable": "${workspaceRoot}/node_modules/.bin/electron",
|
|
||||||
"windows": {
|
|
||||||
"runtimeExecutable": "${workspaceRoot}/node_modules/.bin/electron.cmd",
|
|
||||||
},
|
|
||||||
"cwd": "${workspaceFolder}/electron-app",
|
|
||||||
"args": [
|
|
||||||
".",
|
|
||||||
"--log-level=debug",
|
|
||||||
"--hostname=localhost",
|
|
||||||
"--no-cluster",
|
|
||||||
"--app-project-path=${workspaceRoot}/electron-app",
|
|
||||||
"--remote-debugging-port=9222",
|
|
||||||
"--no-app-auto-install",
|
|
||||||
"--plugins=local-dir:../plugins",
|
|
||||||
"--hosted-plugin-inspect=9339",
|
|
||||||
"--nosplash",
|
|
||||||
"--content-trace",
|
|
||||||
"--open-devtools"
|
|
||||||
],
|
|
||||||
"env": {
|
|
||||||
"NODE_ENV": "development"
|
|
||||||
},
|
|
||||||
"sourceMaps": true,
|
|
||||||
"outFiles": [
|
|
||||||
"${workspaceRoot}/electron-app/src-gen/backend/*.js",
|
|
||||||
"${workspaceRoot}/electron-app/src-gen/frontend/*.js",
|
|
||||||
"${workspaceRoot}/electron-app/lib/**/*.js",
|
|
||||||
"${workspaceRoot}/arduino-ide-extension/lib/**/*.js",
|
|
||||||
"${workspaceRoot}/node_modules/@theia/**/*.js"
|
|
||||||
],
|
|
||||||
"smartStep": true,
|
|
||||||
"internalConsoleOptions": "openOnSessionStart",
|
|
||||||
"outputCapture": "std"
|
|
||||||
},
|
|
||||||
{
|
{
|
||||||
"type": "node",
|
"type": "node",
|
||||||
"request": "launch",
|
"request": "launch",
|
||||||
@@ -48,6 +10,7 @@
|
|||||||
"runtimeExecutable": "${workspaceRoot}/node_modules/.bin/electron.cmd",
|
"runtimeExecutable": "${workspaceRoot}/node_modules/.bin/electron.cmd",
|
||||||
},
|
},
|
||||||
"cwd": "${workspaceFolder}/electron-app",
|
"cwd": "${workspaceFolder}/electron-app",
|
||||||
|
"protocol": "inspector",
|
||||||
"args": [
|
"args": [
|
||||||
".",
|
".",
|
||||||
"--log-level=debug",
|
"--log-level=debug",
|
||||||
@@ -115,6 +78,7 @@
|
|||||||
{
|
{
|
||||||
"type": "node",
|
"type": "node",
|
||||||
"request": "launch",
|
"request": "launch",
|
||||||
|
"protocol": "inspector",
|
||||||
"name": "Run Test [current]",
|
"name": "Run Test [current]",
|
||||||
"program": "${workspaceRoot}/node_modules/mocha/bin/_mocha",
|
"program": "${workspaceRoot}/node_modules/mocha/bin/_mocha",
|
||||||
"args": [
|
"args": [
|
||||||
|
@@ -1,6 +1,6 @@
|
|||||||
{
|
{
|
||||||
"name": "arduino-ide-extension",
|
"name": "arduino-ide-extension",
|
||||||
"version": "2.0.0-rc8",
|
"version": "2.0.0-rc6",
|
||||||
"description": "An extension for Theia building the Arduino IDE",
|
"description": "An extension for Theia building the Arduino IDE",
|
||||||
"license": "AGPL-3.0-or-later",
|
"license": "AGPL-3.0-or-later",
|
||||||
"scripts": {
|
"scripts": {
|
||||||
@@ -21,30 +21,31 @@
|
|||||||
"test:watch": "mocha --watch --watch-files lib \"./lib/test/**/*.test.js\""
|
"test:watch": "mocha --watch --watch-files lib \"./lib/test/**/*.test.js\""
|
||||||
},
|
},
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"@grpc/grpc-js": "^1.6.7",
|
"@grpc/grpc-js": "^1.3.7",
|
||||||
"@theia/application-package": "1.25.0",
|
"@theia/application-package": "1.22.1",
|
||||||
"@theia/core": "1.25.0",
|
"@theia/core": "1.22.1",
|
||||||
"@theia/editor": "1.25.0",
|
"@theia/editor": "1.22.1",
|
||||||
"@theia/electron": "1.25.0",
|
"@theia/editor-preview": "1.22.1",
|
||||||
"@theia/filesystem": "1.25.0",
|
"@theia/electron": "1.22.1",
|
||||||
"@theia/keymaps": "1.25.0",
|
"@theia/filesystem": "1.22.1",
|
||||||
"@theia/markers": "1.25.0",
|
"@theia/git": "1.22.1",
|
||||||
"@theia/monaco": "1.25.0",
|
"@theia/keymaps": "1.22.1",
|
||||||
"@theia/navigator": "1.25.0",
|
"@theia/markers": "1.22.1",
|
||||||
"@theia/outline-view": "1.25.0",
|
"@theia/monaco": "1.22.1",
|
||||||
"@theia/output": "1.25.0",
|
"@theia/navigator": "1.22.1",
|
||||||
"@theia/preferences": "1.25.0",
|
"@theia/outline-view": "1.22.1",
|
||||||
"@theia/search-in-workspace": "1.25.0",
|
"@theia/output": "1.22.1",
|
||||||
"@theia/terminal": "1.25.0",
|
"@theia/preferences": "1.22.1",
|
||||||
"@theia/workspace": "1.25.0",
|
"@theia/search-in-workspace": "1.22.1",
|
||||||
|
"@theia/terminal": "1.22.1",
|
||||||
|
"@theia/workspace": "1.22.1",
|
||||||
"@tippyjs/react": "^4.2.5",
|
"@tippyjs/react": "^4.2.5",
|
||||||
"@types/atob": "^2.1.2",
|
"@types/atob": "^2.1.2",
|
||||||
"@types/auth0-js": "^9.14.0",
|
"@types/auth0-js": "^9.14.0",
|
||||||
"@types/btoa": "^1.2.3",
|
"@types/btoa": "^1.2.3",
|
||||||
"@types/dateformat": "^3.0.1",
|
"@types/dateformat": "^3.0.1",
|
||||||
"@types/deep-equal": "^1.0.1",
|
|
||||||
"@types/deepmerge": "^2.2.0",
|
"@types/deepmerge": "^2.2.0",
|
||||||
"@types/glob": "^7.2.0",
|
"@types/glob": "^5.0.35",
|
||||||
"@types/google-protobuf": "^3.7.2",
|
"@types/google-protobuf": "^3.7.2",
|
||||||
"@types/js-yaml": "^3.12.2",
|
"@types/js-yaml": "^3.12.2",
|
||||||
"@types/keytar": "^4.4.0",
|
"@types/keytar": "^4.4.0",
|
||||||
@@ -57,18 +58,19 @@
|
|||||||
"@types/temp": "^0.8.34",
|
"@types/temp": "^0.8.34",
|
||||||
"@types/which": "^1.3.1",
|
"@types/which": "^1.3.1",
|
||||||
"ajv": "^6.5.3",
|
"ajv": "^6.5.3",
|
||||||
"arduino-serial-plotter-webapp": "0.1.0",
|
"arduino-serial-plotter-webapp": "0.0.17",
|
||||||
"async-mutex": "^0.3.0",
|
"async-mutex": "^0.3.0",
|
||||||
"atob": "^2.1.2",
|
"atob": "^2.1.2",
|
||||||
"auth0-js": "^9.14.0",
|
"auth0-js": "^9.14.0",
|
||||||
"btoa": "^1.2.1",
|
"btoa": "^1.2.1",
|
||||||
|
"css-element-queries": "^1.2.0",
|
||||||
"dateformat": "^3.0.3",
|
"dateformat": "^3.0.3",
|
||||||
"deep-equal": "^2.0.5",
|
|
||||||
"deepmerge": "2.0.1",
|
"deepmerge": "2.0.1",
|
||||||
"electron-updater": "^4.6.5",
|
"electron-updater": "^4.6.5",
|
||||||
"fast-safe-stringify": "^2.1.1",
|
"fuzzy": "^0.1.3",
|
||||||
"glob": "^7.1.6",
|
"glob": "^7.1.6",
|
||||||
"google-protobuf": "^3.20.1",
|
"google-protobuf": "^3.11.4",
|
||||||
|
"grpc": "^1.24.11",
|
||||||
"hash.js": "^1.1.7",
|
"hash.js": "^1.1.7",
|
||||||
"is-valid-path": "^0.1.1",
|
"is-valid-path": "^0.1.1",
|
||||||
"js-yaml": "^3.13.1",
|
"js-yaml": "^3.13.1",
|
||||||
@@ -89,7 +91,6 @@
|
|||||||
"semver": "^7.3.2",
|
"semver": "^7.3.2",
|
||||||
"string-natural-compare": "^2.0.3",
|
"string-natural-compare": "^2.0.3",
|
||||||
"temp": "^0.9.1",
|
"temp": "^0.9.1",
|
||||||
"temp-dir": "^2.0.0",
|
|
||||||
"tree-kill": "^1.2.1",
|
"tree-kill": "^1.2.1",
|
||||||
"upath": "^1.1.2",
|
"upath": "^1.1.2",
|
||||||
"url": "^0.11.0",
|
"url": "^0.11.0",
|
||||||
@@ -156,13 +157,13 @@
|
|||||||
],
|
],
|
||||||
"arduino": {
|
"arduino": {
|
||||||
"cli": {
|
"cli": {
|
||||||
"version": "0.24.0"
|
"version": "0.22.0"
|
||||||
},
|
},
|
||||||
"fwuploader": {
|
"fwuploader": {
|
||||||
"version": "2.2.0"
|
"version": "2.0.0"
|
||||||
},
|
},
|
||||||
"clangd": {
|
"clangd": {
|
||||||
"version": "14.0.0"
|
"version": "13.0.0"
|
||||||
},
|
},
|
||||||
"languageServer": {
|
"languageServer": {
|
||||||
"version": "0.6.0"
|
"version": "0.6.0"
|
||||||
|
@@ -4,93 +4,30 @@
|
|||||||
const version = '1.9.1';
|
const version = '1.9.1';
|
||||||
|
|
||||||
(async () => {
|
(async () => {
|
||||||
const os = require('os');
|
|
||||||
const { promises: fs } = require('fs');
|
|
||||||
const path = require('path');
|
|
||||||
const shell = require('shelljs');
|
|
||||||
const { v4 } = require('uuid');
|
|
||||||
|
|
||||||
const repository = path.join(os.tmpdir(), `${v4()}-arduino-examples`);
|
const os = require('os');
|
||||||
if (shell.mkdir('-p', repository).code !== 0) {
|
const path = require('path');
|
||||||
shell.exit(1);
|
const shell = require('shelljs');
|
||||||
}
|
const { v4 } = require('uuid');
|
||||||
|
|
||||||
if (
|
const repository = path.join(os.tmpdir(), `${v4()}-arduino-examples`);
|
||||||
shell.exec(
|
if (shell.mkdir('-p', repository).code !== 0) {
|
||||||
`git clone https://github.com/arduino/arduino-examples.git ${repository}`
|
shell.exit(1);
|
||||||
).code !== 0
|
process.exit(1);
|
||||||
) {
|
|
||||||
shell.exit(1);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (
|
|
||||||
shell.exec(`git -C ${repository} checkout tags/${version} -b ${version}`)
|
|
||||||
.code !== 0
|
|
||||||
) {
|
|
||||||
shell.exit(1);
|
|
||||||
}
|
|
||||||
|
|
||||||
const destination = path.join(__dirname, '..', 'Examples');
|
|
||||||
shell.mkdir('-p', destination);
|
|
||||||
shell.cp('-fR', path.join(repository, 'examples', '*'), destination);
|
|
||||||
|
|
||||||
const isSketch = async (pathLike) => {
|
|
||||||
try {
|
|
||||||
const names = await fs.readdir(pathLike);
|
|
||||||
const dirName = path.basename(pathLike);
|
|
||||||
return names.indexOf(`${dirName}.ino`) !== -1;
|
|
||||||
} catch (e) {
|
|
||||||
if (e.code === 'ENOTDIR') {
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
throw e;
|
|
||||||
}
|
}
|
||||||
};
|
|
||||||
const examples = [];
|
if (shell.exec(`git clone https://github.com/arduino/arduino-examples.git ${repository}`).code !== 0) {
|
||||||
const categories = await fs.readdir(destination);
|
shell.exit(1);
|
||||||
const visit = async (pathLike, container) => {
|
process.exit(1);
|
||||||
const stat = await fs.lstat(pathLike);
|
|
||||||
if (stat.isDirectory()) {
|
|
||||||
if (await isSketch(pathLike)) {
|
|
||||||
container.sketches.push({
|
|
||||||
name: path.basename(pathLike),
|
|
||||||
relativePath: path.relative(destination, pathLike),
|
|
||||||
});
|
|
||||||
} else {
|
|
||||||
const names = await fs.readdir(pathLike);
|
|
||||||
for (const name of names) {
|
|
||||||
const childPath = path.join(pathLike, name);
|
|
||||||
if (await isSketch(childPath)) {
|
|
||||||
container.sketches.push({
|
|
||||||
name,
|
|
||||||
relativePath: path.relative(destination, childPath),
|
|
||||||
});
|
|
||||||
} else {
|
|
||||||
const child = {
|
|
||||||
label: name,
|
|
||||||
children: [],
|
|
||||||
sketches: [],
|
|
||||||
};
|
|
||||||
container.children.push(child);
|
|
||||||
await visit(childPath, child);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
};
|
|
||||||
for (const category of categories) {
|
if (shell.exec(`git -C ${repository} checkout tags/${version} -b ${version}`).code !== 0) {
|
||||||
const example = {
|
shell.exit(1);
|
||||||
label: category,
|
process.exit(1);
|
||||||
children: [],
|
}
|
||||||
sketches: [],
|
|
||||||
};
|
const destination = path.join(__dirname, '..', 'Examples');
|
||||||
await visit(path.join(destination, category), example);
|
shell.mkdir('-p', destination);
|
||||||
examples.push(example);
|
shell.cp('-fR', path.join(repository, 'examples', '*'), destination);
|
||||||
}
|
|
||||||
await fs.writeFile(
|
|
||||||
path.join(destination, 'examples.json'),
|
|
||||||
JSON.stringify(examples, null, 2),
|
|
||||||
{ encoding: 'utf8' }
|
|
||||||
);
|
|
||||||
shell.echo(`Generated output to ${path.join(destination, 'examples.json')}`);
|
|
||||||
})();
|
})();
|
||||||
|
@@ -66,24 +66,21 @@
|
|||||||
build,
|
build,
|
||||||
`arduino-language-server${platform === 'win32' ? '.exe' : ''}`
|
`arduino-language-server${platform === 'win32' ? '.exe' : ''}`
|
||||||
);
|
);
|
||||||
let clangdExecutablePath, clangFormatExecutablePath, lsSuffix, clangdSuffix;
|
let clangdExecutablePath, lsSuffix, clangdSuffix;
|
||||||
|
|
||||||
switch (platformArch) {
|
switch (platformArch) {
|
||||||
case 'darwin-x64':
|
case 'darwin-x64':
|
||||||
clangdExecutablePath = path.join(build, 'clangd');
|
clangdExecutablePath = path.join(build, 'clangd');
|
||||||
clangFormatExecutablePath = path.join(build, 'clang-format');
|
|
||||||
lsSuffix = 'macOS_64bit.tar.gz';
|
lsSuffix = 'macOS_64bit.tar.gz';
|
||||||
clangdSuffix = 'macOS_64bit';
|
clangdSuffix = 'macOS_64bit';
|
||||||
break;
|
break;
|
||||||
case 'linux-x64':
|
case 'linux-x64':
|
||||||
clangdExecutablePath = path.join(build, 'clangd');
|
clangdExecutablePath = path.join(build, 'clangd');
|
||||||
clangFormatExecutablePath = path.join(build, 'clang-format');
|
|
||||||
lsSuffix = 'Linux_64bit.tar.gz';
|
lsSuffix = 'Linux_64bit.tar.gz';
|
||||||
clangdSuffix = 'Linux_64bit';
|
clangdSuffix = 'Linux_64bit';
|
||||||
break;
|
break;
|
||||||
case 'win32-x64':
|
case 'win32-x64':
|
||||||
clangdExecutablePath = path.join(build, 'clangd.exe');
|
clangdExecutablePath = path.join(build, 'clangd.exe');
|
||||||
clangFormatExecutablePath = path.join(build, 'clang-format.exe');
|
|
||||||
lsSuffix = 'Windows_64bit.zip';
|
lsSuffix = 'Windows_64bit.zip';
|
||||||
clangdSuffix = 'Windows_64bit';
|
clangdSuffix = 'Windows_64bit';
|
||||||
break;
|
break;
|
||||||
@@ -106,15 +103,4 @@
|
|||||||
downloader.downloadUnzipAll(clangdUrl, build, clangdExecutablePath, force, {
|
downloader.downloadUnzipAll(clangdUrl, build, clangdExecutablePath, force, {
|
||||||
strip: 1,
|
strip: 1,
|
||||||
}); // `strip`: the new clangd (12.x) is zipped into a folder, so we have to strip the outmost folder.
|
}); // `strip`: the new clangd (12.x) is zipped into a folder, so we have to strip the outmost folder.
|
||||||
|
|
||||||
const clangdFormatUrl = `https://downloads.arduino.cc/tools/clang-format_${clangdVersion}_${clangdSuffix}.tar.bz2`;
|
|
||||||
downloader.downloadUnzipAll(
|
|
||||||
clangdFormatUrl,
|
|
||||||
build,
|
|
||||||
clangFormatExecutablePath,
|
|
||||||
force,
|
|
||||||
{
|
|
||||||
strip: 1,
|
|
||||||
}
|
|
||||||
);
|
|
||||||
})();
|
})();
|
||||||
|
@@ -1,9 +1,5 @@
|
|||||||
import {
|
import { inject, injectable, postConstruct } from 'inversify';
|
||||||
inject,
|
import * as React from 'react';
|
||||||
injectable,
|
|
||||||
postConstruct,
|
|
||||||
} from '@theia/core/shared/inversify';
|
|
||||||
import * as React from '@theia/core/shared/react';
|
|
||||||
import * as remote from '@theia/core/electron-shared/@electron/remote';
|
import * as remote from '@theia/core/electron-shared/@electron/remote';
|
||||||
import {
|
import {
|
||||||
BoardsService,
|
BoardsService,
|
||||||
@@ -11,7 +7,6 @@ import {
|
|||||||
ExecutableService,
|
ExecutableService,
|
||||||
Sketch,
|
Sketch,
|
||||||
LibraryService,
|
LibraryService,
|
||||||
ArduinoDaemon,
|
|
||||||
} from '../common/protocol';
|
} from '../common/protocol';
|
||||||
import { Mutex } from 'async-mutex';
|
import { Mutex } from 'async-mutex';
|
||||||
import {
|
import {
|
||||||
@@ -22,11 +17,9 @@ import {
|
|||||||
DisposableCollection,
|
DisposableCollection,
|
||||||
} from '@theia/core';
|
} from '@theia/core';
|
||||||
import {
|
import {
|
||||||
Dialog,
|
|
||||||
FrontendApplication,
|
FrontendApplication,
|
||||||
FrontendApplicationContribution,
|
FrontendApplicationContribution,
|
||||||
LocalStorageService,
|
LocalStorageService,
|
||||||
OnWillStopAction,
|
|
||||||
SaveableWidget,
|
SaveableWidget,
|
||||||
StatusBar,
|
StatusBar,
|
||||||
StatusBarAlignment,
|
StatusBarAlignment,
|
||||||
@@ -51,12 +44,19 @@ import {
|
|||||||
EditorManager,
|
EditorManager,
|
||||||
EditorOpenerOptions,
|
EditorOpenerOptions,
|
||||||
} from '@theia/editor/lib/browser';
|
} from '@theia/editor/lib/browser';
|
||||||
|
import { ProblemContribution } from '@theia/markers/lib/browser/problem/problem-contribution';
|
||||||
import { MonacoMenus } from '@theia/monaco/lib/browser/monaco-menu';
|
import { MonacoMenus } from '@theia/monaco/lib/browser/monaco-menu';
|
||||||
import { FileNavigatorCommands } from '@theia/navigator/lib/browser/navigator-contribution';
|
import { FileNavigatorCommands, FileNavigatorContribution } from '@theia/navigator/lib/browser/navigator-contribution';
|
||||||
|
import { OutlineViewContribution } from '@theia/outline-view/lib/browser/outline-view-contribution';
|
||||||
|
import { OutputContribution } from '@theia/output/lib/browser/output-contribution';
|
||||||
|
import { ScmContribution } from '@theia/scm/lib/browser/scm-contribution';
|
||||||
|
import { SearchInWorkspaceFrontendContribution } from '@theia/search-in-workspace/lib/browser/search-in-workspace-frontend-contribution';
|
||||||
import { TerminalMenus } from '@theia/terminal/lib/browser/terminal-frontend-contribution';
|
import { TerminalMenus } from '@theia/terminal/lib/browser/terminal-frontend-contribution';
|
||||||
|
import { HostedPluginSupport } from '@theia/plugin-ext/lib/hosted/browser/hosted-plugin';
|
||||||
import { FileService } from '@theia/filesystem/lib/browser/file-service';
|
import { FileService } from '@theia/filesystem/lib/browser/file-service';
|
||||||
import { FileChangeType } from '@theia/filesystem/lib/browser';
|
import { FileChangeType } from '@theia/filesystem/lib/browser';
|
||||||
import { FrontendApplicationStateService } from '@theia/core/lib/browser/frontend-application-state';
|
import { FrontendApplicationStateService } from '@theia/core/lib/browser/frontend-application-state';
|
||||||
|
import { ConfigService } from '../common/protocol/config-service';
|
||||||
import { ArduinoCommands } from './arduino-commands';
|
import { ArduinoCommands } from './arduino-commands';
|
||||||
import { BoardsConfig } from './boards/boards-config';
|
import { BoardsConfig } from './boards/boards-config';
|
||||||
import { BoardsConfigDialog } from './boards/boards-config-dialog';
|
import { BoardsConfigDialog } from './boards/boards-config-dialog';
|
||||||
@@ -67,15 +67,12 @@ import { ArduinoMenus } from './menu/arduino-menus';
|
|||||||
import { MonitorViewContribution } from './serial/monitor/monitor-view-contribution';
|
import { MonitorViewContribution } from './serial/monitor/monitor-view-contribution';
|
||||||
import { ArduinoToolbar } from './toolbar/arduino-toolbar';
|
import { ArduinoToolbar } from './toolbar/arduino-toolbar';
|
||||||
import { ArduinoPreferences } from './arduino-preferences';
|
import { ArduinoPreferences } from './arduino-preferences';
|
||||||
import {
|
import { SketchesServiceClientImpl } from '../common/protocol/sketches-service-client-impl';
|
||||||
CurrentSketch,
|
|
||||||
SketchesServiceClientImpl,
|
|
||||||
} from '../common/protocol/sketches-service-client-impl';
|
|
||||||
import { SaveAsSketch } from './contributions/save-as-sketch';
|
import { SaveAsSketch } from './contributions/save-as-sketch';
|
||||||
|
import { SketchbookWidgetContribution } from './widgets/sketchbook/sketchbook-widget-contribution';
|
||||||
import { IDEUpdaterDialog } from './dialogs/ide-updater/ide-updater-dialog';
|
import { IDEUpdaterDialog } from './dialogs/ide-updater/ide-updater-dialog';
|
||||||
import { IDEUpdater } from '../common/protocol/ide-updater';
|
import { IDEUpdater } from '../common/protocol/ide-updater';
|
||||||
import { FileSystemFrontendContribution } from '@theia/filesystem/lib/browser/filesystem-frontend-contribution';
|
import { FileSystemFrontendContribution } from '@theia/filesystem/lib/browser/filesystem-frontend-contribution';
|
||||||
import { HostedPluginEvents } from './hosted-plugin-events';
|
|
||||||
|
|
||||||
const INIT_LIBS_AND_PACKAGES = 'initializedLibsAndPackages';
|
const INIT_LIBS_AND_PACKAGES = 'initializedLibsAndPackages';
|
||||||
export const SKIP_IDE_VERSION = 'skipIDEVersion';
|
export const SKIP_IDE_VERSION = 'skipIDEVersion';
|
||||||
@@ -87,73 +84,92 @@ export class ArduinoFrontendContribution
|
|||||||
TabBarToolbarContribution,
|
TabBarToolbarContribution,
|
||||||
CommandContribution,
|
CommandContribution,
|
||||||
MenuContribution,
|
MenuContribution,
|
||||||
ColorContribution
|
ColorContribution {
|
||||||
{
|
|
||||||
@inject(ILogger)
|
@inject(ILogger)
|
||||||
private readonly logger: ILogger;
|
protected logger: ILogger;
|
||||||
|
|
||||||
@inject(MessageService)
|
@inject(MessageService)
|
||||||
private readonly messageService: MessageService;
|
protected readonly messageService: MessageService;
|
||||||
|
|
||||||
@inject(BoardsService)
|
@inject(BoardsService)
|
||||||
private readonly boardsService: BoardsService;
|
protected readonly boardsService: BoardsService;
|
||||||
|
|
||||||
@inject(LibraryService)
|
@inject(LibraryService)
|
||||||
private readonly libraryService: LibraryService;
|
protected readonly libraryService: LibraryService;
|
||||||
|
|
||||||
@inject(BoardsServiceProvider)
|
@inject(BoardsServiceProvider)
|
||||||
private readonly boardsServiceClientImpl: BoardsServiceProvider;
|
protected readonly boardsServiceClientImpl: BoardsServiceProvider;
|
||||||
|
|
||||||
@inject(EditorManager)
|
@inject(EditorManager)
|
||||||
private readonly editorManager: EditorManager;
|
protected readonly editorManager: EditorManager;
|
||||||
|
|
||||||
@inject(FileService)
|
@inject(FileService)
|
||||||
private readonly fileService: FileService;
|
protected readonly fileService: FileService;
|
||||||
|
|
||||||
@inject(SketchesService)
|
@inject(SketchesService)
|
||||||
private readonly sketchService: SketchesService;
|
protected readonly sketchService: SketchesService;
|
||||||
|
|
||||||
@inject(BoardsConfigDialog)
|
@inject(BoardsConfigDialog)
|
||||||
private readonly boardsConfigDialog: BoardsConfigDialog;
|
protected readonly boardsConfigDialog: BoardsConfigDialog;
|
||||||
|
|
||||||
@inject(CommandRegistry)
|
@inject(CommandRegistry)
|
||||||
private readonly commandRegistry: CommandRegistry;
|
protected readonly commandRegistry: CommandRegistry;
|
||||||
|
|
||||||
@inject(StatusBar)
|
@inject(StatusBar)
|
||||||
private readonly statusBar: StatusBar;
|
protected readonly statusBar: StatusBar;
|
||||||
|
|
||||||
|
@inject(FileNavigatorContribution)
|
||||||
|
protected readonly fileNavigatorContributions: FileNavigatorContribution;
|
||||||
|
|
||||||
|
@inject(OutputContribution)
|
||||||
|
protected readonly outputContribution: OutputContribution;
|
||||||
|
|
||||||
|
@inject(OutlineViewContribution)
|
||||||
|
protected readonly outlineContribution: OutlineViewContribution;
|
||||||
|
|
||||||
|
@inject(ProblemContribution)
|
||||||
|
protected readonly problemContribution: ProblemContribution;
|
||||||
|
|
||||||
|
@inject(ScmContribution)
|
||||||
|
protected readonly scmContribution: ScmContribution;
|
||||||
|
|
||||||
|
@inject(SearchInWorkspaceFrontendContribution)
|
||||||
|
protected readonly siwContribution: SearchInWorkspaceFrontendContribution;
|
||||||
|
|
||||||
|
@inject(SketchbookWidgetContribution)
|
||||||
|
protected readonly sketchbookWidgetContribution: SketchbookWidgetContribution;
|
||||||
|
|
||||||
@inject(EditorMode)
|
@inject(EditorMode)
|
||||||
private readonly editorMode: EditorMode;
|
protected readonly editorMode: EditorMode;
|
||||||
|
|
||||||
@inject(HostedPluginEvents)
|
@inject(ConfigService)
|
||||||
private readonly hostedPluginEvents: HostedPluginEvents;
|
protected readonly configService: ConfigService;
|
||||||
|
|
||||||
|
@inject(HostedPluginSupport)
|
||||||
|
protected hostedPluginSupport: HostedPluginSupport;
|
||||||
|
|
||||||
@inject(ExecutableService)
|
@inject(ExecutableService)
|
||||||
private readonly executableService: ExecutableService;
|
protected executableService: ExecutableService;
|
||||||
|
|
||||||
@inject(ArduinoPreferences)
|
@inject(ArduinoPreferences)
|
||||||
private readonly arduinoPreferences: ArduinoPreferences;
|
protected readonly arduinoPreferences: ArduinoPreferences;
|
||||||
|
|
||||||
@inject(SketchesServiceClientImpl)
|
@inject(SketchesServiceClientImpl)
|
||||||
private readonly sketchServiceClient: SketchesServiceClientImpl;
|
protected readonly sketchServiceClient: SketchesServiceClientImpl;
|
||||||
|
|
||||||
@inject(FrontendApplicationStateService)
|
protected readonly appStateService: FrontendApplicationStateService;
|
||||||
private readonly appStateService: FrontendApplicationStateService;
|
|
||||||
|
|
||||||
@inject(LocalStorageService)
|
@inject(LocalStorageService)
|
||||||
private readonly localStorageService: LocalStorageService;
|
protected readonly localStorageService: LocalStorageService;
|
||||||
|
|
||||||
@inject(FileSystemFrontendContribution)
|
@inject(FileSystemFrontendContribution)
|
||||||
private readonly fileSystemFrontendContribution: FileSystemFrontendContribution;
|
protected readonly fileSystemFrontendContribution: FileSystemFrontendContribution;
|
||||||
|
|
||||||
@inject(IDEUpdater)
|
@inject(IDEUpdater)
|
||||||
private readonly updater: IDEUpdater;
|
protected readonly updater: IDEUpdater;
|
||||||
|
|
||||||
@inject(IDEUpdaterDialog)
|
@inject(IDEUpdaterDialog)
|
||||||
private readonly updaterDialog: IDEUpdaterDialog;
|
protected readonly updaterDialog: IDEUpdaterDialog;
|
||||||
|
|
||||||
@inject(ArduinoDaemon)
|
|
||||||
private readonly daemon: ArduinoDaemon;
|
|
||||||
|
|
||||||
protected invalidConfigPopup:
|
protected invalidConfigPopup:
|
||||||
| Promise<void | 'No' | 'Yes' | undefined>
|
| Promise<void | 'No' | 'Yes' | undefined>
|
||||||
@@ -224,10 +240,7 @@ export class ArduinoFrontendContribution
|
|||||||
updateStatusBar(this.boardsServiceClientImpl.boardsConfig);
|
updateStatusBar(this.boardsServiceClientImpl.boardsConfig);
|
||||||
this.appStateService.reachedState('ready').then(async () => {
|
this.appStateService.reachedState('ready').then(async () => {
|
||||||
const sketch = await this.sketchServiceClient.currentSketch();
|
const sketch = await this.sketchServiceClient.currentSketch();
|
||||||
if (
|
if (sketch && !(await this.sketchService.isTemp(sketch))) {
|
||||||
CurrentSketch.isValid(sketch) &&
|
|
||||||
!(await this.sketchService.isTemp(sketch))
|
|
||||||
) {
|
|
||||||
this.toDisposeOnStop.push(this.fileService.watch(new URI(sketch.uri)));
|
this.toDisposeOnStop.push(this.fileService.watch(new URI(sketch.uri)));
|
||||||
this.toDisposeOnStop.push(
|
this.toDisposeOnStop.push(
|
||||||
this.fileService.onDidFilesChange(async (event) => {
|
this.fileService.onDidFilesChange(async (event) => {
|
||||||
@@ -253,6 +266,21 @@ export class ArduinoFrontendContribution
|
|||||||
}
|
}
|
||||||
|
|
||||||
async onStart(app: FrontendApplication): Promise<void> {
|
async onStart(app: FrontendApplication): Promise<void> {
|
||||||
|
// Initialize all `pro-mode` widgets. This is a NOOP if in normal mode.
|
||||||
|
for (const viewContribution of [
|
||||||
|
this.fileNavigatorContributions,
|
||||||
|
this.outputContribution,
|
||||||
|
this.outlineContribution,
|
||||||
|
this.problemContribution,
|
||||||
|
this.scmContribution,
|
||||||
|
this.siwContribution,
|
||||||
|
this.sketchbookWidgetContribution,
|
||||||
|
] as Array<FrontendApplicationContribution>) {
|
||||||
|
if (viewContribution.initializeLayout) {
|
||||||
|
viewContribution.initializeLayout(app);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
this.updater
|
this.updater
|
||||||
.init(
|
.init(
|
||||||
this.arduinoPreferences.get('arduino.ide.updateChannel'),
|
this.arduinoPreferences.get('arduino.ide.updateChannel'),
|
||||||
@@ -286,12 +314,6 @@ export class ArduinoFrontendContribution
|
|||||||
}
|
}
|
||||||
};
|
};
|
||||||
this.boardsServiceClientImpl.onBoardsConfigChanged(start);
|
this.boardsServiceClientImpl.onBoardsConfigChanged(start);
|
||||||
this.hostedPluginEvents.onPluginsDidStart(() =>
|
|
||||||
start(this.boardsServiceClientImpl.boardsConfig)
|
|
||||||
);
|
|
||||||
this.hostedPluginEvents.onPluginsWillUnload(
|
|
||||||
() => (this.languageServerFqbn = undefined)
|
|
||||||
);
|
|
||||||
this.arduinoPreferences.onPreferenceChanged((event) => {
|
this.arduinoPreferences.onPreferenceChanged((event) => {
|
||||||
if (event.newValue !== event.oldValue) {
|
if (event.newValue !== event.oldValue) {
|
||||||
switch (event.preferenceName) {
|
switch (event.preferenceName) {
|
||||||
@@ -322,18 +344,16 @@ export class ArduinoFrontendContribution
|
|||||||
|
|
||||||
app.shell.leftPanelHandler.removeBottomMenu('settings-menu');
|
app.shell.leftPanelHandler.removeBottomMenu('settings-menu');
|
||||||
|
|
||||||
this.fileSystemFrontendContribution.onDidChangeEditorFile(
|
this.fileSystemFrontendContribution.onDidChangeEditorFile(e => {
|
||||||
({ type, editor }) => {
|
if (e.type === FileChangeType.DELETED) {
|
||||||
if (type === FileChangeType.DELETED) {
|
const editorWidget = e.editor;
|
||||||
const editorWidget = editor;
|
if (SaveableWidget.is(editorWidget)) {
|
||||||
if (SaveableWidget.is(editorWidget)) {
|
editorWidget.closeWithoutSaving();
|
||||||
editorWidget.closeWithoutSaving();
|
} else {
|
||||||
} else {
|
editorWidget.close();
|
||||||
editorWidget.close();
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
);
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
onStop(): void {
|
onStop(): void {
|
||||||
@@ -346,13 +366,9 @@ export class ArduinoFrontendContribution
|
|||||||
fqbn: string,
|
fqbn: string,
|
||||||
name: string | undefined
|
name: string | undefined
|
||||||
): Promise<void> {
|
): Promise<void> {
|
||||||
const port = await this.daemon.tryGetPort();
|
|
||||||
if (!port) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
const release = await this.languageServerStartMutex.acquire();
|
const release = await this.languageServerStartMutex.acquire();
|
||||||
try {
|
try {
|
||||||
await this.hostedPluginEvents.didStart;
|
await this.hostedPluginSupport.didStart;
|
||||||
const details = await this.boardsService.getBoardDetails({ fqbn });
|
const details = await this.boardsService.getBoardDetails({ fqbn });
|
||||||
if (!details) {
|
if (!details) {
|
||||||
// Core is not installed for the selected board.
|
// Core is not installed for the selected board.
|
||||||
@@ -387,7 +403,7 @@ export class ArduinoFrontendContribution
|
|||||||
let currentSketchPath: string | undefined = undefined;
|
let currentSketchPath: string | undefined = undefined;
|
||||||
if (log) {
|
if (log) {
|
||||||
const currentSketch = await this.sketchServiceClient.currentSketch();
|
const currentSketch = await this.sketchServiceClient.currentSketch();
|
||||||
if (CurrentSketch.isValid(currentSketch)) {
|
if (currentSketch) {
|
||||||
currentSketchPath = await this.fileService.fsPath(
|
currentSketchPath = await this.fileService.fsPath(
|
||||||
new URI(currentSketch.uri)
|
new URI(currentSketch.uri)
|
||||||
);
|
);
|
||||||
@@ -399,6 +415,8 @@ export class ArduinoFrontendContribution
|
|||||||
this.fileService.fsPath(new URI(lsUri)),
|
this.fileService.fsPath(new URI(lsUri)),
|
||||||
]);
|
]);
|
||||||
|
|
||||||
|
const config = await this.configService.getConfiguration();
|
||||||
|
|
||||||
this.languageServerFqbn = await Promise.race([
|
this.languageServerFqbn = await Promise.race([
|
||||||
new Promise<undefined>((_, reject) =>
|
new Promise<undefined>((_, reject) =>
|
||||||
setTimeout(
|
setTimeout(
|
||||||
@@ -410,7 +428,7 @@ export class ArduinoFrontendContribution
|
|||||||
'arduino.languageserver.start',
|
'arduino.languageserver.start',
|
||||||
{
|
{
|
||||||
lsPath,
|
lsPath,
|
||||||
cliDaemonAddr: `localhost:${port}`,
|
cliDaemonAddr: `localhost:${config.daemon.port}`, // TODO: verify if this port is coming from the BE
|
||||||
clangdPath,
|
clangdPath,
|
||||||
log: currentSketchPath ? currentSketchPath : log,
|
log: currentSketchPath ? currentSketchPath : log,
|
||||||
cliDaemonInstance: '1',
|
cliDaemonInstance: '1',
|
||||||
@@ -476,13 +494,13 @@ export class ArduinoFrontendContribution
|
|||||||
EditorCommands.SPLIT_EDITOR_UP,
|
EditorCommands.SPLIT_EDITOR_UP,
|
||||||
EditorCommands.SPLIT_EDITOR_VERTICAL,
|
EditorCommands.SPLIT_EDITOR_VERTICAL,
|
||||||
EditorCommands.SPLIT_EDITOR_HORIZONTAL,
|
EditorCommands.SPLIT_EDITOR_HORIZONTAL,
|
||||||
FileNavigatorCommands.REVEAL_IN_NAVIGATOR,
|
FileNavigatorCommands.REVEAL_IN_NAVIGATOR
|
||||||
]) {
|
]) {
|
||||||
registry.unregisterCommand(command);
|
registry.unregisterCommand(command);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
registerMenus(registry: MenuModelRegistry): void {
|
registerMenus(registry: MenuModelRegistry) {
|
||||||
const menuId = (menuPath: string[]): string => {
|
const menuId = (menuPath: string[]): string => {
|
||||||
const index = menuPath.length - 1;
|
const index = menuPath.length - 1;
|
||||||
const menuId = menuPath[index];
|
const menuId = menuPath[index];
|
||||||
@@ -551,19 +569,12 @@ export class ArduinoFrontendContribution
|
|||||||
uri: string,
|
uri: string,
|
||||||
forceOpen = false,
|
forceOpen = false,
|
||||||
options?: EditorOpenerOptions | undefined
|
options?: EditorOpenerOptions | undefined
|
||||||
): Promise<unknown> {
|
): Promise<any> {
|
||||||
const widget = this.editorManager.all.find(
|
const widget = this.editorManager.all.find(
|
||||||
(widget) => widget.editor.uri.toString() === uri
|
(widget) => widget.editor.uri.toString() === uri
|
||||||
);
|
);
|
||||||
if (!widget || forceOpen) {
|
if (!widget || forceOpen) {
|
||||||
return this.editorManager.open(
|
return this.editorManager.open(new URI(uri), options);
|
||||||
new URI(uri),
|
|
||||||
options ?? {
|
|
||||||
mode: 'reveal',
|
|
||||||
preview: false,
|
|
||||||
counter: 0,
|
|
||||||
}
|
|
||||||
);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -647,57 +658,4 @@ export class ArduinoFrontendContribution
|
|||||||
}
|
}
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
onWillStop(): OnWillStopAction {
|
|
||||||
return {
|
|
||||||
reason: 'temp-sketch',
|
|
||||||
action: () => {
|
|
||||||
return this.showTempSketchDialog();
|
|
||||||
},
|
|
||||||
};
|
|
||||||
}
|
|
||||||
|
|
||||||
private async showTempSketchDialog(): Promise<boolean> {
|
|
||||||
const sketch = await this.sketchServiceClient.currentSketch();
|
|
||||||
if (!CurrentSketch.isValid(sketch)) {
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
const isTemp = await this.sketchService.isTemp(sketch);
|
|
||||||
if (!isTemp) {
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
const messageBoxResult = await remote.dialog.showMessageBox(
|
|
||||||
remote.getCurrentWindow(),
|
|
||||||
{
|
|
||||||
message: nls.localize(
|
|
||||||
'arduino/sketch/saveTempSketch',
|
|
||||||
'Save your sketch to open it again later.'
|
|
||||||
),
|
|
||||||
title: nls.localize(
|
|
||||||
'theia/core/quitTitle',
|
|
||||||
'Are you sure you want to quit?'
|
|
||||||
),
|
|
||||||
type: 'question',
|
|
||||||
buttons: [
|
|
||||||
Dialog.CANCEL,
|
|
||||||
nls.localizeByDefault('Save As...'),
|
|
||||||
nls.localizeByDefault("Don't Save"),
|
|
||||||
],
|
|
||||||
}
|
|
||||||
);
|
|
||||||
const result = messageBoxResult.response;
|
|
||||||
if (result === 2) {
|
|
||||||
return true;
|
|
||||||
} else if (result === 1) {
|
|
||||||
return !!(await this.commandRegistry.executeCommand(
|
|
||||||
SaveAsSketch.Commands.SAVE_AS_SKETCH.id,
|
|
||||||
{
|
|
||||||
execOnlyIfTemp: false,
|
|
||||||
openAfterMove: false,
|
|
||||||
wipeOriginal: true,
|
|
||||||
}
|
|
||||||
));
|
|
||||||
}
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
@@ -1,5 +1,5 @@
|
|||||||
import '../../src/browser/style/index.css';
|
import '../../src/browser/style/index.css';
|
||||||
import { ContainerModule } from '@theia/core/shared/inversify';
|
import { ContainerModule } from 'inversify';
|
||||||
import { WidgetFactory } from '@theia/core/lib/browser/widget-manager';
|
import { WidgetFactory } from '@theia/core/lib/browser/widget-manager';
|
||||||
import { CommandContribution } from '@theia/core/lib/common/command';
|
import { CommandContribution } from '@theia/core/lib/common/command';
|
||||||
import { bindViewContribution } from '@theia/core/lib/browser/shell/view-contribution';
|
import { bindViewContribution } from '@theia/core/lib/browser/shell/view-contribution';
|
||||||
@@ -42,14 +42,15 @@ import { FileNavigatorContribution as TheiaFileNavigatorContribution } from '@th
|
|||||||
import { KeymapsFrontendContribution } from './theia/keymaps/keymaps-frontend-contribution';
|
import { KeymapsFrontendContribution } from './theia/keymaps/keymaps-frontend-contribution';
|
||||||
import { KeymapsFrontendContribution as TheiaKeymapsFrontendContribution } from '@theia/keymaps/lib/browser/keymaps-frontend-contribution';
|
import { KeymapsFrontendContribution as TheiaKeymapsFrontendContribution } from '@theia/keymaps/lib/browser/keymaps-frontend-contribution';
|
||||||
import { ArduinoToolbarContribution } from './toolbar/arduino-toolbar-contribution';
|
import { ArduinoToolbarContribution } from './toolbar/arduino-toolbar-contribution';
|
||||||
import { EditorContribution as TheiaEditorContribution } from '@theia/editor/lib/browser/editor-contribution';
|
import { EditorPreviewContribution as TheiaEditorPreviewContribution } from '@theia/editor-preview/lib/browser/editor-preview-contribution';
|
||||||
import { EditorContribution } from './theia/editor/editor-contribution';
|
import { EditorPreviewContribution } from './theia/editor/editor-contribution';
|
||||||
import { MonacoStatusBarContribution as TheiaMonacoStatusBarContribution } from '@theia/monaco/lib/browser/monaco-status-bar-contribution';
|
import { MonacoStatusBarContribution as TheiaMonacoStatusBarContribution } from '@theia/monaco/lib/browser/monaco-status-bar-contribution';
|
||||||
import { MonacoStatusBarContribution } from './theia/monaco/monaco-status-bar-contribution';
|
import { MonacoStatusBarContribution } from './theia/monaco/monaco-status-bar-contribution';
|
||||||
import {
|
import {
|
||||||
ApplicationShell as TheiaApplicationShell,
|
ApplicationShell as TheiaApplicationShell,
|
||||||
ShellLayoutRestorer as TheiaShellLayoutRestorer,
|
ShellLayoutRestorer as TheiaShellLayoutRestorer,
|
||||||
CommonFrontendContribution as TheiaCommonFrontendContribution,
|
CommonFrontendContribution as TheiaCommonFrontendContribution,
|
||||||
|
KeybindingRegistry as TheiaKeybindingRegistry,
|
||||||
TabBarRendererFactory,
|
TabBarRendererFactory,
|
||||||
ContextMenuRenderer,
|
ContextMenuRenderer,
|
||||||
createTreeContainer,
|
createTreeContainer,
|
||||||
@@ -121,7 +122,6 @@ import { SaveAsSketch } from './contributions/save-as-sketch';
|
|||||||
import { SaveSketch } from './contributions/save-sketch';
|
import { SaveSketch } from './contributions/save-sketch';
|
||||||
import { VerifySketch } from './contributions/verify-sketch';
|
import { VerifySketch } from './contributions/verify-sketch';
|
||||||
import { UploadSketch } from './contributions/upload-sketch';
|
import { UploadSketch } from './contributions/upload-sketch';
|
||||||
import { SurveyNotification } from './contributions/survey-notification';
|
|
||||||
import { CommonFrontendContribution } from './theia/core/common-frontend-contribution';
|
import { CommonFrontendContribution } from './theia/core/common-frontend-contribution';
|
||||||
import { EditContributions } from './contributions/edit-contributions';
|
import { EditContributions } from './contributions/edit-contributions';
|
||||||
import { OpenSketchExternal } from './contributions/open-sketch-external';
|
import { OpenSketchExternal } from './contributions/open-sketch-external';
|
||||||
@@ -130,6 +130,7 @@ import { PreferencesContribution } from './theia/preferences/preferences-contrib
|
|||||||
import { QuitApp } from './contributions/quit-app';
|
import { QuitApp } from './contributions/quit-app';
|
||||||
import { SketchControl } from './contributions/sketch-control';
|
import { SketchControl } from './contributions/sketch-control';
|
||||||
import { Settings } from './contributions/settings';
|
import { Settings } from './contributions/settings';
|
||||||
|
import { KeybindingRegistry } from './theia/core/keybindings';
|
||||||
import { WorkspaceCommandContribution } from './theia/workspace/workspace-commands';
|
import { WorkspaceCommandContribution } from './theia/workspace/workspace-commands';
|
||||||
import { WorkspaceDeleteHandler as TheiaWorkspaceDeleteHandler } from '@theia/workspace/lib/browser/workspace-delete-handler';
|
import { WorkspaceDeleteHandler as TheiaWorkspaceDeleteHandler } from '@theia/workspace/lib/browser/workspace-delete-handler';
|
||||||
import { WorkspaceDeleteHandler } from './theia/workspace/workspace-delete-handler';
|
import { WorkspaceDeleteHandler } from './theia/workspace/workspace-delete-handler';
|
||||||
@@ -151,14 +152,7 @@ import {
|
|||||||
OutputChannelRegistryMainImpl as TheiaOutputChannelRegistryMainImpl,
|
OutputChannelRegistryMainImpl as TheiaOutputChannelRegistryMainImpl,
|
||||||
OutputChannelRegistryMainImpl,
|
OutputChannelRegistryMainImpl,
|
||||||
} from './theia/plugin-ext/output-channel-registry-main';
|
} from './theia/plugin-ext/output-channel-registry-main';
|
||||||
import {
|
import { ExecutableService, ExecutableServicePath, MonitorManagerProxy, MonitorManagerProxyClient, MonitorManagerProxyFactory, MonitorManagerProxyPath } from '../common/protocol';
|
||||||
ExecutableService,
|
|
||||||
ExecutableServicePath,
|
|
||||||
MonitorManagerProxy,
|
|
||||||
MonitorManagerProxyClient,
|
|
||||||
MonitorManagerProxyFactory,
|
|
||||||
MonitorManagerProxyPath,
|
|
||||||
} from '../common/protocol';
|
|
||||||
import { MonacoTextModelService as TheiaMonacoTextModelService } from '@theia/monaco/lib/browser/monaco-text-model-service';
|
import { MonacoTextModelService as TheiaMonacoTextModelService } from '@theia/monaco/lib/browser/monaco-text-model-service';
|
||||||
import { MonacoTextModelService } from './theia/monaco/monaco-text-model-service';
|
import { MonacoTextModelService } from './theia/monaco/monaco-text-model-service';
|
||||||
import { ResponseServiceImpl } from './response-service-impl';
|
import { ResponseServiceImpl } from './response-service-impl';
|
||||||
@@ -275,49 +269,20 @@ import {
|
|||||||
import { ElectronIpcConnectionProvider } from '@theia/core/lib/electron-browser/messaging/electron-ipc-connection-provider';
|
import { ElectronIpcConnectionProvider } from '@theia/core/lib/electron-browser/messaging/electron-ipc-connection-provider';
|
||||||
import { MonitorModel } from './monitor-model';
|
import { MonitorModel } from './monitor-model';
|
||||||
import { MonitorManagerProxyClientImpl } from './monitor-manager-proxy-client-impl';
|
import { MonitorManagerProxyClientImpl } from './monitor-manager-proxy-client-impl';
|
||||||
import { EditorManager as TheiaEditorManager } from '@theia/editor/lib/browser/editor-manager';
|
|
||||||
import { EditorManager } from './theia/editor/editor-manager';
|
const ElementQueries = require('css-element-queries/src/ElementQueries');
|
||||||
import { HostedPluginEvents } from './hosted-plugin-events';
|
|
||||||
import { HostedPluginSupport } from './theia/plugin-ext/hosted-plugin';
|
|
||||||
import { HostedPluginSupport as TheiaHostedPluginSupport } from '@theia/plugin-ext/lib/hosted/browser/hosted-plugin';
|
|
||||||
import { Formatter, FormatterPath } from '../common/protocol/formatter';
|
|
||||||
import { Format } from './contributions/format';
|
|
||||||
import { MonacoFormattingConflictsContribution } from './theia/monaco/monaco-formatting-conflicts';
|
|
||||||
import { MonacoFormattingConflictsContribution as TheiaMonacoFormattingConflictsContribution } from '@theia/monaco/lib/browser/monaco-formatting-conflicts';
|
|
||||||
import { DefaultJsonSchemaContribution } from './theia/core/json-schema-store';
|
|
||||||
import { DefaultJsonSchemaContribution as TheiaDefaultJsonSchemaContribution } from '@theia/core/lib/browser/json-schema-store';
|
|
||||||
import { EditorNavigationContribution } from './theia/editor/editor-navigation-contribution';
|
|
||||||
import { EditorNavigationContribution as TheiaEditorNavigationContribution } from '@theia/editor/lib/browser/editor-navigation-contribution';
|
|
||||||
import { PreferenceTreeGenerator } from './theia/preferences/preference-tree-generator';
|
|
||||||
import { PreferenceTreeGenerator as TheiaPreferenceTreeGenerator } from '@theia/preferences/lib/browser/util/preference-tree-generator';
|
|
||||||
import { AboutDialog } from './theia/core/about-dialog';
|
|
||||||
import { AboutDialog as TheiaAboutDialog } from '@theia/core/lib/browser/about-dialog';
|
|
||||||
import {
|
|
||||||
SurveyNotificationService,
|
|
||||||
SurveyNotificationServicePath,
|
|
||||||
} from '../common/protocol/survey-service';
|
|
||||||
import { WindowContribution } from './theia/core/window-contribution';
|
|
||||||
import { WindowContribution as TheiaWindowContribution } from '@theia/core/lib/browser/window-contribution';
|
|
||||||
import { CoreErrorHandler } from './contributions/core-error-handler';
|
|
||||||
import { CompilerErrors } from './contributions/compiler-errors';
|
|
||||||
import { WidgetManager } from './theia/core/widget-manager';
|
|
||||||
import { WidgetManager as TheiaWidgetManager } from '@theia/core/lib/browser/widget-manager';
|
|
||||||
|
|
||||||
MonacoThemingService.register({
|
MonacoThemingService.register({
|
||||||
id: 'arduino-theme',
|
id: 'arduino-theme',
|
||||||
label: 'Light (Arduino)',
|
label: 'Light (Arduino)',
|
||||||
uiTheme: 'vs',
|
uiTheme: 'vs',
|
||||||
json: require('../../src/browser/data/default.color-theme.json'),
|
json: require('../../src/browser/data/arduino.color-theme.json'),
|
||||||
});
|
|
||||||
|
|
||||||
MonacoThemingService.register({
|
|
||||||
id: 'arduino-theme-dark',
|
|
||||||
label: 'Dark (Arduino)',
|
|
||||||
uiTheme: 'vs-dark',
|
|
||||||
json: require('../../src/browser/data/dark.color-theme.json'),
|
|
||||||
});
|
});
|
||||||
|
|
||||||
export default new ContainerModule((bind, unbind, isBound, rebind) => {
|
export default new ContainerModule((bind, unbind, isBound, rebind) => {
|
||||||
|
ElementQueries.listen();
|
||||||
|
ElementQueries.init();
|
||||||
|
|
||||||
// Commands and toolbar items
|
// Commands and toolbar items
|
||||||
bind(ArduinoFrontendContribution).toSelf().inSingletonScope();
|
bind(ArduinoFrontendContribution).toSelf().inSingletonScope();
|
||||||
bind(CommandContribution).toService(ArduinoFrontendContribution);
|
bind(CommandContribution).toService(ArduinoFrontendContribution);
|
||||||
@@ -434,7 +399,6 @@ export default new ContainerModule((bind, unbind, isBound, rebind) => {
|
|||||||
)
|
)
|
||||||
)
|
)
|
||||||
.inSingletonScope();
|
.inSingletonScope();
|
||||||
bind(CoreErrorHandler).toSelf().inSingletonScope();
|
|
||||||
|
|
||||||
// Serial monitor
|
// Serial monitor
|
||||||
bind(MonitorWidget).toSelf();
|
bind(MonitorWidget).toSelf();
|
||||||
@@ -447,34 +411,21 @@ export default new ContainerModule((bind, unbind, isBound, rebind) => {
|
|||||||
createWidget: () => {
|
createWidget: () => {
|
||||||
return new MonitorWidget(
|
return new MonitorWidget(
|
||||||
context.container.get<MonitorModel>(MonitorModel),
|
context.container.get<MonitorModel>(MonitorModel),
|
||||||
context.container.get<MonitorManagerProxyClient>(
|
context.container.get<MonitorManagerProxyClient>(MonitorManagerProxyClient),
|
||||||
MonitorManagerProxyClient
|
context.container.get<BoardsServiceProvider>(BoardsServiceProvider),
|
||||||
),
|
|
||||||
context.container.get<BoardsServiceProvider>(BoardsServiceProvider)
|
|
||||||
);
|
);
|
||||||
},
|
}
|
||||||
}));
|
}));
|
||||||
|
|
||||||
bind(MonitorManagerProxyFactory).toFactory(
|
bind(MonitorManagerProxyFactory).toFactory((context) => () => context.container.get<MonitorManagerProxy>(MonitorManagerProxy))
|
||||||
(context) => () =>
|
|
||||||
context.container.get<MonitorManagerProxy>(MonitorManagerProxy)
|
|
||||||
);
|
|
||||||
|
|
||||||
bind(MonitorManagerProxy)
|
bind(MonitorManagerProxy).toDynamicValue((context) =>
|
||||||
.toDynamicValue((context) =>
|
WebSocketConnectionProvider.createProxy(context.container, MonitorManagerProxyPath, context.container.get(MonitorManagerProxyClient))
|
||||||
WebSocketConnectionProvider.createProxy(
|
).inSingletonScope();
|
||||||
context.container,
|
|
||||||
MonitorManagerProxyPath,
|
|
||||||
context.container.get(MonitorManagerProxyClient)
|
|
||||||
)
|
|
||||||
)
|
|
||||||
.inSingletonScope();
|
|
||||||
|
|
||||||
// Monitor manager proxy client to receive and delegate pluggable monitors
|
// Monitor manager proxy client to receive and delegate pluggable monitors
|
||||||
// notifications from the backend
|
// notifications from the backend
|
||||||
bind(MonitorManagerProxyClient)
|
bind(MonitorManagerProxyClient).to(MonitorManagerProxyClientImpl).inSingletonScope();
|
||||||
.to(MonitorManagerProxyClientImpl)
|
|
||||||
.inSingletonScope();
|
|
||||||
|
|
||||||
bind(WorkspaceService).toSelf().inSingletonScope();
|
bind(WorkspaceService).toSelf().inSingletonScope();
|
||||||
rebind(TheiaWorkspaceService).toService(WorkspaceService);
|
rebind(TheiaWorkspaceService).toService(WorkspaceService);
|
||||||
@@ -487,19 +438,6 @@ export default new ContainerModule((bind, unbind, isBound, rebind) => {
|
|||||||
bind(EditorMode).toSelf().inSingletonScope();
|
bind(EditorMode).toSelf().inSingletonScope();
|
||||||
bind(FrontendApplicationContribution).toService(EditorMode);
|
bind(FrontendApplicationContribution).toService(EditorMode);
|
||||||
|
|
||||||
// Survey notification
|
|
||||||
bind(SurveyNotification).toSelf().inSingletonScope();
|
|
||||||
bind(FrontendApplicationContribution).toService(SurveyNotification);
|
|
||||||
|
|
||||||
bind(SurveyNotificationService)
|
|
||||||
.toDynamicValue((context) => {
|
|
||||||
return ElectronIpcConnectionProvider.createProxy(
|
|
||||||
context.container,
|
|
||||||
SurveyNotificationServicePath
|
|
||||||
);
|
|
||||||
})
|
|
||||||
.inSingletonScope();
|
|
||||||
|
|
||||||
// Layout and shell customizations.
|
// Layout and shell customizations.
|
||||||
rebind(TheiaOutlineViewContribution)
|
rebind(TheiaOutlineViewContribution)
|
||||||
.to(OutlineViewContribution)
|
.to(OutlineViewContribution)
|
||||||
@@ -511,7 +449,9 @@ export default new ContainerModule((bind, unbind, isBound, rebind) => {
|
|||||||
rebind(TheiaKeymapsFrontendContribution)
|
rebind(TheiaKeymapsFrontendContribution)
|
||||||
.to(KeymapsFrontendContribution)
|
.to(KeymapsFrontendContribution)
|
||||||
.inSingletonScope();
|
.inSingletonScope();
|
||||||
rebind(TheiaEditorContribution).to(EditorContribution).inSingletonScope();
|
rebind(TheiaEditorPreviewContribution)
|
||||||
|
.to(EditorPreviewContribution)
|
||||||
|
.inSingletonScope();
|
||||||
rebind(TheiaMonacoStatusBarContribution)
|
rebind(TheiaMonacoStatusBarContribution)
|
||||||
.to(MonacoStatusBarContribution)
|
.to(MonacoStatusBarContribution)
|
||||||
.inSingletonScope();
|
.inSingletonScope();
|
||||||
@@ -533,6 +473,7 @@ export default new ContainerModule((bind, unbind, isBound, rebind) => {
|
|||||||
rebind(TheiaPreferencesContribution)
|
rebind(TheiaPreferencesContribution)
|
||||||
.to(PreferencesContribution)
|
.to(PreferencesContribution)
|
||||||
.inSingletonScope();
|
.inSingletonScope();
|
||||||
|
rebind(TheiaKeybindingRegistry).to(KeybindingRegistry).inSingletonScope();
|
||||||
rebind(TheiaWorkspaceCommandContribution)
|
rebind(TheiaWorkspaceCommandContribution)
|
||||||
.to(WorkspaceCommandContribution)
|
.to(WorkspaceCommandContribution)
|
||||||
.inSingletonScope();
|
.inSingletonScope();
|
||||||
@@ -541,12 +482,11 @@ export default new ContainerModule((bind, unbind, isBound, rebind) => {
|
|||||||
.inSingletonScope();
|
.inSingletonScope();
|
||||||
rebind(TheiaEditorWidgetFactory).to(EditorWidgetFactory).inSingletonScope();
|
rebind(TheiaEditorWidgetFactory).to(EditorWidgetFactory).inSingletonScope();
|
||||||
rebind(TabBarToolbarFactory).toFactory(
|
rebind(TabBarToolbarFactory).toFactory(
|
||||||
({ container: parentContainer }) =>
|
({ container: parentContainer }) => () => {
|
||||||
() => {
|
const container = parentContainer.createChild();
|
||||||
const container = parentContainer.createChild();
|
container.bind(TabBarToolbar).toSelf().inSingletonScope();
|
||||||
container.bind(TabBarToolbar).toSelf().inSingletonScope();
|
return container.get(TabBarToolbar);
|
||||||
return container.get(TabBarToolbar);
|
}
|
||||||
}
|
|
||||||
);
|
);
|
||||||
bind(OutputWidget).toSelf().inSingletonScope();
|
bind(OutputWidget).toSelf().inSingletonScope();
|
||||||
rebind(TheiaOutputWidget).toService(OutputWidget);
|
rebind(TheiaOutputWidget).toService(OutputWidget);
|
||||||
@@ -564,10 +504,6 @@ export default new ContainerModule((bind, unbind, isBound, rebind) => {
|
|||||||
bind(SearchInWorkspaceWidget).toSelf();
|
bind(SearchInWorkspaceWidget).toSelf();
|
||||||
rebind(TheiaSearchInWorkspaceWidget).toService(SearchInWorkspaceWidget);
|
rebind(TheiaSearchInWorkspaceWidget).toService(SearchInWorkspaceWidget);
|
||||||
|
|
||||||
// Disabled reference counter in the editor manager to avoid opening the same editor (with different opener options) multiple times.
|
|
||||||
bind(EditorManager).toSelf().inSingletonScope();
|
|
||||||
rebind(TheiaEditorManager).to(EditorManager);
|
|
||||||
|
|
||||||
// replace search icon
|
// replace search icon
|
||||||
rebind(TheiaSearchInWorkspaceFactory)
|
rebind(TheiaSearchInWorkspaceFactory)
|
||||||
.to(SearchInWorkspaceFactory)
|
.to(SearchInWorkspaceFactory)
|
||||||
@@ -610,10 +546,6 @@ export default new ContainerModule((bind, unbind, isBound, rebind) => {
|
|||||||
bind(OutputToolbarContribution).toSelf().inSingletonScope();
|
bind(OutputToolbarContribution).toSelf().inSingletonScope();
|
||||||
rebind(TheiaOutputToolbarContribution).toService(OutputToolbarContribution);
|
rebind(TheiaOutputToolbarContribution).toService(OutputToolbarContribution);
|
||||||
|
|
||||||
// To remove `New Window` from the `File` menu
|
|
||||||
bind(WindowContribution).toSelf().inSingletonScope();
|
|
||||||
rebind(TheiaWindowContribution).toService(WindowContribution);
|
|
||||||
|
|
||||||
bind(ArduinoDaemon)
|
bind(ArduinoDaemon)
|
||||||
.toDynamicValue((context) =>
|
.toDynamicValue((context) =>
|
||||||
WebSocketConnectionProvider.createProxy(
|
WebSocketConnectionProvider.createProxy(
|
||||||
@@ -623,12 +555,6 @@ export default new ContainerModule((bind, unbind, isBound, rebind) => {
|
|||||||
)
|
)
|
||||||
.inSingletonScope();
|
.inSingletonScope();
|
||||||
|
|
||||||
bind(Formatter)
|
|
||||||
.toDynamicValue(({ container }) =>
|
|
||||||
WebSocketConnectionProvider.createProxy(container, FormatterPath)
|
|
||||||
)
|
|
||||||
.inSingletonScope();
|
|
||||||
|
|
||||||
bind(ArduinoFirmwareUploader)
|
bind(ArduinoFirmwareUploader)
|
||||||
.toDynamicValue((context) =>
|
.toDynamicValue((context) =>
|
||||||
WebSocketConnectionProvider.createProxy(
|
WebSocketConnectionProvider.createProxy(
|
||||||
@@ -696,15 +622,6 @@ export default new ContainerModule((bind, unbind, isBound, rebind) => {
|
|||||||
Contribution.configure(bind, ArchiveSketch);
|
Contribution.configure(bind, ArchiveSketch);
|
||||||
Contribution.configure(bind, AddZipLibrary);
|
Contribution.configure(bind, AddZipLibrary);
|
||||||
Contribution.configure(bind, PlotterFrontendContribution);
|
Contribution.configure(bind, PlotterFrontendContribution);
|
||||||
Contribution.configure(bind, Format);
|
|
||||||
Contribution.configure(bind, CompilerErrors);
|
|
||||||
|
|
||||||
// Disabled the quick-pick customization from Theia when multiple formatters are available.
|
|
||||||
// Use the default VS Code behavior, and pick the first one. In the IDE2, clang-format has `exclusive` selectors.
|
|
||||||
bind(MonacoFormattingConflictsContribution).toSelf().inSingletonScope();
|
|
||||||
rebind(TheiaMonacoFormattingConflictsContribution).toService(
|
|
||||||
MonacoFormattingConflictsContribution
|
|
||||||
);
|
|
||||||
|
|
||||||
bind(ResponseServiceImpl)
|
bind(ResponseServiceImpl)
|
||||||
.toSelf()
|
.toSelf()
|
||||||
@@ -734,13 +651,15 @@ export default new ContainerModule((bind, unbind, isBound, rebind) => {
|
|||||||
|
|
||||||
// Enable the dirty indicator on uncloseable widgets.
|
// Enable the dirty indicator on uncloseable widgets.
|
||||||
rebind(TabBarRendererFactory).toFactory((context) => () => {
|
rebind(TabBarRendererFactory).toFactory((context) => () => {
|
||||||
const contextMenuRenderer =
|
const contextMenuRenderer = context.container.get<ContextMenuRenderer>(
|
||||||
context.container.get<ContextMenuRenderer>(ContextMenuRenderer);
|
ContextMenuRenderer
|
||||||
|
);
|
||||||
const decoratorService = context.container.get<TabBarDecoratorService>(
|
const decoratorService = context.container.get<TabBarDecoratorService>(
|
||||||
TabBarDecoratorService
|
TabBarDecoratorService
|
||||||
);
|
);
|
||||||
const iconThemeService =
|
const iconThemeService = context.container.get<IconThemeService>(
|
||||||
context.container.get<IconThemeService>(IconThemeService);
|
IconThemeService
|
||||||
|
);
|
||||||
return new TabBarRenderer(
|
return new TabBarRenderer(
|
||||||
contextMenuRenderer,
|
contextMenuRenderer,
|
||||||
decoratorService,
|
decoratorService,
|
||||||
@@ -750,8 +669,6 @@ export default new ContainerModule((bind, unbind, isBound, rebind) => {
|
|||||||
|
|
||||||
// Workaround for https://github.com/eclipse-theia/theia/issues/8722
|
// Workaround for https://github.com/eclipse-theia/theia/issues/8722
|
||||||
// Do not trigger a save on IDE startup if `"editor.autoSave": "on"` was set as a preference.
|
// Do not trigger a save on IDE startup if `"editor.autoSave": "on"` was set as a preference.
|
||||||
// Note: `"editor.autoSave" was renamed to `"files.autoSave" and `"on"` was replaced with three
|
|
||||||
// different cases, but we treat `!== 'off'` as auto save enabled. (https://github.com/eclipse-theia/theia/issues/10812)
|
|
||||||
bind(EditorCommandContribution).toSelf().inSingletonScope();
|
bind(EditorCommandContribution).toSelf().inSingletonScope();
|
||||||
rebind(TheiaEditorCommandContribution).toService(EditorCommandContribution);
|
rebind(TheiaEditorCommandContribution).toService(EditorCommandContribution);
|
||||||
|
|
||||||
@@ -759,26 +676,6 @@ export default new ContainerModule((bind, unbind, isBound, rebind) => {
|
|||||||
bind(NavigatorTabBarDecorator).toSelf().inSingletonScope();
|
bind(NavigatorTabBarDecorator).toSelf().inSingletonScope();
|
||||||
rebind(TheiaNavigatorTabBarDecorator).toService(NavigatorTabBarDecorator);
|
rebind(TheiaNavigatorTabBarDecorator).toService(NavigatorTabBarDecorator);
|
||||||
|
|
||||||
// Do not fetch the `catalog.json` from Azure on FE load.
|
|
||||||
bind(DefaultJsonSchemaContribution).toSelf().inSingletonScope();
|
|
||||||
rebind(TheiaDefaultJsonSchemaContribution).toService(
|
|
||||||
DefaultJsonSchemaContribution
|
|
||||||
);
|
|
||||||
|
|
||||||
// Do not block the app startup when initializing the editor navigation history.
|
|
||||||
bind(EditorNavigationContribution).toSelf().inSingletonScope();
|
|
||||||
rebind(TheiaEditorNavigationContribution).toService(
|
|
||||||
EditorNavigationContribution
|
|
||||||
);
|
|
||||||
|
|
||||||
// IDE2 does not use the Theia preferences widget, no need to create and sync the underlying tree model.
|
|
||||||
bind(PreferenceTreeGenerator).toSelf().inSingletonScope();
|
|
||||||
rebind(TheiaPreferenceTreeGenerator).toService(PreferenceTreeGenerator);
|
|
||||||
|
|
||||||
// IDE2 has a custom about dialog, so there is no need to load the Theia extensions on FE load
|
|
||||||
bind(AboutDialog).toSelf().inSingletonScope();
|
|
||||||
rebind(TheiaAboutDialog).toService(AboutDialog);
|
|
||||||
|
|
||||||
// To avoid running `Save All` when there are no dirty editors before starting the debug session.
|
// To avoid running `Save All` when there are no dirty editors before starting the debug session.
|
||||||
bind(DebugSessionManager).toSelf().inSingletonScope();
|
bind(DebugSessionManager).toSelf().inSingletonScope();
|
||||||
rebind(TheiaDebugSessionManager).toService(DebugSessionManager);
|
rebind(TheiaDebugSessionManager).toService(DebugSessionManager);
|
||||||
@@ -791,10 +688,6 @@ export default new ContainerModule((bind, unbind, isBound, rebind) => {
|
|||||||
bind(DebugConfigurationManager).toSelf().inSingletonScope();
|
bind(DebugConfigurationManager).toSelf().inSingletonScope();
|
||||||
rebind(TheiaDebugConfigurationManager).toService(DebugConfigurationManager);
|
rebind(TheiaDebugConfigurationManager).toService(DebugConfigurationManager);
|
||||||
|
|
||||||
// To avoid duplicate tabs use deepEqual instead of string equal: https://github.com/eclipse-theia/theia/issues/11309
|
|
||||||
bind(WidgetManager).toSelf().inSingletonScope();
|
|
||||||
rebind(TheiaWidgetManager).toService(WidgetManager);
|
|
||||||
|
|
||||||
// Preferences
|
// Preferences
|
||||||
bindArduinoPreferences(bind);
|
bindArduinoPreferences(bind);
|
||||||
|
|
||||||
@@ -902,9 +795,4 @@ export default new ContainerModule((bind, unbind, isBound, rebind) => {
|
|||||||
);
|
);
|
||||||
})
|
})
|
||||||
.inSingletonScope();
|
.inSingletonScope();
|
||||||
|
|
||||||
bind(HostedPluginSupport).toSelf().inSingletonScope();
|
|
||||||
rebind(TheiaHostedPluginSupport).toService(HostedPluginSupport);
|
|
||||||
bind(HostedPluginEvents).toSelf().inSingletonScope();
|
|
||||||
bind(FrontendApplicationContribution).toService(HostedPluginEvents);
|
|
||||||
});
|
});
|
||||||
|
@@ -1,4 +1,4 @@
|
|||||||
import { interfaces } from '@theia/core/shared/inversify';
|
import { interfaces } from 'inversify';
|
||||||
import {
|
import {
|
||||||
createPreferenceProxy,
|
createPreferenceProxy,
|
||||||
PreferenceProxy,
|
PreferenceProxy,
|
||||||
@@ -13,32 +13,6 @@ export enum UpdateChannel {
|
|||||||
Stable = 'stable',
|
Stable = 'stable',
|
||||||
Nightly = 'nightly',
|
Nightly = 'nightly',
|
||||||
}
|
}
|
||||||
export const ErrorRevealStrategyLiterals = [
|
|
||||||
/**
|
|
||||||
* Scroll vertically as necessary and reveal a line.
|
|
||||||
*/
|
|
||||||
'auto',
|
|
||||||
/**
|
|
||||||
* Scroll vertically as necessary and reveal a line centered vertically.
|
|
||||||
*/
|
|
||||||
'center',
|
|
||||||
/**
|
|
||||||
* Scroll vertically as necessary and reveal a line close to the top of the viewport, optimized for viewing a code definition.
|
|
||||||
*/
|
|
||||||
'top',
|
|
||||||
/**
|
|
||||||
* Scroll vertically as necessary and reveal a line centered vertically only if it lies outside the viewport.
|
|
||||||
*/
|
|
||||||
'centerIfOutsideViewport',
|
|
||||||
] as const;
|
|
||||||
export type ErrorRevealStrategy = typeof ErrorRevealStrategyLiterals[number];
|
|
||||||
export namespace ErrorRevealStrategy {
|
|
||||||
// eslint-disable-next-line @typescript-eslint/explicit-module-boundary-types, @typescript-eslint/no-explicit-any
|
|
||||||
export function is(arg: any): arg is ErrorRevealStrategy {
|
|
||||||
return !!arg && ErrorRevealStrategyLiterals.includes(arg);
|
|
||||||
}
|
|
||||||
export const Default: ErrorRevealStrategy = 'centerIfOutsideViewport';
|
|
||||||
}
|
|
||||||
|
|
||||||
export const ArduinoConfigSchema: PreferenceSchema = {
|
export const ArduinoConfigSchema: PreferenceSchema = {
|
||||||
type: 'object',
|
type: 'object',
|
||||||
@@ -59,23 +33,6 @@ export const ArduinoConfigSchema: PreferenceSchema = {
|
|||||||
),
|
),
|
||||||
default: false,
|
default: false,
|
||||||
},
|
},
|
||||||
'arduino.compile.experimental': {
|
|
||||||
type: 'boolean',
|
|
||||||
description: nls.localize(
|
|
||||||
'arduino/preferences/compile.experimental',
|
|
||||||
'True if the IDE should handle multiple compiler errors. False by default'
|
|
||||||
),
|
|
||||||
default: false,
|
|
||||||
},
|
|
||||||
'arduino.compile.revealRange': {
|
|
||||||
enum: [...ErrorRevealStrategyLiterals],
|
|
||||||
description: nls.localize(
|
|
||||||
'arduino/preferences/compile.revealRange',
|
|
||||||
"Adjusts how compiler errors are revealed in the editor after a failed verify/upload. Possible values: 'auto': Scroll vertically as necessary and reveal a line. 'center': Scroll vertically as necessary and reveal a line centered vertically. 'top': Scroll vertically as necessary and reveal a line close to the top of the viewport, optimized for viewing a code definition. 'centerIfOutsideViewport': Scroll vertically as necessary and reveal a line centered vertically only if it lies outside the viewport. The default value is '{0}'.",
|
|
||||||
ErrorRevealStrategy.Default
|
|
||||||
),
|
|
||||||
default: ErrorRevealStrategy.Default,
|
|
||||||
},
|
|
||||||
'arduino.compile.warnings': {
|
'arduino.compile.warnings': {
|
||||||
enum: [...CompilerWarningLiterals],
|
enum: [...CompilerWarningLiterals],
|
||||||
description: nls.localize(
|
description: nls.localize(
|
||||||
@@ -126,7 +83,7 @@ export const ArduinoConfigSchema: PreferenceSchema = {
|
|||||||
default: 'https://downloads.arduino.cc/arduino-ide',
|
default: 'https://downloads.arduino.cc/arduino-ide',
|
||||||
description: nls.localize(
|
description: nls.localize(
|
||||||
'arduino/preferences/ide.updateBaseUrl',
|
'arduino/preferences/ide.updateBaseUrl',
|
||||||
"The base URL where to download updates from. Defaults to 'https://downloads.arduino.cc/arduino-ide'"
|
`The base URL where to download updates from. Defaults to 'https://downloads.arduino.cc/arduino-ide'`
|
||||||
),
|
),
|
||||||
},
|
},
|
||||||
'arduino.board.certificates': {
|
'arduino.board.certificates': {
|
||||||
@@ -217,30 +174,12 @@ export const ArduinoConfigSchema: PreferenceSchema = {
|
|||||||
),
|
),
|
||||||
default: 'https://auth.arduino.cc/login#/register',
|
default: 'https://auth.arduino.cc/login#/register',
|
||||||
},
|
},
|
||||||
'arduino.survey.notification': {
|
|
||||||
type: 'boolean',
|
|
||||||
description: nls.localize(
|
|
||||||
'arduino/preferences/survey.notification',
|
|
||||||
'True if users should be notified if a survey is available. True by default.'
|
|
||||||
),
|
|
||||||
default: true,
|
|
||||||
},
|
|
||||||
'arduino.cli.daemon.debug': {
|
|
||||||
type: 'boolean',
|
|
||||||
description: nls.localize(
|
|
||||||
'arduino/preferences/cli.daemonDebug',
|
|
||||||
"Enable debug logging of the gRPC calls to the Arduino CLI. A restart of the IDE is needed for this setting to take effect. It's false by default."
|
|
||||||
),
|
|
||||||
default: false,
|
|
||||||
},
|
|
||||||
},
|
},
|
||||||
};
|
};
|
||||||
|
|
||||||
export interface ArduinoConfiguration {
|
export interface ArduinoConfiguration {
|
||||||
'arduino.language.log': boolean;
|
'arduino.language.log': boolean;
|
||||||
'arduino.compile.verbose': boolean;
|
'arduino.compile.verbose': boolean;
|
||||||
'arduino.compile.experimental': boolean;
|
|
||||||
'arduino.compile.revealRange': ErrorRevealStrategy;
|
|
||||||
'arduino.compile.warnings': CompilerWarnings;
|
'arduino.compile.warnings': CompilerWarnings;
|
||||||
'arduino.upload.verbose': boolean;
|
'arduino.upload.verbose': boolean;
|
||||||
'arduino.upload.verify': boolean;
|
'arduino.upload.verify': boolean;
|
||||||
@@ -259,8 +198,6 @@ export interface ArduinoConfiguration {
|
|||||||
'arduino.auth.domain': string;
|
'arduino.auth.domain': string;
|
||||||
'arduino.auth.audience': string;
|
'arduino.auth.audience': string;
|
||||||
'arduino.auth.registerUri': string;
|
'arduino.auth.registerUri': string;
|
||||||
'arduino.survey.notification': boolean;
|
|
||||||
'arduino.cli.daemon.debug': boolean;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
export const ArduinoPreferences = Symbol('ArduinoPreferences');
|
export const ArduinoPreferences = Symbol('ArduinoPreferences');
|
||||||
|
@@ -1,4 +1,4 @@
|
|||||||
import { inject, injectable } from '@theia/core/shared/inversify';
|
import { inject, injectable } from 'inversify';
|
||||||
import { Emitter } from '@theia/core/lib/common/event';
|
import { Emitter } from '@theia/core/lib/common/event';
|
||||||
import { JsonRpcProxy } from '@theia/core/lib/common/messaging/proxy-factory';
|
import { JsonRpcProxy } from '@theia/core/lib/common/messaging/proxy-factory';
|
||||||
import { WindowService } from '@theia/core/lib/browser/window/window-service';
|
import { WindowService } from '@theia/core/lib/browser/window/window-service';
|
||||||
@@ -43,15 +43,13 @@ export class AuthenticationClientService
|
|||||||
|
|
||||||
readonly onSessionDidChange = this.onSessionDidChangeEmitter.event;
|
readonly onSessionDidChange = this.onSessionDidChangeEmitter.event;
|
||||||
|
|
||||||
async onStart(): Promise<void> {
|
onStart(): void {
|
||||||
this.toDispose.push(this.onSessionDidChangeEmitter);
|
this.toDispose.push(this.onSessionDidChangeEmitter);
|
||||||
this.service.setClient(this);
|
this.service.setClient(this);
|
||||||
this.service
|
this.service
|
||||||
.session()
|
.session()
|
||||||
.then((session) => this.notifySessionDidChange(session));
|
.then((session) => this.notifySessionDidChange(session));
|
||||||
|
this.setOptions();
|
||||||
this.setOptions().then(() => this.service.initAuthSession());
|
|
||||||
|
|
||||||
this.arduinoPreferences.onPreferenceChanged((event) => {
|
this.arduinoPreferences.onPreferenceChanged((event) => {
|
||||||
if (event.preferenceName.startsWith('arduino.auth.')) {
|
if (event.preferenceName.startsWith('arduino.auth.')) {
|
||||||
this.setOptions();
|
this.setOptions();
|
||||||
@@ -59,8 +57,8 @@ export class AuthenticationClientService
|
|||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
setOptions(): Promise<void> {
|
setOptions(): void {
|
||||||
return this.service.setOptions({
|
this.service.setOptions({
|
||||||
redirectUri: `http://localhost:${serverPort}/callback`,
|
redirectUri: `http://localhost:${serverPort}/callback`,
|
||||||
responseType: 'code',
|
responseType: 'code',
|
||||||
clientID: this.arduinoPreferences['arduino.auth.clientID'],
|
clientID: this.arduinoPreferences['arduino.auth.clientID'],
|
||||||
|
@@ -1,4 +1,4 @@
|
|||||||
import { injectable, inject } from '@theia/core/shared/inversify';
|
import { injectable, inject } from 'inversify';
|
||||||
import { MessageService } from '@theia/core/lib/common/message-service';
|
import { MessageService } from '@theia/core/lib/common/message-service';
|
||||||
import { FrontendApplicationContribution } from '@theia/core/lib/browser/frontend-application';
|
import { FrontendApplicationContribution } from '@theia/core/lib/browser/frontend-application';
|
||||||
import {
|
import {
|
||||||
|
@@ -1,5 +1,5 @@
|
|||||||
import * as React from '@theia/core/shared/react';
|
import * as React from 'react';
|
||||||
import { injectable, inject } from '@theia/core/shared/inversify';
|
import { injectable, inject } from 'inversify';
|
||||||
import { Emitter } from '@theia/core/lib/common/event';
|
import { Emitter } from '@theia/core/lib/common/event';
|
||||||
import { ReactWidget, Message } from '@theia/core/lib/browser';
|
import { ReactWidget, Message } from '@theia/core/lib/browser';
|
||||||
import { BoardsService } from '../../common/protocol/boards-service';
|
import { BoardsService } from '../../common/protocol/boards-service';
|
||||||
@@ -55,13 +55,12 @@ export class BoardsConfigDialogWidget extends ReactWidget {
|
|||||||
onConfigChange={this.fireConfigChanged}
|
onConfigChange={this.fireConfigChanged}
|
||||||
onFocusNodeSet={this.setFocusNode}
|
onFocusNodeSet={this.setFocusNode}
|
||||||
onFilteredTextDidChangeEvent={this.onFilterTextDidChangeEmitter.event}
|
onFilteredTextDidChangeEvent={this.onFilterTextDidChangeEmitter.event}
|
||||||
onAppStateDidChange={this.notificationCenter.onAppStateDidChange}
|
|
||||||
/>
|
/>
|
||||||
</div>
|
</div>
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
protected override onActivateRequest(msg: Message): void {
|
protected onActivateRequest(msg: Message): void {
|
||||||
super.onActivateRequest(msg);
|
super.onActivateRequest(msg);
|
||||||
if (this.focusNode instanceof HTMLInputElement) {
|
if (this.focusNode instanceof HTMLInputElement) {
|
||||||
this.focusNode.select();
|
this.focusNode.select();
|
||||||
|
@@ -1,5 +1,5 @@
|
|||||||
import { injectable, inject, postConstruct } from '@theia/core/shared/inversify';
|
import { injectable, inject, postConstruct } from 'inversify';
|
||||||
import { Message } from '@theia/core/shared/@phosphor/messaging';
|
import { Message } from '@phosphor/messaging';
|
||||||
import { DialogProps, Widget, DialogError } from '@theia/core/lib/browser';
|
import { DialogProps, Widget, DialogError } from '@theia/core/lib/browser';
|
||||||
import { AbstractDialog } from '../theia/dialogs/dialogs';
|
import { AbstractDialog } from '../theia/dialogs/dialogs';
|
||||||
import { BoardsConfig } from './boards-config';
|
import { BoardsConfig } from './boards-config';
|
||||||
@@ -26,7 +26,7 @@ export class BoardsConfigDialog extends AbstractDialog<BoardsConfig.Config> {
|
|||||||
|
|
||||||
constructor(
|
constructor(
|
||||||
@inject(BoardsConfigDialogProps)
|
@inject(BoardsConfigDialogProps)
|
||||||
protected override readonly props: BoardsConfigDialogProps
|
protected readonly props: BoardsConfigDialogProps
|
||||||
) {
|
) {
|
||||||
super(props);
|
super(props);
|
||||||
|
|
||||||
@@ -52,7 +52,7 @@ export class BoardsConfigDialog extends AbstractDialog<BoardsConfig.Config> {
|
|||||||
/**
|
/**
|
||||||
* Pass in an empty string if you want to reset the search term. Using `undefined` has no effect.
|
* Pass in an empty string if you want to reset the search term. Using `undefined` has no effect.
|
||||||
*/
|
*/
|
||||||
override async open(
|
async open(
|
||||||
query: string | undefined = undefined
|
query: string | undefined = undefined
|
||||||
): Promise<BoardsConfig.Config | undefined> {
|
): Promise<BoardsConfig.Config | undefined> {
|
||||||
if (typeof query === 'string') {
|
if (typeof query === 'string') {
|
||||||
@@ -95,7 +95,7 @@ export class BoardsConfigDialog extends AbstractDialog<BoardsConfig.Config> {
|
|||||||
return head;
|
return head;
|
||||||
}
|
}
|
||||||
|
|
||||||
protected override onAfterAttach(msg: Message): void {
|
protected onAfterAttach(msg: Message): void {
|
||||||
if (this.widget.isAttached) {
|
if (this.widget.isAttached) {
|
||||||
Widget.detach(this.widget);
|
Widget.detach(this.widget);
|
||||||
}
|
}
|
||||||
@@ -110,23 +110,23 @@ export class BoardsConfigDialog extends AbstractDialog<BoardsConfig.Config> {
|
|||||||
this.update();
|
this.update();
|
||||||
}
|
}
|
||||||
|
|
||||||
protected override onUpdateRequest(msg: Message): void {
|
protected onUpdateRequest(msg: Message) {
|
||||||
super.onUpdateRequest(msg);
|
super.onUpdateRequest(msg);
|
||||||
this.widget.update();
|
this.widget.update();
|
||||||
}
|
}
|
||||||
|
|
||||||
protected override onActivateRequest(msg: Message): void {
|
protected onActivateRequest(msg: Message): void {
|
||||||
super.onActivateRequest(msg);
|
super.onActivateRequest(msg);
|
||||||
this.widget.activate();
|
this.widget.activate();
|
||||||
}
|
}
|
||||||
|
|
||||||
protected override handleEnter(event: KeyboardEvent): boolean | void {
|
protected handleEnter(event: KeyboardEvent): boolean | void {
|
||||||
if (event.target instanceof HTMLTextAreaElement) {
|
if (event.target instanceof HTMLTextAreaElement) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
protected override isValid(value: BoardsConfig.Config): DialogError {
|
protected isValid(value: BoardsConfig.Config): DialogError {
|
||||||
if (!value.selectedBoard) {
|
if (!value.selectedBoard) {
|
||||||
if (value.selectedPort) {
|
if (value.selectedPort) {
|
||||||
return nls.localize(
|
return nls.localize(
|
||||||
|
@@ -1,4 +1,4 @@
|
|||||||
import * as React from '@theia/core/shared/react';
|
import * as React from 'react';
|
||||||
import { Event } from '@theia/core/lib/common/event';
|
import { Event } from '@theia/core/lib/common/event';
|
||||||
import { notEmpty } from '@theia/core/lib/common/objects';
|
import { notEmpty } from '@theia/core/lib/common/objects';
|
||||||
import { MaybePromise } from '@theia/core/lib/common/types';
|
import { MaybePromise } from '@theia/core/lib/common/types';
|
||||||
@@ -16,7 +16,6 @@ import {
|
|||||||
} from './boards-service-provider';
|
} from './boards-service-provider';
|
||||||
import { naturalCompare } from '../../common/utils';
|
import { naturalCompare } from '../../common/utils';
|
||||||
import { nls } from '@theia/core/lib/common';
|
import { nls } from '@theia/core/lib/common';
|
||||||
import { FrontendApplicationState } from '@theia/core/lib/common/frontend-application-state';
|
|
||||||
|
|
||||||
export namespace BoardsConfig {
|
export namespace BoardsConfig {
|
||||||
export interface Config {
|
export interface Config {
|
||||||
@@ -30,7 +29,6 @@ export namespace BoardsConfig {
|
|||||||
readonly onConfigChange: (config: Config) => void;
|
readonly onConfigChange: (config: Config) => void;
|
||||||
readonly onFocusNodeSet: (element: HTMLElement | undefined) => void;
|
readonly onFocusNodeSet: (element: HTMLElement | undefined) => void;
|
||||||
readonly onFilteredTextDidChangeEvent: Event<string>;
|
readonly onFilteredTextDidChangeEvent: Event<string>;
|
||||||
readonly onAppStateDidChange: Event<FrontendApplicationState>;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
export interface State extends Config {
|
export interface State extends Config {
|
||||||
@@ -49,7 +47,7 @@ export abstract class Item<T> extends React.Component<{
|
|||||||
missing?: boolean;
|
missing?: boolean;
|
||||||
details?: string;
|
details?: string;
|
||||||
}> {
|
}> {
|
||||||
override render(): React.ReactNode {
|
render(): React.ReactNode {
|
||||||
const { selected, label, missing, details } = this.props;
|
const { selected, label, missing, details } = this.props;
|
||||||
const classNames = ['item'];
|
const classNames = ['item'];
|
||||||
if (selected) {
|
if (selected) {
|
||||||
@@ -101,18 +99,14 @@ export class BoardsConfig extends React.Component<
|
|||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
override componentDidMount(): void {
|
componentDidMount() {
|
||||||
|
this.updateBoards();
|
||||||
|
this.updatePorts(
|
||||||
|
this.props.boardsServiceProvider.availableBoards
|
||||||
|
.map(({ port }) => port)
|
||||||
|
.filter(notEmpty)
|
||||||
|
);
|
||||||
this.toDispose.pushAll([
|
this.toDispose.pushAll([
|
||||||
this.props.onAppStateDidChange((state) => {
|
|
||||||
if (state === 'ready') {
|
|
||||||
this.updateBoards();
|
|
||||||
this.updatePorts(
|
|
||||||
this.props.boardsServiceProvider.availableBoards
|
|
||||||
.map(({ port }) => port)
|
|
||||||
.filter(notEmpty)
|
|
||||||
);
|
|
||||||
}
|
|
||||||
}),
|
|
||||||
this.props.notificationCenter.onAttachedBoardsChanged((event) =>
|
this.props.notificationCenter.onAttachedBoardsChanged((event) =>
|
||||||
this.updatePorts(
|
this.updatePorts(
|
||||||
event.newState.ports,
|
event.newState.ports,
|
||||||
@@ -147,11 +141,11 @@ export class BoardsConfig extends React.Component<
|
|||||||
]);
|
]);
|
||||||
}
|
}
|
||||||
|
|
||||||
override componentWillUnmount(): void {
|
componentWillUnmount(): void {
|
||||||
this.toDispose.dispose();
|
this.toDispose.dispose();
|
||||||
}
|
}
|
||||||
|
|
||||||
protected fireConfigChanged(): void {
|
protected fireConfigChanged() {
|
||||||
const { selectedBoard, selectedPort } = this.state;
|
const { selectedBoard, selectedPort } = this.state;
|
||||||
this.props.onConfigChange({ selectedBoard, selectedPort });
|
this.props.onConfigChange({ selectedBoard, selectedPort });
|
||||||
}
|
}
|
||||||
@@ -256,7 +250,7 @@ export class BoardsConfig extends React.Component<
|
|||||||
this.props.onFocusNodeSet(element || undefined);
|
this.props.onFocusNodeSet(element || undefined);
|
||||||
};
|
};
|
||||||
|
|
||||||
override render(): React.ReactNode {
|
render(): React.ReactNode {
|
||||||
return (
|
return (
|
||||||
<div className="body">
|
<div className="body">
|
||||||
{this.renderContainer('boards', this.renderBoards.bind(this))}
|
{this.renderContainer('boards', this.renderBoards.bind(this))}
|
||||||
|
@@ -1,5 +1,5 @@
|
|||||||
import * as PQueue from 'p-queue';
|
import * as PQueue from 'p-queue';
|
||||||
import { inject, injectable } from '@theia/core/shared/inversify';
|
import { inject, injectable } from 'inversify';
|
||||||
import { CommandRegistry } from '@theia/core/lib/common/command';
|
import { CommandRegistry } from '@theia/core/lib/common/command';
|
||||||
import { MenuModelRegistry } from '@theia/core/lib/common/menu';
|
import { MenuModelRegistry } from '@theia/core/lib/common/menu';
|
||||||
import {
|
import {
|
||||||
@@ -13,7 +13,6 @@ import { BoardsDataStore } from './boards-data-store';
|
|||||||
import { MainMenuManager } from '../../common/main-menu-manager';
|
import { MainMenuManager } from '../../common/main-menu-manager';
|
||||||
import { ArduinoMenus, unregisterSubmenu } from '../menu/arduino-menus';
|
import { ArduinoMenus, unregisterSubmenu } from '../menu/arduino-menus';
|
||||||
import { nls } from '@theia/core/lib/common';
|
import { nls } from '@theia/core/lib/common';
|
||||||
import { FrontendApplicationStateService } from '@theia/core/lib/browser/frontend-application-state';
|
|
||||||
|
|
||||||
@injectable()
|
@injectable()
|
||||||
export class BoardsDataMenuUpdater implements FrontendApplicationContribution {
|
export class BoardsDataMenuUpdater implements FrontendApplicationContribution {
|
||||||
@@ -32,20 +31,11 @@ export class BoardsDataMenuUpdater implements FrontendApplicationContribution {
|
|||||||
@inject(BoardsServiceProvider)
|
@inject(BoardsServiceProvider)
|
||||||
protected readonly boardsServiceClient: BoardsServiceProvider;
|
protected readonly boardsServiceClient: BoardsServiceProvider;
|
||||||
|
|
||||||
@inject(FrontendApplicationStateService)
|
|
||||||
private readonly appStateService: FrontendApplicationStateService;
|
|
||||||
|
|
||||||
protected readonly queue = new PQueue({ autoStart: true, concurrency: 1 });
|
protected readonly queue = new PQueue({ autoStart: true, concurrency: 1 });
|
||||||
protected readonly toDisposeOnBoardChange = new DisposableCollection();
|
protected readonly toDisposeOnBoardChange = new DisposableCollection();
|
||||||
|
|
||||||
async onStart(): Promise<void> {
|
async onStart(): Promise<void> {
|
||||||
this.appStateService
|
this.updateMenuActions(this.boardsServiceClient.boardsConfig.selectedBoard);
|
||||||
.reachedState('ready')
|
|
||||||
.then(() =>
|
|
||||||
this.updateMenuActions(
|
|
||||||
this.boardsServiceClient.boardsConfig.selectedBoard
|
|
||||||
)
|
|
||||||
);
|
|
||||||
this.boardsDataStore.onChanged(() =>
|
this.boardsDataStore.onChanged(() =>
|
||||||
this.updateMenuActions(
|
this.updateMenuActions(
|
||||||
this.boardsServiceClient.boardsConfig.selectedBoard
|
this.boardsServiceClient.boardsConfig.selectedBoard
|
||||||
|
@@ -1,4 +1,4 @@
|
|||||||
import { injectable, inject, named } from '@theia/core/shared/inversify';
|
import { injectable, inject, named } from 'inversify';
|
||||||
import { ILogger } from '@theia/core/lib/common/logger';
|
import { ILogger } from '@theia/core/lib/common/logger';
|
||||||
import { deepClone } from '@theia/core/lib/common/objects';
|
import { deepClone } from '@theia/core/lib/common/objects';
|
||||||
import { Event, Emitter } from '@theia/core/lib/common/event';
|
import { Event, Emitter } from '@theia/core/lib/common/event';
|
||||||
|
@@ -1,4 +1,4 @@
|
|||||||
import { inject, injectable, postConstruct } from '@theia/core/shared/inversify';
|
import { inject, injectable, postConstruct } from 'inversify';
|
||||||
import {
|
import {
|
||||||
BoardsPackage,
|
BoardsPackage,
|
||||||
BoardsService,
|
BoardsService,
|
||||||
@@ -30,7 +30,7 @@ export class BoardsListWidget extends ListWidget<BoardsPackage> {
|
|||||||
}
|
}
|
||||||
|
|
||||||
@postConstruct()
|
@postConstruct()
|
||||||
protected override init(): void {
|
protected init(): void {
|
||||||
super.init();
|
super.init();
|
||||||
this.toDispose.pushAll([
|
this.toDispose.pushAll([
|
||||||
this.notificationCenter.onPlatformInstalled(() =>
|
this.notificationCenter.onPlatformInstalled(() =>
|
||||||
@@ -42,7 +42,7 @@ export class BoardsListWidget extends ListWidget<BoardsPackage> {
|
|||||||
]);
|
]);
|
||||||
}
|
}
|
||||||
|
|
||||||
protected override async install({
|
protected async install({
|
||||||
item,
|
item,
|
||||||
progressId,
|
progressId,
|
||||||
version,
|
version,
|
||||||
@@ -63,7 +63,7 @@ export class BoardsListWidget extends ListWidget<BoardsPackage> {
|
|||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
protected override async uninstall({
|
protected async uninstall({
|
||||||
item,
|
item,
|
||||||
progressId,
|
progressId,
|
||||||
}: {
|
}: {
|
||||||
|
@@ -1,4 +1,4 @@
|
|||||||
import { injectable, inject } from '@theia/core/shared/inversify';
|
import { injectable, inject } from 'inversify';
|
||||||
import { Emitter } from '@theia/core/lib/common/event';
|
import { Emitter } from '@theia/core/lib/common/event';
|
||||||
import { ILogger } from '@theia/core/lib/common/logger';
|
import { ILogger } from '@theia/core/lib/common/logger';
|
||||||
import { CommandService } from '@theia/core/lib/common/command';
|
import { CommandService } from '@theia/core/lib/common/command';
|
||||||
|
@@ -1,5 +1,5 @@
|
|||||||
import * as React from '@theia/core/shared/react';
|
import * as React from 'react';
|
||||||
import * as ReactDOM from '@theia/core/shared/react-dom';
|
import * as ReactDOM from 'react-dom';
|
||||||
import { CommandRegistry } from '@theia/core/lib/common/command';
|
import { CommandRegistry } from '@theia/core/lib/common/command';
|
||||||
import { DisposableCollection } from '@theia/core/lib/common/disposable';
|
import { DisposableCollection } from '@theia/core/lib/common/disposable';
|
||||||
import { Port } from '../../common/protocol';
|
import { Port } from '../../common/protocol';
|
||||||
@@ -41,7 +41,7 @@ export class BoardsDropDown extends React.Component<BoardsDropDown.Props> {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
override render(): React.ReactNode {
|
render(): React.ReactNode {
|
||||||
return ReactDOM.createPortal(this.renderNode(), this.dropdownElement);
|
return ReactDOM.createPortal(this.renderNode(), this.dropdownElement);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -130,13 +130,13 @@ export class BoardsToolBarItem extends React.Component<
|
|||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
override componentDidMount(): void {
|
componentDidMount() {
|
||||||
this.props.boardsServiceClient.onAvailableBoardsChanged((availableBoards) =>
|
this.props.boardsServiceClient.onAvailableBoardsChanged((availableBoards) =>
|
||||||
this.setState({ availableBoards })
|
this.setState({ availableBoards })
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
override componentWillUnmount(): void {
|
componentWillUnmount(): void {
|
||||||
this.toDispose.dispose();
|
this.toDispose.dispose();
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -161,7 +161,7 @@ export class BoardsToolBarItem extends React.Component<
|
|||||||
event.nativeEvent.stopImmediatePropagation();
|
event.nativeEvent.stopImmediatePropagation();
|
||||||
};
|
};
|
||||||
|
|
||||||
override render(): React.ReactNode {
|
render(): React.ReactNode {
|
||||||
const { coords, availableBoards } = this.state;
|
const { coords, availableBoards } = this.state;
|
||||||
const boardsConfig = this.props.boardsServiceClient.boardsConfig;
|
const boardsConfig = this.props.boardsServiceClient.boardsConfig;
|
||||||
const title = BoardsConfig.Config.toString(boardsConfig, {
|
const title = BoardsConfig.Config.toString(boardsConfig, {
|
||||||
|
@@ -1,4 +1,4 @@
|
|||||||
import { injectable } from '@theia/core/shared/inversify';
|
import { injectable } from 'inversify';
|
||||||
import { BoardsListWidget } from './boards-list-widget';
|
import { BoardsListWidget } from './boards-list-widget';
|
||||||
import { BoardsPackage } from '../../common/protocol/boards-service';
|
import { BoardsPackage } from '../../common/protocol/boards-service';
|
||||||
import { ListWidgetFrontendContribution } from '../widgets/component-list/list-widget-frontend-contribution';
|
import { ListWidgetFrontendContribution } from '../widgets/component-list/list-widget-frontend-contribution';
|
||||||
@@ -18,7 +18,7 @@ export class BoardsListWidgetFrontendContribution extends ListWidgetFrontendCont
|
|||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
override async initializeLayout(): Promise<void> {
|
async initializeLayout(): Promise<void> {
|
||||||
this.openView();
|
this.openView();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@@ -1,4 +1,4 @@
|
|||||||
import * as React from '@theia/core/shared/react';
|
import * as React from 'react';
|
||||||
|
|
||||||
export type ProgressBarProps = {
|
export type ProgressBarProps = {
|
||||||
percent?: number;
|
percent?: number;
|
||||||
|
@@ -1,4 +1,4 @@
|
|||||||
import { inject, injectable } from '@theia/core/shared/inversify';
|
import { inject, injectable } from 'inversify';
|
||||||
import * as moment from 'moment';
|
import * as moment from 'moment';
|
||||||
import * as remote from '@theia/core/electron-shared/@electron/remote';
|
import * as remote from '@theia/core/electron-shared/@electron/remote';
|
||||||
import { isOSX, isWindows } from '@theia/core/lib/common/os';
|
import { isOSX, isWindows } from '@theia/core/lib/common/os';
|
||||||
@@ -22,13 +22,13 @@ export class About extends Contribution {
|
|||||||
@inject(ConfigService)
|
@inject(ConfigService)
|
||||||
protected readonly configService: ConfigService;
|
protected readonly configService: ConfigService;
|
||||||
|
|
||||||
override registerCommands(registry: CommandRegistry): void {
|
registerCommands(registry: CommandRegistry): void {
|
||||||
registry.registerCommand(About.Commands.ABOUT_APP, {
|
registry.registerCommand(About.Commands.ABOUT_APP, {
|
||||||
execute: () => this.showAbout(),
|
execute: () => this.showAbout(),
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
override registerMenus(registry: MenuModelRegistry): void {
|
registerMenus(registry: MenuModelRegistry): void {
|
||||||
registry.registerMenuAction(ArduinoMenus.HELP__ABOUT_GROUP, {
|
registry.registerMenuAction(ArduinoMenus.HELP__ABOUT_GROUP, {
|
||||||
commandId: About.Commands.ABOUT_APP.id,
|
commandId: About.Commands.ABOUT_APP.id,
|
||||||
label: nls.localize(
|
label: nls.localize(
|
||||||
|
@@ -1,4 +1,4 @@
|
|||||||
import { inject, injectable } from '@theia/core/shared/inversify';
|
import { inject, injectable } from 'inversify';
|
||||||
import * as remote from '@theia/core/electron-shared/@electron/remote';
|
import * as remote from '@theia/core/electron-shared/@electron/remote';
|
||||||
import { ArduinoMenus } from '../menu/arduino-menus';
|
import { ArduinoMenus } from '../menu/arduino-menus';
|
||||||
import {
|
import {
|
||||||
@@ -10,20 +10,19 @@ import {
|
|||||||
} from './contribution';
|
} from './contribution';
|
||||||
import { FileDialogService } from '@theia/filesystem/lib/browser';
|
import { FileDialogService } from '@theia/filesystem/lib/browser';
|
||||||
import { nls } from '@theia/core/lib/common';
|
import { nls } from '@theia/core/lib/common';
|
||||||
import { CurrentSketch } from '../../common/protocol/sketches-service-client-impl';
|
|
||||||
|
|
||||||
@injectable()
|
@injectable()
|
||||||
export class AddFile extends SketchContribution {
|
export class AddFile extends SketchContribution {
|
||||||
@inject(FileDialogService)
|
@inject(FileDialogService)
|
||||||
protected readonly fileDialogService: FileDialogService;
|
protected readonly fileDialogService: FileDialogService;
|
||||||
|
|
||||||
override registerCommands(registry: CommandRegistry): void {
|
registerCommands(registry: CommandRegistry): void {
|
||||||
registry.registerCommand(AddFile.Commands.ADD_FILE, {
|
registry.registerCommand(AddFile.Commands.ADD_FILE, {
|
||||||
execute: () => this.addFile(),
|
execute: () => this.addFile(),
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
override registerMenus(registry: MenuModelRegistry): void {
|
registerMenus(registry: MenuModelRegistry): void {
|
||||||
registry.registerMenuAction(ArduinoMenus.SKETCH__UTILS_GROUP, {
|
registry.registerMenuAction(ArduinoMenus.SKETCH__UTILS_GROUP, {
|
||||||
commandId: AddFile.Commands.ADD_FILE.id,
|
commandId: AddFile.Commands.ADD_FILE.id,
|
||||||
label: nls.localize('arduino/contributions/addFile', 'Add File') + '...',
|
label: nls.localize('arduino/contributions/addFile', 'Add File') + '...',
|
||||||
@@ -33,7 +32,7 @@ export class AddFile extends SketchContribution {
|
|||||||
|
|
||||||
protected async addFile(): Promise<void> {
|
protected async addFile(): Promise<void> {
|
||||||
const sketch = await this.sketchServiceClient.currentSketch();
|
const sketch = await this.sketchServiceClient.currentSketch();
|
||||||
if (!CurrentSketch.isValid(sketch)) {
|
if (!sketch) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
const toAddUri = await this.fileDialogService.showOpenDialog({
|
const toAddUri = await this.fileDialogService.showOpenDialog({
|
||||||
|
@@ -1,4 +1,4 @@
|
|||||||
import { inject, injectable } from '@theia/core/shared/inversify';
|
import { inject, injectable } from 'inversify';
|
||||||
import * as remote from '@theia/core/electron-shared/@electron/remote';
|
import * as remote from '@theia/core/electron-shared/@electron/remote';
|
||||||
import URI from '@theia/core/lib/common/uri';
|
import URI from '@theia/core/lib/common/uri';
|
||||||
import { ConfirmDialog } from '@theia/core/lib/browser/dialogs';
|
import { ConfirmDialog } from '@theia/core/lib/browser/dialogs';
|
||||||
@@ -28,13 +28,13 @@ export class AddZipLibrary extends SketchContribution {
|
|||||||
@inject(LibraryService)
|
@inject(LibraryService)
|
||||||
protected readonly libraryService: LibraryService;
|
protected readonly libraryService: LibraryService;
|
||||||
|
|
||||||
override registerCommands(registry: CommandRegistry): void {
|
registerCommands(registry: CommandRegistry): void {
|
||||||
registry.registerCommand(AddZipLibrary.Commands.ADD_ZIP_LIBRARY, {
|
registry.registerCommand(AddZipLibrary.Commands.ADD_ZIP_LIBRARY, {
|
||||||
execute: () => this.addZipLibrary(),
|
execute: () => this.addZipLibrary(),
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
override registerMenus(registry: MenuModelRegistry): void {
|
registerMenus(registry: MenuModelRegistry): void {
|
||||||
const includeLibMenuPath = [
|
const includeLibMenuPath = [
|
||||||
...ArduinoMenus.SKETCH__UTILS_GROUP,
|
...ArduinoMenus.SKETCH__UTILS_GROUP,
|
||||||
'0_include',
|
'0_include',
|
||||||
|
@@ -1,4 +1,4 @@
|
|||||||
import { injectable } from '@theia/core/shared/inversify';
|
import { injectable } from 'inversify';
|
||||||
import * as remote from '@theia/core/electron-shared/@electron/remote';
|
import * as remote from '@theia/core/electron-shared/@electron/remote';
|
||||||
import * as dateFormat from 'dateformat';
|
import * as dateFormat from 'dateformat';
|
||||||
import URI from '@theia/core/lib/common/uri';
|
import URI from '@theia/core/lib/common/uri';
|
||||||
@@ -10,17 +10,16 @@ import {
|
|||||||
MenuModelRegistry,
|
MenuModelRegistry,
|
||||||
} from './contribution';
|
} from './contribution';
|
||||||
import { nls } from '@theia/core/lib/common';
|
import { nls } from '@theia/core/lib/common';
|
||||||
import { CurrentSketch } from '../../common/protocol/sketches-service-client-impl';
|
|
||||||
|
|
||||||
@injectable()
|
@injectable()
|
||||||
export class ArchiveSketch extends SketchContribution {
|
export class ArchiveSketch extends SketchContribution {
|
||||||
override registerCommands(registry: CommandRegistry): void {
|
registerCommands(registry: CommandRegistry): void {
|
||||||
registry.registerCommand(ArchiveSketch.Commands.ARCHIVE_SKETCH, {
|
registry.registerCommand(ArchiveSketch.Commands.ARCHIVE_SKETCH, {
|
||||||
execute: () => this.archiveSketch(),
|
execute: () => this.archiveSketch(),
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
override registerMenus(registry: MenuModelRegistry): void {
|
registerMenus(registry: MenuModelRegistry): void {
|
||||||
registry.registerMenuAction(ArduinoMenus.TOOLS__MAIN_GROUP, {
|
registry.registerMenuAction(ArduinoMenus.TOOLS__MAIN_GROUP, {
|
||||||
commandId: ArchiveSketch.Commands.ARCHIVE_SKETCH.id,
|
commandId: ArchiveSketch.Commands.ARCHIVE_SKETCH.id,
|
||||||
label: nls.localize('arduino/sketch/archiveSketch', 'Archive Sketch'),
|
label: nls.localize('arduino/sketch/archiveSketch', 'Archive Sketch'),
|
||||||
@@ -33,7 +32,7 @@ export class ArchiveSketch extends SketchContribution {
|
|||||||
this.sketchServiceClient.currentSketch(),
|
this.sketchServiceClient.currentSketch(),
|
||||||
this.configService.getConfiguration(),
|
this.configService.getConfiguration(),
|
||||||
]);
|
]);
|
||||||
if (!CurrentSketch.isValid(sketch)) {
|
if (!sketch) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
const archiveBasename = `${sketch.name}-${dateFormat(
|
const archiveBasename = `${sketch.name}-${dateFormat(
|
||||||
|
@@ -1,4 +1,4 @@
|
|||||||
import { inject, injectable } from '@theia/core/shared/inversify';
|
import { inject, injectable } from 'inversify';
|
||||||
import * as remote from '@theia/core/electron-shared/@electron/remote';
|
import * as remote from '@theia/core/electron-shared/@electron/remote';
|
||||||
import { MenuModelRegistry } from '@theia/core/lib/common/menu';
|
import { MenuModelRegistry } from '@theia/core/lib/common/menu';
|
||||||
import {
|
import {
|
||||||
@@ -47,7 +47,7 @@ export class BoardSelection extends SketchContribution {
|
|||||||
|
|
||||||
protected readonly toDisposeBeforeMenuRebuild = new DisposableCollection();
|
protected readonly toDisposeBeforeMenuRebuild = new DisposableCollection();
|
||||||
|
|
||||||
override registerCommands(registry: CommandRegistry): void {
|
registerCommands(registry: CommandRegistry): void {
|
||||||
registry.registerCommand(BoardSelection.Commands.GET_BOARD_INFO, {
|
registry.registerCommand(BoardSelection.Commands.GET_BOARD_INFO, {
|
||||||
execute: async () => {
|
execute: async () => {
|
||||||
const { selectedBoard, selectedPort } =
|
const { selectedBoard, selectedPort } =
|
||||||
@@ -100,20 +100,19 @@ PID: ${PID}`;
|
|||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
override onStart(): void {
|
onStart(): void {
|
||||||
this.notificationCenter.onPlatformInstalled(() => this.updateMenus());
|
|
||||||
this.notificationCenter.onPlatformUninstalled(() => this.updateMenus());
|
|
||||||
this.boardsServiceProvider.onBoardsConfigChanged(() => this.updateMenus());
|
|
||||||
this.boardsServiceProvider.onAvailableBoardsChanged(() =>
|
|
||||||
this.updateMenus()
|
|
||||||
);
|
|
||||||
this.boardsServiceProvider.onAvailablePortsChanged(() =>
|
|
||||||
this.updateMenus()
|
|
||||||
);
|
|
||||||
}
|
|
||||||
|
|
||||||
override async onReady(): Promise<void> {
|
|
||||||
this.updateMenus();
|
this.updateMenus();
|
||||||
|
this.notificationCenter.onPlatformInstalled(this.updateMenus.bind(this));
|
||||||
|
this.notificationCenter.onPlatformUninstalled(this.updateMenus.bind(this));
|
||||||
|
this.boardsServiceProvider.onBoardsConfigChanged(
|
||||||
|
this.updateMenus.bind(this)
|
||||||
|
);
|
||||||
|
this.boardsServiceProvider.onAvailableBoardsChanged(
|
||||||
|
this.updateMenus.bind(this)
|
||||||
|
);
|
||||||
|
this.boardsServiceProvider.onAvailablePortsChanged(
|
||||||
|
this.updateMenus.bind(this)
|
||||||
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
protected async updateMenus(): Promise<void> {
|
protected async updateMenus(): Promise<void> {
|
||||||
|
@@ -1,9 +1,11 @@
|
|||||||
import { inject, injectable } from '@theia/core/shared/inversify';
|
import { inject, injectable } from 'inversify';
|
||||||
|
import { OutputChannelManager } from '@theia/output/lib/browser/output-channel';
|
||||||
|
import { CoreService } from '../../common/protocol';
|
||||||
import { ArduinoMenus } from '../menu/arduino-menus';
|
import { ArduinoMenus } from '../menu/arduino-menus';
|
||||||
import { BoardsDataStore } from '../boards/boards-data-store';
|
import { BoardsDataStore } from '../boards/boards-data-store';
|
||||||
import { BoardsServiceProvider } from '../boards/boards-service-provider';
|
import { BoardsServiceProvider } from '../boards/boards-service-provider';
|
||||||
import {
|
import {
|
||||||
CoreServiceContribution,
|
SketchContribution,
|
||||||
Command,
|
Command,
|
||||||
CommandRegistry,
|
CommandRegistry,
|
||||||
MenuModelRegistry,
|
MenuModelRegistry,
|
||||||
@@ -11,20 +13,27 @@ import {
|
|||||||
import { nls } from '@theia/core/lib/common';
|
import { nls } from '@theia/core/lib/common';
|
||||||
|
|
||||||
@injectable()
|
@injectable()
|
||||||
export class BurnBootloader extends CoreServiceContribution {
|
export class BurnBootloader extends SketchContribution {
|
||||||
|
@inject(CoreService)
|
||||||
|
protected readonly coreService: CoreService;
|
||||||
|
|
||||||
|
|
||||||
@inject(BoardsDataStore)
|
@inject(BoardsDataStore)
|
||||||
protected readonly boardsDataStore: BoardsDataStore;
|
protected readonly boardsDataStore: BoardsDataStore;
|
||||||
|
|
||||||
@inject(BoardsServiceProvider)
|
@inject(BoardsServiceProvider)
|
||||||
protected readonly boardsServiceClientImpl: BoardsServiceProvider;
|
protected readonly boardsServiceClientImpl: BoardsServiceProvider;
|
||||||
|
|
||||||
override registerCommands(registry: CommandRegistry): void {
|
@inject(OutputChannelManager)
|
||||||
|
protected readonly outputChannelManager: OutputChannelManager;
|
||||||
|
|
||||||
|
registerCommands(registry: CommandRegistry): void {
|
||||||
registry.registerCommand(BurnBootloader.Commands.BURN_BOOTLOADER, {
|
registry.registerCommand(BurnBootloader.Commands.BURN_BOOTLOADER, {
|
||||||
execute: () => this.burnBootloader(),
|
execute: () => this.burnBootloader(),
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
override registerMenus(registry: MenuModelRegistry): void {
|
registerMenus(registry: MenuModelRegistry): void {
|
||||||
registry.registerMenuAction(ArduinoMenus.TOOLS__BOARD_SETTINGS_GROUP, {
|
registry.registerMenuAction(ArduinoMenus.TOOLS__BOARD_SETTINGS_GROUP, {
|
||||||
commandId: BurnBootloader.Commands.BURN_BOOTLOADER.id,
|
commandId: BurnBootloader.Commands.BURN_BOOTLOADER.id,
|
||||||
label: nls.localize(
|
label: nls.localize(
|
||||||
@@ -53,7 +62,7 @@ export class BurnBootloader extends CoreServiceContribution {
|
|||||||
...boardsConfig.selectedBoard,
|
...boardsConfig.selectedBoard,
|
||||||
name: boardsConfig.selectedBoard?.name || '',
|
name: boardsConfig.selectedBoard?.name || '',
|
||||||
fqbn,
|
fqbn,
|
||||||
};
|
}
|
||||||
this.outputChannelManager.getChannel('Arduino').clear();
|
this.outputChannelManager.getChannel('Arduino').clear();
|
||||||
await this.coreService.burnBootloader({
|
await this.coreService.burnBootloader({
|
||||||
board,
|
board,
|
||||||
@@ -72,7 +81,13 @@ export class BurnBootloader extends CoreServiceContribution {
|
|||||||
}
|
}
|
||||||
);
|
);
|
||||||
} catch (e) {
|
} catch (e) {
|
||||||
this.handleError(e);
|
let errorMessage = "";
|
||||||
|
if (typeof e === "string") {
|
||||||
|
errorMessage = e;
|
||||||
|
} else {
|
||||||
|
errorMessage = e.toString();
|
||||||
|
}
|
||||||
|
this.messageService.error(errorMessage);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@@ -1,10 +1,12 @@
|
|||||||
import { inject, injectable } from '@theia/core/shared/inversify';
|
import { inject, injectable } from 'inversify';
|
||||||
|
import { toArray } from '@phosphor/algorithm';
|
||||||
import * as remote from '@theia/core/electron-shared/@electron/remote';
|
import * as remote from '@theia/core/electron-shared/@electron/remote';
|
||||||
import { MonacoEditor } from '@theia/monaco/lib/browser/monaco-editor';
|
import { MonacoEditor } from '@theia/monaco/lib/browser/monaco-editor';
|
||||||
import { EditorManager } from '@theia/editor/lib/browser/editor-manager';
|
import { EditorManager } from '@theia/editor/lib/browser/editor-manager';
|
||||||
import { ApplicationShell } from '@theia/core/lib/browser/shell/application-shell';
|
import { ApplicationShell } from '@theia/core/lib/browser/shell/application-shell';
|
||||||
import { FrontendApplication } from '@theia/core/lib/browser/frontend-application';
|
import { FrontendApplication } from '@theia/core/lib/browser/frontend-application';
|
||||||
import { ArduinoMenus } from '../menu/arduino-menus';
|
import { ArduinoMenus } from '../menu/arduino-menus';
|
||||||
|
import { SaveAsSketch } from './save-as-sketch';
|
||||||
import {
|
import {
|
||||||
SketchContribution,
|
SketchContribution,
|
||||||
Command,
|
Command,
|
||||||
@@ -21,21 +23,90 @@ import { nls } from '@theia/core/lib/common';
|
|||||||
@injectable()
|
@injectable()
|
||||||
export class Close extends SketchContribution {
|
export class Close extends SketchContribution {
|
||||||
@inject(EditorManager)
|
@inject(EditorManager)
|
||||||
protected override readonly editorManager: EditorManager;
|
protected readonly editorManager: EditorManager;
|
||||||
|
|
||||||
protected shell: ApplicationShell;
|
protected shell: ApplicationShell;
|
||||||
|
|
||||||
override onStart(app: FrontendApplication): void {
|
onStart(app: FrontendApplication): void {
|
||||||
this.shell = app.shell;
|
this.shell = app.shell;
|
||||||
}
|
}
|
||||||
|
|
||||||
override registerCommands(registry: CommandRegistry): void {
|
registerCommands(registry: CommandRegistry): void {
|
||||||
registry.registerCommand(Close.Commands.CLOSE, {
|
registry.registerCommand(Close.Commands.CLOSE, {
|
||||||
execute: () => remote.getCurrentWindow().close()
|
execute: async () => {
|
||||||
|
// Close current editor if closeable.
|
||||||
|
const { currentEditor } = this.editorManager;
|
||||||
|
if (currentEditor && currentEditor.title.closable) {
|
||||||
|
currentEditor.close();
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Close current widget from the main area if possible.
|
||||||
|
const { currentWidget } = this.shell;
|
||||||
|
if (currentWidget) {
|
||||||
|
const currentWidgetInMain = toArray(
|
||||||
|
this.shell.mainPanel.widgets()
|
||||||
|
).find((widget) => widget === currentWidget);
|
||||||
|
if (currentWidgetInMain && currentWidgetInMain.title.closable) {
|
||||||
|
return currentWidgetInMain.close();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Close the sketch (window).
|
||||||
|
const sketch = await this.sketchServiceClient.currentSketch();
|
||||||
|
if (!sketch) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
const isTemp = await this.sketchService.isTemp(sketch);
|
||||||
|
const uri = await this.sketchServiceClient.currentSketchFile();
|
||||||
|
if (!uri) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
if (isTemp && (await this.wasTouched(uri))) {
|
||||||
|
const { response } = await remote.dialog.showMessageBox({
|
||||||
|
type: 'question',
|
||||||
|
buttons: [
|
||||||
|
nls.localize(
|
||||||
|
'vscode/abstractTaskService/saveBeforeRun.dontSave',
|
||||||
|
"Don't Save"
|
||||||
|
),
|
||||||
|
nls.localize('vscode/issueMainService/cancel', 'Cancel'),
|
||||||
|
nls.localize(
|
||||||
|
'vscode/abstractTaskService/saveBeforeRun.save',
|
||||||
|
'Save'
|
||||||
|
),
|
||||||
|
],
|
||||||
|
message: nls.localize(
|
||||||
|
'arduino/common/saveChangesToSketch',
|
||||||
|
'Do you want to save changes to this sketch before closing?'
|
||||||
|
),
|
||||||
|
detail: nls.localize(
|
||||||
|
'arduino/common/loseChanges',
|
||||||
|
"If you don't save, your changes will be lost."
|
||||||
|
),
|
||||||
|
});
|
||||||
|
if (response === 1) {
|
||||||
|
// Cancel
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
if (response === 2) {
|
||||||
|
// Save
|
||||||
|
const saved = await this.commandService.executeCommand(
|
||||||
|
SaveAsSketch.Commands.SAVE_AS_SKETCH.id,
|
||||||
|
{ openAfterMove: false, execOnlyIfTemp: true }
|
||||||
|
);
|
||||||
|
if (!saved) {
|
||||||
|
// If it was not saved, do bail the close.
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
window.close();
|
||||||
|
},
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
override registerMenus(registry: MenuModelRegistry): void {
|
registerMenus(registry: MenuModelRegistry): void {
|
||||||
registry.registerMenuAction(ArduinoMenus.FILE__SKETCH_GROUP, {
|
registry.registerMenuAction(ArduinoMenus.FILE__SKETCH_GROUP, {
|
||||||
commandId: Close.Commands.CLOSE.id,
|
commandId: Close.Commands.CLOSE.id,
|
||||||
label: nls.localize('vscode/editor.contribution/close', 'Close'),
|
label: nls.localize('vscode/editor.contribution/close', 'Close'),
|
||||||
@@ -43,7 +114,7 @@ export class Close extends SketchContribution {
|
|||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
override registerKeybindings(registry: KeybindingRegistry): void {
|
registerKeybindings(registry: KeybindingRegistry): void {
|
||||||
registry.registerKeybinding({
|
registry.registerKeybinding({
|
||||||
command: Close.Commands.CLOSE.id,
|
command: Close.Commands.CLOSE.id,
|
||||||
keybinding: 'CtrlCmd+W',
|
keybinding: 'CtrlCmd+W',
|
||||||
|
@@ -1,656 +0,0 @@
|
|||||||
import {
|
|
||||||
Command,
|
|
||||||
CommandRegistry,
|
|
||||||
Disposable,
|
|
||||||
DisposableCollection,
|
|
||||||
Emitter,
|
|
||||||
MaybePromise,
|
|
||||||
nls,
|
|
||||||
notEmpty,
|
|
||||||
} from '@theia/core';
|
|
||||||
import { ApplicationShell, FrontendApplication } from '@theia/core/lib/browser';
|
|
||||||
import URI from '@theia/core/lib/common/uri';
|
|
||||||
import { inject, injectable } from '@theia/core/shared/inversify';
|
|
||||||
import {
|
|
||||||
Location,
|
|
||||||
Range,
|
|
||||||
} from '@theia/core/shared/vscode-languageserver-protocol';
|
|
||||||
import {
|
|
||||||
EditorWidget,
|
|
||||||
TextDocumentChangeEvent,
|
|
||||||
} from '@theia/editor/lib/browser';
|
|
||||||
import {
|
|
||||||
EditorDecoration,
|
|
||||||
TrackedRangeStickiness,
|
|
||||||
} from '@theia/editor/lib/browser/decorations/editor-decoration';
|
|
||||||
import { EditorManager } from '@theia/editor/lib/browser/editor-manager';
|
|
||||||
import * as monaco from '@theia/monaco-editor-core';
|
|
||||||
import { MonacoEditor } from '@theia/monaco/lib/browser/monaco-editor';
|
|
||||||
import { MonacoToProtocolConverter } from '@theia/monaco/lib/browser/monaco-to-protocol-converter';
|
|
||||||
import { ProtocolToMonacoConverter } from '@theia/monaco/lib/browser/protocol-to-monaco-converter';
|
|
||||||
import { CoreError } from '../../common/protocol/core-service';
|
|
||||||
import {
|
|
||||||
ArduinoPreferences,
|
|
||||||
ErrorRevealStrategy,
|
|
||||||
} from '../arduino-preferences';
|
|
||||||
import { InoSelector } from '../ino-selectors';
|
|
||||||
import { fullRange } from '../utils/monaco';
|
|
||||||
import { Contribution } from './contribution';
|
|
||||||
import { CoreErrorHandler } from './core-error-handler';
|
|
||||||
|
|
||||||
interface ErrorDecoration {
|
|
||||||
/**
|
|
||||||
* This is the unique ID of the decoration given by `monaco`.
|
|
||||||
*/
|
|
||||||
readonly id: string;
|
|
||||||
/**
|
|
||||||
* The resource this decoration belongs to.
|
|
||||||
*/
|
|
||||||
readonly uri: string;
|
|
||||||
}
|
|
||||||
namespace ErrorDecoration {
|
|
||||||
export function rangeOf(
|
|
||||||
{ id, uri }: ErrorDecoration,
|
|
||||||
editorProvider: (uri: string) => Promise<MonacoEditor | undefined>
|
|
||||||
): Promise<monaco.Range | undefined>;
|
|
||||||
export function rangeOf(
|
|
||||||
{ id, uri }: ErrorDecoration,
|
|
||||||
editorProvider: MonacoEditor
|
|
||||||
): monaco.Range | undefined;
|
|
||||||
export function rangeOf(
|
|
||||||
{ id, uri }: ErrorDecoration,
|
|
||||||
editorProvider:
|
|
||||||
| ((uri: string) => Promise<MonacoEditor | undefined>)
|
|
||||||
| MonacoEditor
|
|
||||||
): MaybePromise<monaco.Range | undefined> {
|
|
||||||
if (editorProvider instanceof MonacoEditor) {
|
|
||||||
const control = editorProvider.getControl();
|
|
||||||
const model = control.getModel();
|
|
||||||
if (model) {
|
|
||||||
return control
|
|
||||||
.getDecorationsInRange(fullRange(model))
|
|
||||||
?.find(({ id: candidateId }) => id === candidateId)?.range;
|
|
||||||
}
|
|
||||||
return undefined;
|
|
||||||
}
|
|
||||||
return editorProvider(uri).then((editor) => {
|
|
||||||
if (editor) {
|
|
||||||
return rangeOf({ id, uri }, editor);
|
|
||||||
}
|
|
||||||
return undefined;
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
// export async function rangeOf(
|
|
||||||
// { id, uri }: ErrorDecoration,
|
|
||||||
// editorProvider:
|
|
||||||
// | ((uri: string) => Promise<MonacoEditor | undefined>)
|
|
||||||
// | MonacoEditor
|
|
||||||
// ): Promise<monaco.Range | undefined> {
|
|
||||||
// const editor =
|
|
||||||
// editorProvider instanceof MonacoEditor
|
|
||||||
// ? editorProvider
|
|
||||||
// : await editorProvider(uri);
|
|
||||||
// if (editor) {
|
|
||||||
// const control = editor.getControl();
|
|
||||||
// const model = control.getModel();
|
|
||||||
// if (model) {
|
|
||||||
// return control
|
|
||||||
// .getDecorationsInRange(fullRange(model))
|
|
||||||
// ?.find(({ id: candidateId }) => id === candidateId)?.range;
|
|
||||||
// }
|
|
||||||
// }
|
|
||||||
// return undefined;
|
|
||||||
// }
|
|
||||||
export function sameAs(
|
|
||||||
left: ErrorDecoration,
|
|
||||||
right: ErrorDecoration
|
|
||||||
): boolean {
|
|
||||||
return left.id === right.id && left.uri === right.uri;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
@injectable()
|
|
||||||
export class CompilerErrors
|
|
||||||
extends Contribution
|
|
||||||
implements monaco.languages.CodeLensProvider
|
|
||||||
{
|
|
||||||
@inject(EditorManager)
|
|
||||||
private readonly editorManager: EditorManager;
|
|
||||||
|
|
||||||
@inject(ProtocolToMonacoConverter)
|
|
||||||
private readonly p2m: ProtocolToMonacoConverter;
|
|
||||||
|
|
||||||
@inject(MonacoToProtocolConverter)
|
|
||||||
private readonly mp2: MonacoToProtocolConverter;
|
|
||||||
|
|
||||||
@inject(CoreErrorHandler)
|
|
||||||
private readonly coreErrorHandler: CoreErrorHandler;
|
|
||||||
|
|
||||||
@inject(ArduinoPreferences)
|
|
||||||
private readonly preferences: ArduinoPreferences;
|
|
||||||
|
|
||||||
private readonly errors: ErrorDecoration[] = [];
|
|
||||||
private readonly onDidChangeEmitter = new monaco.Emitter<this>();
|
|
||||||
private readonly currentErrorDidChangEmitter = new Emitter<ErrorDecoration>();
|
|
||||||
private readonly onCurrentErrorDidChange =
|
|
||||||
this.currentErrorDidChangEmitter.event;
|
|
||||||
private readonly toDisposeOnCompilerErrorDidChange =
|
|
||||||
new DisposableCollection();
|
|
||||||
private shell: ApplicationShell | undefined;
|
|
||||||
private revealStrategy = ErrorRevealStrategy.Default;
|
|
||||||
private currentError: ErrorDecoration | undefined;
|
|
||||||
private get currentErrorIndex(): number {
|
|
||||||
const current = this.currentError;
|
|
||||||
if (!current) {
|
|
||||||
return -1;
|
|
||||||
}
|
|
||||||
return this.errors.findIndex((error) =>
|
|
||||||
ErrorDecoration.sameAs(error, current)
|
|
||||||
);
|
|
||||||
}
|
|
||||||
|
|
||||||
override onStart(app: FrontendApplication): void {
|
|
||||||
this.shell = app.shell;
|
|
||||||
monaco.languages.registerCodeLensProvider(InoSelector, this);
|
|
||||||
this.coreErrorHandler.onCompilerErrorsDidChange((errors) =>
|
|
||||||
this.filter(errors).then(this.handleCompilerErrorsDidChange.bind(this))
|
|
||||||
);
|
|
||||||
this.onCurrentErrorDidChange(async (error) => {
|
|
||||||
const range = await ErrorDecoration.rangeOf(error, (uri) =>
|
|
||||||
this.monacoEditor(uri)
|
|
||||||
);
|
|
||||||
if (!range) {
|
|
||||||
console.warn(
|
|
||||||
'compiler-errors',
|
|
||||||
`Could not find range of decoration: ${error.id}`
|
|
||||||
);
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
const editor = await this.revealLocationInEditor({
|
|
||||||
uri: error.uri,
|
|
||||||
range: this.mp2.asRange(range),
|
|
||||||
});
|
|
||||||
if (!editor) {
|
|
||||||
console.warn(
|
|
||||||
'compiler-errors',
|
|
||||||
`Failed to mark error ${error.id} as the current one.`
|
|
||||||
);
|
|
||||||
}
|
|
||||||
});
|
|
||||||
this.preferences.ready.then(() => {
|
|
||||||
this.preferences.onPreferenceChanged(({ preferenceName, newValue }) => {
|
|
||||||
if (preferenceName === 'arduino.compile.revealRange') {
|
|
||||||
this.revealStrategy = ErrorRevealStrategy.is(newValue)
|
|
||||||
? newValue
|
|
||||||
: ErrorRevealStrategy.Default;
|
|
||||||
}
|
|
||||||
});
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
override registerCommands(registry: CommandRegistry): void {
|
|
||||||
registry.registerCommand(CompilerErrors.Commands.NEXT_ERROR, {
|
|
||||||
execute: () => {
|
|
||||||
const index = this.currentErrorIndex;
|
|
||||||
if (index < 0) {
|
|
||||||
console.warn(
|
|
||||||
'compiler-errors',
|
|
||||||
`Could not advance to next error. Unknown current error.`
|
|
||||||
);
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
const nextError =
|
|
||||||
this.errors[index === this.errors.length - 1 ? 0 : index + 1];
|
|
||||||
this.markAsCurrentError(nextError);
|
|
||||||
},
|
|
||||||
isEnabled: () => !!this.currentError && this.errors.length > 1,
|
|
||||||
});
|
|
||||||
registry.registerCommand(CompilerErrors.Commands.PREVIOUS_ERROR, {
|
|
||||||
execute: () => {
|
|
||||||
const index = this.currentErrorIndex;
|
|
||||||
if (index < 0) {
|
|
||||||
console.warn(
|
|
||||||
'compiler-errors',
|
|
||||||
`Could not advance to previous error. Unknown current error.`
|
|
||||||
);
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
const previousError =
|
|
||||||
this.errors[index === 0 ? this.errors.length - 1 : index - 1];
|
|
||||||
this.markAsCurrentError(previousError);
|
|
||||||
},
|
|
||||||
isEnabled: () => !!this.currentError && this.errors.length > 1,
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
get onDidChange(): monaco.IEvent<this> {
|
|
||||||
return this.onDidChangeEmitter.event;
|
|
||||||
}
|
|
||||||
|
|
||||||
async provideCodeLenses(
|
|
||||||
model: monaco.editor.ITextModel,
|
|
||||||
// eslint-disable-next-line @typescript-eslint/no-unused-vars
|
|
||||||
_token: monaco.CancellationToken
|
|
||||||
): Promise<monaco.languages.CodeLensList> {
|
|
||||||
const lenses: monaco.languages.CodeLens[] = [];
|
|
||||||
if (
|
|
||||||
this.currentError &&
|
|
||||||
this.currentError.uri === model.uri.toString() &&
|
|
||||||
this.errors.length > 1
|
|
||||||
) {
|
|
||||||
const range = await ErrorDecoration.rangeOf(this.currentError, (uri) =>
|
|
||||||
this.monacoEditor(uri)
|
|
||||||
);
|
|
||||||
if (range) {
|
|
||||||
lenses.push(
|
|
||||||
{
|
|
||||||
range,
|
|
||||||
command: {
|
|
||||||
id: CompilerErrors.Commands.PREVIOUS_ERROR.id,
|
|
||||||
title: nls.localize(
|
|
||||||
'arduino/editor/previousError',
|
|
||||||
'Previous Error'
|
|
||||||
),
|
|
||||||
arguments: [this.currentError],
|
|
||||||
},
|
|
||||||
},
|
|
||||||
{
|
|
||||||
range,
|
|
||||||
command: {
|
|
||||||
id: CompilerErrors.Commands.NEXT_ERROR.id,
|
|
||||||
title: nls.localize('arduino/editor/nextError', 'Next Error'),
|
|
||||||
arguments: [this.currentError],
|
|
||||||
},
|
|
||||||
}
|
|
||||||
);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return {
|
|
||||||
lenses,
|
|
||||||
dispose: () => {
|
|
||||||
/* NOOP */
|
|
||||||
},
|
|
||||||
};
|
|
||||||
}
|
|
||||||
|
|
||||||
private async handleCompilerErrorsDidChange(
|
|
||||||
errors: CoreError.Compiler[]
|
|
||||||
): Promise<void> {
|
|
||||||
this.toDisposeOnCompilerErrorDidChange.dispose();
|
|
||||||
const compilerErrorsPerResource = this.groupByResource(
|
|
||||||
await this.filter(errors)
|
|
||||||
);
|
|
||||||
const decorations = await this.decorateEditors(compilerErrorsPerResource);
|
|
||||||
this.errors.push(...decorations.errors);
|
|
||||||
this.toDisposeOnCompilerErrorDidChange.pushAll([
|
|
||||||
Disposable.create(() => (this.errors.length = 0)),
|
|
||||||
Disposable.create(() => this.onDidChangeEmitter.fire(this)),
|
|
||||||
...(await Promise.all([
|
|
||||||
decorations.dispose,
|
|
||||||
this.trackEditors(
|
|
||||||
compilerErrorsPerResource,
|
|
||||||
(editor) =>
|
|
||||||
editor.editor.onSelectionChanged((selection) =>
|
|
||||||
this.handleSelectionChange(editor, selection)
|
|
||||||
),
|
|
||||||
(editor) =>
|
|
||||||
editor.onDidDispose(() =>
|
|
||||||
this.handleEditorDidDispose(editor.editor.uri.toString())
|
|
||||||
),
|
|
||||||
(editor) =>
|
|
||||||
editor.editor.onDocumentContentChanged((event) =>
|
|
||||||
this.handleDocumentContentChange(editor, event)
|
|
||||||
)
|
|
||||||
),
|
|
||||||
])),
|
|
||||||
]);
|
|
||||||
const currentError = this.errors[0];
|
|
||||||
if (currentError) {
|
|
||||||
await this.markAsCurrentError(currentError);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
private async filter(
|
|
||||||
errors: CoreError.Compiler[]
|
|
||||||
): Promise<CoreError.Compiler[]> {
|
|
||||||
if (!errors.length) {
|
|
||||||
return [];
|
|
||||||
}
|
|
||||||
await this.preferences.ready;
|
|
||||||
if (this.preferences['arduino.compile.experimental']) {
|
|
||||||
return errors;
|
|
||||||
}
|
|
||||||
// Always shows maximum one error; hence the code lens navigation is unavailable.
|
|
||||||
return [errors[0]];
|
|
||||||
}
|
|
||||||
|
|
||||||
private async decorateEditors(
|
|
||||||
errors: Map<string, CoreError.Compiler[]>
|
|
||||||
): Promise<{ dispose: Disposable; errors: ErrorDecoration[] }> {
|
|
||||||
const composite = await Promise.all(
|
|
||||||
[...errors.entries()].map(([uri, errors]) =>
|
|
||||||
this.decorateEditor(uri, errors)
|
|
||||||
)
|
|
||||||
);
|
|
||||||
return {
|
|
||||||
dispose: new DisposableCollection(
|
|
||||||
...composite.map(({ dispose }) => dispose)
|
|
||||||
),
|
|
||||||
errors: composite.reduce(
|
|
||||||
(acc, { errors }) => acc.concat(errors),
|
|
||||||
[] as ErrorDecoration[]
|
|
||||||
),
|
|
||||||
};
|
|
||||||
}
|
|
||||||
|
|
||||||
private async decorateEditor(
|
|
||||||
uri: string,
|
|
||||||
errors: CoreError.Compiler[]
|
|
||||||
): Promise<{ dispose: Disposable; errors: ErrorDecoration[] }> {
|
|
||||||
const editor = await this.editorManager.getByUri(new URI(uri));
|
|
||||||
if (!editor) {
|
|
||||||
return { dispose: Disposable.NULL, errors: [] };
|
|
||||||
}
|
|
||||||
const oldDecorations = editor.editor.deltaDecorations({
|
|
||||||
oldDecorations: [],
|
|
||||||
newDecorations: errors.map((error) =>
|
|
||||||
this.compilerErrorDecoration(error.location.range)
|
|
||||||
),
|
|
||||||
});
|
|
||||||
return {
|
|
||||||
dispose: Disposable.create(() => {
|
|
||||||
if (editor) {
|
|
||||||
editor.editor.deltaDecorations({
|
|
||||||
oldDecorations,
|
|
||||||
newDecorations: [],
|
|
||||||
});
|
|
||||||
}
|
|
||||||
}),
|
|
||||||
errors: oldDecorations.map((id) => ({ id, uri })),
|
|
||||||
};
|
|
||||||
}
|
|
||||||
|
|
||||||
private compilerErrorDecoration(range: Range): EditorDecoration {
|
|
||||||
return {
|
|
||||||
range,
|
|
||||||
options: {
|
|
||||||
isWholeLine: true,
|
|
||||||
className: 'compiler-error',
|
|
||||||
stickiness: TrackedRangeStickiness.AlwaysGrowsWhenTypingAtEdges,
|
|
||||||
},
|
|
||||||
};
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Tracks the selection in all editors that have an error. If the editor selection overlaps one of the compiler error's range, mark as current error.
|
|
||||||
*/
|
|
||||||
private handleSelectionChange(editor: EditorWidget, selection: Range): void {
|
|
||||||
const monacoEditor = this.monacoEditor(editor);
|
|
||||||
if (!monacoEditor) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
const uri = monacoEditor.uri.toString();
|
|
||||||
const monacoSelection = this.p2m.asRange(selection);
|
|
||||||
console.log(
|
|
||||||
'compiler-errors',
|
|
||||||
`Handling selection change in editor ${uri}. New (monaco) selection: ${monacoSelection.toJSON()}`
|
|
||||||
);
|
|
||||||
const calculatePriority = (
|
|
||||||
candidateErrorRange: monaco.Range,
|
|
||||||
currentSelection: monaco.Range
|
|
||||||
) => {
|
|
||||||
console.trace(
|
|
||||||
'compiler-errors',
|
|
||||||
`Candidate error range: ${candidateErrorRange.toJSON()}`
|
|
||||||
);
|
|
||||||
console.trace(
|
|
||||||
'compiler-errors',
|
|
||||||
`Current selection range: ${currentSelection.toJSON()}`
|
|
||||||
);
|
|
||||||
if (candidateErrorRange.intersectRanges(currentSelection)) {
|
|
||||||
console.trace('Intersects.');
|
|
||||||
return { score: 2 };
|
|
||||||
}
|
|
||||||
if (
|
|
||||||
candidateErrorRange.startLineNumber <=
|
|
||||||
currentSelection.startLineNumber &&
|
|
||||||
candidateErrorRange.endLineNumber >= currentSelection.endLineNumber
|
|
||||||
) {
|
|
||||||
console.trace('Same line.');
|
|
||||||
return { score: 1 };
|
|
||||||
}
|
|
||||||
|
|
||||||
console.trace('No match');
|
|
||||||
return undefined;
|
|
||||||
};
|
|
||||||
const error = this.errors
|
|
||||||
.filter((error) => error.uri === uri)
|
|
||||||
.map((error) => ({
|
|
||||||
error,
|
|
||||||
range: ErrorDecoration.rangeOf(error, monacoEditor),
|
|
||||||
}))
|
|
||||||
.map(({ error, range }) => {
|
|
||||||
if (range) {
|
|
||||||
const priority = calculatePriority(range, monacoSelection);
|
|
||||||
if (priority) {
|
|
||||||
return { ...priority, error };
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return undefined;
|
|
||||||
})
|
|
||||||
.filter(notEmpty)
|
|
||||||
.sort((left, right) => right.score - left.score) // highest first
|
|
||||||
.map(({ error }) => error)
|
|
||||||
.shift();
|
|
||||||
if (error) {
|
|
||||||
this.markAsCurrentError(error);
|
|
||||||
} else {
|
|
||||||
console.info(
|
|
||||||
'compiler-errors',
|
|
||||||
`New (monaco) selection ${monacoSelection.toJSON()} does not intersect any error locations. Skipping.`
|
|
||||||
);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* This code does not deal with resource deletion, but tracks editor dispose events. It does not matter what was the cause of the editor disposal.
|
|
||||||
* If editor closes, delete the decorators.
|
|
||||||
*/
|
|
||||||
private handleEditorDidDispose(uri: string): void {
|
|
||||||
let i = this.errors.length;
|
|
||||||
// `splice` re-indexes the array. It's better to "iterate and modify" from the last element.
|
|
||||||
while (i--) {
|
|
||||||
const error = this.errors[i];
|
|
||||||
if (error.uri === uri) {
|
|
||||||
this.errors.splice(i, 1);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
this.onDidChangeEmitter.fire(this);
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* If a document change "destroys" the range of the decoration, the decoration must be removed.
|
|
||||||
*/
|
|
||||||
private handleDocumentContentChange(
|
|
||||||
editor: EditorWidget,
|
|
||||||
event: TextDocumentChangeEvent
|
|
||||||
): void {
|
|
||||||
const monacoEditor = this.monacoEditor(editor);
|
|
||||||
if (!monacoEditor) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
// A decoration location can be "destroyed", hence should be deleted when:
|
|
||||||
// - deleting range (start != end AND text is empty)
|
|
||||||
// - inserting text into range (start != end AND text is not empty)
|
|
||||||
// Filter unrelated delta changes to spare the CPU.
|
|
||||||
const relevantChanges = event.contentChanges.filter(
|
|
||||||
({ range: { start, end } }) =>
|
|
||||||
start.line !== end.line || start.character !== end.character
|
|
||||||
);
|
|
||||||
if (!relevantChanges.length) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
const resolvedMarkers = this.errors
|
|
||||||
.filter((error) => error.uri === event.document.uri)
|
|
||||||
.map((error, index) => {
|
|
||||||
const range = ErrorDecoration.rangeOf(error, monacoEditor);
|
|
||||||
if (range) {
|
|
||||||
return { error, range, index };
|
|
||||||
}
|
|
||||||
return undefined;
|
|
||||||
})
|
|
||||||
.filter(notEmpty);
|
|
||||||
|
|
||||||
const decorationIdsToRemove = relevantChanges
|
|
||||||
.map(({ range }) => this.p2m.asRange(range))
|
|
||||||
.map((changeRange) =>
|
|
||||||
resolvedMarkers.filter(({ range: decorationRange }) =>
|
|
||||||
changeRange.containsRange(decorationRange)
|
|
||||||
)
|
|
||||||
)
|
|
||||||
.reduce((acc, curr) => acc.concat(curr), [])
|
|
||||||
.map(({ error, index }) => {
|
|
||||||
this.errors.splice(index, 1);
|
|
||||||
return error.id;
|
|
||||||
});
|
|
||||||
if (!decorationIdsToRemove.length) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
monacoEditor.getControl().deltaDecorations(decorationIdsToRemove, []);
|
|
||||||
this.onDidChangeEmitter.fire(this);
|
|
||||||
}
|
|
||||||
|
|
||||||
private async trackEditors(
|
|
||||||
errors: Map<string, CoreError.Compiler[]>,
|
|
||||||
...track: ((editor: EditorWidget) => Disposable)[]
|
|
||||||
): Promise<Disposable> {
|
|
||||||
return new DisposableCollection(
|
|
||||||
...(await Promise.all(
|
|
||||||
Array.from(errors.keys()).map(async (uri) => {
|
|
||||||
const editor = await this.editorManager.getByUri(new URI(uri));
|
|
||||||
if (!editor) {
|
|
||||||
return Disposable.NULL;
|
|
||||||
}
|
|
||||||
return new DisposableCollection(...track.map((t) => t(editor)));
|
|
||||||
})
|
|
||||||
))
|
|
||||||
);
|
|
||||||
}
|
|
||||||
|
|
||||||
private async markAsCurrentError(error: ErrorDecoration): Promise<void> {
|
|
||||||
const index = this.errors.findIndex((candidate) =>
|
|
||||||
ErrorDecoration.sameAs(candidate, error)
|
|
||||||
);
|
|
||||||
if (index < 0) {
|
|
||||||
console.warn(
|
|
||||||
'compiler-errors',
|
|
||||||
`Failed to mark error ${
|
|
||||||
error.id
|
|
||||||
} as the current one. Error is unknown. Known errors are: ${this.errors.map(
|
|
||||||
({ id }) => id
|
|
||||||
)}`
|
|
||||||
);
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
const newError = this.errors[index];
|
|
||||||
if (
|
|
||||||
!this.currentError ||
|
|
||||||
!ErrorDecoration.sameAs(this.currentError, newError)
|
|
||||||
) {
|
|
||||||
this.currentError = this.errors[index];
|
|
||||||
console.log(
|
|
||||||
'compiler-errors',
|
|
||||||
`Current error changed to ${this.currentError.id}`
|
|
||||||
);
|
|
||||||
this.currentErrorDidChangEmitter.fire(this.currentError);
|
|
||||||
this.onDidChangeEmitter.fire(this);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// The double editor activation logic is required: https://github.com/eclipse-theia/theia/issues/11284
|
|
||||||
private async revealLocationInEditor(
|
|
||||||
location: Location
|
|
||||||
): Promise<EditorWidget | undefined> {
|
|
||||||
const { uri, range } = location;
|
|
||||||
const editor = await this.editorManager.getByUri(new URI(uri), {
|
|
||||||
mode: 'activate',
|
|
||||||
});
|
|
||||||
if (editor && this.shell) {
|
|
||||||
// to avoid flickering, reveal the range here and not with `getByUri`, because it uses `at: 'center'` for the reveal option.
|
|
||||||
// TODO: check the community reaction whether it is better to set the focus at the error marker. it might cause flickering even if errors are close to each other
|
|
||||||
editor.editor.revealRange(range, { at: this.revealStrategy });
|
|
||||||
const activeWidget = await this.shell.activateWidget(editor.id);
|
|
||||||
if (!activeWidget) {
|
|
||||||
console.warn(
|
|
||||||
'compiler-errors',
|
|
||||||
`editor widget activation has failed. editor widget ${editor.id} expected to be the active one.`
|
|
||||||
);
|
|
||||||
return editor;
|
|
||||||
}
|
|
||||||
if (editor !== activeWidget) {
|
|
||||||
console.warn(
|
|
||||||
'compiler-errors',
|
|
||||||
`active widget was not the same as previously activated editor. editor widget ID ${editor.id}, active widget ID: ${activeWidget.id}`
|
|
||||||
);
|
|
||||||
}
|
|
||||||
return editor;
|
|
||||||
}
|
|
||||||
console.warn(
|
|
||||||
'compiler-errors',
|
|
||||||
`could not found editor widget for URI: ${uri}`
|
|
||||||
);
|
|
||||||
return undefined;
|
|
||||||
}
|
|
||||||
|
|
||||||
private groupByResource(
|
|
||||||
errors: CoreError.Compiler[]
|
|
||||||
): Map<string, CoreError.Compiler[]> {
|
|
||||||
return errors.reduce((acc, curr) => {
|
|
||||||
const {
|
|
||||||
location: { uri },
|
|
||||||
} = curr;
|
|
||||||
let errors = acc.get(uri);
|
|
||||||
if (!errors) {
|
|
||||||
errors = [];
|
|
||||||
acc.set(uri, errors);
|
|
||||||
}
|
|
||||||
errors.push(curr);
|
|
||||||
return acc;
|
|
||||||
}, new Map<string, CoreError.Compiler[]>());
|
|
||||||
}
|
|
||||||
|
|
||||||
private monacoEditor(widget: EditorWidget): MonacoEditor | undefined;
|
|
||||||
private monacoEditor(uri: string): Promise<MonacoEditor | undefined>;
|
|
||||||
private monacoEditor(
|
|
||||||
uriOrWidget: string | EditorWidget
|
|
||||||
): MaybePromise<MonacoEditor | undefined> {
|
|
||||||
if (uriOrWidget instanceof EditorWidget) {
|
|
||||||
const editor = uriOrWidget.editor;
|
|
||||||
if (editor instanceof MonacoEditor) {
|
|
||||||
return editor;
|
|
||||||
}
|
|
||||||
return undefined;
|
|
||||||
} else {
|
|
||||||
return this.editorManager
|
|
||||||
.getByUri(new URI(uriOrWidget))
|
|
||||||
.then((editor) => {
|
|
||||||
if (editor) {
|
|
||||||
return this.monacoEditor(editor);
|
|
||||||
}
|
|
||||||
return undefined;
|
|
||||||
});
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
export namespace CompilerErrors {
|
|
||||||
export namespace Commands {
|
|
||||||
export const NEXT_ERROR: Command = {
|
|
||||||
id: 'arduino-editor-next-error',
|
|
||||||
};
|
|
||||||
export const PREVIOUS_ERROR: Command = {
|
|
||||||
id: 'arduino-editor-previous-error',
|
|
||||||
};
|
|
||||||
}
|
|
||||||
}
|
|
@@ -1,9 +1,4 @@
|
|||||||
import {
|
import { inject, injectable, interfaces } from 'inversify';
|
||||||
inject,
|
|
||||||
injectable,
|
|
||||||
interfaces,
|
|
||||||
postConstruct,
|
|
||||||
} from '@theia/core/shared/inversify';
|
|
||||||
import URI from '@theia/core/lib/common/uri';
|
import URI from '@theia/core/lib/common/uri';
|
||||||
import { ILogger } from '@theia/core/lib/common/logger';
|
import { ILogger } from '@theia/core/lib/common/logger';
|
||||||
import { Saveable } from '@theia/core/lib/browser/saveable';
|
import { Saveable } from '@theia/core/lib/browser/saveable';
|
||||||
@@ -14,7 +9,7 @@ import { EditorManager } from '@theia/editor/lib/browser/editor-manager';
|
|||||||
import { MessageService } from '@theia/core/lib/common/message-service';
|
import { MessageService } from '@theia/core/lib/common/message-service';
|
||||||
import { WorkspaceService } from '@theia/workspace/lib/browser/workspace-service';
|
import { WorkspaceService } from '@theia/workspace/lib/browser/workspace-service';
|
||||||
import { open, OpenerService } from '@theia/core/lib/browser/opener-service';
|
import { open, OpenerService } from '@theia/core/lib/browser/opener-service';
|
||||||
|
import { OutputChannelManager } from '@theia/output/lib/browser/output-channel';
|
||||||
import {
|
import {
|
||||||
MenuModelRegistry,
|
MenuModelRegistry,
|
||||||
MenuContribution,
|
MenuContribution,
|
||||||
@@ -39,24 +34,14 @@ import {
|
|||||||
} from '@theia/core/lib/common/command';
|
} from '@theia/core/lib/common/command';
|
||||||
import { EditorMode } from '../editor-mode';
|
import { EditorMode } from '../editor-mode';
|
||||||
import { SettingsService } from '../dialogs/settings/settings';
|
import { SettingsService } from '../dialogs/settings/settings';
|
||||||
import {
|
import { SketchesServiceClientImpl } from '../../common/protocol/sketches-service-client-impl';
|
||||||
CurrentSketch,
|
|
||||||
SketchesServiceClientImpl,
|
|
||||||
} from '../../common/protocol/sketches-service-client-impl';
|
|
||||||
import {
|
import {
|
||||||
SketchesService,
|
SketchesService,
|
||||||
ConfigService,
|
ConfigService,
|
||||||
FileSystemExt,
|
FileSystemExt,
|
||||||
Sketch,
|
Sketch,
|
||||||
CoreService,
|
|
||||||
CoreError,
|
|
||||||
} from '../../common/protocol';
|
} from '../../common/protocol';
|
||||||
import { ArduinoPreferences } from '../arduino-preferences';
|
import { ArduinoPreferences } from '../arduino-preferences';
|
||||||
import { FrontendApplicationStateService } from '@theia/core/lib/browser/frontend-application-state';
|
|
||||||
import { CoreErrorHandler } from './core-error-handler';
|
|
||||||
import { nls } from '@theia/core';
|
|
||||||
import { OutputChannelManager } from '../theia/output/output-channel';
|
|
||||||
import { ClipboardService } from '@theia/core/lib/browser/clipboard-service';
|
|
||||||
|
|
||||||
export {
|
export {
|
||||||
Command,
|
Command,
|
||||||
@@ -99,31 +84,15 @@ export abstract class Contribution
|
|||||||
@inject(SettingsService)
|
@inject(SettingsService)
|
||||||
protected readonly settingsService: SettingsService;
|
protected readonly settingsService: SettingsService;
|
||||||
|
|
||||||
@inject(FrontendApplicationStateService)
|
|
||||||
protected readonly appStateService: FrontendApplicationStateService;
|
|
||||||
|
|
||||||
@postConstruct()
|
|
||||||
protected init(): void {
|
|
||||||
this.appStateService.reachedState('ready').then(() => this.onReady());
|
|
||||||
}
|
|
||||||
|
|
||||||
// eslint-disable-next-line @typescript-eslint/no-unused-vars, @typescript-eslint/no-empty-function, unused-imports/no-unused-vars
|
|
||||||
onStart(app: FrontendApplication): MaybePromise<void> {}
|
onStart(app: FrontendApplication): MaybePromise<void> {}
|
||||||
|
|
||||||
// eslint-disable-next-line @typescript-eslint/no-unused-vars, @typescript-eslint/no-empty-function, unused-imports/no-unused-vars
|
|
||||||
registerCommands(registry: CommandRegistry): void {}
|
registerCommands(registry: CommandRegistry): void {}
|
||||||
|
|
||||||
// eslint-disable-next-line @typescript-eslint/no-unused-vars, @typescript-eslint/no-empty-function, unused-imports/no-unused-vars
|
|
||||||
registerMenus(registry: MenuModelRegistry): void {}
|
registerMenus(registry: MenuModelRegistry): void {}
|
||||||
|
|
||||||
// eslint-disable-next-line @typescript-eslint/no-unused-vars, @typescript-eslint/no-empty-function, unused-imports/no-unused-vars
|
|
||||||
registerKeybindings(registry: KeybindingRegistry): void {}
|
registerKeybindings(registry: KeybindingRegistry): void {}
|
||||||
|
|
||||||
// eslint-disable-next-line @typescript-eslint/no-unused-vars, @typescript-eslint/no-empty-function, unused-imports/no-unused-vars
|
|
||||||
registerToolbarItems(registry: TabBarToolbarRegistry): void {}
|
registerToolbarItems(registry: TabBarToolbarRegistry): void {}
|
||||||
|
|
||||||
// eslint-disable-next-line @typescript-eslint/no-empty-function
|
|
||||||
onReady(): MaybePromise<void> {}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@injectable()
|
@injectable()
|
||||||
@@ -158,7 +127,7 @@ export abstract class SketchContribution extends Contribution {
|
|||||||
protected async sourceOverride(): Promise<Record<string, string>> {
|
protected async sourceOverride(): Promise<Record<string, string>> {
|
||||||
const override: Record<string, string> = {};
|
const override: Record<string, string> = {};
|
||||||
const sketch = await this.sketchServiceClient.currentSketch();
|
const sketch = await this.sketchServiceClient.currentSketch();
|
||||||
if (CurrentSketch.isValid(sketch)) {
|
if (sketch) {
|
||||||
for (const editor of this.editorManager.all) {
|
for (const editor of this.editorManager.all) {
|
||||||
const uri = editor.editor.uri;
|
const uri = editor.editor.uri;
|
||||||
if (Saveable.isDirty(editor) && Sketch.isInSketch(uri, sketch)) {
|
if (Saveable.isDirty(editor) && Sketch.isInSketch(uri, sketch)) {
|
||||||
@@ -170,58 +139,8 @@ export abstract class SketchContribution extends Contribution {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@injectable()
|
|
||||||
export class CoreServiceContribution extends SketchContribution {
|
|
||||||
@inject(CoreService)
|
|
||||||
protected readonly coreService: CoreService;
|
|
||||||
|
|
||||||
@inject(CoreErrorHandler)
|
|
||||||
protected readonly coreErrorHandler: CoreErrorHandler;
|
|
||||||
|
|
||||||
@inject(ClipboardService)
|
|
||||||
private readonly clipboardService: ClipboardService;
|
|
||||||
|
|
||||||
protected handleError(error: unknown): void {
|
|
||||||
this.coreErrorHandler.tryHandle(error);
|
|
||||||
this.tryToastErrorMessage(error);
|
|
||||||
}
|
|
||||||
|
|
||||||
private tryToastErrorMessage(error: unknown): void {
|
|
||||||
let message: undefined | string = undefined;
|
|
||||||
if (CoreError.is(error)) {
|
|
||||||
message = error.message;
|
|
||||||
} else if (error instanceof Error) {
|
|
||||||
message = error.message;
|
|
||||||
} else if (typeof error === 'string') {
|
|
||||||
message = error;
|
|
||||||
} else {
|
|
||||||
try {
|
|
||||||
message = JSON.stringify(error);
|
|
||||||
} catch {}
|
|
||||||
}
|
|
||||||
if (message) {
|
|
||||||
const copyAction = nls.localize(
|
|
||||||
'arduino/coreContribution/copyError',
|
|
||||||
'Copy error messages'
|
|
||||||
);
|
|
||||||
this.messageService.error(message, copyAction).then(async (action) => {
|
|
||||||
if (action === copyAction) {
|
|
||||||
const content = await this.outputChannelManager.contentOfChannel(
|
|
||||||
'Arduino'
|
|
||||||
);
|
|
||||||
if (content) {
|
|
||||||
this.clipboardService.writeText(content);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
});
|
|
||||||
} else {
|
|
||||||
throw error;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
export namespace Contribution {
|
export namespace Contribution {
|
||||||
export function configure(
|
export function configure<T>(
|
||||||
bind: interfaces.Bind,
|
bind: interfaces.Bind,
|
||||||
serviceIdentifier: typeof Contribution
|
serviceIdentifier: typeof Contribution
|
||||||
): void {
|
): void {
|
||||||
|
@@ -1,32 +0,0 @@
|
|||||||
import { Emitter, Event } from '@theia/core';
|
|
||||||
import { injectable } from '@theia/core/shared/inversify';
|
|
||||||
import { CoreError } from '../../common/protocol/core-service';
|
|
||||||
|
|
||||||
@injectable()
|
|
||||||
export class CoreErrorHandler {
|
|
||||||
private readonly compilerErrors: CoreError.Compiler[] = [];
|
|
||||||
private readonly compilerErrorsDidChangeEmitter = new Emitter<
|
|
||||||
CoreError.Compiler[]
|
|
||||||
>();
|
|
||||||
|
|
||||||
tryHandle(error: unknown): void {
|
|
||||||
if (CoreError.is(error)) {
|
|
||||||
this.compilerErrors.length = 0;
|
|
||||||
this.compilerErrors.push(...error.data.filter(CoreError.Compiler.is));
|
|
||||||
this.fireCompilerErrorsDidChange();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
reset(): void {
|
|
||||||
this.compilerErrors.length = 0;
|
|
||||||
this.fireCompilerErrorsDidChange();
|
|
||||||
}
|
|
||||||
|
|
||||||
get onCompilerErrorsDidChange(): Event<CoreError.Compiler[]> {
|
|
||||||
return this.compilerErrorsDidChangeEmitter.event;
|
|
||||||
}
|
|
||||||
|
|
||||||
private fireCompilerErrorsDidChange(): void {
|
|
||||||
this.compilerErrorsDidChangeEmitter.fire(this.compilerErrors.slice());
|
|
||||||
}
|
|
||||||
}
|
|
@@ -1,4 +1,4 @@
|
|||||||
import { inject, injectable } from '@theia/core/shared/inversify';
|
import { inject, injectable } from 'inversify';
|
||||||
import { Event, Emitter } from '@theia/core/lib/common/event';
|
import { Event, Emitter } from '@theia/core/lib/common/event';
|
||||||
import { HostedPluginSupport } from '@theia/plugin-ext/lib/hosted/browser/hosted-plugin';
|
import { HostedPluginSupport } from '@theia/plugin-ext/lib/hosted/browser/hosted-plugin';
|
||||||
import { ArduinoToolbar } from '../toolbar/arduino-toolbar';
|
import { ArduinoToolbar } from '../toolbar/arduino-toolbar';
|
||||||
@@ -12,8 +12,7 @@ import {
|
|||||||
SketchContribution,
|
SketchContribution,
|
||||||
TabBarToolbarRegistry,
|
TabBarToolbarRegistry,
|
||||||
} from './contribution';
|
} from './contribution';
|
||||||
import { MaybePromise, nls } from '@theia/core/lib/common';
|
import { nls } from '@theia/core/lib/common';
|
||||||
import { CurrentSketch } from '../../common/protocol/sketches-service-client-impl';
|
|
||||||
|
|
||||||
@injectable()
|
@injectable()
|
||||||
export class Debug extends SketchContribution {
|
export class Debug extends SketchContribution {
|
||||||
@@ -67,7 +66,7 @@ export class Debug extends SketchContribution {
|
|||||||
onDidChange: this.onDisabledMessageDidChange as Event<void>,
|
onDidChange: this.onDisabledMessageDidChange as Event<void>,
|
||||||
};
|
};
|
||||||
|
|
||||||
override onStart(): void {
|
onStart(): void {
|
||||||
this.onDisabledMessageDidChange(
|
this.onDisabledMessageDidChange(
|
||||||
() =>
|
() =>
|
||||||
(this.debugToolbarItem.tooltip = `${
|
(this.debugToolbarItem.tooltip = `${
|
||||||
@@ -80,18 +79,55 @@ export class Debug extends SketchContribution {
|
|||||||
: Debug.Commands.START_DEBUGGING.label
|
: Debug.Commands.START_DEBUGGING.label
|
||||||
}`)
|
}`)
|
||||||
);
|
);
|
||||||
|
const refreshState = async (
|
||||||
|
board: Board | undefined = this.boardsServiceProvider.boardsConfig
|
||||||
|
.selectedBoard
|
||||||
|
) => {
|
||||||
|
if (!board) {
|
||||||
|
this.disabledMessage = nls.localize(
|
||||||
|
'arduino/common/noBoardSelected',
|
||||||
|
'No board selected'
|
||||||
|
);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
const fqbn = board.fqbn;
|
||||||
|
if (!fqbn) {
|
||||||
|
this.disabledMessage = nls.localize(
|
||||||
|
'arduino/debug/noPlatformInstalledFor',
|
||||||
|
"Platform is not installed for '{0}'",
|
||||||
|
board.name
|
||||||
|
);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
const details = await this.boardService.getBoardDetails({ fqbn });
|
||||||
|
if (!details) {
|
||||||
|
this.disabledMessage = nls.localize(
|
||||||
|
'arduino/debug/noPlatformInstalledFor',
|
||||||
|
"Platform is not installed for '{0}'",
|
||||||
|
board.name
|
||||||
|
);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
const { debuggingSupported } = details;
|
||||||
|
if (!debuggingSupported) {
|
||||||
|
this.disabledMessage = nls.localize(
|
||||||
|
'arduino/debug/debuggingNotSupported',
|
||||||
|
"Debugging is not supported by '{0}'",
|
||||||
|
board.name
|
||||||
|
);
|
||||||
|
} else {
|
||||||
|
this.disabledMessage = undefined;
|
||||||
|
}
|
||||||
|
};
|
||||||
this.boardsServiceProvider.onBoardsConfigChanged(({ selectedBoard }) =>
|
this.boardsServiceProvider.onBoardsConfigChanged(({ selectedBoard }) =>
|
||||||
this.refreshState(selectedBoard)
|
refreshState(selectedBoard)
|
||||||
);
|
);
|
||||||
this.notificationCenter.onPlatformInstalled(() => this.refreshState());
|
this.notificationCenter.onPlatformInstalled(() => refreshState());
|
||||||
this.notificationCenter.onPlatformUninstalled(() => this.refreshState());
|
this.notificationCenter.onPlatformUninstalled(() => refreshState());
|
||||||
|
refreshState();
|
||||||
}
|
}
|
||||||
|
|
||||||
override onReady(): MaybePromise<void> {
|
registerCommands(registry: CommandRegistry): void {
|
||||||
this.refreshState();
|
|
||||||
}
|
|
||||||
|
|
||||||
override registerCommands(registry: CommandRegistry): void {
|
|
||||||
registry.registerCommand(Debug.Commands.START_DEBUGGING, {
|
registry.registerCommand(Debug.Commands.START_DEBUGGING, {
|
||||||
execute: () => this.startDebug(),
|
execute: () => this.startDebug(),
|
||||||
isVisible: (widget) =>
|
isVisible: (widget) =>
|
||||||
@@ -100,51 +136,10 @@ export class Debug extends SketchContribution {
|
|||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
override registerToolbarItems(registry: TabBarToolbarRegistry): void {
|
registerToolbarItems(registry: TabBarToolbarRegistry): void {
|
||||||
registry.registerItem(this.debugToolbarItem);
|
registry.registerItem(this.debugToolbarItem);
|
||||||
}
|
}
|
||||||
|
|
||||||
private async refreshState(
|
|
||||||
board: Board | undefined = this.boardsServiceProvider.boardsConfig
|
|
||||||
.selectedBoard
|
|
||||||
): Promise<void> {
|
|
||||||
if (!board) {
|
|
||||||
this.disabledMessage = nls.localize(
|
|
||||||
'arduino/common/noBoardSelected',
|
|
||||||
'No board selected'
|
|
||||||
);
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
const fqbn = board.fqbn;
|
|
||||||
if (!fqbn) {
|
|
||||||
this.disabledMessage = nls.localize(
|
|
||||||
'arduino/debug/noPlatformInstalledFor',
|
|
||||||
"Platform is not installed for '{0}'",
|
|
||||||
board.name
|
|
||||||
);
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
const details = await this.boardService.getBoardDetails({ fqbn });
|
|
||||||
if (!details) {
|
|
||||||
this.disabledMessage = nls.localize(
|
|
||||||
'arduino/debug/noPlatformInstalledFor',
|
|
||||||
"Platform is not installed for '{0}'",
|
|
||||||
board.name
|
|
||||||
);
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
const { debuggingSupported } = details;
|
|
||||||
if (!debuggingSupported) {
|
|
||||||
this.disabledMessage = nls.localize(
|
|
||||||
'arduino/debug/debuggingNotSupported',
|
|
||||||
"Debugging is not supported by '{0}'",
|
|
||||||
board.name
|
|
||||||
);
|
|
||||||
} else {
|
|
||||||
this.disabledMessage = undefined;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
protected async startDebug(
|
protected async startDebug(
|
||||||
board: Board | undefined = this.boardsServiceProvider.boardsConfig
|
board: Board | undefined = this.boardsServiceProvider.boardsConfig
|
||||||
.selectedBoard
|
.selectedBoard
|
||||||
@@ -161,7 +156,7 @@ export class Debug extends SketchContribution {
|
|||||||
this.sketchServiceClient.currentSketch(),
|
this.sketchServiceClient.currentSketch(),
|
||||||
this.executableService.list(),
|
this.executableService.list(),
|
||||||
]);
|
]);
|
||||||
if (!CurrentSketch.isValid(sketch)) {
|
if (!sketch) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
const ideTempFolderUri = await this.sketchService.getIdeTempFolderUri(
|
const ideTempFolderUri = await this.sketchService.getIdeTempFolderUri(
|
||||||
|
@@ -1,4 +1,4 @@
|
|||||||
import { inject, injectable } from '@theia/core/shared/inversify';
|
import { inject, injectable } from 'inversify';
|
||||||
import { CommonCommands } from '@theia/core/lib/browser/common-frontend-contribution';
|
import { CommonCommands } from '@theia/core/lib/browser/common-frontend-contribution';
|
||||||
import { ClipboardService } from '@theia/core/lib/browser/clipboard-service';
|
import { ClipboardService } from '@theia/core/lib/browser/clipboard-service';
|
||||||
import { PreferenceService } from '@theia/core/lib/browser/preferences/preference-service';
|
import { PreferenceService } from '@theia/core/lib/browser/preferences/preference-service';
|
||||||
@@ -12,8 +12,6 @@ import {
|
|||||||
} from './contribution';
|
} from './contribution';
|
||||||
import { ArduinoMenus } from '../menu/arduino-menus';
|
import { ArduinoMenus } from '../menu/arduino-menus';
|
||||||
import { nls } from '@theia/core/lib/common';
|
import { nls } from '@theia/core/lib/common';
|
||||||
import type { ICodeEditor } from '@theia/monaco-editor-core/esm/vs/editor/browser/editorBrowser';
|
|
||||||
import type { StandaloneCodeEditor } from '@theia/monaco-editor-core/esm/vs/editor/standalone/browser/standaloneCodeEditor';
|
|
||||||
|
|
||||||
// TODO: [macOS]: to remove `Start Dictation...` and `Emoji & Symbol` see this thread: https://github.com/electron/electron/issues/8283#issuecomment-269522072
|
// TODO: [macOS]: to remove `Start Dictation...` and `Emoji & Symbol` see this thread: https://github.com/electron/electron/issues/8283#issuecomment-269522072
|
||||||
// Depends on https://github.com/eclipse-theia/theia/pull/7964
|
// Depends on https://github.com/eclipse-theia/theia/pull/7964
|
||||||
@@ -28,7 +26,7 @@ export class EditContributions extends Contribution {
|
|||||||
@inject(PreferenceService)
|
@inject(PreferenceService)
|
||||||
protected readonly preferences: PreferenceService;
|
protected readonly preferences: PreferenceService;
|
||||||
|
|
||||||
override registerCommands(registry: CommandRegistry): void {
|
registerCommands(registry: CommandRegistry): void {
|
||||||
registry.registerCommand(EditContributions.Commands.GO_TO_LINE, {
|
registry.registerCommand(EditContributions.Commands.GO_TO_LINE, {
|
||||||
execute: () => this.run('editor.action.gotoLine'),
|
execute: () => this.run('editor.action.gotoLine'),
|
||||||
});
|
});
|
||||||
@@ -93,7 +91,7 @@ ${value}
|
|||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
override registerMenus(registry: MenuModelRegistry): void {
|
registerMenus(registry: MenuModelRegistry): void {
|
||||||
registry.registerMenuAction(ArduinoMenus.EDIT__TEXT_CONTROL_GROUP, {
|
registry.registerMenuAction(ArduinoMenus.EDIT__TEXT_CONTROL_GROUP, {
|
||||||
commandId: CommonCommands.CUT.id,
|
commandId: CommonCommands.CUT.id,
|
||||||
order: '0',
|
order: '0',
|
||||||
@@ -201,7 +199,7 @@ ${value}
|
|||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
override registerKeybindings(registry: KeybindingRegistry): void {
|
registerKeybindings(registry: KeybindingRegistry): void {
|
||||||
registry.registerKeybinding({
|
registry.registerKeybinding({
|
||||||
command: EditContributions.Commands.COPY_FOR_FORUM.id,
|
command: EditContributions.Commands.COPY_FOR_FORUM.id,
|
||||||
keybinding: 'CtrlCmd+Shift+C',
|
keybinding: 'CtrlCmd+Shift+C',
|
||||||
@@ -252,10 +250,10 @@ ${value}
|
|||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
protected async current(): Promise<ICodeEditor | StandaloneCodeEditor | undefined> {
|
protected async current(): Promise<monaco.editor.ICodeEditor | undefined> {
|
||||||
return (
|
return (
|
||||||
this.codeEditorService.getFocusedCodeEditor() ||
|
this.codeEditorService.getFocusedCodeEditor() ||
|
||||||
this.codeEditorService.getActiveCodeEditor() || undefined
|
this.codeEditorService.getActiveCodeEditor()
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@@ -1,5 +1,5 @@
|
|||||||
import * as PQueue from 'p-queue';
|
import * as PQueue from 'p-queue';
|
||||||
import { inject, injectable } from '@theia/core/shared/inversify';
|
import { inject, injectable, postConstruct } from 'inversify';
|
||||||
import { CommandHandler } from '@theia/core/lib/common/command';
|
import { CommandHandler } from '@theia/core/lib/common/command';
|
||||||
import {
|
import {
|
||||||
MenuPath,
|
MenuPath,
|
||||||
@@ -21,7 +21,7 @@ import {
|
|||||||
MenuModelRegistry,
|
MenuModelRegistry,
|
||||||
} from './contribution';
|
} from './contribution';
|
||||||
import { NotificationCenter } from '../notification-center';
|
import { NotificationCenter } from '../notification-center';
|
||||||
import { Board, SketchRef, SketchContainer } from '../../common/protocol';
|
import { Board, Sketch, SketchContainer } from '../../common/protocol';
|
||||||
import { nls } from '@theia/core/lib/common';
|
import { nls } from '@theia/core/lib/common';
|
||||||
|
|
||||||
@injectable()
|
@injectable()
|
||||||
@@ -43,8 +43,8 @@ export abstract class Examples extends SketchContribution {
|
|||||||
|
|
||||||
protected readonly toDispose = new DisposableCollection();
|
protected readonly toDispose = new DisposableCollection();
|
||||||
|
|
||||||
protected override init(): void {
|
@postConstruct()
|
||||||
super.init();
|
init(): void {
|
||||||
this.boardsServiceClient.onBoardsConfigChanged(({ selectedBoard }) =>
|
this.boardsServiceClient.onBoardsConfigChanged(({ selectedBoard }) =>
|
||||||
this.handleBoardChanged(selectedBoard)
|
this.handleBoardChanged(selectedBoard)
|
||||||
);
|
);
|
||||||
@@ -54,7 +54,7 @@ export abstract class Examples extends SketchContribution {
|
|||||||
// NOOP
|
// NOOP
|
||||||
}
|
}
|
||||||
|
|
||||||
override registerMenus(registry: MenuModelRegistry): void {
|
registerMenus(registry: MenuModelRegistry): void {
|
||||||
try {
|
try {
|
||||||
// This is a hack the ensures the desired menu ordering! We cannot use https://github.com/eclipse-theia/theia/pull/8377 due to ATL-222.
|
// This is a hack the ensures the desired menu ordering! We cannot use https://github.com/eclipse-theia/theia/pull/8377 due to ATL-222.
|
||||||
const index = ArduinoMenus.FILE__EXAMPLES_SUBMENU.length - 1;
|
const index = ArduinoMenus.FILE__EXAMPLES_SUBMENU.length - 1;
|
||||||
@@ -82,7 +82,7 @@ export abstract class Examples extends SketchContribution {
|
|||||||
registerRecursively(
|
registerRecursively(
|
||||||
sketchContainerOrPlaceholder:
|
sketchContainerOrPlaceholder:
|
||||||
| SketchContainer
|
| SketchContainer
|
||||||
| (SketchRef | SketchContainer)[]
|
| (Sketch | SketchContainer)[]
|
||||||
| string,
|
| string,
|
||||||
menuPath: MenuPath,
|
menuPath: MenuPath,
|
||||||
pushToDispose: DisposableCollection = new DisposableCollection(),
|
pushToDispose: DisposableCollection = new DisposableCollection(),
|
||||||
@@ -100,7 +100,7 @@ export abstract class Examples extends SketchContribution {
|
|||||||
)
|
)
|
||||||
);
|
);
|
||||||
} else {
|
} else {
|
||||||
const sketches: SketchRef[] = [];
|
const sketches: Sketch[] = [];
|
||||||
const children: SketchContainer[] = [];
|
const children: SketchContainer[] = [];
|
||||||
let submenuPath = menuPath;
|
let submenuPath = menuPath;
|
||||||
|
|
||||||
@@ -161,7 +161,7 @@ export abstract class Examples extends SketchContribution {
|
|||||||
|
|
||||||
@injectable()
|
@injectable()
|
||||||
export class BuiltInExamples extends Examples {
|
export class BuiltInExamples extends Examples {
|
||||||
override async onReady(): Promise<void> {
|
onStart(): void {
|
||||||
this.register(); // no `await`
|
this.register(); // no `await`
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -201,16 +201,13 @@ export class LibraryExamples extends Examples {
|
|||||||
|
|
||||||
protected readonly queue = new PQueue({ autoStart: true, concurrency: 1 });
|
protected readonly queue = new PQueue({ autoStart: true, concurrency: 1 });
|
||||||
|
|
||||||
override onStart(): void {
|
onStart(): void {
|
||||||
|
this.register(); // no `await`
|
||||||
this.notificationCenter.onLibraryInstalled(() => this.register());
|
this.notificationCenter.onLibraryInstalled(() => this.register());
|
||||||
this.notificationCenter.onLibraryUninstalled(() => this.register());
|
this.notificationCenter.onLibraryUninstalled(() => this.register());
|
||||||
}
|
}
|
||||||
|
|
||||||
override async onReady(): Promise<void> {
|
protected handleBoardChanged(board: Board | undefined): void {
|
||||||
this.register(); // no `await`
|
|
||||||
}
|
|
||||||
|
|
||||||
protected override handleBoardChanged(board: Board | undefined): void {
|
|
||||||
this.register(board);
|
this.register(board);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@@ -1,79 +0,0 @@
|
|||||||
import { MaybePromise } from '@theia/core';
|
|
||||||
import { inject, injectable } from '@theia/core/shared/inversify';
|
|
||||||
import * as monaco from '@theia/monaco-editor-core';
|
|
||||||
import { Formatter } from '../../common/protocol/formatter';
|
|
||||||
import { InoSelector } from '../ino-selectors';
|
|
||||||
import { fullRange } from '../utils/monaco';
|
|
||||||
import { Contribution, URI } from './contribution';
|
|
||||||
|
|
||||||
@injectable()
|
|
||||||
export class Format
|
|
||||||
extends Contribution
|
|
||||||
implements
|
|
||||||
monaco.languages.DocumentRangeFormattingEditProvider,
|
|
||||||
monaco.languages.DocumentFormattingEditProvider
|
|
||||||
{
|
|
||||||
@inject(Formatter)
|
|
||||||
private readonly formatter: Formatter;
|
|
||||||
|
|
||||||
override onStart(): MaybePromise<void> {
|
|
||||||
monaco.languages.registerDocumentRangeFormattingEditProvider(
|
|
||||||
InoSelector,
|
|
||||||
this
|
|
||||||
);
|
|
||||||
monaco.languages.registerDocumentFormattingEditProvider(InoSelector, this);
|
|
||||||
}
|
|
||||||
async provideDocumentRangeFormattingEdits(
|
|
||||||
model: monaco.editor.ITextModel,
|
|
||||||
range: monaco.Range,
|
|
||||||
options: monaco.languages.FormattingOptions,
|
|
||||||
// eslint-disable-next-line @typescript-eslint/no-unused-vars
|
|
||||||
_token: monaco.CancellationToken
|
|
||||||
): Promise<monaco.languages.TextEdit[]> {
|
|
||||||
const text = await this.format(model, range, options);
|
|
||||||
return [{ range, text }];
|
|
||||||
}
|
|
||||||
|
|
||||||
async provideDocumentFormattingEdits(
|
|
||||||
model: monaco.editor.ITextModel,
|
|
||||||
options: monaco.languages.FormattingOptions,
|
|
||||||
// eslint-disable-next-line @typescript-eslint/no-unused-vars
|
|
||||||
_token: monaco.CancellationToken
|
|
||||||
): Promise<monaco.languages.TextEdit[]> {
|
|
||||||
const range = fullRange(model);
|
|
||||||
const text = await this.format(model, range, options);
|
|
||||||
return [{ range, text }];
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* From the currently opened workspaces (IDE2 has always one), it calculates all possible
|
|
||||||
* folder locations where the `.clang-format` file could be.
|
|
||||||
*/
|
|
||||||
private formatterConfigFolderUris(model: monaco.editor.ITextModel): string[] {
|
|
||||||
const editorUri = new URI(model.uri.toString());
|
|
||||||
return this.workspaceService
|
|
||||||
.tryGetRoots()
|
|
||||||
.map(({ resource }) => resource)
|
|
||||||
.filter((workspaceUri) => workspaceUri.isEqualOrParent(editorUri))
|
|
||||||
.map((uri) => uri.toString());
|
|
||||||
}
|
|
||||||
|
|
||||||
private format(
|
|
||||||
model: monaco.editor.ITextModel,
|
|
||||||
range: monaco.Range,
|
|
||||||
options: monaco.languages.FormattingOptions
|
|
||||||
): Promise<string> {
|
|
||||||
console.info(
|
|
||||||
`Formatting ${model.uri.toString()} [Range: ${JSON.stringify(
|
|
||||||
range.toJSON()
|
|
||||||
)}]`
|
|
||||||
);
|
|
||||||
const content = model.getValueInRange(range);
|
|
||||||
const formatterConfigFolderUris = this.formatterConfigFolderUris(model);
|
|
||||||
return this.formatter.format({
|
|
||||||
content,
|
|
||||||
formatterConfigFolderUris,
|
|
||||||
options,
|
|
||||||
});
|
|
||||||
}
|
|
||||||
}
|
|
@@ -1,4 +1,4 @@
|
|||||||
import { inject, injectable } from '@theia/core/shared/inversify';
|
import { inject, injectable } from 'inversify';
|
||||||
import { MonacoEditor } from '@theia/monaco/lib/browser/monaco-editor';
|
import { MonacoEditor } from '@theia/monaco/lib/browser/monaco-editor';
|
||||||
import { EditorManager } from '@theia/editor/lib/browser/editor-manager';
|
import { EditorManager } from '@theia/editor/lib/browser/editor-manager';
|
||||||
import { WindowService } from '@theia/core/lib/browser/window/window-service';
|
import { WindowService } from '@theia/core/lib/browser/window/window-service';
|
||||||
@@ -15,7 +15,6 @@ import {
|
|||||||
import { nls } from '@theia/core/lib/common';
|
import { nls } from '@theia/core/lib/common';
|
||||||
import { IDEUpdaterCommands } from '../ide-updater/ide-updater-commands';
|
import { IDEUpdaterCommands } from '../ide-updater/ide-updater-commands';
|
||||||
import { ElectronCommands } from '@theia/core/lib/electron-browser/menu/electron-menu-contribution';
|
import { ElectronCommands } from '@theia/core/lib/electron-browser/menu/electron-menu-contribution';
|
||||||
import * as monaco from '@theia/monaco-editor-core';
|
|
||||||
|
|
||||||
@injectable()
|
@injectable()
|
||||||
export class Help extends Contribution {
|
export class Help extends Contribution {
|
||||||
@@ -28,7 +27,7 @@ export class Help extends Contribution {
|
|||||||
@inject(QuickInputService)
|
@inject(QuickInputService)
|
||||||
protected readonly quickInputService: QuickInputService;
|
protected readonly quickInputService: QuickInputService;
|
||||||
|
|
||||||
override registerCommands(registry: CommandRegistry): void {
|
registerCommands(registry: CommandRegistry): void {
|
||||||
const open = (url: string) =>
|
const open = (url: string) =>
|
||||||
this.windowService.openNewWindow(url, { external: true });
|
this.windowService.openNewWindow(url, { external: true });
|
||||||
const createOpenHandler = (url: string) =>
|
const createOpenHandler = (url: string) =>
|
||||||
@@ -92,7 +91,7 @@ export class Help extends Contribution {
|
|||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
override registerMenus(registry: MenuModelRegistry): void {
|
registerMenus(registry: MenuModelRegistry): void {
|
||||||
registry.unregisterMenuAction({
|
registry.unregisterMenuAction({
|
||||||
commandId: ElectronCommands.TOGGLE_DEVELOPER_TOOLS.id,
|
commandId: ElectronCommands.TOGGLE_DEVELOPER_TOOLS.id,
|
||||||
});
|
});
|
||||||
@@ -136,7 +135,7 @@ export class Help extends Contribution {
|
|||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
override registerKeybindings(registry: KeybindingRegistry): void {
|
registerKeybindings(registry: KeybindingRegistry): void {
|
||||||
registry.registerKeybinding({
|
registry.registerKeybinding({
|
||||||
command: Help.Commands.FIND_IN_REFERENCE.id,
|
command: Help.Commands.FIND_IN_REFERENCE.id,
|
||||||
keybinding: 'CtrlCmd+Shift+F',
|
keybinding: 'CtrlCmd+Shift+F',
|
||||||
|
@@ -1,5 +1,5 @@
|
|||||||
import * as PQueue from 'p-queue';
|
import * as PQueue from 'p-queue';
|
||||||
import { inject, injectable } from '@theia/core/shared/inversify';
|
import { inject, injectable } from 'inversify';
|
||||||
import URI from '@theia/core/lib/common/uri';
|
import URI from '@theia/core/lib/common/uri';
|
||||||
import { MonacoEditor } from '@theia/monaco/lib/browser/monaco-editor';
|
import { MonacoEditor } from '@theia/monaco/lib/browser/monaco-editor';
|
||||||
import { EditorManager } from '@theia/editor/lib/browser';
|
import { EditorManager } from '@theia/editor/lib/browser';
|
||||||
@@ -16,8 +16,6 @@ import { BoardsServiceProvider } from '../boards/boards-service-provider';
|
|||||||
import { SketchContribution, Command, CommandRegistry } from './contribution';
|
import { SketchContribution, Command, CommandRegistry } from './contribution';
|
||||||
import { NotificationCenter } from '../notification-center';
|
import { NotificationCenter } from '../notification-center';
|
||||||
import { nls } from '@theia/core/lib/common';
|
import { nls } from '@theia/core/lib/common';
|
||||||
import * as monaco from '@theia/monaco-editor-core';
|
|
||||||
import { CurrentSketch } from '../../common/protocol/sketches-service-client-impl';
|
|
||||||
|
|
||||||
@injectable()
|
@injectable()
|
||||||
export class IncludeLibrary extends SketchContribution {
|
export class IncludeLibrary extends SketchContribution {
|
||||||
@@ -31,7 +29,7 @@ export class IncludeLibrary extends SketchContribution {
|
|||||||
protected readonly mainMenuManager: MainMenuManager;
|
protected readonly mainMenuManager: MainMenuManager;
|
||||||
|
|
||||||
@inject(EditorManager)
|
@inject(EditorManager)
|
||||||
protected override readonly editorManager: EditorManager;
|
protected readonly editorManager: EditorManager;
|
||||||
|
|
||||||
@inject(NotificationCenter)
|
@inject(NotificationCenter)
|
||||||
protected readonly notificationCenter: NotificationCenter;
|
protected readonly notificationCenter: NotificationCenter;
|
||||||
@@ -45,7 +43,8 @@ export class IncludeLibrary extends SketchContribution {
|
|||||||
protected readonly queue = new PQueue({ autoStart: true, concurrency: 1 });
|
protected readonly queue = new PQueue({ autoStart: true, concurrency: 1 });
|
||||||
protected readonly toDispose = new DisposableCollection();
|
protected readonly toDispose = new DisposableCollection();
|
||||||
|
|
||||||
override onStart(): void {
|
onStart(): void {
|
||||||
|
this.updateMenuActions();
|
||||||
this.boardsServiceClient.onBoardsConfigChanged(() =>
|
this.boardsServiceClient.onBoardsConfigChanged(() =>
|
||||||
this.updateMenuActions()
|
this.updateMenuActions()
|
||||||
);
|
);
|
||||||
@@ -55,11 +54,7 @@ export class IncludeLibrary extends SketchContribution {
|
|||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
override async onReady(): Promise<void> {
|
registerMenus(registry: MenuModelRegistry): void {
|
||||||
this.updateMenuActions();
|
|
||||||
}
|
|
||||||
|
|
||||||
override registerMenus(registry: MenuModelRegistry): void {
|
|
||||||
// `Include Library` submenu
|
// `Include Library` submenu
|
||||||
const includeLibMenuPath = [
|
const includeLibMenuPath = [
|
||||||
...ArduinoMenus.SKETCH__UTILS_GROUP,
|
...ArduinoMenus.SKETCH__UTILS_GROUP,
|
||||||
@@ -82,7 +77,7 @@ export class IncludeLibrary extends SketchContribution {
|
|||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
override registerCommands(registry: CommandRegistry): void {
|
registerCommands(registry: CommandRegistry): void {
|
||||||
registry.registerCommand(IncludeLibrary.Commands.INCLUDE_LIBRARY, {
|
registry.registerCommand(IncludeLibrary.Commands.INCLUDE_LIBRARY, {
|
||||||
execute: async (arg) => {
|
execute: async (arg) => {
|
||||||
if (LibraryPackage.is(arg)) {
|
if (LibraryPackage.is(arg)) {
|
||||||
@@ -173,7 +168,7 @@ export class IncludeLibrary extends SketchContribution {
|
|||||||
|
|
||||||
protected async includeLibrary(library: LibraryPackage): Promise<void> {
|
protected async includeLibrary(library: LibraryPackage): Promise<void> {
|
||||||
const sketch = await this.sketchServiceClient.currentSketch();
|
const sketch = await this.sketchServiceClient.currentSketch();
|
||||||
if (!CurrentSketch.isValid(sketch)) {
|
if (!sketch) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
// If the current editor is one of the additional files from the sketch, we use that.
|
// If the current editor is one of the additional files from the sketch, we use that.
|
||||||
|
@@ -1,5 +1,5 @@
|
|||||||
import { nls } from '@theia/core/lib/common';
|
import { nls } from '@theia/core/lib/common';
|
||||||
import { injectable } from '@theia/core/shared/inversify';
|
import { injectable } from 'inversify';
|
||||||
import { ArduinoMenus } from '../menu/arduino-menus';
|
import { ArduinoMenus } from '../menu/arduino-menus';
|
||||||
import { ArduinoToolbar } from '../toolbar/arduino-toolbar';
|
import { ArduinoToolbar } from '../toolbar/arduino-toolbar';
|
||||||
import {
|
import {
|
||||||
@@ -14,7 +14,7 @@ import {
|
|||||||
|
|
||||||
@injectable()
|
@injectable()
|
||||||
export class NewSketch extends SketchContribution {
|
export class NewSketch extends SketchContribution {
|
||||||
override registerCommands(registry: CommandRegistry): void {
|
registerCommands(registry: CommandRegistry): void {
|
||||||
registry.registerCommand(NewSketch.Commands.NEW_SKETCH, {
|
registry.registerCommand(NewSketch.Commands.NEW_SKETCH, {
|
||||||
execute: () => this.newSketch(),
|
execute: () => this.newSketch(),
|
||||||
});
|
});
|
||||||
@@ -25,7 +25,7 @@ export class NewSketch extends SketchContribution {
|
|||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
override registerMenus(registry: MenuModelRegistry): void {
|
registerMenus(registry: MenuModelRegistry): void {
|
||||||
registry.registerMenuAction(ArduinoMenus.FILE__SKETCH_GROUP, {
|
registry.registerMenuAction(ArduinoMenus.FILE__SKETCH_GROUP, {
|
||||||
commandId: NewSketch.Commands.NEW_SKETCH.id,
|
commandId: NewSketch.Commands.NEW_SKETCH.id,
|
||||||
label: nls.localize('arduino/sketch/new', 'New'),
|
label: nls.localize('arduino/sketch/new', 'New'),
|
||||||
@@ -33,14 +33,14 @@ export class NewSketch extends SketchContribution {
|
|||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
override registerKeybindings(registry: KeybindingRegistry): void {
|
registerKeybindings(registry: KeybindingRegistry): void {
|
||||||
registry.registerKeybinding({
|
registry.registerKeybinding({
|
||||||
command: NewSketch.Commands.NEW_SKETCH.id,
|
command: NewSketch.Commands.NEW_SKETCH.id,
|
||||||
keybinding: 'CtrlCmd+N',
|
keybinding: 'CtrlCmd+N',
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
override registerToolbarItems(registry: TabBarToolbarRegistry): void {
|
registerToolbarItems(registry: TabBarToolbarRegistry): void {
|
||||||
registry.registerItem({
|
registry.registerItem({
|
||||||
id: NewSketch.Commands.NEW_SKETCH__TOOLBAR.id,
|
id: NewSketch.Commands.NEW_SKETCH__TOOLBAR.id,
|
||||||
command: NewSketch.Commands.NEW_SKETCH__TOOLBAR.id,
|
command: NewSketch.Commands.NEW_SKETCH__TOOLBAR.id,
|
||||||
|
@@ -1,4 +1,4 @@
|
|||||||
import { inject, injectable } from '@theia/core/shared/inversify';
|
import { inject, injectable } from 'inversify';
|
||||||
import { WorkspaceServer } from '@theia/workspace/lib/common/workspace-protocol';
|
import { WorkspaceServer } from '@theia/workspace/lib/common/workspace-protocol';
|
||||||
import {
|
import {
|
||||||
Disposable,
|
Disposable,
|
||||||
@@ -35,19 +35,18 @@ export class OpenRecentSketch extends SketchContribution {
|
|||||||
|
|
||||||
protected toDisposeBeforeRegister = new Map<string, DisposableCollection>();
|
protected toDisposeBeforeRegister = new Map<string, DisposableCollection>();
|
||||||
|
|
||||||
override onStart(): void {
|
onStart(): void {
|
||||||
|
const refreshMenu = (sketches: Sketch[]) => {
|
||||||
|
this.register(sketches);
|
||||||
|
this.mainMenuManager.update();
|
||||||
|
};
|
||||||
this.notificationCenter.onRecentSketchesChanged(({ sketches }) =>
|
this.notificationCenter.onRecentSketchesChanged(({ sketches }) =>
|
||||||
this.refreshMenu(sketches)
|
refreshMenu(sketches)
|
||||||
);
|
);
|
||||||
|
this.sketchService.recentlyOpenedSketches().then(refreshMenu);
|
||||||
}
|
}
|
||||||
|
|
||||||
override async onReady(): Promise<void> {
|
registerMenus(registry: MenuModelRegistry): void {
|
||||||
this.sketchService
|
|
||||||
.recentlyOpenedSketches()
|
|
||||||
.then((sketches) => this.refreshMenu(sketches));
|
|
||||||
}
|
|
||||||
|
|
||||||
override registerMenus(registry: MenuModelRegistry): void {
|
|
||||||
registry.registerSubmenu(
|
registry.registerSubmenu(
|
||||||
ArduinoMenus.FILE__OPEN_RECENT_SUBMENU,
|
ArduinoMenus.FILE__OPEN_RECENT_SUBMENU,
|
||||||
nls.localize('arduino/sketch/openRecent', 'Open Recent'),
|
nls.localize('arduino/sketch/openRecent', 'Open Recent'),
|
||||||
@@ -55,11 +54,6 @@ export class OpenRecentSketch extends SketchContribution {
|
|||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
private refreshMenu(sketches: Sketch[]): void {
|
|
||||||
this.register(sketches);
|
|
||||||
this.mainMenuManager.update();
|
|
||||||
}
|
|
||||||
|
|
||||||
protected register(sketches: Sketch[]): void {
|
protected register(sketches: Sketch[]): void {
|
||||||
const order = 0;
|
const order = 0;
|
||||||
for (const sketch of sketches) {
|
for (const sketch of sketches) {
|
||||||
|
@@ -1,4 +1,4 @@
|
|||||||
import { injectable } from '@theia/core/shared/inversify';
|
import { injectable } from 'inversify';
|
||||||
import * as remote from '@theia/core/electron-shared/@electron/remote';
|
import * as remote from '@theia/core/electron-shared/@electron/remote';
|
||||||
import URI from '@theia/core/lib/common/uri';
|
import URI from '@theia/core/lib/common/uri';
|
||||||
import { ArduinoMenus } from '../menu/arduino-menus';
|
import { ArduinoMenus } from '../menu/arduino-menus';
|
||||||
@@ -13,13 +13,13 @@ import { nls } from '@theia/core/lib/common';
|
|||||||
|
|
||||||
@injectable()
|
@injectable()
|
||||||
export class OpenSketchExternal extends SketchContribution {
|
export class OpenSketchExternal extends SketchContribution {
|
||||||
override registerCommands(registry: CommandRegistry): void {
|
registerCommands(registry: CommandRegistry): void {
|
||||||
registry.registerCommand(OpenSketchExternal.Commands.OPEN_EXTERNAL, {
|
registry.registerCommand(OpenSketchExternal.Commands.OPEN_EXTERNAL, {
|
||||||
execute: () => this.openExternal(),
|
execute: () => this.openExternal(),
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
override registerMenus(registry: MenuModelRegistry): void {
|
registerMenus(registry: MenuModelRegistry): void {
|
||||||
registry.registerMenuAction(ArduinoMenus.SKETCH__UTILS_GROUP, {
|
registry.registerMenuAction(ArduinoMenus.SKETCH__UTILS_GROUP, {
|
||||||
commandId: OpenSketchExternal.Commands.OPEN_EXTERNAL.id,
|
commandId: OpenSketchExternal.Commands.OPEN_EXTERNAL.id,
|
||||||
label: nls.localize('arduino/sketch/showFolder', 'Show Sketch Folder'),
|
label: nls.localize('arduino/sketch/showFolder', 'Show Sketch Folder'),
|
||||||
@@ -27,7 +27,7 @@ export class OpenSketchExternal extends SketchContribution {
|
|||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
override registerKeybindings(registry: KeybindingRegistry): void {
|
registerKeybindings(registry: KeybindingRegistry): void {
|
||||||
registry.registerKeybinding({
|
registry.registerKeybinding({
|
||||||
command: OpenSketchExternal.Commands.OPEN_EXTERNAL.id,
|
command: OpenSketchExternal.Commands.OPEN_EXTERNAL.id,
|
||||||
keybinding: 'CtrlCmd+Alt+K',
|
keybinding: 'CtrlCmd+Alt+K',
|
||||||
|
@@ -1,4 +1,4 @@
|
|||||||
import { inject, injectable } from '@theia/core/shared/inversify';
|
import { inject, injectable } from 'inversify';
|
||||||
import * as remote from '@theia/core/electron-shared/@electron/remote';
|
import * as remote from '@theia/core/electron-shared/@electron/remote';
|
||||||
import { MaybePromise } from '@theia/core/lib/common/types';
|
import { MaybePromise } from '@theia/core/lib/common/types';
|
||||||
import { Widget, ContextMenuRenderer } from '@theia/core/lib/browser';
|
import { Widget, ContextMenuRenderer } from '@theia/core/lib/browser';
|
||||||
@@ -43,7 +43,7 @@ export class OpenSketch extends SketchContribution {
|
|||||||
|
|
||||||
protected readonly toDispose = new DisposableCollection();
|
protected readonly toDispose = new DisposableCollection();
|
||||||
|
|
||||||
override registerCommands(registry: CommandRegistry): void {
|
registerCommands(registry: CommandRegistry): void {
|
||||||
registry.registerCommand(OpenSketch.Commands.OPEN_SKETCH, {
|
registry.registerCommand(OpenSketch.Commands.OPEN_SKETCH, {
|
||||||
execute: (arg) =>
|
execute: (arg) =>
|
||||||
Sketch.is(arg) ? this.openSketch(arg) : this.openSketch(),
|
Sketch.is(arg) ? this.openSketch(arg) : this.openSketch(),
|
||||||
@@ -116,7 +116,7 @@ export class OpenSketch extends SketchContribution {
|
|||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
override registerMenus(registry: MenuModelRegistry): void {
|
registerMenus(registry: MenuModelRegistry): void {
|
||||||
registry.registerMenuAction(ArduinoMenus.FILE__SKETCH_GROUP, {
|
registry.registerMenuAction(ArduinoMenus.FILE__SKETCH_GROUP, {
|
||||||
commandId: OpenSketch.Commands.OPEN_SKETCH.id,
|
commandId: OpenSketch.Commands.OPEN_SKETCH.id,
|
||||||
label: nls.localize('vscode/workspaceActions/openFileFolder', 'Open...'),
|
label: nls.localize('vscode/workspaceActions/openFileFolder', 'Open...'),
|
||||||
@@ -124,14 +124,14 @@ export class OpenSketch extends SketchContribution {
|
|||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
override registerKeybindings(registry: KeybindingRegistry): void {
|
registerKeybindings(registry: KeybindingRegistry): void {
|
||||||
registry.registerKeybinding({
|
registry.registerKeybinding({
|
||||||
command: OpenSketch.Commands.OPEN_SKETCH.id,
|
command: OpenSketch.Commands.OPEN_SKETCH.id,
|
||||||
keybinding: 'CtrlCmd+O',
|
keybinding: 'CtrlCmd+O',
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
override registerToolbarItems(registry: TabBarToolbarRegistry): void {
|
registerToolbarItems(registry: TabBarToolbarRegistry): void {
|
||||||
registry.registerItem({
|
registry.registerItem({
|
||||||
id: OpenSketch.Commands.OPEN_SKETCH__TOOLBAR.id,
|
id: OpenSketch.Commands.OPEN_SKETCH__TOOLBAR.id,
|
||||||
command: OpenSketch.Commands.OPEN_SKETCH__TOOLBAR.id,
|
command: OpenSketch.Commands.OPEN_SKETCH__TOOLBAR.id,
|
||||||
|
@@ -1,4 +1,4 @@
|
|||||||
import { injectable } from '@theia/core/shared/inversify';
|
import { injectable } from 'inversify';
|
||||||
import * as remote from '@theia/core/electron-shared/@electron/remote';
|
import * as remote from '@theia/core/electron-shared/@electron/remote';
|
||||||
import { isOSX } from '@theia/core/lib/common/os';
|
import { isOSX } from '@theia/core/lib/common/os';
|
||||||
import {
|
import {
|
||||||
@@ -13,7 +13,7 @@ import { nls } from '@theia/core/lib/common';
|
|||||||
|
|
||||||
@injectable()
|
@injectable()
|
||||||
export class QuitApp extends Contribution {
|
export class QuitApp extends Contribution {
|
||||||
override registerCommands(registry: CommandRegistry): void {
|
registerCommands(registry: CommandRegistry): void {
|
||||||
if (!isOSX) {
|
if (!isOSX) {
|
||||||
registry.registerCommand(QuitApp.Commands.QUIT_APP, {
|
registry.registerCommand(QuitApp.Commands.QUIT_APP, {
|
||||||
execute: () => remote.app.quit(),
|
execute: () => remote.app.quit(),
|
||||||
@@ -21,7 +21,7 @@ export class QuitApp extends Contribution {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
override registerMenus(registry: MenuModelRegistry): void {
|
registerMenus(registry: MenuModelRegistry): void {
|
||||||
// On macOS we will get the `Quit ${YOUR_APP_NAME}` menu item natively, no need to duplicate it.
|
// On macOS we will get the `Quit ${YOUR_APP_NAME}` menu item natively, no need to duplicate it.
|
||||||
if (!isOSX) {
|
if (!isOSX) {
|
||||||
registry.registerMenuAction(ArduinoMenus.FILE__QUIT_GROUP, {
|
registry.registerMenuAction(ArduinoMenus.FILE__QUIT_GROUP, {
|
||||||
@@ -32,7 +32,7 @@ export class QuitApp extends Contribution {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
override registerKeybindings(registry: KeybindingRegistry): void {
|
registerKeybindings(registry: KeybindingRegistry): void {
|
||||||
if (!isOSX) {
|
if (!isOSX) {
|
||||||
registry.registerKeybinding({
|
registry.registerKeybinding({
|
||||||
command: QuitApp.Commands.QUIT_APP.id,
|
command: QuitApp.Commands.QUIT_APP.id,
|
||||||
|
@@ -1,4 +1,4 @@
|
|||||||
import { inject, injectable } from '@theia/core/shared/inversify';
|
import { inject, injectable } from 'inversify';
|
||||||
import * as remote from '@theia/core/electron-shared/@electron/remote';
|
import * as remote from '@theia/core/electron-shared/@electron/remote';
|
||||||
import * as dateFormat from 'dateformat';
|
import * as dateFormat from 'dateformat';
|
||||||
import { ArduinoMenus } from '../menu/arduino-menus';
|
import { ArduinoMenus } from '../menu/arduino-menus';
|
||||||
@@ -14,7 +14,6 @@ import { nls } from '@theia/core/lib/common';
|
|||||||
import { ApplicationShell, NavigatableWidget, Saveable } from '@theia/core/lib/browser';
|
import { ApplicationShell, NavigatableWidget, Saveable } from '@theia/core/lib/browser';
|
||||||
import { EditorManager } from '@theia/editor/lib/browser';
|
import { EditorManager } from '@theia/editor/lib/browser';
|
||||||
import { WindowService } from '@theia/core/lib/browser/window/window-service';
|
import { WindowService } from '@theia/core/lib/browser/window/window-service';
|
||||||
import { CurrentSketch } from '../../common/protocol/sketches-service-client-impl';
|
|
||||||
|
|
||||||
@injectable()
|
@injectable()
|
||||||
export class SaveAsSketch extends SketchContribution {
|
export class SaveAsSketch extends SketchContribution {
|
||||||
@@ -23,18 +22,18 @@ export class SaveAsSketch extends SketchContribution {
|
|||||||
protected readonly applicationShell: ApplicationShell;
|
protected readonly applicationShell: ApplicationShell;
|
||||||
|
|
||||||
@inject(EditorManager)
|
@inject(EditorManager)
|
||||||
protected override readonly editorManager: EditorManager;
|
protected readonly editorManager: EditorManager;
|
||||||
|
|
||||||
@inject(WindowService)
|
@inject(WindowService)
|
||||||
protected readonly windowService: WindowService;
|
protected readonly windowService: WindowService;
|
||||||
|
|
||||||
override registerCommands(registry: CommandRegistry): void {
|
registerCommands(registry: CommandRegistry): void {
|
||||||
registry.registerCommand(SaveAsSketch.Commands.SAVE_AS_SKETCH, {
|
registry.registerCommand(SaveAsSketch.Commands.SAVE_AS_SKETCH, {
|
||||||
execute: (args) => this.saveAs(args),
|
execute: (args) => this.saveAs(args),
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
override registerMenus(registry: MenuModelRegistry): void {
|
registerMenus(registry: MenuModelRegistry): void {
|
||||||
registry.registerMenuAction(ArduinoMenus.FILE__SKETCH_GROUP, {
|
registry.registerMenuAction(ArduinoMenus.FILE__SKETCH_GROUP, {
|
||||||
commandId: SaveAsSketch.Commands.SAVE_AS_SKETCH.id,
|
commandId: SaveAsSketch.Commands.SAVE_AS_SKETCH.id,
|
||||||
label: nls.localize('vscode/fileCommands/saveAs', 'Save As...'),
|
label: nls.localize('vscode/fileCommands/saveAs', 'Save As...'),
|
||||||
@@ -42,7 +41,7 @@ export class SaveAsSketch extends SketchContribution {
|
|||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
override registerKeybindings(registry: KeybindingRegistry): void {
|
registerKeybindings(registry: KeybindingRegistry): void {
|
||||||
registry.registerKeybinding({
|
registry.registerKeybinding({
|
||||||
command: SaveAsSketch.Commands.SAVE_AS_SKETCH.id,
|
command: SaveAsSketch.Commands.SAVE_AS_SKETCH.id,
|
||||||
keybinding: 'CtrlCmd+Shift+S',
|
keybinding: 'CtrlCmd+Shift+S',
|
||||||
@@ -60,7 +59,7 @@ export class SaveAsSketch extends SketchContribution {
|
|||||||
}: SaveAsSketch.Options = SaveAsSketch.Options.DEFAULT
|
}: SaveAsSketch.Options = SaveAsSketch.Options.DEFAULT
|
||||||
): Promise<boolean> {
|
): Promise<boolean> {
|
||||||
const sketch = await this.sketchServiceClient.currentSketch();
|
const sketch = await this.sketchServiceClient.currentSketch();
|
||||||
if (!CurrentSketch.isValid(sketch)) {
|
if (!sketch) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@@ -1,4 +1,4 @@
|
|||||||
import { injectable } from '@theia/core/shared/inversify';
|
import { injectable } from 'inversify';
|
||||||
import { CommonCommands } from '@theia/core/lib/browser/common-frontend-contribution';
|
import { CommonCommands } from '@theia/core/lib/browser/common-frontend-contribution';
|
||||||
import { ArduinoMenus } from '../menu/arduino-menus';
|
import { ArduinoMenus } from '../menu/arduino-menus';
|
||||||
import { ArduinoToolbar } from '../toolbar/arduino-toolbar';
|
import { ArduinoToolbar } from '../toolbar/arduino-toolbar';
|
||||||
@@ -12,11 +12,10 @@ import {
|
|||||||
TabBarToolbarRegistry,
|
TabBarToolbarRegistry,
|
||||||
} from './contribution';
|
} from './contribution';
|
||||||
import { nls } from '@theia/core/lib/common';
|
import { nls } from '@theia/core/lib/common';
|
||||||
import { CurrentSketch } from '../../common/protocol/sketches-service-client-impl';
|
|
||||||
|
|
||||||
@injectable()
|
@injectable()
|
||||||
export class SaveSketch extends SketchContribution {
|
export class SaveSketch extends SketchContribution {
|
||||||
override registerCommands(registry: CommandRegistry): void {
|
registerCommands(registry: CommandRegistry): void {
|
||||||
registry.registerCommand(SaveSketch.Commands.SAVE_SKETCH, {
|
registry.registerCommand(SaveSketch.Commands.SAVE_SKETCH, {
|
||||||
execute: () => this.saveSketch(),
|
execute: () => this.saveSketch(),
|
||||||
});
|
});
|
||||||
@@ -28,7 +27,7 @@ export class SaveSketch extends SketchContribution {
|
|||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
override registerMenus(registry: MenuModelRegistry): void {
|
registerMenus(registry: MenuModelRegistry): void {
|
||||||
registry.registerMenuAction(ArduinoMenus.FILE__SKETCH_GROUP, {
|
registry.registerMenuAction(ArduinoMenus.FILE__SKETCH_GROUP, {
|
||||||
commandId: SaveSketch.Commands.SAVE_SKETCH.id,
|
commandId: SaveSketch.Commands.SAVE_SKETCH.id,
|
||||||
label: nls.localize('vscode/fileCommands/save', 'Save'),
|
label: nls.localize('vscode/fileCommands/save', 'Save'),
|
||||||
@@ -36,14 +35,14 @@ export class SaveSketch extends SketchContribution {
|
|||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
override registerKeybindings(registry: KeybindingRegistry): void {
|
registerKeybindings(registry: KeybindingRegistry): void {
|
||||||
registry.registerKeybinding({
|
registry.registerKeybinding({
|
||||||
command: SaveSketch.Commands.SAVE_SKETCH.id,
|
command: SaveSketch.Commands.SAVE_SKETCH.id,
|
||||||
keybinding: 'CtrlCmd+S',
|
keybinding: 'CtrlCmd+S',
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
override registerToolbarItems(registry: TabBarToolbarRegistry): void {
|
registerToolbarItems(registry: TabBarToolbarRegistry): void {
|
||||||
registry.registerItem({
|
registry.registerItem({
|
||||||
id: SaveSketch.Commands.SAVE_SKETCH__TOOLBAR.id,
|
id: SaveSketch.Commands.SAVE_SKETCH__TOOLBAR.id,
|
||||||
command: SaveSketch.Commands.SAVE_SKETCH__TOOLBAR.id,
|
command: SaveSketch.Commands.SAVE_SKETCH__TOOLBAR.id,
|
||||||
@@ -54,7 +53,7 @@ export class SaveSketch extends SketchContribution {
|
|||||||
|
|
||||||
async saveSketch(): Promise<void> {
|
async saveSketch(): Promise<void> {
|
||||||
const sketch = await this.sketchServiceClient.currentSketch();
|
const sketch = await this.sketchServiceClient.currentSketch();
|
||||||
if (!CurrentSketch.isValid(sketch)) {
|
if (!sketch) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
const isTemp = await this.sketchService.isTemp(sketch);
|
const isTemp = await this.sketchService.isTemp(sketch);
|
||||||
|
@@ -1,4 +1,4 @@
|
|||||||
import { inject, injectable } from '@theia/core/shared/inversify';
|
import { inject, injectable } from 'inversify';
|
||||||
import {
|
import {
|
||||||
Command,
|
Command,
|
||||||
MenuModelRegistry,
|
MenuModelRegistry,
|
||||||
@@ -18,7 +18,7 @@ export class Settings extends SketchContribution {
|
|||||||
|
|
||||||
protected settingsOpened = false;
|
protected settingsOpened = false;
|
||||||
|
|
||||||
override registerCommands(registry: CommandRegistry): void {
|
registerCommands(registry: CommandRegistry): void {
|
||||||
registry.registerCommand(Settings.Commands.OPEN, {
|
registry.registerCommand(Settings.Commands.OPEN, {
|
||||||
execute: async () => {
|
execute: async () => {
|
||||||
let settings: Preferences | undefined = undefined;
|
let settings: Preferences | undefined = undefined;
|
||||||
@@ -39,7 +39,7 @@ export class Settings extends SketchContribution {
|
|||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
override registerMenus(registry: MenuModelRegistry): void {
|
registerMenus(registry: MenuModelRegistry): void {
|
||||||
registry.registerMenuAction(ArduinoMenus.FILE__PREFERENCES_GROUP, {
|
registry.registerMenuAction(ArduinoMenus.FILE__PREFERENCES_GROUP, {
|
||||||
commandId: Settings.Commands.OPEN.id,
|
commandId: Settings.Commands.OPEN.id,
|
||||||
label:
|
label:
|
||||||
@@ -52,7 +52,7 @@ export class Settings extends SketchContribution {
|
|||||||
registry.registerSubmenu(ArduinoMenus.FILE__ADVANCED_SUBMENU, 'Advanced');
|
registry.registerSubmenu(ArduinoMenus.FILE__ADVANCED_SUBMENU, 'Advanced');
|
||||||
}
|
}
|
||||||
|
|
||||||
override registerKeybindings(registry: KeybindingRegistry): void {
|
registerKeybindings(registry: KeybindingRegistry): void {
|
||||||
registry.registerKeybinding({
|
registry.registerKeybinding({
|
||||||
command: Settings.Commands.OPEN.id,
|
command: Settings.Commands.OPEN.id,
|
||||||
keybinding: 'CtrlCmd+,',
|
keybinding: 'CtrlCmd+,',
|
||||||
|
@@ -1,4 +1,4 @@
|
|||||||
import { inject, injectable } from '@theia/core/shared/inversify';
|
import { inject, injectable } from 'inversify';
|
||||||
import { CommonCommands } from '@theia/core/lib/browser/common-frontend-contribution';
|
import { CommonCommands } from '@theia/core/lib/browser/common-frontend-contribution';
|
||||||
import { ApplicationShell } from '@theia/core/lib/browser/shell/application-shell';
|
import { ApplicationShell } from '@theia/core/lib/browser/shell/application-shell';
|
||||||
import { WorkspaceCommands } from '@theia/workspace/lib/browser';
|
import { WorkspaceCommands } from '@theia/workspace/lib/browser';
|
||||||
@@ -19,10 +19,7 @@ import {
|
|||||||
} from './contribution';
|
} from './contribution';
|
||||||
import { ArduinoMenus, PlaceholderMenuNode } from '../menu/arduino-menus';
|
import { ArduinoMenus, PlaceholderMenuNode } from '../menu/arduino-menus';
|
||||||
import { EditorManager } from '@theia/editor/lib/browser/editor-manager';
|
import { EditorManager } from '@theia/editor/lib/browser/editor-manager';
|
||||||
import {
|
import { SketchesServiceClientImpl } from '../../common/protocol/sketches-service-client-impl';
|
||||||
CurrentSketch,
|
|
||||||
SketchesServiceClientImpl,
|
|
||||||
} from '../../common/protocol/sketches-service-client-impl';
|
|
||||||
import { LocalCacheFsProvider } from '../local-cache/local-cache-fs-provider';
|
import { LocalCacheFsProvider } from '../local-cache/local-cache-fs-provider';
|
||||||
import { nls } from '@theia/core/lib/common';
|
import { nls } from '@theia/core/lib/common';
|
||||||
|
|
||||||
@@ -38,7 +35,7 @@ export class SketchControl extends SketchContribution {
|
|||||||
protected readonly contextMenuRenderer: ContextMenuRenderer;
|
protected readonly contextMenuRenderer: ContextMenuRenderer;
|
||||||
|
|
||||||
@inject(EditorManager)
|
@inject(EditorManager)
|
||||||
protected override readonly editorManager: EditorManager;
|
protected readonly editorManager: EditorManager;
|
||||||
|
|
||||||
@inject(SketchesServiceClientImpl)
|
@inject(SketchesServiceClientImpl)
|
||||||
protected readonly sketchesServiceClient: SketchesServiceClientImpl;
|
protected readonly sketchesServiceClient: SketchesServiceClientImpl;
|
||||||
@@ -49,7 +46,7 @@ export class SketchControl extends SketchContribution {
|
|||||||
protected readonly toDisposeBeforeCreateNewContextMenu =
|
protected readonly toDisposeBeforeCreateNewContextMenu =
|
||||||
new DisposableCollection();
|
new DisposableCollection();
|
||||||
|
|
||||||
override registerCommands(registry: CommandRegistry): void {
|
registerCommands(registry: CommandRegistry): void {
|
||||||
registry.registerCommand(
|
registry.registerCommand(
|
||||||
SketchControl.Commands.OPEN_SKETCH_CONTROL__TOOLBAR,
|
SketchControl.Commands.OPEN_SKETCH_CONTROL__TOOLBAR,
|
||||||
{
|
{
|
||||||
@@ -58,7 +55,7 @@ export class SketchControl extends SketchContribution {
|
|||||||
execute: async () => {
|
execute: async () => {
|
||||||
this.toDisposeBeforeCreateNewContextMenu.dispose();
|
this.toDisposeBeforeCreateNewContextMenu.dispose();
|
||||||
const sketch = await this.sketchServiceClient.currentSketch();
|
const sketch = await this.sketchServiceClient.currentSketch();
|
||||||
if (!CurrentSketch.isValid(sketch)) {
|
if (!sketch) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -73,22 +70,25 @@ export class SketchControl extends SketchContribution {
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
const { mainFileUri, rootFolderFileUris } = sketch;
|
const { mainFileUri, rootFolderFileUris } =
|
||||||
|
await this.sketchService.loadSketch(sketch.uri);
|
||||||
const uris = [mainFileUri, ...rootFolderFileUris];
|
const uris = [mainFileUri, ...rootFolderFileUris];
|
||||||
|
|
||||||
const parentSketchUri = this.editorManager.currentEditor
|
const currentSketch =
|
||||||
|
await this.sketchesServiceClient.currentSketch();
|
||||||
|
const parentsketchUri = this.editorManager.currentEditor
|
||||||
?.getResourceUri()
|
?.getResourceUri()
|
||||||
?.toString();
|
?.toString();
|
||||||
const parentSketch = await this.sketchService.getSketchFolder(
|
const parentsketch = await this.sketchService.getSketchFolder(
|
||||||
parentSketchUri || ''
|
parentsketchUri || ''
|
||||||
);
|
);
|
||||||
|
|
||||||
// if the current file is in the current opened sketch, show extra menus
|
// if the current file is in the current opened sketch, show extra menus
|
||||||
if (
|
if (
|
||||||
sketch &&
|
currentSketch &&
|
||||||
parentSketch &&
|
parentsketch &&
|
||||||
parentSketch.uri === sketch.uri &&
|
parentsketch.uri === currentSketch.uri &&
|
||||||
this.allowRename(parentSketch.uri)
|
this.allowRename(parentsketch.uri)
|
||||||
) {
|
) {
|
||||||
this.menuRegistry.registerMenuAction(
|
this.menuRegistry.registerMenuAction(
|
||||||
ArduinoMenus.SKETCH_CONTROL__CONTEXT__MAIN_GROUP,
|
ArduinoMenus.SKETCH_CONTROL__CONTEXT__MAIN_GROUP,
|
||||||
@@ -122,10 +122,10 @@ export class SketchControl extends SketchContribution {
|
|||||||
}
|
}
|
||||||
|
|
||||||
if (
|
if (
|
||||||
sketch &&
|
currentSketch &&
|
||||||
parentSketch &&
|
parentsketch &&
|
||||||
parentSketch.uri === sketch.uri &&
|
parentsketch.uri === currentSketch.uri &&
|
||||||
this.allowDelete(parentSketch.uri)
|
this.allowDelete(parentsketch.uri)
|
||||||
) {
|
) {
|
||||||
this.menuRegistry.registerMenuAction(
|
this.menuRegistry.registerMenuAction(
|
||||||
ArduinoMenus.SKETCH_CONTROL__CONTEXT__MAIN_GROUP,
|
ArduinoMenus.SKETCH_CONTROL__CONTEXT__MAIN_GROUP,
|
||||||
@@ -200,7 +200,7 @@ export class SketchControl extends SketchContribution {
|
|||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
override registerMenus(registry: MenuModelRegistry): void {
|
registerMenus(registry: MenuModelRegistry): void {
|
||||||
registry.registerMenuAction(
|
registry.registerMenuAction(
|
||||||
ArduinoMenus.SKETCH_CONTROL__CONTEXT__MAIN_GROUP,
|
ArduinoMenus.SKETCH_CONTROL__CONTEXT__MAIN_GROUP,
|
||||||
{
|
{
|
||||||
@@ -228,7 +228,7 @@ export class SketchControl extends SketchContribution {
|
|||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
override registerKeybindings(registry: KeybindingRegistry): void {
|
registerKeybindings(registry: KeybindingRegistry): void {
|
||||||
registry.registerKeybinding({
|
registry.registerKeybinding({
|
||||||
command: WorkspaceCommands.NEW_FILE.id,
|
command: WorkspaceCommands.NEW_FILE.id,
|
||||||
keybinding: 'CtrlCmd+Shift+N',
|
keybinding: 'CtrlCmd+Shift+N',
|
||||||
@@ -243,7 +243,7 @@ export class SketchControl extends SketchContribution {
|
|||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
override registerToolbarItems(registry: TabBarToolbarRegistry): void {
|
registerToolbarItems(registry: TabBarToolbarRegistry): void {
|
||||||
registry.registerItem({
|
registry.registerItem({
|
||||||
id: SketchControl.Commands.OPEN_SKETCH_CONTROL__TOOLBAR.id,
|
id: SketchControl.Commands.OPEN_SKETCH_CONTROL__TOOLBAR.id,
|
||||||
command: SketchControl.Commands.OPEN_SKETCH_CONTROL__TOOLBAR.id,
|
command: SketchControl.Commands.OPEN_SKETCH_CONTROL__TOOLBAR.id,
|
||||||
|
@@ -1,4 +1,4 @@
|
|||||||
import { inject, injectable } from '@theia/core/shared/inversify';
|
import { inject, injectable } from 'inversify';
|
||||||
import { CommandHandler } from '@theia/core/lib/common/command';
|
import { CommandHandler } from '@theia/core/lib/common/command';
|
||||||
import { CommandRegistry, MenuModelRegistry } from './contribution';
|
import { CommandRegistry, MenuModelRegistry } from './contribution';
|
||||||
import { ArduinoMenus } from '../menu/arduino-menus';
|
import { ArduinoMenus } from '../menu/arduino-menus';
|
||||||
@@ -12,10 +12,10 @@ import { nls } from '@theia/core/lib/common';
|
|||||||
@injectable()
|
@injectable()
|
||||||
export class Sketchbook extends Examples {
|
export class Sketchbook extends Examples {
|
||||||
@inject(CommandRegistry)
|
@inject(CommandRegistry)
|
||||||
protected override readonly commandRegistry: CommandRegistry;
|
protected readonly commandRegistry: CommandRegistry;
|
||||||
|
|
||||||
@inject(MenuModelRegistry)
|
@inject(MenuModelRegistry)
|
||||||
protected override readonly menuRegistry: MenuModelRegistry;
|
protected readonly menuRegistry: MenuModelRegistry;
|
||||||
|
|
||||||
@inject(MainMenuManager)
|
@inject(MainMenuManager)
|
||||||
protected readonly mainMenuManager: MainMenuManager;
|
protected readonly mainMenuManager: MainMenuManager;
|
||||||
@@ -23,7 +23,11 @@ export class Sketchbook extends Examples {
|
|||||||
@inject(NotificationCenter)
|
@inject(NotificationCenter)
|
||||||
protected readonly notificationCenter: NotificationCenter;
|
protected readonly notificationCenter: NotificationCenter;
|
||||||
|
|
||||||
override onStart(): void {
|
onStart(): void {
|
||||||
|
this.sketchService.getSketches({}).then((container) => {
|
||||||
|
this.register(container);
|
||||||
|
this.mainMenuManager.update();
|
||||||
|
});
|
||||||
this.sketchServiceClient.onSketchbookDidChange(() => {
|
this.sketchServiceClient.onSketchbookDidChange(() => {
|
||||||
this.sketchService.getSketches({}).then((container) => {
|
this.sketchService.getSketches({}).then((container) => {
|
||||||
this.register(container);
|
this.register(container);
|
||||||
@@ -32,14 +36,7 @@ export class Sketchbook extends Examples {
|
|||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
override async onReady(): Promise<void> {
|
registerMenus(registry: MenuModelRegistry): void {
|
||||||
this.sketchService.getSketches({}).then((container) => {
|
|
||||||
this.register(container);
|
|
||||||
this.mainMenuManager.update();
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
override registerMenus(registry: MenuModelRegistry): void {
|
|
||||||
registry.registerSubmenu(
|
registry.registerSubmenu(
|
||||||
ArduinoMenus.FILE__SKETCHBOOK_SUBMENU,
|
ArduinoMenus.FILE__SKETCHBOOK_SUBMENU,
|
||||||
nls.localize('arduino/sketch/sketchbook', 'Sketchbook'),
|
nls.localize('arduino/sketch/sketchbook', 'Sketchbook'),
|
||||||
@@ -56,7 +53,7 @@ export class Sketchbook extends Examples {
|
|||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
protected override createHandler(uri: string): CommandHandler {
|
protected createHandler(uri: string): CommandHandler {
|
||||||
return {
|
return {
|
||||||
execute: async () => {
|
execute: async () => {
|
||||||
const sketch = await this.sketchService.loadSketch(uri);
|
const sketch = await this.sketchService.loadSketch(uri);
|
||||||
|
@@ -1,78 +0,0 @@
|
|||||||
import { MessageService } from '@theia/core';
|
|
||||||
import { FrontendApplicationContribution } from '@theia/core/lib/browser';
|
|
||||||
import { inject, injectable } from '@theia/core/shared/inversify';
|
|
||||||
import { LocalStorageService } from '@theia/core/lib/browser';
|
|
||||||
import { nls } from '@theia/core/lib/common';
|
|
||||||
import { WindowService } from '@theia/core/lib/browser/window/window-service';
|
|
||||||
import { ArduinoPreferences } from '../arduino-preferences';
|
|
||||||
import { SurveyNotificationService } from '../../common/protocol/survey-service';
|
|
||||||
|
|
||||||
const SURVEY_MESSAGE = nls.localize(
|
|
||||||
'arduino/survey/surveyMessage',
|
|
||||||
'Please help us improve by answering this super short survey. We value our community and would like to get to know our supporters a little better.'
|
|
||||||
);
|
|
||||||
const DO_NOT_SHOW_AGAIN = nls.localize(
|
|
||||||
'arduino/survey/dismissSurvey',
|
|
||||||
"Don't show again"
|
|
||||||
);
|
|
||||||
const GO_TO_SURVEY = nls.localize(
|
|
||||||
'arduino/survey/answerSurvey',
|
|
||||||
'Answer survey'
|
|
||||||
);
|
|
||||||
|
|
||||||
const SURVEY_BASE_URL = 'https://surveys.hotjar.com/';
|
|
||||||
const surveyId = '17887b40-e1f0-4bd6-b9f0-a37f229ccd8b';
|
|
||||||
|
|
||||||
@injectable()
|
|
||||||
export class SurveyNotification implements FrontendApplicationContribution {
|
|
||||||
@inject(MessageService)
|
|
||||||
private readonly messageService: MessageService;
|
|
||||||
|
|
||||||
@inject(LocalStorageService)
|
|
||||||
private readonly localStorageService: LocalStorageService;
|
|
||||||
|
|
||||||
@inject(WindowService)
|
|
||||||
private readonly windowService: WindowService;
|
|
||||||
|
|
||||||
@inject(ArduinoPreferences)
|
|
||||||
private readonly arduinoPreferences: ArduinoPreferences;
|
|
||||||
|
|
||||||
@inject(SurveyNotificationService)
|
|
||||||
private readonly surveyNotificationService: SurveyNotificationService;
|
|
||||||
|
|
||||||
onStart(): void {
|
|
||||||
this.arduinoPreferences.ready.then(async () => {
|
|
||||||
if (
|
|
||||||
(await this.surveyNotificationService.isFirstInstance()) &&
|
|
||||||
this.arduinoPreferences.get('arduino.survey.notification')
|
|
||||||
) {
|
|
||||||
const surveyAnswered = await this.localStorageService.getData(
|
|
||||||
this.surveyKey(surveyId)
|
|
||||||
);
|
|
||||||
if (surveyAnswered !== undefined) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
const answer = await this.messageService.info(
|
|
||||||
SURVEY_MESSAGE,
|
|
||||||
DO_NOT_SHOW_AGAIN,
|
|
||||||
GO_TO_SURVEY
|
|
||||||
);
|
|
||||||
switch (answer) {
|
|
||||||
case GO_TO_SURVEY:
|
|
||||||
this.windowService.openNewWindow(SURVEY_BASE_URL + surveyId, {
|
|
||||||
external: true,
|
|
||||||
});
|
|
||||||
this.localStorageService.setData(this.surveyKey(surveyId), true);
|
|
||||||
break;
|
|
||||||
case DO_NOT_SHOW_AGAIN:
|
|
||||||
this.localStorageService.setData(this.surveyKey(surveyId), false);
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
private surveyKey(id: string): string {
|
|
||||||
return `answered_survey:${id}`;
|
|
||||||
}
|
|
||||||
}
|
|
@@ -1,4 +1,4 @@
|
|||||||
import { inject, injectable } from '@theia/core/shared/inversify';
|
import { inject, injectable } from 'inversify';
|
||||||
import {
|
import {
|
||||||
Command,
|
Command,
|
||||||
MenuModelRegistry,
|
MenuModelRegistry,
|
||||||
@@ -39,7 +39,7 @@ export class UploadCertificate extends Contribution {
|
|||||||
|
|
||||||
protected dialogOpened = false;
|
protected dialogOpened = false;
|
||||||
|
|
||||||
override registerCommands(registry: CommandRegistry): void {
|
registerCommands(registry: CommandRegistry): void {
|
||||||
registry.registerCommand(UploadCertificate.Commands.OPEN, {
|
registry.registerCommand(UploadCertificate.Commands.OPEN, {
|
||||||
execute: async () => {
|
execute: async () => {
|
||||||
try {
|
try {
|
||||||
@@ -93,7 +93,7 @@ export class UploadCertificate extends Contribution {
|
|||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
override registerMenus(registry: MenuModelRegistry): void {
|
registerMenus(registry: MenuModelRegistry): void {
|
||||||
registry.registerMenuAction(ArduinoMenus.TOOLS__FIRMWARE_UPLOADER_GROUP, {
|
registry.registerMenuAction(ArduinoMenus.TOOLS__FIRMWARE_UPLOADER_GROUP, {
|
||||||
commandId: UploadCertificate.Commands.OPEN.id,
|
commandId: UploadCertificate.Commands.OPEN.id,
|
||||||
label: UploadCertificate.Commands.OPEN.label,
|
label: UploadCertificate.Commands.OPEN.label,
|
||||||
|
@@ -1,4 +1,4 @@
|
|||||||
import { inject, injectable } from '@theia/core/shared/inversify';
|
import { inject, injectable } from 'inversify';
|
||||||
import {
|
import {
|
||||||
Command,
|
Command,
|
||||||
MenuModelRegistry,
|
MenuModelRegistry,
|
||||||
@@ -16,7 +16,7 @@ export class UploadFirmware extends Contribution {
|
|||||||
|
|
||||||
protected dialogOpened = false;
|
protected dialogOpened = false;
|
||||||
|
|
||||||
override registerCommands(registry: CommandRegistry): void {
|
registerCommands(registry: CommandRegistry): void {
|
||||||
registry.registerCommand(UploadFirmware.Commands.OPEN, {
|
registry.registerCommand(UploadFirmware.Commands.OPEN, {
|
||||||
execute: async () => {
|
execute: async () => {
|
||||||
try {
|
try {
|
||||||
@@ -30,7 +30,7 @@ export class UploadFirmware extends Contribution {
|
|||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
override registerMenus(registry: MenuModelRegistry): void {
|
registerMenus(registry: MenuModelRegistry): void {
|
||||||
registry.registerMenuAction(ArduinoMenus.TOOLS__FIRMWARE_UPLOADER_GROUP, {
|
registry.registerMenuAction(ArduinoMenus.TOOLS__FIRMWARE_UPLOADER_GROUP, {
|
||||||
commandId: UploadFirmware.Commands.OPEN.id,
|
commandId: UploadFirmware.Commands.OPEN.id,
|
||||||
label: UploadFirmware.Commands.OPEN.label,
|
label: UploadFirmware.Commands.OPEN.label,
|
||||||
|
@@ -1,4 +1,4 @@
|
|||||||
import { inject, injectable } from '@theia/core/shared/inversify';
|
import { inject, injectable, postConstruct } from 'inversify';
|
||||||
import { Emitter } from '@theia/core/lib/common/event';
|
import { Emitter } from '@theia/core/lib/common/event';
|
||||||
import { BoardUserField, CoreService } from '../../common/protocol';
|
import { BoardUserField, CoreService } from '../../common/protocol';
|
||||||
import { ArduinoMenus, PlaceholderMenuNode } from '../menu/arduino-menus';
|
import { ArduinoMenus, PlaceholderMenuNode } from '../menu/arduino-menus';
|
||||||
@@ -6,7 +6,7 @@ import { ArduinoToolbar } from '../toolbar/arduino-toolbar';
|
|||||||
import { BoardsDataStore } from '../boards/boards-data-store';
|
import { BoardsDataStore } from '../boards/boards-data-store';
|
||||||
import { BoardsServiceProvider } from '../boards/boards-service-provider';
|
import { BoardsServiceProvider } from '../boards/boards-service-provider';
|
||||||
import {
|
import {
|
||||||
CoreServiceContribution,
|
SketchContribution,
|
||||||
Command,
|
Command,
|
||||||
CommandRegistry,
|
CommandRegistry,
|
||||||
MenuModelRegistry,
|
MenuModelRegistry,
|
||||||
@@ -15,10 +15,12 @@ import {
|
|||||||
} from './contribution';
|
} from './contribution';
|
||||||
import { UserFieldsDialog } from '../dialogs/user-fields/user-fields-dialog';
|
import { UserFieldsDialog } from '../dialogs/user-fields/user-fields-dialog';
|
||||||
import { DisposableCollection, nls } from '@theia/core/lib/common';
|
import { DisposableCollection, nls } from '@theia/core/lib/common';
|
||||||
import { CurrentSketch } from '../../common/protocol/sketches-service-client-impl';
|
|
||||||
|
|
||||||
@injectable()
|
@injectable()
|
||||||
export class UploadSketch extends CoreServiceContribution {
|
export class UploadSketch extends SketchContribution {
|
||||||
|
@inject(CoreService)
|
||||||
|
protected readonly coreService: CoreService;
|
||||||
|
|
||||||
@inject(MenuModelRegistry)
|
@inject(MenuModelRegistry)
|
||||||
protected readonly menuRegistry: MenuModelRegistry;
|
protected readonly menuRegistry: MenuModelRegistry;
|
||||||
|
|
||||||
@@ -41,8 +43,8 @@ export class UploadSketch extends CoreServiceContribution {
|
|||||||
|
|
||||||
protected readonly menuActionsDisposables = new DisposableCollection();
|
protected readonly menuActionsDisposables = new DisposableCollection();
|
||||||
|
|
||||||
protected override init(): void {
|
@postConstruct()
|
||||||
super.init();
|
protected init(): void {
|
||||||
this.boardsServiceClientImpl.onBoardsConfigChanged(async () => {
|
this.boardsServiceClientImpl.onBoardsConfigChanged(async () => {
|
||||||
const userFields =
|
const userFields =
|
||||||
await this.boardsServiceClientImpl.selectedBoardUserFields();
|
await this.boardsServiceClientImpl.selectedBoardUserFields();
|
||||||
@@ -66,7 +68,7 @@ export class UploadSketch extends CoreServiceContribution {
|
|||||||
return fqbn + '|' + address;
|
return fqbn + '|' + address;
|
||||||
}
|
}
|
||||||
|
|
||||||
override registerCommands(registry: CommandRegistry): void {
|
registerCommands(registry: CommandRegistry): void {
|
||||||
registry.registerCommand(UploadSketch.Commands.UPLOAD_SKETCH, {
|
registry.registerCommand(UploadSketch.Commands.UPLOAD_SKETCH, {
|
||||||
execute: async () => {
|
execute: async () => {
|
||||||
const key = this.selectedFqbnAddress();
|
const key = this.selectedFqbnAddress();
|
||||||
@@ -128,7 +130,7 @@ export class UploadSketch extends CoreServiceContribution {
|
|||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
override registerMenus(registry: MenuModelRegistry): void {
|
registerMenus(registry: MenuModelRegistry): void {
|
||||||
this.menuActionsDisposables.dispose();
|
this.menuActionsDisposables.dispose();
|
||||||
|
|
||||||
this.menuActionsDisposables.push(
|
this.menuActionsDisposables.push(
|
||||||
@@ -171,7 +173,7 @@ export class UploadSketch extends CoreServiceContribution {
|
|||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
override registerKeybindings(registry: KeybindingRegistry): void {
|
registerKeybindings(registry: KeybindingRegistry): void {
|
||||||
registry.registerKeybinding({
|
registry.registerKeybinding({
|
||||||
command: UploadSketch.Commands.UPLOAD_SKETCH.id,
|
command: UploadSketch.Commands.UPLOAD_SKETCH.id,
|
||||||
keybinding: 'CtrlCmd+U',
|
keybinding: 'CtrlCmd+U',
|
||||||
@@ -182,7 +184,7 @@ export class UploadSketch extends CoreServiceContribution {
|
|||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
override registerToolbarItems(registry: TabBarToolbarRegistry): void {
|
registerToolbarItems(registry: TabBarToolbarRegistry): void {
|
||||||
registry.registerItem({
|
registry.registerItem({
|
||||||
id: UploadSketch.Commands.UPLOAD_SKETCH_TOOLBAR.id,
|
id: UploadSketch.Commands.UPLOAD_SKETCH_TOOLBAR.id,
|
||||||
command: UploadSketch.Commands.UPLOAD_SKETCH_TOOLBAR.id,
|
command: UploadSketch.Commands.UPLOAD_SKETCH_TOOLBAR.id,
|
||||||
@@ -198,17 +200,16 @@ export class UploadSketch extends CoreServiceContribution {
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// toggle the toolbar button and menu item state.
|
||||||
|
// uploadInProgress will be set to false whether the upload fails or not
|
||||||
|
this.uploadInProgress = true;
|
||||||
|
this.onDidChangeEmitter.fire();
|
||||||
const sketch = await this.sketchServiceClient.currentSketch();
|
const sketch = await this.sketchServiceClient.currentSketch();
|
||||||
if (!CurrentSketch.isValid(sketch)) {
|
if (!sketch) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
try {
|
try {
|
||||||
// toggle the toolbar button and menu item state.
|
|
||||||
// uploadInProgress will be set to false whether the upload fails or not
|
|
||||||
this.uploadInProgress = true;
|
|
||||||
this.coreErrorHandler.reset();
|
|
||||||
this.onDidChangeEmitter.fire();
|
|
||||||
const { boardsConfig } = this.boardsServiceClientImpl;
|
const { boardsConfig } = this.boardsServiceClientImpl;
|
||||||
const [fqbn, { selectedProgrammer }, verify, verbose, sourceOverride] =
|
const [fqbn, { selectedProgrammer }, verify, verbose, sourceOverride] =
|
||||||
await Promise.all([
|
await Promise.all([
|
||||||
@@ -225,8 +226,9 @@ export class UploadSketch extends CoreServiceContribution {
|
|||||||
...boardsConfig.selectedBoard,
|
...boardsConfig.selectedBoard,
|
||||||
name: boardsConfig.selectedBoard?.name || '',
|
name: boardsConfig.selectedBoard?.name || '',
|
||||||
fqbn,
|
fqbn,
|
||||||
};
|
}
|
||||||
let options: CoreService.Upload.Options | undefined = undefined;
|
let options: CoreService.Upload.Options | undefined = undefined;
|
||||||
|
const sketchUri = sketch.uri;
|
||||||
const optimizeForDebug = this.editorMode.compileForDebug;
|
const optimizeForDebug = this.editorMode.compileForDebug;
|
||||||
const { selectedPort } = boardsConfig;
|
const { selectedPort } = boardsConfig;
|
||||||
const port = selectedPort;
|
const port = selectedPort;
|
||||||
@@ -245,7 +247,7 @@ export class UploadSketch extends CoreServiceContribution {
|
|||||||
if (usingProgrammer) {
|
if (usingProgrammer) {
|
||||||
const programmer = selectedProgrammer;
|
const programmer = selectedProgrammer;
|
||||||
options = {
|
options = {
|
||||||
sketch,
|
sketchUri,
|
||||||
board,
|
board,
|
||||||
optimizeForDebug,
|
optimizeForDebug,
|
||||||
programmer,
|
programmer,
|
||||||
@@ -257,7 +259,7 @@ export class UploadSketch extends CoreServiceContribution {
|
|||||||
};
|
};
|
||||||
} else {
|
} else {
|
||||||
options = {
|
options = {
|
||||||
sketch,
|
sketchUri,
|
||||||
board,
|
board,
|
||||||
optimizeForDebug,
|
optimizeForDebug,
|
||||||
port,
|
port,
|
||||||
@@ -278,7 +280,13 @@ export class UploadSketch extends CoreServiceContribution {
|
|||||||
{ timeout: 3000 }
|
{ timeout: 3000 }
|
||||||
);
|
);
|
||||||
} catch (e) {
|
} catch (e) {
|
||||||
this.handleError(e);
|
let errorMessage = '';
|
||||||
|
if (typeof e === 'string') {
|
||||||
|
errorMessage = e;
|
||||||
|
} else {
|
||||||
|
errorMessage = e.toString();
|
||||||
|
}
|
||||||
|
this.messageService.error(errorMessage);
|
||||||
} finally {
|
} finally {
|
||||||
this.uploadInProgress = false;
|
this.uploadInProgress = false;
|
||||||
this.onDidChangeEmitter.fire();
|
this.onDidChangeEmitter.fire();
|
||||||
|
@@ -1,11 +1,12 @@
|
|||||||
import { inject, injectable } from '@theia/core/shared/inversify';
|
import { inject, injectable } from 'inversify';
|
||||||
import { Emitter } from '@theia/core/lib/common/event';
|
import { Emitter } from '@theia/core/lib/common/event';
|
||||||
|
import { CoreService } from '../../common/protocol';
|
||||||
import { ArduinoMenus } from '../menu/arduino-menus';
|
import { ArduinoMenus } from '../menu/arduino-menus';
|
||||||
import { ArduinoToolbar } from '../toolbar/arduino-toolbar';
|
import { ArduinoToolbar } from '../toolbar/arduino-toolbar';
|
||||||
import { BoardsDataStore } from '../boards/boards-data-store';
|
import { BoardsDataStore } from '../boards/boards-data-store';
|
||||||
import { BoardsServiceProvider } from '../boards/boards-service-provider';
|
import { BoardsServiceProvider } from '../boards/boards-service-provider';
|
||||||
import {
|
import {
|
||||||
CoreServiceContribution,
|
SketchContribution,
|
||||||
Command,
|
Command,
|
||||||
CommandRegistry,
|
CommandRegistry,
|
||||||
MenuModelRegistry,
|
MenuModelRegistry,
|
||||||
@@ -13,10 +14,12 @@ import {
|
|||||||
TabBarToolbarRegistry,
|
TabBarToolbarRegistry,
|
||||||
} from './contribution';
|
} from './contribution';
|
||||||
import { nls } from '@theia/core/lib/common';
|
import { nls } from '@theia/core/lib/common';
|
||||||
import { CurrentSketch } from '../../common/protocol/sketches-service-client-impl';
|
|
||||||
|
|
||||||
@injectable()
|
@injectable()
|
||||||
export class VerifySketch extends CoreServiceContribution {
|
export class VerifySketch extends SketchContribution {
|
||||||
|
@inject(CoreService)
|
||||||
|
protected readonly coreService: CoreService;
|
||||||
|
|
||||||
@inject(BoardsDataStore)
|
@inject(BoardsDataStore)
|
||||||
protected readonly boardsDataStore: BoardsDataStore;
|
protected readonly boardsDataStore: BoardsDataStore;
|
||||||
|
|
||||||
@@ -28,7 +31,7 @@ export class VerifySketch extends CoreServiceContribution {
|
|||||||
|
|
||||||
protected verifyInProgress = false;
|
protected verifyInProgress = false;
|
||||||
|
|
||||||
override registerCommands(registry: CommandRegistry): void {
|
registerCommands(registry: CommandRegistry): void {
|
||||||
registry.registerCommand(VerifySketch.Commands.VERIFY_SKETCH, {
|
registry.registerCommand(VerifySketch.Commands.VERIFY_SKETCH, {
|
||||||
execute: () => this.verifySketch(),
|
execute: () => this.verifySketch(),
|
||||||
isEnabled: () => !this.verifyInProgress,
|
isEnabled: () => !this.verifyInProgress,
|
||||||
@@ -47,7 +50,7 @@ export class VerifySketch extends CoreServiceContribution {
|
|||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
override registerMenus(registry: MenuModelRegistry): void {
|
registerMenus(registry: MenuModelRegistry): void {
|
||||||
registry.registerMenuAction(ArduinoMenus.SKETCH__MAIN_GROUP, {
|
registry.registerMenuAction(ArduinoMenus.SKETCH__MAIN_GROUP, {
|
||||||
commandId: VerifySketch.Commands.VERIFY_SKETCH.id,
|
commandId: VerifySketch.Commands.VERIFY_SKETCH.id,
|
||||||
label: nls.localize('arduino/sketch/verifyOrCompile', 'Verify/Compile'),
|
label: nls.localize('arduino/sketch/verifyOrCompile', 'Verify/Compile'),
|
||||||
@@ -63,7 +66,7 @@ export class VerifySketch extends CoreServiceContribution {
|
|||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
override registerKeybindings(registry: KeybindingRegistry): void {
|
registerKeybindings(registry: KeybindingRegistry): void {
|
||||||
registry.registerKeybinding({
|
registry.registerKeybinding({
|
||||||
command: VerifySketch.Commands.VERIFY_SKETCH.id,
|
command: VerifySketch.Commands.VERIFY_SKETCH.id,
|
||||||
keybinding: 'CtrlCmd+R',
|
keybinding: 'CtrlCmd+R',
|
||||||
@@ -74,7 +77,7 @@ export class VerifySketch extends CoreServiceContribution {
|
|||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
override registerToolbarItems(registry: TabBarToolbarRegistry): void {
|
registerToolbarItems(registry: TabBarToolbarRegistry): void {
|
||||||
registry.registerItem({
|
registry.registerItem({
|
||||||
id: VerifySketch.Commands.VERIFY_SKETCH_TOOLBAR.id,
|
id: VerifySketch.Commands.VERIFY_SKETCH_TOOLBAR.id,
|
||||||
command: VerifySketch.Commands.VERIFY_SKETCH_TOOLBAR.id,
|
command: VerifySketch.Commands.VERIFY_SKETCH_TOOLBAR.id,
|
||||||
@@ -92,14 +95,14 @@ export class VerifySketch extends CoreServiceContribution {
|
|||||||
|
|
||||||
// toggle the toolbar button and menu item state.
|
// toggle the toolbar button and menu item state.
|
||||||
// verifyInProgress will be set to false whether the compilation fails or not
|
// verifyInProgress will be set to false whether the compilation fails or not
|
||||||
|
this.verifyInProgress = true;
|
||||||
|
this.onDidChangeEmitter.fire();
|
||||||
const sketch = await this.sketchServiceClient.currentSketch();
|
const sketch = await this.sketchServiceClient.currentSketch();
|
||||||
if (!CurrentSketch.isValid(sketch)) {
|
|
||||||
|
if (!sketch) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
try {
|
try {
|
||||||
this.verifyInProgress = true;
|
|
||||||
this.coreErrorHandler.reset();
|
|
||||||
this.onDidChangeEmitter.fire();
|
|
||||||
const { boardsConfig } = this.boardsServiceClientImpl;
|
const { boardsConfig } = this.boardsServiceClientImpl;
|
||||||
const [fqbn, sourceOverride] = await Promise.all([
|
const [fqbn, sourceOverride] = await Promise.all([
|
||||||
this.boardsDataStore.appendConfigToFqbn(
|
this.boardsDataStore.appendConfigToFqbn(
|
||||||
@@ -111,12 +114,12 @@ export class VerifySketch extends CoreServiceContribution {
|
|||||||
...boardsConfig.selectedBoard,
|
...boardsConfig.selectedBoard,
|
||||||
name: boardsConfig.selectedBoard?.name || '',
|
name: boardsConfig.selectedBoard?.name || '',
|
||||||
fqbn,
|
fqbn,
|
||||||
};
|
}
|
||||||
const verbose = this.preferences.get('arduino.compile.verbose');
|
const verbose = this.preferences.get('arduino.compile.verbose');
|
||||||
const compilerWarnings = this.preferences.get('arduino.compile.warnings');
|
const compilerWarnings = this.preferences.get('arduino.compile.warnings');
|
||||||
this.outputChannelManager.getChannel('Arduino').clear();
|
this.outputChannelManager.getChannel('Arduino').clear();
|
||||||
await this.coreService.compile({
|
await this.coreService.compile({
|
||||||
sketch,
|
sketchUri: sketch.uri,
|
||||||
board,
|
board,
|
||||||
optimizeForDebug: this.editorMode.compileForDebug,
|
optimizeForDebug: this.editorMode.compileForDebug,
|
||||||
verbose,
|
verbose,
|
||||||
@@ -129,7 +132,13 @@ export class VerifySketch extends CoreServiceContribution {
|
|||||||
{ timeout: 3000 }
|
{ timeout: 3000 }
|
||||||
);
|
);
|
||||||
} catch (e) {
|
} catch (e) {
|
||||||
this.handleError(e);
|
let errorMessage = "";
|
||||||
|
if (typeof e === "string") {
|
||||||
|
errorMessage = e;
|
||||||
|
} else {
|
||||||
|
errorMessage = e.toString();
|
||||||
|
}
|
||||||
|
this.messageService.error(errorMessage);
|
||||||
} finally {
|
} finally {
|
||||||
this.verifyInProgress = false;
|
this.verifyInProgress = false;
|
||||||
this.onDidChangeEmitter.fire();
|
this.onDidChangeEmitter.fire();
|
||||||
|
@@ -1,4 +1,4 @@
|
|||||||
import { injectable, inject } from '@theia/core/shared/inversify';
|
import { injectable, inject } from 'inversify';
|
||||||
import * as createPaths from './create-paths';
|
import * as createPaths from './create-paths';
|
||||||
import { posix } from './create-paths';
|
import { posix } from './create-paths';
|
||||||
import { AuthenticationClientService } from '../auth/authentication-client-service';
|
import { AuthenticationClientService } from '../auth/authentication-client-service';
|
||||||
@@ -117,11 +117,11 @@ export class CreateApi {
|
|||||||
headers,
|
headers,
|
||||||
})
|
})
|
||||||
).sketches;
|
).sketches;
|
||||||
if (partialSketches.length !== 0) {
|
if (partialSketches.length != 0) {
|
||||||
result.sketches = result.sketches.concat(partialSketches);
|
result.sketches = result.sketches.concat(partialSketches);
|
||||||
}
|
}
|
||||||
currentOffset = currentOffset + limit;
|
currentOffset = currentOffset + limit;
|
||||||
} while (partialSketches.length !== 0);
|
} while (partialSketches.length != 0);
|
||||||
|
|
||||||
result.sketches.forEach((sketch) => this.sketchCache.addSketch(sketch));
|
result.sketches.forEach((sketch) => this.sketchCache.addSketch(sketch));
|
||||||
return result.sketches;
|
return result.sketches;
|
||||||
|
@@ -1,4 +1,4 @@
|
|||||||
import { inject, injectable } from '@theia/core/shared/inversify';
|
import { inject, injectable } from 'inversify';
|
||||||
import URI from '@theia/core/lib/common/uri';
|
import URI from '@theia/core/lib/common/uri';
|
||||||
import { Event } from '@theia/core/lib/common/event';
|
import { Event } from '@theia/core/lib/common/event';
|
||||||
import {
|
import {
|
||||||
|
@@ -1,149 +0,0 @@
|
|||||||
{
|
|
||||||
"name": "Arduino dark",
|
|
||||||
"type": "dark",
|
|
||||||
"colors": {
|
|
||||||
"list.highlightForeground": "#0ca1a6",
|
|
||||||
"list.activeSelectionForeground": "#dae3e3",
|
|
||||||
"list.activeSelectionBackground": "#434f54",
|
|
||||||
"list.inactiveSelectionForeground": "#dae3e3",
|
|
||||||
"list.inactiveSelectionBackground": "#434f54",
|
|
||||||
"list.hoverBackground": "#1f272a",
|
|
||||||
"progressBar.background": "#005c5f",
|
|
||||||
"editor.background": "#1f272a",
|
|
||||||
"editor.foreground": "#dae3e3",
|
|
||||||
"editor.lineHighlightBackground": "#434f5410",
|
|
||||||
"editor.selectionBackground": "#f1c40f",
|
|
||||||
"editorCursor.foreground": "#434f54",
|
|
||||||
"editorWhitespace.foreground": "#bfbfbf",
|
|
||||||
"editorWidget.background": "#171e21",
|
|
||||||
"focusBorder": "#dae3e3",
|
|
||||||
"menubar.selectionBackground": "#ffffff",
|
|
||||||
"menubar.selectionForeground": "#212121",
|
|
||||||
"menu.selectionBackground": "#dae3e3",
|
|
||||||
"menu.selectionForeground": "#212121",
|
|
||||||
"editorGroupHeader.tabsBackground": "#171e21",
|
|
||||||
"button.background": "#0ca1a6",
|
|
||||||
"titleBar.activeBackground": "#171e21",
|
|
||||||
"titleBar.activeForeground": "#dae3e3",
|
|
||||||
"terminal.background": "#000000",
|
|
||||||
"terminal.foreground": "#e0e0e0",
|
|
||||||
"dropdown.border": "#7fcbcd",
|
|
||||||
"dropdown.background": "#2c353a",
|
|
||||||
"dropdown.foreground": "#dae3e3",
|
|
||||||
"activityBar.background": "#171e21",
|
|
||||||
"activityBar.foreground": "#dae3e3",
|
|
||||||
"activityBar.inactiveForeground": "#4e5b61",
|
|
||||||
"activityBar.activeBorder": "#0ca1a6",
|
|
||||||
"statusBar.background": "#171e21",
|
|
||||||
"secondaryButton.background": "#ff000000",
|
|
||||||
"secondaryButton.foreground": "#dae3e3",
|
|
||||||
"secondaryButton.hoverBackground": "#434f54",
|
|
||||||
"arduino.branding.primary": "#0ca1a6",
|
|
||||||
"arduino.branding.secondary": "#b5c8c9",
|
|
||||||
"arduino.foreground": "#edf1f1",
|
|
||||||
"arduino.output.foreground": "#ffffff",
|
|
||||||
"arduino.output.background": "#000000",
|
|
||||||
"arduino.toolbar.hoverBackground": "#dae3e3",
|
|
||||||
"sideBar.background": "#101618",
|
|
||||||
"input.background": "#000000",
|
|
||||||
"foreground": "#dae3e3",
|
|
||||||
"settings.headerForeground": "#dae3e3",
|
|
||||||
"tree.indentGuidesStroke": "#374146",
|
|
||||||
"tab.unfocusedActiveForeground": "#dae3e3",
|
|
||||||
"tab.inactiveBackground": "#171e21"
|
|
||||||
},
|
|
||||||
"tokenColors": [
|
|
||||||
{
|
|
||||||
"name": "",
|
|
||||||
"settings": {
|
|
||||||
"foreground": "#dae3e3"
|
|
||||||
}
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"name": "Comments",
|
|
||||||
"scope": "comment",
|
|
||||||
"settings": {
|
|
||||||
"foreground": "#7f8c8d"
|
|
||||||
}
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"name": "Keywords Attributes",
|
|
||||||
"scope": [
|
|
||||||
"storage",
|
|
||||||
"support",
|
|
||||||
"string.quoted.single.c"
|
|
||||||
],
|
|
||||||
"settings": {
|
|
||||||
"foreground": "#0ca1a6"
|
|
||||||
}
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"name": "literal",
|
|
||||||
"scope": [
|
|
||||||
"meta.function.c",
|
|
||||||
"entity.name.function",
|
|
||||||
"meta.function-call.c",
|
|
||||||
"variable.other"
|
|
||||||
],
|
|
||||||
"settings": {
|
|
||||||
"foreground": "#F39C12"
|
|
||||||
}
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"name": "punctuation",
|
|
||||||
"scope": [
|
|
||||||
"punctuation.section",
|
|
||||||
"meta.function-call.c",
|
|
||||||
"meta.block.c",
|
|
||||||
"meta.function.c",
|
|
||||||
"variable",
|
|
||||||
"variable.name"
|
|
||||||
],
|
|
||||||
"settings": {
|
|
||||||
"foreground": "#dae3e3"
|
|
||||||
}
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"name": "function preprocessor",
|
|
||||||
"scope": [
|
|
||||||
"entity.name.function.preprocessor.c",
|
|
||||||
"meta.preprocessor.macro.c"
|
|
||||||
],
|
|
||||||
"settings": {
|
|
||||||
"foreground": "#569CD6"
|
|
||||||
}
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"name": "constants",
|
|
||||||
"scope": [
|
|
||||||
"string.quoted.double",
|
|
||||||
"string.quoted.other.lt-gt",
|
|
||||||
"constant"
|
|
||||||
],
|
|
||||||
"settings": {
|
|
||||||
"foreground": "#7fcbcd"
|
|
||||||
}
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"name": "meta keywords",
|
|
||||||
"scope": [
|
|
||||||
"keyword.control",
|
|
||||||
"meta.preprocessor.c"
|
|
||||||
],
|
|
||||||
"settings": {
|
|
||||||
"foreground": "#C586C0"
|
|
||||||
}
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"name": "numeric preprocessor",
|
|
||||||
"scope": [
|
|
||||||
"meta.preprocessor.macro.c",
|
|
||||||
"constant.numeric.preprocessor.c",
|
|
||||||
"meta.preprocessor.c"
|
|
||||||
],
|
|
||||||
"settings": {
|
|
||||||
"foreground": "#434f54"
|
|
||||||
}
|
|
||||||
}
|
|
||||||
]
|
|
||||||
}
|
|
@@ -1,149 +0,0 @@
|
|||||||
{
|
|
||||||
"name": "Arduino default",
|
|
||||||
"type": "default",
|
|
||||||
"colors": {
|
|
||||||
"list.highlightForeground": "#008184",
|
|
||||||
"list.activeSelectionForeground": "#4e5b61",
|
|
||||||
"list.activeSelectionBackground": "#dae3e3",
|
|
||||||
"list.inactiveSelectionForeground": "#4e5b61",
|
|
||||||
"list.inactiveSelectionBackground": "#dae3e3",
|
|
||||||
"list.hoverBackground": "#ecf1f1",
|
|
||||||
"progressBar.background": "#005c5f",
|
|
||||||
"editor.background": "#ffffff",
|
|
||||||
"editor.foreground": "#4e5b61",
|
|
||||||
"editor.lineHighlightBackground": "#434f5410",
|
|
||||||
"editor.selectionBackground": "#f1c40f",
|
|
||||||
"editorCursor.foreground": "#434f54",
|
|
||||||
"editorWhitespace.foreground": "#bfbfbf",
|
|
||||||
"editorWidget.background": "#f7f9f9",
|
|
||||||
"focusBorder": "#7fcbcd",
|
|
||||||
"menubar.selectionBackground": "#ffffff",
|
|
||||||
"menubar.selectionForeground": "#212121",
|
|
||||||
"menu.selectionBackground": "#dae3e3",
|
|
||||||
"menu.selectionForeground": "#212121",
|
|
||||||
"editorGroupHeader.tabsBackground": "#ecf1f1",
|
|
||||||
"button.background": "#7fcbcd",
|
|
||||||
"titleBar.activeBackground": "#006d70",
|
|
||||||
"titleBar.activeForeground": "#f7f9f9",
|
|
||||||
"terminal.background": "#000000",
|
|
||||||
"terminal.foreground": "#e0e0e0",
|
|
||||||
"dropdown.border": "#f7f9f9",
|
|
||||||
"dropdown.background": "#ffffff",
|
|
||||||
"dropdown.foreground": "#4e5b61",
|
|
||||||
"activityBar.background": "#ecf1f1",
|
|
||||||
"activityBar.foreground": "#4e5b61",
|
|
||||||
"activityBar.inactiveForeground": "#bdc7c7",
|
|
||||||
"activityBar.activeBorder": "#008184",
|
|
||||||
"statusBar.background": "#006d70",
|
|
||||||
"secondaryButton.background": "#ff000000",
|
|
||||||
"secondaryButton.foreground": "#008184",
|
|
||||||
"secondaryButton.hoverBackground": "#dae3e3",
|
|
||||||
"arduino.branding.primary": "#008184",
|
|
||||||
"arduino.branding.secondary": "#b5c8c9",
|
|
||||||
"arduino.foreground": "#edf1f1",
|
|
||||||
"arduino.output.foreground": "#ffffff",
|
|
||||||
"arduino.output.background": "#000000",
|
|
||||||
"arduino.toolbar.hoverBackground": "#f7f9f9",
|
|
||||||
"sideBar.background": "#f7f9f9",
|
|
||||||
"input.background": "#ffffff",
|
|
||||||
"foreground": "#4e5b61",
|
|
||||||
"settings.headerForeground": "#4e5b61",
|
|
||||||
"tree.indentGuidesStroke": "#dae3e3",
|
|
||||||
"tab.unfocusedActiveForeground": "#4e5b61",
|
|
||||||
"tab.inactiveBackground": "#ecf1f1"
|
|
||||||
},
|
|
||||||
"tokenColors": [
|
|
||||||
{
|
|
||||||
"name": "",
|
|
||||||
"settings": {
|
|
||||||
"foreground": "#434f54"
|
|
||||||
}
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"name": "Comments",
|
|
||||||
"scope": "comment",
|
|
||||||
"settings": {
|
|
||||||
"foreground": "#95a5a6cc"
|
|
||||||
}
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"name": "Keywords Attributes",
|
|
||||||
"scope": [
|
|
||||||
"storage",
|
|
||||||
"support",
|
|
||||||
"string.quoted.single.c"
|
|
||||||
],
|
|
||||||
"settings": {
|
|
||||||
"foreground": "#00979D"
|
|
||||||
}
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"name": "literal",
|
|
||||||
"scope": [
|
|
||||||
"meta.function.c",
|
|
||||||
"entity.name.function",
|
|
||||||
"meta.function-call.c",
|
|
||||||
"variable.other"
|
|
||||||
],
|
|
||||||
"settings": {
|
|
||||||
"foreground": "#D35400"
|
|
||||||
}
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"name": "punctuation",
|
|
||||||
"scope": [
|
|
||||||
"punctuation.section",
|
|
||||||
"meta.function-call.c",
|
|
||||||
"meta.block.c",
|
|
||||||
"meta.function.c",
|
|
||||||
"variable",
|
|
||||||
"variable.name"
|
|
||||||
],
|
|
||||||
"settings": {
|
|
||||||
"foreground": "#434f54"
|
|
||||||
}
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"name": "function preprocessor",
|
|
||||||
"scope": [
|
|
||||||
"entity.name.function.preprocessor.c",
|
|
||||||
"meta.preprocessor.macro.c"
|
|
||||||
],
|
|
||||||
"settings": {
|
|
||||||
"foreground": "#9e846d"
|
|
||||||
}
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"name": "constants",
|
|
||||||
"scope": [
|
|
||||||
"string.quoted.double",
|
|
||||||
"string.quoted.other.lt-gt",
|
|
||||||
"constant"
|
|
||||||
],
|
|
||||||
"settings": {
|
|
||||||
"foreground": "#005C5F"
|
|
||||||
}
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"name": "meta keywords",
|
|
||||||
"scope": [
|
|
||||||
"keyword.control",
|
|
||||||
"meta.preprocessor.c"
|
|
||||||
],
|
|
||||||
"settings": {
|
|
||||||
"foreground": "#728E00"
|
|
||||||
}
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"name": "numeric preprocessor",
|
|
||||||
"scope": [
|
|
||||||
"meta.preprocessor.macro.c",
|
|
||||||
"constant.numeric.preprocessor.c",
|
|
||||||
"meta.preprocessor.c"
|
|
||||||
],
|
|
||||||
"settings": {
|
|
||||||
"foreground": "#434f54"
|
|
||||||
}
|
|
||||||
}
|
|
||||||
]
|
|
||||||
}
|
|
@@ -1,5 +1,5 @@
|
|||||||
import { nls } from '@theia/core/lib/common';
|
import { nls } from '@theia/core/lib/common';
|
||||||
import * as React from '@theia/core/shared/react';
|
import * as React from 'react';
|
||||||
|
|
||||||
export const CertificateAddComponent = ({
|
export const CertificateAddComponent = ({
|
||||||
addCertificate,
|
addCertificate,
|
||||||
@@ -8,12 +8,9 @@ export const CertificateAddComponent = ({
|
|||||||
}): React.ReactElement => {
|
}): React.ReactElement => {
|
||||||
const [value, setValue] = React.useState('');
|
const [value, setValue] = React.useState('');
|
||||||
|
|
||||||
const handleChange = React.useCallback(
|
const handleChange = React.useCallback((event) => {
|
||||||
(event: React.ChangeEvent<HTMLInputElement>) => {
|
setValue(event.target.value);
|
||||||
setValue(event.target.value);
|
}, []);
|
||||||
},
|
|
||||||
[]
|
|
||||||
);
|
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<form
|
<form
|
||||||
|
@@ -1,4 +1,4 @@
|
|||||||
import * as React from '@theia/core/shared/react';
|
import * as React from 'react';
|
||||||
|
|
||||||
export const CertificateListComponent = ({
|
export const CertificateListComponent = ({
|
||||||
certificates,
|
certificates,
|
||||||
|
@@ -1,4 +1,4 @@
|
|||||||
import * as React from '@theia/core/shared/react';
|
import * as React from 'react';
|
||||||
import Tippy from '@tippyjs/react';
|
import Tippy from '@tippyjs/react';
|
||||||
import { AvailableBoard } from '../../boards/boards-service-provider';
|
import { AvailableBoard } from '../../boards/boards-service-provider';
|
||||||
import { CertificateListComponent } from './certificate-list';
|
import { CertificateListComponent } from './certificate-list';
|
||||||
|
@@ -1,9 +1,9 @@
|
|||||||
import * as React from '@theia/core/shared/react';
|
import * as React from 'react';
|
||||||
import { inject, injectable, postConstruct } from '@theia/core/shared/inversify';
|
import { inject, injectable, postConstruct } from 'inversify';
|
||||||
import { DialogProps } from '@theia/core/lib/browser/dialogs';
|
import { DialogProps } from '@theia/core/lib/browser/dialogs';
|
||||||
import { AbstractDialog } from '../../theia/dialogs/dialogs';
|
import { AbstractDialog } from '../../theia/dialogs/dialogs';
|
||||||
import { Widget } from '@theia/core/shared/@phosphor/widgets';
|
import { Widget } from '@phosphor/widgets';
|
||||||
import { Message } from '@theia/core/shared/@phosphor/messaging';
|
import { Message } from '@phosphor/messaging';
|
||||||
import { ReactWidget } from '@theia/core/lib/browser/widgets/react-widget';
|
import { ReactWidget } from '@theia/core/lib/browser/widgets/react-widget';
|
||||||
import {
|
import {
|
||||||
AvailableBoard,
|
AvailableBoard,
|
||||||
@@ -139,7 +139,7 @@ export class UploadCertificateDialog extends AbstractDialog<void> {
|
|||||||
|
|
||||||
constructor(
|
constructor(
|
||||||
@inject(UploadCertificateDialogProps)
|
@inject(UploadCertificateDialogProps)
|
||||||
protected override readonly props: UploadCertificateDialogProps
|
protected readonly props: UploadCertificateDialogProps
|
||||||
) {
|
) {
|
||||||
super({
|
super({
|
||||||
title: nls.localize(
|
title: nls.localize(
|
||||||
@@ -155,7 +155,7 @@ export class UploadCertificateDialog extends AbstractDialog<void> {
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
protected override onAfterAttach(msg: Message): void {
|
protected onAfterAttach(msg: Message): void {
|
||||||
if (this.widget.isAttached) {
|
if (this.widget.isAttached) {
|
||||||
Widget.detach(this.widget);
|
Widget.detach(this.widget);
|
||||||
}
|
}
|
||||||
@@ -165,21 +165,21 @@ export class UploadCertificateDialog extends AbstractDialog<void> {
|
|||||||
this.update();
|
this.update();
|
||||||
}
|
}
|
||||||
|
|
||||||
protected override onUpdateRequest(msg: Message): void {
|
protected onUpdateRequest(msg: Message): void {
|
||||||
super.onUpdateRequest(msg);
|
super.onUpdateRequest(msg);
|
||||||
this.widget.update();
|
this.widget.update();
|
||||||
}
|
}
|
||||||
|
|
||||||
protected override onActivateRequest(msg: Message): void {
|
protected onActivateRequest(msg: Message): void {
|
||||||
super.onActivateRequest(msg);
|
super.onActivateRequest(msg);
|
||||||
this.widget.activate();
|
this.widget.activate();
|
||||||
}
|
}
|
||||||
|
|
||||||
protected override handleEnter(event: KeyboardEvent): boolean | void {
|
protected handleEnter(event: KeyboardEvent): boolean | void {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
override close(): void {
|
close(): void {
|
||||||
if (this.busy) {
|
if (this.busy) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
@@ -1,5 +1,5 @@
|
|||||||
import { nls } from '@theia/core/lib/common';
|
import { nls } from '@theia/core/lib/common';
|
||||||
import * as React from '@theia/core/shared/react';
|
import * as React from 'react';
|
||||||
import { AvailableBoard } from '../../boards/boards-service-provider';
|
import { AvailableBoard } from '../../boards/boards-service-provider';
|
||||||
import { ArduinoSelect } from '../../widgets/arduino-select';
|
import { ArduinoSelect } from '../../widgets/arduino-select';
|
||||||
|
|
||||||
|
@@ -1,7 +1,7 @@
|
|||||||
import * as React from '@theia/core/shared/react';
|
import * as React from 'react';
|
||||||
import { inject, injectable } from '@theia/core/shared/inversify';
|
import { inject, injectable } from 'inversify';
|
||||||
import { Widget } from '@theia/core/shared/@phosphor/widgets';
|
import { Widget } from '@phosphor/widgets';
|
||||||
import { Message } from '@theia/core/shared/@phosphor/messaging';
|
import { Message } from '@phosphor/messaging';
|
||||||
import { clipboard } from 'electron';
|
import { clipboard } from 'electron';
|
||||||
import { ReactWidget, DialogProps } from '@theia/core/lib/browser';
|
import { ReactWidget, DialogProps } from '@theia/core/lib/browser';
|
||||||
import { AbstractDialog } from '../theia/dialogs/dialogs';
|
import { AbstractDialog } from '../theia/dialogs/dialogs';
|
||||||
@@ -149,7 +149,7 @@ export class ShareSketchDialog extends AbstractDialog<void> {
|
|||||||
|
|
||||||
constructor(
|
constructor(
|
||||||
@inject(ShareSketchDialogProps)
|
@inject(ShareSketchDialogProps)
|
||||||
protected override readonly props: ShareSketchDialogProps
|
protected readonly props: ShareSketchDialogProps
|
||||||
) {
|
) {
|
||||||
super({ title: props.title });
|
super({ title: props.title });
|
||||||
this.contentNode.classList.add('arduino-share-sketch-dialog');
|
this.contentNode.classList.add('arduino-share-sketch-dialog');
|
||||||
@@ -159,7 +159,7 @@ export class ShareSketchDialog extends AbstractDialog<void> {
|
|||||||
get value(): void {
|
get value(): void {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
protected override onAfterAttach(msg: Message): void {
|
protected onAfterAttach(msg: Message): void {
|
||||||
if (this.widget.isAttached) {
|
if (this.widget.isAttached) {
|
||||||
Widget.detach(this.widget);
|
Widget.detach(this.widget);
|
||||||
}
|
}
|
||||||
@@ -168,12 +168,12 @@ export class ShareSketchDialog extends AbstractDialog<void> {
|
|||||||
this.update();
|
this.update();
|
||||||
}
|
}
|
||||||
|
|
||||||
protected override onUpdateRequest(msg: Message): void {
|
protected onUpdateRequest(msg: Message): void {
|
||||||
super.onUpdateRequest(msg);
|
super.onUpdateRequest(msg);
|
||||||
this.widget.update();
|
this.widget.update();
|
||||||
}
|
}
|
||||||
|
|
||||||
protected override onActivateRequest(msg: Message): void {
|
protected onActivateRequest(msg: Message): void {
|
||||||
super.onActivateRequest(msg);
|
super.onActivateRequest(msg);
|
||||||
this.widget.activate();
|
this.widget.activate();
|
||||||
}
|
}
|
||||||
|
@@ -1,5 +1,5 @@
|
|||||||
import { inject, injectable } from '@theia/core/shared/inversify';
|
import { inject, injectable } from 'inversify';
|
||||||
import { Widget } from '@theia/core/shared/@phosphor/widgets';
|
import { Widget } from '@phosphor/widgets';
|
||||||
import { CancellationTokenSource } from '@theia/core/lib/common/cancellation';
|
import { CancellationTokenSource } from '@theia/core/lib/common/cancellation';
|
||||||
import {
|
import {
|
||||||
ConfirmDialog,
|
ConfirmDialog,
|
||||||
@@ -19,7 +19,7 @@ export class DoNotAskAgainConfirmDialog extends ConfirmDialog {
|
|||||||
|
|
||||||
constructor(
|
constructor(
|
||||||
@inject(DoNotAskAgainDialogProps)
|
@inject(DoNotAskAgainDialogProps)
|
||||||
protected override readonly props: DoNotAskAgainDialogProps
|
protected readonly props: DoNotAskAgainDialogProps
|
||||||
) {
|
) {
|
||||||
super(props);
|
super(props);
|
||||||
this.controlPanel.removeChild(this.errorMessageNode);
|
this.controlPanel.removeChild(this.errorMessageNode);
|
||||||
@@ -42,7 +42,7 @@ export class DoNotAskAgainConfirmDialog extends ConfirmDialog {
|
|||||||
this.doNotAskAgainCheckbox.type = 'checkbox';
|
this.doNotAskAgainCheckbox.type = 'checkbox';
|
||||||
}
|
}
|
||||||
|
|
||||||
protected override async accept(): Promise<void> {
|
protected async accept(): Promise<void> {
|
||||||
if (!this.resolve) {
|
if (!this.resolve) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
@@ -65,7 +65,7 @@ export class DoNotAskAgainConfirmDialog extends ConfirmDialog {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
protected override setErrorMessage(error: DialogError): void {
|
protected setErrorMessage(error: DialogError): void {
|
||||||
if (this.acceptButton) {
|
if (this.acceptButton) {
|
||||||
this.acceptButton.disabled = !DialogError.getResult(error);
|
this.acceptButton.disabled = !DialogError.getResult(error);
|
||||||
}
|
}
|
||||||
|
@@ -1,5 +1,5 @@
|
|||||||
import { nls } from '@theia/core/lib/common';
|
import { nls } from '@theia/core/lib/common';
|
||||||
import * as React from '@theia/core/shared/react';
|
import * as React from 'react';
|
||||||
import { Port } from '../../../common/protocol';
|
import { Port } from '../../../common/protocol';
|
||||||
import {
|
import {
|
||||||
ArduinoFirmwareUploader,
|
ArduinoFirmwareUploader,
|
||||||
|
@@ -1,13 +1,9 @@
|
|||||||
import * as React from '@theia/core/shared/react';
|
import * as React from 'react';
|
||||||
import {
|
import { inject, injectable, postConstruct } from 'inversify';
|
||||||
inject,
|
|
||||||
injectable,
|
|
||||||
postConstruct,
|
|
||||||
} from '@theia/core/shared/inversify';
|
|
||||||
import { DialogProps } from '@theia/core/lib/browser/dialogs';
|
import { DialogProps } from '@theia/core/lib/browser/dialogs';
|
||||||
import { AbstractDialog } from '../../theia/dialogs/dialogs';
|
import { AbstractDialog } from '../../theia/dialogs/dialogs';
|
||||||
import { Widget } from '@theia/core/shared/@phosphor/widgets';
|
import { Widget } from '@phosphor/widgets';
|
||||||
import { Message } from '@theia/core/shared/@phosphor/messaging';
|
import { Message } from '@phosphor/messaging';
|
||||||
import { ReactWidget } from '@theia/core/lib/browser/widgets/react-widget';
|
import { ReactWidget } from '@theia/core/lib/browser/widgets/react-widget';
|
||||||
import {
|
import {
|
||||||
AvailableBoard,
|
AvailableBoard,
|
||||||
@@ -20,7 +16,6 @@ import {
|
|||||||
import { FirmwareUploaderComponent } from './firmware-uploader-component';
|
import { FirmwareUploaderComponent } from './firmware-uploader-component';
|
||||||
import { UploadFirmware } from '../../contributions/upload-firmware';
|
import { UploadFirmware } from '../../contributions/upload-firmware';
|
||||||
import { Port } from '../../../common/protocol';
|
import { Port } from '../../../common/protocol';
|
||||||
import { FrontendApplicationStateService } from '@theia/core/lib/browser/frontend-application-state';
|
|
||||||
|
|
||||||
@injectable()
|
@injectable()
|
||||||
export class UploadFirmwareDialogWidget extends ReactWidget {
|
export class UploadFirmwareDialogWidget extends ReactWidget {
|
||||||
@@ -30,9 +25,6 @@ export class UploadFirmwareDialogWidget extends ReactWidget {
|
|||||||
@inject(ArduinoFirmwareUploader)
|
@inject(ArduinoFirmwareUploader)
|
||||||
protected readonly arduinoFirmwareUploader: ArduinoFirmwareUploader;
|
protected readonly arduinoFirmwareUploader: ArduinoFirmwareUploader;
|
||||||
|
|
||||||
@inject(FrontendApplicationStateService)
|
|
||||||
private readonly appStatusService: FrontendApplicationStateService;
|
|
||||||
|
|
||||||
protected updatableFqbns: string[] = [];
|
protected updatableFqbns: string[] = [];
|
||||||
protected availableBoards: AvailableBoard[] = [];
|
protected availableBoards: AvailableBoard[] = [];
|
||||||
protected isOpen = new Object();
|
protected isOpen = new Object();
|
||||||
@@ -47,8 +39,7 @@ export class UploadFirmwareDialogWidget extends ReactWidget {
|
|||||||
|
|
||||||
@postConstruct()
|
@postConstruct()
|
||||||
protected init(): void {
|
protected init(): void {
|
||||||
this.appStatusService.reachedState('ready').then(async () => {
|
this.arduinoFirmwareUploader.updatableBoards().then((fqbns) => {
|
||||||
const fqbns = await this.arduinoFirmwareUploader.updatableBoards();
|
|
||||||
this.updatableFqbns = fqbns;
|
this.updatableFqbns = fqbns;
|
||||||
this.update();
|
this.update();
|
||||||
});
|
});
|
||||||
@@ -66,7 +57,7 @@ export class UploadFirmwareDialogWidget extends ReactWidget {
|
|||||||
.finally(() => this.busyCallback(false));
|
.finally(() => this.busyCallback(false));
|
||||||
}
|
}
|
||||||
|
|
||||||
protected override onCloseRequest(msg: Message): void {
|
onCloseRequest(msg: Message): void {
|
||||||
super.onCloseRequest(msg);
|
super.onCloseRequest(msg);
|
||||||
this.isOpen = new Object();
|
this.isOpen = new Object();
|
||||||
}
|
}
|
||||||
@@ -98,7 +89,7 @@ export class UploadFirmwareDialog extends AbstractDialog<void> {
|
|||||||
|
|
||||||
constructor(
|
constructor(
|
||||||
@inject(UploadFirmwareDialogProps)
|
@inject(UploadFirmwareDialogProps)
|
||||||
protected override readonly props: UploadFirmwareDialogProps
|
protected readonly props: UploadFirmwareDialogProps
|
||||||
) {
|
) {
|
||||||
super({ title: UploadFirmware.Commands.OPEN.label || '' });
|
super({ title: UploadFirmware.Commands.OPEN.label || '' });
|
||||||
this.contentNode.classList.add('firmware-uploader-dialog');
|
this.contentNode.classList.add('firmware-uploader-dialog');
|
||||||
@@ -109,7 +100,7 @@ export class UploadFirmwareDialog extends AbstractDialog<void> {
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
protected override onAfterAttach(msg: Message): void {
|
protected onAfterAttach(msg: Message): void {
|
||||||
if (this.widget.isAttached) {
|
if (this.widget.isAttached) {
|
||||||
Widget.detach(this.widget);
|
Widget.detach(this.widget);
|
||||||
}
|
}
|
||||||
@@ -119,21 +110,21 @@ export class UploadFirmwareDialog extends AbstractDialog<void> {
|
|||||||
this.update();
|
this.update();
|
||||||
}
|
}
|
||||||
|
|
||||||
protected override onUpdateRequest(msg: Message): void {
|
protected onUpdateRequest(msg: Message): void {
|
||||||
super.onUpdateRequest(msg);
|
super.onUpdateRequest(msg);
|
||||||
this.widget.update();
|
this.widget.update();
|
||||||
}
|
}
|
||||||
|
|
||||||
protected override onActivateRequest(msg: Message): void {
|
protected onActivateRequest(msg: Message): void {
|
||||||
super.onActivateRequest(msg);
|
super.onActivateRequest(msg);
|
||||||
this.widget.activate();
|
this.widget.activate();
|
||||||
}
|
}
|
||||||
|
|
||||||
protected override handleEnter(event: KeyboardEvent): boolean | void {
|
protected handleEnter(event: KeyboardEvent): boolean | void {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
override close(): void {
|
close(): void {
|
||||||
if (this.busy) {
|
if (this.busy) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
@@ -1,8 +1,8 @@
|
|||||||
import { WindowService } from '@theia/core/lib/browser/window/window-service';
|
import { WindowService } from '@theia/core/lib/browser/window/window-service';
|
||||||
import { nls } from '@theia/core/lib/common';
|
import { nls } from '@theia/core/lib/common';
|
||||||
import { shell } from 'electron';
|
import { shell } from 'electron';
|
||||||
import * as React from '@theia/core/shared/react';
|
import * as React from 'react';
|
||||||
import * as ReactDOM from '@theia/core/shared/react-dom';
|
import * as ReactDOM from 'react-dom';
|
||||||
import ReactMarkdown from 'react-markdown';
|
import ReactMarkdown from 'react-markdown';
|
||||||
import { ProgressInfo, UpdateInfo } from '../../../common/protocol/ide-updater';
|
import { ProgressInfo, UpdateInfo } from '../../../common/protocol/ide-updater';
|
||||||
import ProgressBar from '../../components/ProgressBar';
|
import ProgressBar from '../../components/ProgressBar';
|
||||||
|
@@ -1,9 +1,9 @@
|
|||||||
import * as React from '@theia/core/shared/react';
|
import * as React from 'react';
|
||||||
import { inject, injectable } from '@theia/core/shared/inversify';
|
import { inject, injectable } from 'inversify';
|
||||||
import { DialogProps } from '@theia/core/lib/browser/dialogs';
|
import { DialogProps } from '@theia/core/lib/browser/dialogs';
|
||||||
import { AbstractDialog } from '../../theia/dialogs/dialogs';
|
import { AbstractDialog } from '../../theia/dialogs/dialogs';
|
||||||
import { Widget } from '@theia/core/shared/@phosphor/widgets';
|
import { Widget } from '@phosphor/widgets';
|
||||||
import { Message } from '@theia/core/shared/@phosphor/messaging';
|
import { Message } from '@phosphor/messaging';
|
||||||
import { ReactWidget } from '@theia/core/lib/browser/widgets/react-widget';
|
import { ReactWidget } from '@theia/core/lib/browser/widgets/react-widget';
|
||||||
import { nls } from '@theia/core';
|
import { nls } from '@theia/core';
|
||||||
import { IDEUpdaterComponent } from './ide-updater-component';
|
import { IDEUpdaterComponent } from './ide-updater-component';
|
||||||
@@ -70,7 +70,7 @@ export class IDEUpdaterDialogWidget extends ReactWidget {
|
|||||||
this.close();
|
this.close();
|
||||||
}
|
}
|
||||||
|
|
||||||
override close(): void {
|
close(): void {
|
||||||
super.close();
|
super.close();
|
||||||
this.onClose();
|
this.onClose();
|
||||||
}
|
}
|
||||||
@@ -122,7 +122,7 @@ export class IDEUpdaterDialog extends AbstractDialog<UpdateInfo> {
|
|||||||
|
|
||||||
constructor(
|
constructor(
|
||||||
@inject(IDEUpdaterDialogProps)
|
@inject(IDEUpdaterDialogProps)
|
||||||
protected override readonly props: IDEUpdaterDialogProps
|
protected readonly props: IDEUpdaterDialogProps
|
||||||
) {
|
) {
|
||||||
super({
|
super({
|
||||||
title: nls.localize(
|
title: nls.localize(
|
||||||
@@ -138,7 +138,7 @@ export class IDEUpdaterDialog extends AbstractDialog<UpdateInfo> {
|
|||||||
return this.widget.updateInfo;
|
return this.widget.updateInfo;
|
||||||
}
|
}
|
||||||
|
|
||||||
protected override onAfterAttach(msg: Message): void {
|
protected onAfterAttach(msg: Message): void {
|
||||||
if (this.widget.isAttached) {
|
if (this.widget.isAttached) {
|
||||||
Widget.detach(this.widget);
|
Widget.detach(this.widget);
|
||||||
}
|
}
|
||||||
@@ -147,7 +147,7 @@ export class IDEUpdaterDialog extends AbstractDialog<UpdateInfo> {
|
|||||||
this.update();
|
this.update();
|
||||||
}
|
}
|
||||||
|
|
||||||
override async open(
|
async open(
|
||||||
data: UpdateInfo | undefined = undefined
|
data: UpdateInfo | undefined = undefined
|
||||||
): Promise<UpdateInfo | undefined> {
|
): Promise<UpdateInfo | undefined> {
|
||||||
if (data && data.version) {
|
if (data && data.version) {
|
||||||
@@ -156,17 +156,17 @@ export class IDEUpdaterDialog extends AbstractDialog<UpdateInfo> {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
protected override onUpdateRequest(msg: Message): void {
|
protected onUpdateRequest(msg: Message): void {
|
||||||
super.onUpdateRequest(msg);
|
super.onUpdateRequest(msg);
|
||||||
this.widget.update();
|
this.widget.update();
|
||||||
}
|
}
|
||||||
|
|
||||||
protected override onActivateRequest(msg: Message): void {
|
protected onActivateRequest(msg: Message): void {
|
||||||
super.onActivateRequest(msg);
|
super.onActivateRequest(msg);
|
||||||
this.widget.activate();
|
this.widget.activate();
|
||||||
}
|
}
|
||||||
|
|
||||||
override close(): void {
|
close(): void {
|
||||||
this.widget.dispose();
|
this.widget.dispose();
|
||||||
super.close();
|
super.close();
|
||||||
}
|
}
|
||||||
|
@@ -1,4 +1,4 @@
|
|||||||
import * as React from '@theia/core/shared/react';
|
import * as React from 'react';
|
||||||
import { Tab, Tabs, TabList, TabPanel } from 'react-tabs';
|
import { Tab, Tabs, TabList, TabPanel } from 'react-tabs';
|
||||||
import 'react-tabs/style/react-tabs.css';
|
import 'react-tabs/style/react-tabs.css';
|
||||||
import { Disable } from 'react-disable';
|
import { Disable } from 'react-disable';
|
||||||
@@ -17,10 +17,7 @@ import {
|
|||||||
import { nls } from '@theia/core/lib/common';
|
import { nls } from '@theia/core/lib/common';
|
||||||
import { Settings, SettingsService } from './settings';
|
import { Settings, SettingsService } from './settings';
|
||||||
import { AdditionalUrlsDialog } from './settings-dialog';
|
import { AdditionalUrlsDialog } from './settings-dialog';
|
||||||
import {
|
import { AsyncLocalizationProvider } from '@theia/core/lib/common/i18n/localization';
|
||||||
AsyncLocalizationProvider,
|
|
||||||
LanguageInfo,
|
|
||||||
} from '@theia/core/lib/common/i18n/localization';
|
|
||||||
|
|
||||||
export class SettingsComponent extends React.Component<
|
export class SettingsComponent extends React.Component<
|
||||||
SettingsComponent.Props,
|
SettingsComponent.Props,
|
||||||
@@ -32,7 +29,7 @@ export class SettingsComponent extends React.Component<
|
|||||||
super(props);
|
super(props);
|
||||||
}
|
}
|
||||||
|
|
||||||
override componentDidUpdate(
|
componentDidUpdate(
|
||||||
_: SettingsComponent.Props,
|
_: SettingsComponent.Props,
|
||||||
prevState: SettingsComponent.State
|
prevState: SettingsComponent.State
|
||||||
): void {
|
): void {
|
||||||
@@ -49,7 +46,7 @@ export class SettingsComponent extends React.Component<
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
override componentDidMount(): void {
|
componentDidMount(): void {
|
||||||
this.props.settingsService
|
this.props.settingsService
|
||||||
.settings()
|
.settings()
|
||||||
.then((settings) =>
|
.then((settings) =>
|
||||||
@@ -67,11 +64,11 @@ export class SettingsComponent extends React.Component<
|
|||||||
]);
|
]);
|
||||||
}
|
}
|
||||||
|
|
||||||
override componentWillUnmount(): void {
|
componentWillUnmount(): void {
|
||||||
this.toDispose.dispose();
|
this.toDispose.dispose();
|
||||||
}
|
}
|
||||||
|
|
||||||
override render(): React.ReactNode {
|
render(): React.ReactNode {
|
||||||
if (!this.state) {
|
if (!this.state) {
|
||||||
return <div />;
|
return <div />;
|
||||||
}
|
}
|
||||||
@@ -216,9 +213,11 @@ export class SettingsComponent extends React.Component<
|
|||||||
value={this.state.currentLanguage}
|
value={this.state.currentLanguage}
|
||||||
onChange={this.languageDidChange}
|
onChange={this.languageDidChange}
|
||||||
>
|
>
|
||||||
{this.state.languages.map((label) =>
|
{this.state.languages.map((label) => (
|
||||||
this.toSelectOptions(label)
|
<option key={label} value={label}>
|
||||||
)}
|
{label}
|
||||||
|
</option>
|
||||||
|
))}
|
||||||
</select>
|
</select>
|
||||||
<span style={{ marginLeft: '5px' }}>
|
<span style={{ marginLeft: '5px' }}>
|
||||||
(
|
(
|
||||||
@@ -276,7 +275,7 @@ export class SettingsComponent extends React.Component<
|
|||||||
<label className="flex-line">
|
<label className="flex-line">
|
||||||
<input
|
<input
|
||||||
type="checkbox"
|
type="checkbox"
|
||||||
checked={this.state.autoSave !== 'off'}
|
checked={this.state.autoSave === 'on'}
|
||||||
onChange={this.autoSaveDidChange}
|
onChange={this.autoSaveDidChange}
|
||||||
/>
|
/>
|
||||||
{nls.localize(
|
{nls.localize(
|
||||||
@@ -315,24 +314,6 @@ export class SettingsComponent extends React.Component<
|
|||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
private toSelectOptions(language: string | LanguageInfo): JSX.Element {
|
|
||||||
const plain = typeof language === 'string';
|
|
||||||
const key = plain ? language : language.languageId;
|
|
||||||
const value = plain ? language : language.languageId;
|
|
||||||
const label = plain
|
|
||||||
? language === 'en'
|
|
||||||
? 'English'
|
|
||||||
: language
|
|
||||||
: language.localizedLanguageName ||
|
|
||||||
language.languageName ||
|
|
||||||
language.languageId;
|
|
||||||
return (
|
|
||||||
<option key={key} value={value}>
|
|
||||||
{label}
|
|
||||||
</option>
|
|
||||||
);
|
|
||||||
}
|
|
||||||
|
|
||||||
protected renderNetwork(): React.ReactNode {
|
protected renderNetwork(): React.ReactNode {
|
||||||
return (
|
return (
|
||||||
<div className="content noselect">
|
<div className="content noselect">
|
||||||
@@ -568,9 +549,7 @@ export class SettingsComponent extends React.Component<
|
|||||||
protected autoSaveDidChange = (
|
protected autoSaveDidChange = (
|
||||||
event: React.ChangeEvent<HTMLInputElement>
|
event: React.ChangeEvent<HTMLInputElement>
|
||||||
): void => {
|
): void => {
|
||||||
this.setState({
|
this.setState({ autoSave: event.target.checked ? 'on' : 'off' });
|
||||||
autoSave: event.target.checked ? Settings.AutoSave.DEFAULT_ON : 'off',
|
|
||||||
});
|
|
||||||
};
|
};
|
||||||
|
|
||||||
protected quickSuggestionsOtherDidChange = (
|
protected quickSuggestionsOtherDidChange = (
|
||||||
|
@@ -1,7 +1,7 @@
|
|||||||
import * as React from '@theia/core/shared/react';
|
import * as React from 'react';
|
||||||
import { injectable, inject, postConstruct } from '@theia/core/shared/inversify';
|
import { injectable, inject, postConstruct } from 'inversify';
|
||||||
import { Widget } from '@theia/core/shared/@phosphor/widgets';
|
import { Widget } from '@phosphor/widgets';
|
||||||
import { Message } from '@theia/core/shared/@phosphor/messaging';
|
import { Message } from '@phosphor/messaging';
|
||||||
import { DialogError, ReactWidget } from '@theia/core/lib/browser';
|
import { DialogError, ReactWidget } from '@theia/core/lib/browser';
|
||||||
import { AbstractDialog, DialogProps } from '@theia/core/lib/browser';
|
import { AbstractDialog, DialogProps } from '@theia/core/lib/browser';
|
||||||
import { Settings, SettingsService } from './settings';
|
import { Settings, SettingsService } from './settings';
|
||||||
@@ -56,7 +56,7 @@ export class SettingsDialog extends AbstractDialog<Promise<Settings>> {
|
|||||||
|
|
||||||
constructor(
|
constructor(
|
||||||
@inject(SettingsDialogProps)
|
@inject(SettingsDialogProps)
|
||||||
protected override readonly props: SettingsDialogProps
|
protected readonly props: SettingsDialogProps
|
||||||
) {
|
) {
|
||||||
super(props);
|
super(props);
|
||||||
this.contentNode.classList.add('arduino-settings-dialog');
|
this.contentNode.classList.add('arduino-settings-dialog');
|
||||||
@@ -73,7 +73,7 @@ export class SettingsDialog extends AbstractDialog<Promise<Settings>> {
|
|||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
protected override async isValid(settings: Promise<Settings>): Promise<DialogError> {
|
protected async isValid(settings: Promise<Settings>): Promise<DialogError> {
|
||||||
const result = await this.settingsService.validate(settings);
|
const result = await this.settingsService.validate(settings);
|
||||||
if (typeof result === 'string') {
|
if (typeof result === 'string') {
|
||||||
return result;
|
return result;
|
||||||
@@ -85,7 +85,7 @@ export class SettingsDialog extends AbstractDialog<Promise<Settings>> {
|
|||||||
return this.settingsService.settings();
|
return this.settingsService.settings();
|
||||||
}
|
}
|
||||||
|
|
||||||
protected override onAfterAttach(msg: Message): void {
|
protected onAfterAttach(msg: Message): void {
|
||||||
if (this.widget.isAttached) {
|
if (this.widget.isAttached) {
|
||||||
Widget.detach(this.widget);
|
Widget.detach(this.widget);
|
||||||
}
|
}
|
||||||
@@ -97,12 +97,12 @@ export class SettingsDialog extends AbstractDialog<Promise<Settings>> {
|
|||||||
this.update();
|
this.update();
|
||||||
}
|
}
|
||||||
|
|
||||||
protected override onUpdateRequest(msg: Message): void {
|
protected onUpdateRequest(msg: Message): void {
|
||||||
super.onUpdateRequest(msg);
|
super.onUpdateRequest(msg);
|
||||||
this.widget.update();
|
this.widget.update();
|
||||||
}
|
}
|
||||||
|
|
||||||
protected override onActivateRequest(msg: Message): void {
|
protected onActivateRequest(msg: Message): void {
|
||||||
super.onActivateRequest(msg);
|
super.onActivateRequest(msg);
|
||||||
|
|
||||||
// calling settingsService.reset() in order to reload the settings from the preferenceService
|
// calling settingsService.reset() in order to reload the settings from the preferenceService
|
||||||
@@ -172,17 +172,17 @@ export class AdditionalUrlsDialog extends AbstractDialog<string[]> {
|
|||||||
return AdditionalUrls.parse(this.textArea.value, 'newline');
|
return AdditionalUrls.parse(this.textArea.value, 'newline');
|
||||||
}
|
}
|
||||||
|
|
||||||
protected override onAfterAttach(message: Message): void {
|
protected onAfterAttach(message: Message): void {
|
||||||
super.onAfterAttach(message);
|
super.onAfterAttach(message);
|
||||||
this.addUpdateListener(this.textArea, 'input');
|
this.addUpdateListener(this.textArea, 'input');
|
||||||
}
|
}
|
||||||
|
|
||||||
protected override onActivateRequest(message: Message): void {
|
protected onActivateRequest(message: Message): void {
|
||||||
super.onActivateRequest(message);
|
super.onActivateRequest(message);
|
||||||
this.textArea.focus();
|
this.textArea.focus();
|
||||||
}
|
}
|
||||||
|
|
||||||
protected override handleEnter(event: KeyboardEvent): boolean | void {
|
protected handleEnter(event: KeyboardEvent): boolean | void {
|
||||||
if (event.target instanceof HTMLInputElement) {
|
if (event.target instanceof HTMLInputElement) {
|
||||||
return super.handleEnter(event);
|
return super.handleEnter(event);
|
||||||
}
|
}
|
||||||
|
@@ -1,8 +1,4 @@
|
|||||||
import {
|
import { injectable, inject, postConstruct } from 'inversify';
|
||||||
injectable,
|
|
||||||
inject,
|
|
||||||
postConstruct,
|
|
||||||
} from '@theia/core/shared/inversify';
|
|
||||||
import URI from '@theia/core/lib/common/uri';
|
import URI from '@theia/core/lib/common/uri';
|
||||||
import { Emitter } from '@theia/core/lib/common/event';
|
import { Emitter } from '@theia/core/lib/common/event';
|
||||||
import { Deferred, timeout } from '@theia/core/lib/common/promise-util';
|
import { Deferred, timeout } from '@theia/core/lib/common/promise-util';
|
||||||
@@ -20,15 +16,12 @@ import {
|
|||||||
Network,
|
Network,
|
||||||
} from '../../../common/protocol';
|
} from '../../../common/protocol';
|
||||||
import { CommandService, nls } from '@theia/core/lib/common';
|
import { CommandService, nls } from '@theia/core/lib/common';
|
||||||
import {
|
import { AsyncLocalizationProvider } from '@theia/core/lib/common/i18n/localization';
|
||||||
AsyncLocalizationProvider,
|
|
||||||
LanguageInfo,
|
|
||||||
} from '@theia/core/lib/common/i18n/localization';
|
|
||||||
import { ElectronCommands } from '@theia/core/lib/electron-browser/menu/electron-menu-contribution';
|
import { ElectronCommands } from '@theia/core/lib/electron-browser/menu/electron-menu-contribution';
|
||||||
|
|
||||||
export const EDITOR_SETTING = 'editor';
|
export const EDITOR_SETTING = 'editor';
|
||||||
export const FONT_SIZE_SETTING = `${EDITOR_SETTING}.fontSize`;
|
export const FONT_SIZE_SETTING = `${EDITOR_SETTING}.fontSize`;
|
||||||
export const AUTO_SAVE_SETTING = `files.autoSave`;
|
export const AUTO_SAVE_SETTING = `${EDITOR_SETTING}.autoSave`;
|
||||||
export const QUICK_SUGGESTIONS_SETTING = `${EDITOR_SETTING}.quickSuggestions`;
|
export const QUICK_SUGGESTIONS_SETTING = `${EDITOR_SETTING}.quickSuggestions`;
|
||||||
export const ARDUINO_SETTING = 'arduino';
|
export const ARDUINO_SETTING = 'arduino';
|
||||||
export const WINDOW_SETTING = `${ARDUINO_SETTING}.window`;
|
export const WINDOW_SETTING = `${ARDUINO_SETTING}.window`;
|
||||||
@@ -46,10 +39,10 @@ export const SHOW_ALL_FILES_SETTING = `${SKETCHBOOK_SETTING}.showAllFiles`;
|
|||||||
export interface Settings {
|
export interface Settings {
|
||||||
editorFontSize: number; // `editor.fontSize`
|
editorFontSize: number; // `editor.fontSize`
|
||||||
themeId: string; // `workbench.colorTheme`
|
themeId: string; // `workbench.colorTheme`
|
||||||
autoSave: Settings.AutoSave; // `files.autoSave`
|
autoSave: 'on' | 'off'; // `editor.autoSave`
|
||||||
quickSuggestions: Record<'other' | 'comments' | 'strings', boolean>; // `editor.quickSuggestions`
|
quickSuggestions: Record<'other' | 'comments' | 'strings', boolean>; // `editor.quickSuggestions`
|
||||||
|
|
||||||
languages: (string | LanguageInfo)[]; // `languages from the plugins`
|
languages: string[]; // `languages from the plugins`
|
||||||
currentLanguage: string;
|
currentLanguage: string;
|
||||||
|
|
||||||
autoScaleInterface: boolean; // `arduino.window.autoScale`
|
autoScaleInterface: boolean; // `arduino.window.autoScale`
|
||||||
@@ -68,14 +61,6 @@ export namespace Settings {
|
|||||||
export function belongsToCli<K extends keyof Settings>(key: K): boolean {
|
export function belongsToCli<K extends keyof Settings>(key: K): boolean {
|
||||||
return key === 'sketchbookPath' || key === 'additionalUrls';
|
return key === 'sketchbookPath' || key === 'additionalUrls';
|
||||||
}
|
}
|
||||||
export type AutoSave =
|
|
||||||
| 'off'
|
|
||||||
| 'afterDelay'
|
|
||||||
| 'onFocusChange'
|
|
||||||
| 'onWindowChange';
|
|
||||||
export namespace AutoSave {
|
|
||||||
export const DEFAULT_ON: AutoSave = 'afterDelay'; // https://github.com/eclipse-theia/theia/issues/10812
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@injectable()
|
@injectable()
|
||||||
@@ -141,10 +126,7 @@ export class SettingsService {
|
|||||||
'workbench.colorTheme',
|
'workbench.colorTheme',
|
||||||
'arduino-theme'
|
'arduino-theme'
|
||||||
),
|
),
|
||||||
this.preferenceService.get<Settings.AutoSave>(
|
this.preferenceService.get<'on' | 'off'>(AUTO_SAVE_SETTING, 'on'),
|
||||||
AUTO_SAVE_SETTING,
|
|
||||||
Settings.AutoSave.DEFAULT_ON
|
|
||||||
),
|
|
||||||
this.preferenceService.get<
|
this.preferenceService.get<
|
||||||
Record<'other' | 'comments' | 'strings', boolean>
|
Record<'other' | 'comments' | 'strings', boolean>
|
||||||
>(QUICK_SUGGESTIONS_SETTING, {
|
>(QUICK_SUGGESTIONS_SETTING, {
|
||||||
@@ -280,7 +262,7 @@ export class SettingsService {
|
|||||||
|
|
||||||
await this.savePreference('editor.fontSize', editorFontSize);
|
await this.savePreference('editor.fontSize', editorFontSize);
|
||||||
await this.savePreference('workbench.colorTheme', themeId);
|
await this.savePreference('workbench.colorTheme', themeId);
|
||||||
await this.savePreference(AUTO_SAVE_SETTING, autoSave);
|
await this.savePreference('editor.autoSave', autoSave);
|
||||||
await this.savePreference('editor.quickSuggestions', quickSuggestions);
|
await this.savePreference('editor.quickSuggestions', quickSuggestions);
|
||||||
await this.savePreference(AUTO_SCALE_SETTING, autoScaleInterface);
|
await this.savePreference(AUTO_SCALE_SETTING, autoScaleInterface);
|
||||||
await this.savePreference(ZOOM_LEVEL_SETTING, interfaceScale);
|
await this.savePreference(ZOOM_LEVEL_SETTING, interfaceScale);
|
@@ -1,4 +1,4 @@
|
|||||||
import * as React from '@theia/core/shared/react';
|
import * as React from 'react';
|
||||||
import { BoardUserField } from '../../../common/protocol';
|
import { BoardUserField } from '../../../common/protocol';
|
||||||
import { nls } from '@theia/core/lib/common';
|
import { nls } from '@theia/core/lib/common';
|
||||||
|
|
||||||
|
@@ -1,12 +1,12 @@
|
|||||||
import * as React from '@theia/core/shared/react';
|
import * as React from 'react';
|
||||||
import { inject, injectable } from '@theia/core/shared/inversify';
|
import { inject, injectable } from 'inversify';
|
||||||
import {
|
import {
|
||||||
AbstractDialog,
|
AbstractDialog,
|
||||||
DialogProps,
|
DialogProps,
|
||||||
ReactWidget,
|
ReactWidget,
|
||||||
} from '@theia/core/lib/browser';
|
} from '@theia/core/lib/browser';
|
||||||
import { Widget } from '@theia/core/shared/@phosphor/widgets';
|
import { Widget } from '@phosphor/widgets';
|
||||||
import { Message } from '@theia/core/shared/@phosphor/messaging';
|
import { Message } from '@phosphor/messaging';
|
||||||
import { UploadSketch } from '../../contributions/upload-sketch';
|
import { UploadSketch } from '../../contributions/upload-sketch';
|
||||||
import { UserFieldsComponent } from './user-fields-component';
|
import { UserFieldsComponent } from './user-fields-component';
|
||||||
import { BoardUserField } from '../../../common/protocol';
|
import { BoardUserField } from '../../../common/protocol';
|
||||||
@@ -61,7 +61,7 @@ export class UserFieldsDialog extends AbstractDialog<BoardUserField[]> {
|
|||||||
|
|
||||||
constructor(
|
constructor(
|
||||||
@inject(UserFieldsDialogProps)
|
@inject(UserFieldsDialogProps)
|
||||||
protected override readonly props: UserFieldsDialogProps
|
protected readonly props: UserFieldsDialogProps
|
||||||
) {
|
) {
|
||||||
super({
|
super({
|
||||||
title: UploadSketch.Commands.UPLOAD_WITH_CONFIGURATION.label || '',
|
title: UploadSketch.Commands.UPLOAD_WITH_CONFIGURATION.label || '',
|
||||||
@@ -83,7 +83,7 @@ export class UserFieldsDialog extends AbstractDialog<BoardUserField[]> {
|
|||||||
return this.widget.currentUserFields;
|
return this.widget.currentUserFields;
|
||||||
}
|
}
|
||||||
|
|
||||||
protected override onAfterAttach(msg: Message): void {
|
protected onAfterAttach(msg: Message): void {
|
||||||
if (this.widget.isAttached) {
|
if (this.widget.isAttached) {
|
||||||
Widget.detach(this.widget);
|
Widget.detach(this.widget);
|
||||||
}
|
}
|
||||||
@@ -92,17 +92,17 @@ export class UserFieldsDialog extends AbstractDialog<BoardUserField[]> {
|
|||||||
this.update();
|
this.update();
|
||||||
}
|
}
|
||||||
|
|
||||||
protected override onUpdateRequest(msg: Message): void {
|
protected onUpdateRequest(msg: Message): void {
|
||||||
super.onUpdateRequest(msg);
|
super.onUpdateRequest(msg);
|
||||||
this.widget.update();
|
this.widget.update();
|
||||||
}
|
}
|
||||||
|
|
||||||
protected override onActivateRequest(msg: Message): void {
|
protected onActivateRequest(msg: Message): void {
|
||||||
super.onActivateRequest(msg);
|
super.onActivateRequest(msg);
|
||||||
this.widget.activate();
|
this.widget.activate();
|
||||||
}
|
}
|
||||||
|
|
||||||
protected override async accept(): Promise<void> {
|
protected async accept(): Promise<void> {
|
||||||
// If the user presses enter and at least
|
// If the user presses enter and at least
|
||||||
// a field is empty don't accept the input
|
// a field is empty don't accept the input
|
||||||
for (const field of this.value) {
|
for (const field of this.value) {
|
||||||
@@ -113,7 +113,7 @@ export class UserFieldsDialog extends AbstractDialog<BoardUserField[]> {
|
|||||||
return super.accept();
|
return super.accept();
|
||||||
}
|
}
|
||||||
|
|
||||||
override close(): void {
|
close(): void {
|
||||||
this.widget.resetUserFieldsValue();
|
this.widget.resetUserFieldsValue();
|
||||||
this.widget.close();
|
this.widget.close();
|
||||||
super.close();
|
super.close();
|
||||||
|
@@ -1,4 +1,4 @@
|
|||||||
import { injectable, inject } from '@theia/core/shared/inversify';
|
import { injectable, inject } from 'inversify';
|
||||||
import {
|
import {
|
||||||
FrontendApplicationContribution,
|
FrontendApplicationContribution,
|
||||||
FrontendApplication,
|
FrontendApplication,
|
||||||
|
@@ -1,74 +0,0 @@
|
|||||||
import { DisposableCollection, Emitter, Event } from '@theia/core';
|
|
||||||
import { FrontendApplicationContribution } from '@theia/core/lib/browser';
|
|
||||||
import { inject, injectable } from '@theia/core/shared/inversify';
|
|
||||||
import { HostedPluginSupport } from './theia/plugin-ext/hosted-plugin';
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Frontend contribution to watch VS Code extension start/stop events from Theia.
|
|
||||||
*
|
|
||||||
* In Theia, there are no events when a VS Code extension is loaded, started, unloaded, and stopped.
|
|
||||||
* Currently, it's possible to `@inject` the `HostedPluginSupport` service from Theia and `await`
|
|
||||||
* for the `didStart` promise to resolve. But if the OS goes to sleep, the VS Code extensions will
|
|
||||||
* be unloaded and loaded and started again when the OS awakes. Theia reloads the VS Code extensions
|
|
||||||
* after the OS awake event, but the `didStart` promise was already resolved, so IDE2 cannot restart the LS.
|
|
||||||
* This service is meant to work around the limitation of Theia and fire an event every time the VS Code extensions
|
|
||||||
* loaded and started.
|
|
||||||
*/
|
|
||||||
@injectable()
|
|
||||||
export class HostedPluginEvents implements FrontendApplicationContribution {
|
|
||||||
@inject(HostedPluginSupport)
|
|
||||||
private readonly hostedPluginSupport: HostedPluginSupport;
|
|
||||||
|
|
||||||
private firstStart = true;
|
|
||||||
private readonly onPluginsDidStartEmitter = new Emitter<void>();
|
|
||||||
private readonly onPluginsWillUnloadEmitter = new Emitter<void>();
|
|
||||||
private readonly toDispose = new DisposableCollection(
|
|
||||||
this.onPluginsDidStartEmitter,
|
|
||||||
this.onPluginsWillUnloadEmitter
|
|
||||||
);
|
|
||||||
|
|
||||||
onStart(): void {
|
|
||||||
this.hostedPluginSupport.onDidLoad(() => {
|
|
||||||
// Fire the first event, when `didStart` resolves.
|
|
||||||
if (!this.firstStart) {
|
|
||||||
console.debug('HostedPluginEvents', "Received 'onDidLoad' event.");
|
|
||||||
this.onPluginsDidStartEmitter.fire();
|
|
||||||
} else {
|
|
||||||
console.debug(
|
|
||||||
'HostedPluginEvents',
|
|
||||||
"Received 'onDidLoad' event before the first start. Skipping."
|
|
||||||
);
|
|
||||||
}
|
|
||||||
});
|
|
||||||
this.hostedPluginSupport.didStart.then(() => {
|
|
||||||
console.debug('HostedPluginEvents', "Hosted plugins 'didStart'.");
|
|
||||||
if (!this.firstStart) {
|
|
||||||
throw new Error(
|
|
||||||
'Unexpectedly received a `didStart` event after the first start.'
|
|
||||||
);
|
|
||||||
}
|
|
||||||
this.firstStart = false;
|
|
||||||
this.onPluginsDidStartEmitter.fire();
|
|
||||||
});
|
|
||||||
this.hostedPluginSupport.onDidCloseConnection(() => {
|
|
||||||
console.debug('HostedPluginEvents', "Received 'onDidCloseConnection'.");
|
|
||||||
this.onPluginsWillUnloadEmitter.fire();
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
onStop(): void {
|
|
||||||
this.toDispose.dispose();
|
|
||||||
}
|
|
||||||
|
|
||||||
get onPluginsDidStart(): Event<void> {
|
|
||||||
return this.onPluginsDidStartEmitter.event;
|
|
||||||
}
|
|
||||||
|
|
||||||
get onPluginsWillUnload(): Event<void> {
|
|
||||||
return this.onPluginsWillUnloadEmitter.event;
|
|
||||||
}
|
|
||||||
|
|
||||||
get didStart(): Promise<void> {
|
|
||||||
return this.hostedPluginSupport.didStart;
|
|
||||||
}
|
|
||||||
}
|
|
@@ -5,7 +5,7 @@ import {
|
|||||||
MessageService,
|
MessageService,
|
||||||
nls,
|
nls,
|
||||||
} from '@theia/core';
|
} from '@theia/core';
|
||||||
import { injectable, inject } from '@theia/core/shared/inversify';
|
import { injectable, inject } from 'inversify';
|
||||||
import { IDEUpdater, UpdateInfo } from '../../common/protocol/ide-updater';
|
import { IDEUpdater, UpdateInfo } from '../../common/protocol/ide-updater';
|
||||||
import { IDEUpdaterDialog } from '../dialogs/ide-updater/ide-updater-dialog';
|
import { IDEUpdaterDialog } from '../dialogs/ide-updater/ide-updater-dialog';
|
||||||
|
|
||||||
|
@@ -1,13 +0,0 @@
|
|||||||
import * as monaco from '@theia/monaco-editor-core';
|
|
||||||
/**
|
|
||||||
* Exclusive "ino" document selector for monaco.
|
|
||||||
*/
|
|
||||||
export const InoSelector = selectorOf('ino', 'c', 'cpp', 'h', 'hpp', 'pde');
|
|
||||||
function selectorOf(
|
|
||||||
...languageId: string[]
|
|
||||||
): monaco.languages.LanguageSelector {
|
|
||||||
return languageId.map((language) => ({
|
|
||||||
language,
|
|
||||||
exclusive: true, // <-- this should make sure the custom formatter has higher precedence over the LS formatter.
|
|
||||||
}));
|
|
||||||
}
|
|
@@ -1,5 +1,5 @@
|
|||||||
import { injectable, postConstruct, inject } from '@theia/core/shared/inversify';
|
import { injectable, postConstruct, inject } from 'inversify';
|
||||||
import { Message } from '@theia/core/shared/@phosphor/messaging';
|
import { Message } from '@phosphor/messaging';
|
||||||
import { addEventListener } from '@theia/core/lib/browser/widgets/widget';
|
import { addEventListener } from '@theia/core/lib/browser/widgets/widget';
|
||||||
import { DialogProps } from '@theia/core/lib/browser/dialogs';
|
import { DialogProps } from '@theia/core/lib/browser/dialogs';
|
||||||
import { AbstractDialog } from '../theia/dialogs/dialogs';
|
import { AbstractDialog } from '../theia/dialogs/dialogs';
|
||||||
@@ -38,7 +38,7 @@ export class LibraryListWidget extends ListWidget<LibraryPackage> {
|
|||||||
}
|
}
|
||||||
|
|
||||||
@postConstruct()
|
@postConstruct()
|
||||||
protected override init(): void {
|
protected init(): void {
|
||||||
super.init();
|
super.init();
|
||||||
this.toDispose.pushAll([
|
this.toDispose.pushAll([
|
||||||
this.notificationCenter.onLibraryInstalled(() => this.refresh(undefined)),
|
this.notificationCenter.onLibraryInstalled(() => this.refresh(undefined)),
|
||||||
@@ -48,7 +48,7 @@ export class LibraryListWidget extends ListWidget<LibraryPackage> {
|
|||||||
]);
|
]);
|
||||||
}
|
}
|
||||||
|
|
||||||
protected override async install({
|
protected async install({
|
||||||
item,
|
item,
|
||||||
progressId,
|
progressId,
|
||||||
version,
|
version,
|
||||||
@@ -158,7 +158,7 @@ export class LibraryListWidget extends ListWidget<LibraryPackage> {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
protected override async uninstall({
|
protected async uninstall({
|
||||||
item,
|
item,
|
||||||
progressId,
|
progressId,
|
||||||
}: {
|
}: {
|
||||||
@@ -199,7 +199,7 @@ class MessageBoxDialog extends AbstractDialog<MessageBoxDialog.Result> {
|
|||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
protected override onCloseRequest(message: Message): void {
|
protected onCloseRequest(message: Message): void {
|
||||||
super.onCloseRequest(message);
|
super.onCloseRequest(message);
|
||||||
this.accept();
|
this.accept();
|
||||||
}
|
}
|
||||||
@@ -217,7 +217,7 @@ class MessageBoxDialog extends AbstractDialog<MessageBoxDialog.Result> {
|
|||||||
return message;
|
return message;
|
||||||
}
|
}
|
||||||
|
|
||||||
protected override handleEnter(event: KeyboardEvent): boolean | void {
|
protected handleEnter(event: KeyboardEvent): boolean | void {
|
||||||
this.response = 0;
|
this.response = 0;
|
||||||
super.handleEnter(event);
|
super.handleEnter(event);
|
||||||
}
|
}
|
||||||
|
@@ -1,4 +1,4 @@
|
|||||||
import { injectable } from '@theia/core/shared/inversify';
|
import { injectable } from 'inversify';
|
||||||
import { FrontendApplicationContribution } from '@theia/core/lib/browser/frontend-application';
|
import { FrontendApplicationContribution } from '@theia/core/lib/browser/frontend-application';
|
||||||
import { AbstractViewContribution } from '@theia/core/lib/browser/shell/view-contribution';
|
import { AbstractViewContribution } from '@theia/core/lib/browser/shell/view-contribution';
|
||||||
import { MenuModelRegistry } from '@theia/core';
|
import { MenuModelRegistry } from '@theia/core';
|
||||||
@@ -28,7 +28,7 @@ export class LibraryListWidgetFrontendContribution
|
|||||||
this.openView();
|
this.openView();
|
||||||
}
|
}
|
||||||
|
|
||||||
override registerMenus(menus: MenuModelRegistry): void {
|
registerMenus(menus: MenuModelRegistry): void {
|
||||||
if (this.toggleCommand) {
|
if (this.toggleCommand) {
|
||||||
menus.registerMenuAction(ArduinoMenus.TOOLS__MAIN_GROUP, {
|
menus.registerMenuAction(ArduinoMenus.TOOLS__MAIN_GROUP, {
|
||||||
commandId: this.toggleCommand.id,
|
commandId: this.toggleCommand.id,
|
||||||
|
@@ -1,4 +1,4 @@
|
|||||||
import { inject, injectable } from '@theia/core/shared/inversify';
|
import { inject, injectable } from 'inversify';
|
||||||
import { URI as Uri } from 'vscode-uri';
|
import { URI as Uri } from 'vscode-uri';
|
||||||
import URI from '@theia/core/lib/common/uri';
|
import URI from '@theia/core/lib/common/uri';
|
||||||
import { Deferred } from '@theia/core/lib/common/promise-util';
|
import { Deferred } from '@theia/core/lib/common/promise-util';
|
||||||
|
@@ -1,10 +1,4 @@
|
|||||||
import {
|
import { Emitter, MessageService } from '@theia/core';
|
||||||
CommandRegistry,
|
|
||||||
Disposable,
|
|
||||||
Emitter,
|
|
||||||
MessageService,
|
|
||||||
nls,
|
|
||||||
} from '@theia/core';
|
|
||||||
import { inject, injectable } from '@theia/core/shared/inversify';
|
import { inject, injectable } from '@theia/core/shared/inversify';
|
||||||
import { Board, Port } from '../common/protocol';
|
import { Board, Port } from '../common/protocol';
|
||||||
import {
|
import {
|
||||||
@@ -16,8 +10,6 @@ import {
|
|||||||
PluggableMonitorSettings,
|
PluggableMonitorSettings,
|
||||||
MonitorSettings,
|
MonitorSettings,
|
||||||
} from '../node/monitor-settings/monitor-settings-provider';
|
} from '../node/monitor-settings/monitor-settings-provider';
|
||||||
import { BoardsConfig } from './boards/boards-config';
|
|
||||||
import { BoardsServiceProvider } from './boards/boards-service-provider';
|
|
||||||
|
|
||||||
@injectable()
|
@injectable()
|
||||||
export class MonitorManagerProxyClientImpl
|
export class MonitorManagerProxyClientImpl
|
||||||
@@ -32,20 +24,13 @@ export class MonitorManagerProxyClientImpl
|
|||||||
}>();
|
}>();
|
||||||
readonly onMessagesReceived = this.onMessagesReceivedEmitter.event;
|
readonly onMessagesReceived = this.onMessagesReceivedEmitter.event;
|
||||||
|
|
||||||
protected readonly onMonitorSettingsDidChangeEmitter =
|
protected readonly onWSConnectionChangedEmitter = new Emitter<boolean>();
|
||||||
new Emitter<MonitorSettings>();
|
readonly onWSConnectionChanged = this.onWSConnectionChangedEmitter.event;
|
||||||
readonly onMonitorSettingsDidChange =
|
|
||||||
this.onMonitorSettingsDidChangeEmitter.event;
|
|
||||||
|
|
||||||
protected readonly onMonitorShouldResetEmitter = new Emitter();
|
|
||||||
readonly onMonitorShouldReset = this.onMonitorShouldResetEmitter.event;
|
|
||||||
|
|
||||||
// WebSocket used to handle pluggable monitor communication between
|
// WebSocket used to handle pluggable monitor communication between
|
||||||
// frontend and backend.
|
// frontend and backend.
|
||||||
private webSocket?: WebSocket;
|
private webSocket?: WebSocket;
|
||||||
private wsPort?: number;
|
private wsPort?: number;
|
||||||
private lastConnectedBoard: BoardsConfig.Config;
|
|
||||||
private onBoardsConfigChanged: Disposable | undefined;
|
|
||||||
|
|
||||||
getWebSocketPort(): number | undefined {
|
getWebSocketPort(): number | undefined {
|
||||||
return this.wsPort;
|
return this.wsPort;
|
||||||
@@ -57,46 +42,28 @@ export class MonitorManagerProxyClientImpl
|
|||||||
|
|
||||||
// This is necessary to call the backend methods from the frontend
|
// This is necessary to call the backend methods from the frontend
|
||||||
@inject(MonitorManagerProxyFactory)
|
@inject(MonitorManagerProxyFactory)
|
||||||
protected server: MonitorManagerProxyFactory,
|
protected server: MonitorManagerProxyFactory
|
||||||
|
|
||||||
@inject(CommandRegistry)
|
|
||||||
protected readonly commandRegistry: CommandRegistry,
|
|
||||||
|
|
||||||
@inject(BoardsServiceProvider)
|
|
||||||
protected readonly boardsServiceProvider: BoardsServiceProvider
|
|
||||||
) {}
|
) {}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Connects a localhost WebSocket using the specified port.
|
* Connects a localhost WebSocket using the specified port.
|
||||||
* @param addressPort port of the WebSocket
|
* @param addressPort port of the WebSocket
|
||||||
*/
|
*/
|
||||||
async connect(addressPort: number): Promise<void> {
|
connect(addressPort: number): void {
|
||||||
if (!!this.webSocket) {
|
if (this.webSocket) {
|
||||||
if (this.wsPort === addressPort) return;
|
return;
|
||||||
else this.disconnect();
|
|
||||||
}
|
}
|
||||||
try {
|
try {
|
||||||
this.webSocket = new WebSocket(`ws://localhost:${addressPort}`);
|
this.webSocket = new WebSocket(`ws://localhost:${addressPort}`);
|
||||||
|
this.onWSConnectionChangedEmitter.fire(true);
|
||||||
} catch {
|
} catch {
|
||||||
this.messageService.error(
|
this.messageService.error('Unable to connect to websocket');
|
||||||
nls.localize(
|
|
||||||
'arduino/monitor/unableToConnectToWebSocket',
|
|
||||||
'Unable to connect to websocket'
|
|
||||||
)
|
|
||||||
);
|
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
this.webSocket.onmessage = (message) => {
|
this.webSocket.onmessage = (res) => {
|
||||||
const parsedMessage = JSON.parse(message.data);
|
const messages = JSON.parse(res.data);
|
||||||
if (Array.isArray(parsedMessage))
|
this.onMessagesReceivedEmitter.fire({ messages });
|
||||||
this.onMessagesReceivedEmitter.fire({ messages: parsedMessage });
|
|
||||||
else if (
|
|
||||||
parsedMessage.command ===
|
|
||||||
Monitor.MiddlewareCommand.ON_SETTINGS_DID_CHANGE
|
|
||||||
) {
|
|
||||||
this.onMonitorSettingsDidChangeEmitter.fire(parsedMessage.data);
|
|
||||||
}
|
|
||||||
};
|
};
|
||||||
this.wsPort = addressPort;
|
this.wsPort = addressPort;
|
||||||
}
|
}
|
||||||
@@ -105,19 +72,12 @@ export class MonitorManagerProxyClientImpl
|
|||||||
* Disconnects the WebSocket if connected.
|
* Disconnects the WebSocket if connected.
|
||||||
*/
|
*/
|
||||||
disconnect(): void {
|
disconnect(): void {
|
||||||
if (!this.webSocket) return;
|
|
||||||
this.onBoardsConfigChanged?.dispose();
|
|
||||||
this.onBoardsConfigChanged = undefined;
|
|
||||||
try {
|
try {
|
||||||
this.webSocket?.close();
|
this.webSocket?.close();
|
||||||
this.webSocket = undefined;
|
this.webSocket = undefined;
|
||||||
|
this.onWSConnectionChangedEmitter.fire(false);
|
||||||
} catch {
|
} catch {
|
||||||
this.messageService.error(
|
this.messageService.error('Unable to close websocket');
|
||||||
nls.localize(
|
|
||||||
'arduino/monitor/unableToCloseWebSocket',
|
|
||||||
'Unable to close websocket'
|
|
||||||
)
|
|
||||||
);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -125,49 +85,15 @@ export class MonitorManagerProxyClientImpl
|
|||||||
return !!this.webSocket;
|
return !!this.webSocket;
|
||||||
}
|
}
|
||||||
|
|
||||||
async startMonitor(settings?: PluggableMonitorSettings): Promise<void> {
|
async startMonitor(
|
||||||
this.lastConnectedBoard = {
|
board: Board,
|
||||||
selectedBoard: this.boardsServiceProvider.boardsConfig.selectedBoard,
|
port: Port,
|
||||||
selectedPort: this.boardsServiceProvider.boardsConfig.selectedPort,
|
settings?: PluggableMonitorSettings
|
||||||
};
|
): Promise<void> {
|
||||||
|
return this.server().startMonitor(board, port, settings);
|
||||||
if (!this.onBoardsConfigChanged) {
|
|
||||||
this.onBoardsConfigChanged =
|
|
||||||
this.boardsServiceProvider.onBoardsConfigChanged(
|
|
||||||
async ({ selectedBoard, selectedPort }) => {
|
|
||||||
if (
|
|
||||||
typeof selectedBoard === 'undefined' ||
|
|
||||||
typeof selectedPort === 'undefined'
|
|
||||||
)
|
|
||||||
return;
|
|
||||||
|
|
||||||
// a board is plugged and it's different from the old connected board
|
|
||||||
if (
|
|
||||||
selectedBoard?.fqbn !==
|
|
||||||
this.lastConnectedBoard?.selectedBoard?.fqbn ||
|
|
||||||
selectedPort?.id !== this.lastConnectedBoard?.selectedPort?.id
|
|
||||||
) {
|
|
||||||
this.onMonitorShouldResetEmitter.fire(null);
|
|
||||||
this.lastConnectedBoard = {
|
|
||||||
selectedBoard: selectedBoard,
|
|
||||||
selectedPort: selectedPort,
|
|
||||||
};
|
|
||||||
} else {
|
|
||||||
// a board is plugged and it's the same as prev, rerun "this.startMonitor" to
|
|
||||||
// recreate the listener callback
|
|
||||||
this.startMonitor();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
);
|
|
||||||
}
|
|
||||||
|
|
||||||
const { selectedBoard, selectedPort } =
|
|
||||||
this.boardsServiceProvider.boardsConfig;
|
|
||||||
if (!selectedBoard || !selectedBoard.fqbn || !selectedPort) return;
|
|
||||||
await this.server().startMonitor(selectedBoard, selectedPort, settings);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
getCurrentSettings(board: Board, port: Port): Promise<MonitorSettings> {
|
getCurrentSettings(board: Board, port: Port): MonitorSettings {
|
||||||
return this.server().getCurrentSettings(board, port);
|
return this.server().getCurrentSettings(board, port);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -178,7 +104,7 @@ export class MonitorManagerProxyClientImpl
|
|||||||
|
|
||||||
this.webSocket.send(
|
this.webSocket.send(
|
||||||
JSON.stringify({
|
JSON.stringify({
|
||||||
command: Monitor.ClientCommand.SEND_MESSAGE,
|
command: Monitor.Command.SEND_MESSAGE,
|
||||||
data: message,
|
data: message,
|
||||||
})
|
})
|
||||||
);
|
);
|
||||||
@@ -191,7 +117,9 @@ export class MonitorManagerProxyClientImpl
|
|||||||
|
|
||||||
this.webSocket.send(
|
this.webSocket.send(
|
||||||
JSON.stringify({
|
JSON.stringify({
|
||||||
command: Monitor.ClientCommand.CHANGE_SETTINGS,
|
command: Monitor.Command.CHANGE_SETTINGS,
|
||||||
|
// TODO: This might be wrong, verify if it works
|
||||||
|
// SPOILER: It doesn't
|
||||||
data: settings,
|
data: settings,
|
||||||
})
|
})
|
||||||
);
|
);
|
||||||
|
@@ -4,9 +4,6 @@ import {
|
|||||||
LocalStorageService,
|
LocalStorageService,
|
||||||
} from '@theia/core/lib/browser';
|
} from '@theia/core/lib/browser';
|
||||||
import { inject, injectable } from '@theia/core/shared/inversify';
|
import { inject, injectable } from '@theia/core/shared/inversify';
|
||||||
import { MonitorManagerProxyClient } from '../common/protocol';
|
|
||||||
import { isNullOrUndefined } from '../common/utils';
|
|
||||||
import { MonitorSettings } from '../node/monitor-settings/monitor-settings-provider';
|
|
||||||
|
|
||||||
@injectable()
|
@injectable()
|
||||||
export class MonitorModel implements FrontendApplicationContribution {
|
export class MonitorModel implements FrontendApplicationContribution {
|
||||||
@@ -15,9 +12,6 @@ export class MonitorModel implements FrontendApplicationContribution {
|
|||||||
@inject(LocalStorageService)
|
@inject(LocalStorageService)
|
||||||
protected readonly localStorageService: LocalStorageService;
|
protected readonly localStorageService: LocalStorageService;
|
||||||
|
|
||||||
@inject(MonitorManagerProxyClient)
|
|
||||||
protected readonly monitorManagerProxy: MonitorManagerProxyClient;
|
|
||||||
|
|
||||||
protected readonly onChangeEmitter: Emitter<
|
protected readonly onChangeEmitter: Emitter<
|
||||||
MonitorModel.State.Change<keyof MonitorModel.State>
|
MonitorModel.State.Change<keyof MonitorModel.State>
|
||||||
>;
|
>;
|
||||||
@@ -26,20 +20,12 @@ export class MonitorModel implements FrontendApplicationContribution {
|
|||||||
protected _timestamp: boolean;
|
protected _timestamp: boolean;
|
||||||
protected _lineEnding: MonitorModel.EOL;
|
protected _lineEnding: MonitorModel.EOL;
|
||||||
protected _interpolate: boolean;
|
protected _interpolate: boolean;
|
||||||
protected _darkTheme: boolean;
|
|
||||||
protected _wsPort: number;
|
|
||||||
protected _serialPort: string;
|
|
||||||
protected _connected: boolean;
|
|
||||||
|
|
||||||
constructor() {
|
constructor() {
|
||||||
this._autoscroll = true;
|
this._autoscroll = true;
|
||||||
this._timestamp = false;
|
this._timestamp = false;
|
||||||
this._interpolate = false;
|
this._interpolate = false;
|
||||||
this._lineEnding = MonitorModel.EOL.DEFAULT;
|
this._lineEnding = MonitorModel.EOL.DEFAULT;
|
||||||
this._darkTheme = false;
|
|
||||||
this._wsPort = 0;
|
|
||||||
this._serialPort = '';
|
|
||||||
this._connected = true;
|
|
||||||
|
|
||||||
this.onChangeEmitter = new Emitter<
|
this.onChangeEmitter = new Emitter<
|
||||||
MonitorModel.State.Change<keyof MonitorModel.State>
|
MonitorModel.State.Change<keyof MonitorModel.State>
|
||||||
@@ -49,11 +35,7 @@ export class MonitorModel implements FrontendApplicationContribution {
|
|||||||
onStart(): void {
|
onStart(): void {
|
||||||
this.localStorageService
|
this.localStorageService
|
||||||
.getData<MonitorModel.State>(MonitorModel.STORAGE_ID)
|
.getData<MonitorModel.State>(MonitorModel.STORAGE_ID)
|
||||||
.then(this.restoreState.bind(this));
|
.then(this.restoreState);
|
||||||
|
|
||||||
this.monitorManagerProxy.onMonitorSettingsDidChange(
|
|
||||||
this.onMonitorSettingsDidChange.bind(this)
|
|
||||||
);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
get onChange(): Event<MonitorModel.State.Change<keyof MonitorModel.State>> {
|
get onChange(): Event<MonitorModel.State.Change<keyof MonitorModel.State>> {
|
||||||
@@ -68,7 +50,6 @@ export class MonitorModel implements FrontendApplicationContribution {
|
|||||||
this._timestamp = state.timestamp;
|
this._timestamp = state.timestamp;
|
||||||
this._lineEnding = state.lineEnding;
|
this._lineEnding = state.lineEnding;
|
||||||
this._interpolate = state.interpolate;
|
this._interpolate = state.interpolate;
|
||||||
this._serialPort = state.serialPort;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
protected async storeState(): Promise<void> {
|
protected async storeState(): Promise<void> {
|
||||||
@@ -77,7 +58,6 @@ export class MonitorModel implements FrontendApplicationContribution {
|
|||||||
timestamp: this._timestamp,
|
timestamp: this._timestamp,
|
||||||
lineEnding: this._lineEnding,
|
lineEnding: this._lineEnding,
|
||||||
interpolate: this._interpolate,
|
interpolate: this._interpolate,
|
||||||
serialPort: this._serialPort,
|
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -85,34 +65,22 @@ export class MonitorModel implements FrontendApplicationContribution {
|
|||||||
return this._autoscroll;
|
return this._autoscroll;
|
||||||
}
|
}
|
||||||
|
|
||||||
set autoscroll(autoscroll: boolean) {
|
toggleAutoscroll(): void {
|
||||||
if (autoscroll === this._autoscroll) return;
|
this._autoscroll = !this._autoscroll;
|
||||||
this._autoscroll = autoscroll;
|
|
||||||
this.monitorManagerProxy.changeSettings({
|
|
||||||
monitorUISettings: { autoscroll },
|
|
||||||
});
|
|
||||||
this.storeState().then(() => {
|
this.storeState().then(() => {
|
||||||
this.onChangeEmitter.fire({
|
this.onChangeEmitter.fire({
|
||||||
property: 'autoscroll',
|
property: 'autoscroll',
|
||||||
value: this._autoscroll,
|
value: this._timestamp,
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
toggleAutoscroll(): void {
|
|
||||||
this.autoscroll = !this._autoscroll;
|
|
||||||
}
|
|
||||||
|
|
||||||
get timestamp(): boolean {
|
get timestamp(): boolean {
|
||||||
return this._timestamp;
|
return this._timestamp;
|
||||||
}
|
}
|
||||||
|
|
||||||
set timestamp(timestamp: boolean) {
|
toggleTimestamp(): void {
|
||||||
if (timestamp === this._timestamp) return;
|
this._timestamp = !this._timestamp;
|
||||||
this._timestamp = timestamp;
|
|
||||||
this.monitorManagerProxy.changeSettings({
|
|
||||||
monitorUISettings: { timestamp },
|
|
||||||
});
|
|
||||||
this.storeState().then(() =>
|
this.storeState().then(() =>
|
||||||
this.onChangeEmitter.fire({
|
this.onChangeEmitter.fire({
|
||||||
property: 'timestamp',
|
property: 'timestamp',
|
||||||
@@ -121,20 +89,12 @@ export class MonitorModel implements FrontendApplicationContribution {
|
|||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
toggleTimestamp(): void {
|
|
||||||
this.timestamp = !this._timestamp;
|
|
||||||
}
|
|
||||||
|
|
||||||
get lineEnding(): MonitorModel.EOL {
|
get lineEnding(): MonitorModel.EOL {
|
||||||
return this._lineEnding;
|
return this._lineEnding;
|
||||||
}
|
}
|
||||||
|
|
||||||
set lineEnding(lineEnding: MonitorModel.EOL) {
|
set lineEnding(lineEnding: MonitorModel.EOL) {
|
||||||
if (lineEnding === this._lineEnding) return;
|
|
||||||
this._lineEnding = lineEnding;
|
this._lineEnding = lineEnding;
|
||||||
this.monitorManagerProxy.changeSettings({
|
|
||||||
monitorUISettings: { lineEnding },
|
|
||||||
});
|
|
||||||
this.storeState().then(() =>
|
this.storeState().then(() =>
|
||||||
this.onChangeEmitter.fire({
|
this.onChangeEmitter.fire({
|
||||||
property: 'lineEnding',
|
property: 'lineEnding',
|
||||||
@@ -147,12 +107,8 @@ export class MonitorModel implements FrontendApplicationContribution {
|
|||||||
return this._interpolate;
|
return this._interpolate;
|
||||||
}
|
}
|
||||||
|
|
||||||
set interpolate(interpolate: boolean) {
|
set interpolate(i: boolean) {
|
||||||
if (interpolate === this._interpolate) return;
|
this._interpolate = i;
|
||||||
this._interpolate = interpolate;
|
|
||||||
this.monitorManagerProxy.changeSettings({
|
|
||||||
monitorUISettings: { interpolate },
|
|
||||||
});
|
|
||||||
this.storeState().then(() =>
|
this.storeState().then(() =>
|
||||||
this.onChangeEmitter.fire({
|
this.onChangeEmitter.fire({
|
||||||
property: 'interpolate',
|
property: 'interpolate',
|
||||||
@@ -160,96 +116,6 @@ export class MonitorModel implements FrontendApplicationContribution {
|
|||||||
})
|
})
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
get darkTheme(): boolean {
|
|
||||||
return this._darkTheme;
|
|
||||||
}
|
|
||||||
|
|
||||||
set darkTheme(darkTheme: boolean) {
|
|
||||||
if (darkTheme === this._darkTheme) return;
|
|
||||||
this._darkTheme = darkTheme;
|
|
||||||
this.monitorManagerProxy.changeSettings({
|
|
||||||
monitorUISettings: { darkTheme },
|
|
||||||
});
|
|
||||||
this.onChangeEmitter.fire({
|
|
||||||
property: 'darkTheme',
|
|
||||||
value: this._darkTheme,
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
get wsPort(): number {
|
|
||||||
return this._wsPort;
|
|
||||||
}
|
|
||||||
|
|
||||||
set wsPort(wsPort: number) {
|
|
||||||
if (wsPort === this._wsPort) return;
|
|
||||||
this._wsPort = wsPort;
|
|
||||||
this.monitorManagerProxy.changeSettings({
|
|
||||||
monitorUISettings: { wsPort },
|
|
||||||
});
|
|
||||||
this.onChangeEmitter.fire({
|
|
||||||
property: 'wsPort',
|
|
||||||
value: this._wsPort,
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
get serialPort(): string {
|
|
||||||
return this._serialPort;
|
|
||||||
}
|
|
||||||
|
|
||||||
set serialPort(serialPort: string) {
|
|
||||||
if (serialPort === this._serialPort) return;
|
|
||||||
this._serialPort = serialPort;
|
|
||||||
this.monitorManagerProxy.changeSettings({
|
|
||||||
monitorUISettings: { serialPort },
|
|
||||||
});
|
|
||||||
this.storeState().then(() =>
|
|
||||||
this.onChangeEmitter.fire({
|
|
||||||
property: 'serialPort',
|
|
||||||
value: this._serialPort,
|
|
||||||
})
|
|
||||||
);
|
|
||||||
}
|
|
||||||
|
|
||||||
get connected(): boolean {
|
|
||||||
return this._connected;
|
|
||||||
}
|
|
||||||
|
|
||||||
set connected(connected: boolean) {
|
|
||||||
if (connected === this._connected) return;
|
|
||||||
this._connected = connected;
|
|
||||||
this.monitorManagerProxy.changeSettings({
|
|
||||||
monitorUISettings: { connected },
|
|
||||||
});
|
|
||||||
this.onChangeEmitter.fire({
|
|
||||||
property: 'connected',
|
|
||||||
value: this._connected,
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
protected onMonitorSettingsDidChange = (settings: MonitorSettings): void => {
|
|
||||||
const { monitorUISettings } = settings;
|
|
||||||
if (!monitorUISettings) return;
|
|
||||||
const {
|
|
||||||
autoscroll,
|
|
||||||
interpolate,
|
|
||||||
lineEnding,
|
|
||||||
timestamp,
|
|
||||||
darkTheme,
|
|
||||||
wsPort,
|
|
||||||
serialPort,
|
|
||||||
connected,
|
|
||||||
} = monitorUISettings;
|
|
||||||
|
|
||||||
if (!isNullOrUndefined(autoscroll)) this.autoscroll = autoscroll;
|
|
||||||
if (!isNullOrUndefined(interpolate)) this.interpolate = interpolate;
|
|
||||||
if (!isNullOrUndefined(lineEnding)) this.lineEnding = lineEnding;
|
|
||||||
if (!isNullOrUndefined(timestamp)) this.timestamp = timestamp;
|
|
||||||
if (!isNullOrUndefined(darkTheme)) this.darkTheme = darkTheme;
|
|
||||||
if (!isNullOrUndefined(wsPort)) this.wsPort = wsPort;
|
|
||||||
if (!isNullOrUndefined(serialPort)) this.serialPort = serialPort;
|
|
||||||
if (!isNullOrUndefined(connected)) this.connected = connected;
|
|
||||||
};
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// TODO: Move this to /common
|
// TODO: Move this to /common
|
||||||
@@ -259,10 +125,6 @@ export namespace MonitorModel {
|
|||||||
timestamp: boolean;
|
timestamp: boolean;
|
||||||
lineEnding: EOL;
|
lineEnding: EOL;
|
||||||
interpolate: boolean;
|
interpolate: boolean;
|
||||||
darkTheme: boolean;
|
|
||||||
wsPort: number;
|
|
||||||
serialPort: string;
|
|
||||||
connected: boolean;
|
|
||||||
}
|
}
|
||||||
export namespace State {
|
export namespace State {
|
||||||
export interface Change<K extends keyof State> {
|
export interface Change<K extends keyof State> {
|
||||||
|
@@ -1,8 +1,4 @@
|
|||||||
import {
|
import { inject, injectable, postConstruct } from 'inversify';
|
||||||
inject,
|
|
||||||
injectable,
|
|
||||||
postConstruct,
|
|
||||||
} from '@theia/core/shared/inversify';
|
|
||||||
import { Emitter } from '@theia/core/lib/common/event';
|
import { Emitter } from '@theia/core/lib/common/event';
|
||||||
import { JsonRpcProxy } from '@theia/core/lib/common/messaging/proxy-factory';
|
import { JsonRpcProxy } from '@theia/core/lib/common/messaging/proxy-factory';
|
||||||
import { DisposableCollection } from '@theia/core/lib/common/disposable';
|
import { DisposableCollection } from '@theia/core/lib/common/disposable';
|
||||||
@@ -18,10 +14,6 @@ import {
|
|||||||
Config,
|
Config,
|
||||||
Sketch,
|
Sketch,
|
||||||
} from '../common/protocol';
|
} from '../common/protocol';
|
||||||
import {
|
|
||||||
FrontendApplicationStateService,
|
|
||||||
FrontendApplicationState,
|
|
||||||
} from '@theia/core/lib/browser/frontend-application-state';
|
|
||||||
|
|
||||||
@injectable()
|
@injectable()
|
||||||
export class NotificationCenter
|
export class NotificationCenter
|
||||||
@@ -30,11 +22,8 @@ export class NotificationCenter
|
|||||||
@inject(NotificationServiceServer)
|
@inject(NotificationServiceServer)
|
||||||
protected readonly server: JsonRpcProxy<NotificationServiceServer>;
|
protected readonly server: JsonRpcProxy<NotificationServiceServer>;
|
||||||
|
|
||||||
@inject(FrontendApplicationStateService)
|
|
||||||
private readonly appStateService: FrontendApplicationStateService;
|
|
||||||
|
|
||||||
protected readonly indexUpdatedEmitter = new Emitter<void>();
|
protected readonly indexUpdatedEmitter = new Emitter<void>();
|
||||||
protected readonly daemonStartedEmitter = new Emitter<string>();
|
protected readonly daemonStartedEmitter = new Emitter<void>();
|
||||||
protected readonly daemonStoppedEmitter = new Emitter<void>();
|
protected readonly daemonStoppedEmitter = new Emitter<void>();
|
||||||
protected readonly configChangedEmitter = new Emitter<{
|
protected readonly configChangedEmitter = new Emitter<{
|
||||||
config: Config | undefined;
|
config: Config | undefined;
|
||||||
@@ -56,8 +45,6 @@ export class NotificationCenter
|
|||||||
protected readonly recentSketchesChangedEmitter = new Emitter<{
|
protected readonly recentSketchesChangedEmitter = new Emitter<{
|
||||||
sketches: Sketch[];
|
sketches: Sketch[];
|
||||||
}>();
|
}>();
|
||||||
private readonly onAppStateDidChangeEmitter =
|
|
||||||
new Emitter<FrontendApplicationState>();
|
|
||||||
|
|
||||||
protected readonly toDispose = new DisposableCollection(
|
protected readonly toDispose = new DisposableCollection(
|
||||||
this.indexUpdatedEmitter,
|
this.indexUpdatedEmitter,
|
||||||
@@ -81,16 +68,10 @@ export class NotificationCenter
|
|||||||
readonly onLibraryUninstalled = this.libraryUninstalledEmitter.event;
|
readonly onLibraryUninstalled = this.libraryUninstalledEmitter.event;
|
||||||
readonly onAttachedBoardsChanged = this.attachedBoardsChangedEmitter.event;
|
readonly onAttachedBoardsChanged = this.attachedBoardsChangedEmitter.event;
|
||||||
readonly onRecentSketchesChanged = this.recentSketchesChangedEmitter.event;
|
readonly onRecentSketchesChanged = this.recentSketchesChangedEmitter.event;
|
||||||
readonly onAppStateDidChange = this.onAppStateDidChangeEmitter.event;
|
|
||||||
|
|
||||||
@postConstruct()
|
@postConstruct()
|
||||||
protected init(): void {
|
protected init(): void {
|
||||||
this.server.setClient(this);
|
this.server.setClient(this);
|
||||||
this.toDispose.push(
|
|
||||||
this.appStateService.onStateChanged((state) =>
|
|
||||||
this.onAppStateDidChangeEmitter.fire(state)
|
|
||||||
)
|
|
||||||
);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
onStop(): void {
|
onStop(): void {
|
||||||
@@ -101,8 +82,8 @@ export class NotificationCenter
|
|||||||
this.indexUpdatedEmitter.fire();
|
this.indexUpdatedEmitter.fire();
|
||||||
}
|
}
|
||||||
|
|
||||||
notifyDaemonStarted(port: string): void {
|
notifyDaemonStarted(): void {
|
||||||
this.daemonStartedEmitter.fire(port);
|
this.daemonStartedEmitter.fire();
|
||||||
}
|
}
|
||||||
|
|
||||||
notifyDaemonStopped(): void {
|
notifyDaemonStopped(): void {
|
||||||
|
@@ -1,9 +1,7 @@
|
|||||||
import { inject, injectable } from '@theia/core/shared/inversify';
|
import { inject, injectable } from 'inversify';
|
||||||
import { Emitter } from '@theia/core/lib/common/event';
|
import { Emitter } from '@theia/core/lib/common/event';
|
||||||
import {
|
import { OutputContribution } from '@theia/output/lib/browser/output-contribution';
|
||||||
OutputChannelManager,
|
import { OutputChannelManager } from '@theia/output/lib/browser/output-channel';
|
||||||
OutputChannelSeverity,
|
|
||||||
} from '@theia/output/lib/browser/output-channel';
|
|
||||||
import {
|
import {
|
||||||
OutputMessage,
|
OutputMessage,
|
||||||
ProgressMessage,
|
ProgressMessage,
|
||||||
@@ -12,10 +10,13 @@ import {
|
|||||||
|
|
||||||
@injectable()
|
@injectable()
|
||||||
export class ResponseServiceImpl implements ResponseServiceArduino {
|
export class ResponseServiceImpl implements ResponseServiceArduino {
|
||||||
@inject(OutputChannelManager)
|
@inject(OutputContribution)
|
||||||
private readonly outputChannelManager: OutputChannelManager;
|
protected outputContribution: OutputContribution;
|
||||||
|
|
||||||
private readonly progressDidChangeEmitter = new Emitter<ProgressMessage>();
|
@inject(OutputChannelManager)
|
||||||
|
protected outputChannelManager: OutputChannelManager;
|
||||||
|
|
||||||
|
protected readonly progressDidChangeEmitter = new Emitter<ProgressMessage>();
|
||||||
|
|
||||||
readonly onProgressDidChange = this.progressDidChangeEmitter.event;
|
readonly onProgressDidChange = this.progressDidChangeEmitter.event;
|
||||||
|
|
||||||
@@ -24,22 +25,13 @@ export class ResponseServiceImpl implements ResponseServiceArduino {
|
|||||||
}
|
}
|
||||||
|
|
||||||
appendToOutput(message: OutputMessage): void {
|
appendToOutput(message: OutputMessage): void {
|
||||||
const { chunk, severity } = message;
|
const { chunk } = message;
|
||||||
const channel = this.outputChannelManager.getChannel('Arduino');
|
const channel = this.outputChannelManager.getChannel('Arduino');
|
||||||
channel.show({ preserveFocus: true });
|
channel.show({ preserveFocus: true });
|
||||||
channel.append(chunk, mapSeverity(severity));
|
channel.append(chunk);
|
||||||
}
|
}
|
||||||
|
|
||||||
reportProgress(progress: ProgressMessage): void {
|
reportProgress(progress: ProgressMessage): void {
|
||||||
this.progressDidChangeEmitter.fire(progress);
|
this.progressDidChangeEmitter.fire(progress);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
function mapSeverity(severity?: OutputMessage.Severity): OutputChannelSeverity {
|
|
||||||
if (severity === OutputMessage.Severity.Error) {
|
|
||||||
return OutputChannelSeverity.Error;
|
|
||||||
} else if (severity === OutputMessage.Severity.Warning) {
|
|
||||||
return OutputChannelSeverity.Warning;
|
|
||||||
}
|
|
||||||
return OutputChannelSeverity.Info;
|
|
||||||
}
|
|
||||||
|
@@ -1,5 +1,5 @@
|
|||||||
import * as React from '@theia/core/shared/react';
|
import * as React from 'react';
|
||||||
import { injectable, inject } from '@theia/core/shared/inversify';
|
import { injectable, inject } from 'inversify';
|
||||||
import { AbstractViewContribution, codicon } from '@theia/core/lib/browser';
|
import { AbstractViewContribution, codicon } from '@theia/core/lib/browser';
|
||||||
import { MonitorWidget } from './monitor-widget';
|
import { MonitorWidget } from './monitor-widget';
|
||||||
import { MenuModelRegistry, Command, CommandRegistry } from '@theia/core';
|
import { MenuModelRegistry, Command, CommandRegistry } from '@theia/core';
|
||||||
@@ -11,7 +11,6 @@ import { ArduinoToolbar } from '../../toolbar/arduino-toolbar';
|
|||||||
import { ArduinoMenus } from '../../menu/arduino-menus';
|
import { ArduinoMenus } from '../../menu/arduino-menus';
|
||||||
import { nls } from '@theia/core/lib/common';
|
import { nls } from '@theia/core/lib/common';
|
||||||
import { MonitorModel } from '../../monitor-model';
|
import { MonitorModel } from '../../monitor-model';
|
||||||
import { MonitorManagerProxyClient } from '../../../common/protocol';
|
|
||||||
|
|
||||||
export namespace SerialMonitor {
|
export namespace SerialMonitor {
|
||||||
export namespace Commands {
|
export namespace Commands {
|
||||||
@@ -48,15 +47,11 @@ export class MonitorViewContribution
|
|||||||
static readonly TOGGLE_SERIAL_MONITOR = MonitorWidget.ID + ':toggle';
|
static readonly TOGGLE_SERIAL_MONITOR = MonitorWidget.ID + ':toggle';
|
||||||
static readonly TOGGLE_SERIAL_MONITOR_TOOLBAR =
|
static readonly TOGGLE_SERIAL_MONITOR_TOOLBAR =
|
||||||
MonitorWidget.ID + ':toggle-toolbar';
|
MonitorWidget.ID + ':toggle-toolbar';
|
||||||
static readonly RESET_SERIAL_MONITOR = MonitorWidget.ID + ':reset';
|
|
||||||
|
|
||||||
constructor(
|
@inject(MonitorModel)
|
||||||
@inject(MonitorModel)
|
protected readonly model: MonitorModel;
|
||||||
protected readonly model: MonitorModel,
|
|
||||||
|
|
||||||
@inject(MonitorManagerProxyClient)
|
constructor() {
|
||||||
protected readonly monitorManagerProxy: MonitorManagerProxyClient
|
|
||||||
) {
|
|
||||||
super({
|
super({
|
||||||
widgetId: MonitorWidget.ID,
|
widgetId: MonitorWidget.ID,
|
||||||
widgetName: MonitorWidget.LABEL,
|
widgetName: MonitorWidget.LABEL,
|
||||||
@@ -66,10 +61,9 @@ export class MonitorViewContribution
|
|||||||
toggleCommandId: MonitorViewContribution.TOGGLE_SERIAL_MONITOR,
|
toggleCommandId: MonitorViewContribution.TOGGLE_SERIAL_MONITOR,
|
||||||
toggleKeybinding: 'CtrlCmd+Shift+M',
|
toggleKeybinding: 'CtrlCmd+Shift+M',
|
||||||
});
|
});
|
||||||
this.monitorManagerProxy.onMonitorShouldReset(() => this.reset());
|
|
||||||
}
|
}
|
||||||
|
|
||||||
override registerMenus(menus: MenuModelRegistry): void {
|
registerMenus(menus: MenuModelRegistry): void {
|
||||||
if (this.toggleCommand) {
|
if (this.toggleCommand) {
|
||||||
menus.registerMenuAction(ArduinoMenus.TOOLS__MAIN_GROUP, {
|
menus.registerMenuAction(ArduinoMenus.TOOLS__MAIN_GROUP, {
|
||||||
commandId: this.toggleCommand.id,
|
commandId: this.toggleCommand.id,
|
||||||
@@ -102,7 +96,7 @@ export class MonitorViewContribution
|
|||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
override registerCommands(commands: CommandRegistry): void {
|
registerCommands(commands: CommandRegistry): void {
|
||||||
commands.registerCommand(SerialMonitor.Commands.CLEAR_OUTPUT, {
|
commands.registerCommand(SerialMonitor.Commands.CLEAR_OUTPUT, {
|
||||||
isEnabled: (widget) => widget instanceof MonitorWidget,
|
isEnabled: (widget) => widget instanceof MonitorWidget,
|
||||||
isVisible: (widget) => widget instanceof MonitorWidget,
|
isVisible: (widget) => widget instanceof MonitorWidget,
|
||||||
@@ -125,10 +119,6 @@ export class MonitorViewContribution
|
|||||||
}
|
}
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
commands.registerCommand(
|
|
||||||
{ id: MonitorViewContribution.RESET_SERIAL_MONITOR },
|
|
||||||
{ execute: () => this.reset() }
|
|
||||||
);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
protected async toggle(): Promise<void> {
|
protected async toggle(): Promise<void> {
|
||||||
@@ -140,14 +130,6 @@ export class MonitorViewContribution
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
protected async reset(): Promise<void> {
|
|
||||||
const widget = this.tryGetWidget();
|
|
||||||
if (widget) {
|
|
||||||
widget.dispose();
|
|
||||||
await this.openView({ activate: true, reveal: true });
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
protected renderAutoScrollButton(): React.ReactNode {
|
protected renderAutoScrollButton(): React.ReactNode {
|
||||||
return (
|
return (
|
||||||
<React.Fragment key="autoscroll-toolbar-item">
|
<React.Fragment key="autoscroll-toolbar-item">
|
||||||
|
@@ -1,5 +1,5 @@
|
|||||||
import * as React from '@theia/core/shared/react';
|
import * as React from 'react';
|
||||||
import { injectable, inject } from '@theia/core/shared/inversify';
|
import { postConstruct, injectable, inject } from 'inversify';
|
||||||
import { OptionsType } from 'react-select/src/types';
|
import { OptionsType } from 'react-select/src/types';
|
||||||
import { Emitter } from '@theia/core/lib/common/event';
|
import { Emitter } from '@theia/core/lib/common/event';
|
||||||
import { Disposable } from '@theia/core/lib/common/disposable';
|
import { Disposable } from '@theia/core/lib/common/disposable';
|
||||||
@@ -26,8 +26,6 @@ export class MonitorWidget extends ReactWidget {
|
|||||||
);
|
);
|
||||||
static readonly ID = 'serial-monitor';
|
static readonly ID = 'serial-monitor';
|
||||||
|
|
||||||
protected settings: MonitorSettings = {};
|
|
||||||
|
|
||||||
protected widgetHeight: number;
|
protected widgetHeight: number;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -61,28 +59,33 @@ export class MonitorWidget extends ReactWidget {
|
|||||||
this.toDispose.push(
|
this.toDispose.push(
|
||||||
Disposable.create(() => this.monitorManagerProxy.disconnect())
|
Disposable.create(() => this.monitorManagerProxy.disconnect())
|
||||||
);
|
);
|
||||||
|
|
||||||
|
// Start monitor right away if there is already a board/port combination selected
|
||||||
|
const { selectedBoard, selectedPort } =
|
||||||
|
this.boardsServiceProvider.boardsConfig;
|
||||||
|
if (selectedBoard && selectedBoard.fqbn && selectedPort) {
|
||||||
|
this.monitorManagerProxy.startMonitor(selectedBoard, selectedPort);
|
||||||
|
}
|
||||||
|
|
||||||
|
this.toDispose.push(
|
||||||
|
this.boardsServiceProvider.onBoardsConfigChanged(
|
||||||
|
async ({ selectedBoard, selectedPort }) => {
|
||||||
|
if (selectedBoard && selectedBoard.fqbn && selectedPort) {
|
||||||
|
await this.monitorManagerProxy.startMonitor(
|
||||||
|
selectedBoard,
|
||||||
|
selectedPort
|
||||||
|
);
|
||||||
|
this.update();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
)
|
||||||
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
protected override onBeforeAttach(msg: Message): void {
|
@postConstruct()
|
||||||
|
protected init(): void {
|
||||||
this.update();
|
this.update();
|
||||||
this.toDispose.push(this.monitorModel.onChange(() => this.update()));
|
this.toDispose.push(this.monitorModel.onChange(() => this.update()));
|
||||||
this.getCurrentSettings().then(this.onMonitorSettingsDidChange.bind(this));
|
|
||||||
this.monitorManagerProxy.onMonitorSettingsDidChange(
|
|
||||||
this.onMonitorSettingsDidChange.bind(this)
|
|
||||||
);
|
|
||||||
|
|
||||||
this.monitorManagerProxy.startMonitor();
|
|
||||||
}
|
|
||||||
|
|
||||||
onMonitorSettingsDidChange(settings: MonitorSettings): void {
|
|
||||||
this.settings = {
|
|
||||||
...this.settings,
|
|
||||||
pluggableMonitorSettings: {
|
|
||||||
...this.settings.pluggableMonitorSettings,
|
|
||||||
...settings.pluggableMonitorSettings,
|
|
||||||
},
|
|
||||||
};
|
|
||||||
this.update();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
clearConsole(): void {
|
clearConsole(): void {
|
||||||
@@ -90,16 +93,16 @@ export class MonitorWidget extends ReactWidget {
|
|||||||
this.update();
|
this.update();
|
||||||
}
|
}
|
||||||
|
|
||||||
override dispose(): void {
|
dispose(): void {
|
||||||
super.dispose();
|
super.dispose();
|
||||||
}
|
}
|
||||||
|
|
||||||
protected override onCloseRequest(msg: Message): void {
|
onCloseRequest(msg: Message): void {
|
||||||
this.closing = true;
|
this.closing = true;
|
||||||
super.onCloseRequest(msg);
|
super.onCloseRequest(msg);
|
||||||
}
|
}
|
||||||
|
|
||||||
protected override onUpdateRequest(msg: Message): void {
|
protected onUpdateRequest(msg: Message): void {
|
||||||
// TODO: `this.isAttached`
|
// TODO: `this.isAttached`
|
||||||
// See: https://github.com/eclipse-theia/theia/issues/6704#issuecomment-562574713
|
// See: https://github.com/eclipse-theia/theia/issues/6704#issuecomment-562574713
|
||||||
if (!this.closing && this.isAttached) {
|
if (!this.closing && this.isAttached) {
|
||||||
@@ -107,13 +110,13 @@ export class MonitorWidget extends ReactWidget {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
protected override onResize(msg: Widget.ResizeMessage): void {
|
protected onResize(msg: Widget.ResizeMessage): void {
|
||||||
super.onResize(msg);
|
super.onResize(msg);
|
||||||
this.widgetHeight = msg.height;
|
this.widgetHeight = msg.height;
|
||||||
this.update();
|
this.update();
|
||||||
}
|
}
|
||||||
|
|
||||||
protected override onActivateRequest(msg: Message): void {
|
protected onActivateRequest(msg: Message): void {
|
||||||
super.onActivateRequest(msg);
|
super.onActivateRequest(msg);
|
||||||
(this.focusNode || this.node).focus();
|
(this.focusNode || this.node).focus();
|
||||||
}
|
}
|
||||||
@@ -154,40 +157,63 @@ export class MonitorWidget extends ReactWidget {
|
|||||||
];
|
];
|
||||||
}
|
}
|
||||||
|
|
||||||
private getCurrentSettings(): Promise<MonitorSettings> {
|
private getCurrentSettings(): MonitorSettings {
|
||||||
const board = this.boardsServiceProvider.boardsConfig.selectedBoard;
|
const board = this.boardsServiceProvider.boardsConfig.selectedBoard;
|
||||||
const port = this.boardsServiceProvider.boardsConfig.selectedPort;
|
const port = this.boardsServiceProvider.boardsConfig.selectedPort;
|
||||||
if (!board || !port) {
|
if (!board || !port) {
|
||||||
return Promise.resolve(this.settings || {});
|
return {};
|
||||||
}
|
}
|
||||||
return this.monitorManagerProxy.getCurrentSettings(board, port);
|
return this.monitorManagerProxy.getCurrentSettings(board, port);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
//////////////////////////////////////////////////
|
||||||
|
////////////////////IMPORTANT/////////////////////
|
||||||
|
//////////////////////////////////////////////////
|
||||||
|
// baudRates and selectedBaudRates as of now are hardcoded
|
||||||
|
// like this to retrieve the baudrate settings from the ones
|
||||||
|
// received by the monitor.
|
||||||
|
// We're doing it like since the frontend as of now doesn't
|
||||||
|
// support a fully customizable list of options that would
|
||||||
|
// be require to support pluggable monitors completely.
|
||||||
|
// As soon as the frontend UI is updated to support
|
||||||
|
// any custom settings this methods MUST be removed and
|
||||||
|
// made generic.
|
||||||
|
//
|
||||||
|
// This breaks if the user tries to open a monitor that
|
||||||
|
// doesn't support the baudrate setting.
|
||||||
|
protected get baudRates(): string[] {
|
||||||
|
const { pluggableMonitorSettings } = this.getCurrentSettings();
|
||||||
|
if (!pluggableMonitorSettings || !pluggableMonitorSettings['baudrate']) {
|
||||||
|
return [];
|
||||||
|
}
|
||||||
|
|
||||||
|
const baudRateSettings = pluggableMonitorSettings['baudrate'];
|
||||||
|
|
||||||
|
return baudRateSettings.values;
|
||||||
|
}
|
||||||
|
|
||||||
|
protected get selectedBaudRate(): string {
|
||||||
|
const { pluggableMonitorSettings } = this.getCurrentSettings();
|
||||||
|
if (!pluggableMonitorSettings || !pluggableMonitorSettings['baudrate']) {
|
||||||
|
return '';
|
||||||
|
}
|
||||||
|
const baudRateSettings = pluggableMonitorSettings['baudrate'];
|
||||||
|
return baudRateSettings.selectedValue;
|
||||||
|
}
|
||||||
|
|
||||||
protected render(): React.ReactNode {
|
protected render(): React.ReactNode {
|
||||||
const baudrate = this.settings?.pluggableMonitorSettings
|
const { baudRates, lineEndings } = this;
|
||||||
? this.settings.pluggableMonitorSettings.baudrate
|
|
||||||
: undefined;
|
|
||||||
|
|
||||||
const baudrateOptions = baudrate?.values.map((b) => ({
|
|
||||||
label: b + ' baud',
|
|
||||||
value: b,
|
|
||||||
}));
|
|
||||||
const baudrateSelectedOption = baudrateOptions?.find(
|
|
||||||
(b) => b.value === baudrate?.selectedValue
|
|
||||||
);
|
|
||||||
|
|
||||||
const lineEnding =
|
const lineEnding =
|
||||||
this.lineEndings.find(
|
lineEndings.find((item) => item.value === this.monitorModel.lineEnding) ||
|
||||||
(item) => item.value === this.monitorModel.lineEnding
|
lineEndings[1]; // Defaults to `\n`.
|
||||||
) || this.lineEndings[1]; // Defaults to `\n`.
|
const baudRate = baudRates.find((item) => item === this.selectedBaudRate);
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<div className="serial-monitor">
|
<div className="serial-monitor">
|
||||||
<div className="head">
|
<div className="head">
|
||||||
<div className="send">
|
<div className="send">
|
||||||
<SerialMonitorSendInput
|
<SerialMonitorSendInput
|
||||||
boardsServiceProvider={this.boardsServiceProvider}
|
boardsServiceProvider={this.boardsServiceProvider}
|
||||||
monitorModel={this.monitorModel}
|
monitorManagerProxy={this.monitorManagerProxy}
|
||||||
resolveFocus={this.onFocusResolved}
|
resolveFocus={this.onFocusResolved}
|
||||||
onSend={this.onSend}
|
onSend={this.onSend}
|
||||||
/>
|
/>
|
||||||
@@ -196,22 +222,20 @@ export class MonitorWidget extends ReactWidget {
|
|||||||
<div className="select">
|
<div className="select">
|
||||||
<ArduinoSelect
|
<ArduinoSelect
|
||||||
maxMenuHeight={this.widgetHeight - 40}
|
maxMenuHeight={this.widgetHeight - 40}
|
||||||
options={this.lineEndings}
|
options={lineEndings}
|
||||||
value={lineEnding}
|
value={lineEnding}
|
||||||
onChange={this.onChangeLineEnding}
|
onChange={this.onChangeLineEnding}
|
||||||
/>
|
/>
|
||||||
</div>
|
</div>
|
||||||
{baudrateOptions && baudrateSelectedOption && (
|
<div className="select">
|
||||||
<div className="select">
|
<ArduinoSelect
|
||||||
<ArduinoSelect
|
className="select"
|
||||||
className="select"
|
maxMenuHeight={this.widgetHeight - 40}
|
||||||
maxMenuHeight={this.widgetHeight - 40}
|
options={baudRates}
|
||||||
options={baudrateOptions}
|
value={baudRate}
|
||||||
value={baudrateSelectedOption}
|
onChange={this.onChangeBaudRate}
|
||||||
onChange={this.onChangeBaudRate}
|
/>
|
||||||
/>
|
</div>
|
||||||
</div>
|
|
||||||
)}
|
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<div className="body">
|
<div className="body">
|
||||||
@@ -233,21 +257,16 @@ export class MonitorWidget extends ReactWidget {
|
|||||||
|
|
||||||
protected readonly onChangeLineEnding = (
|
protected readonly onChangeLineEnding = (
|
||||||
option: SerialMonitorOutput.SelectOption<MonitorModel.EOL>
|
option: SerialMonitorOutput.SelectOption<MonitorModel.EOL>
|
||||||
): void => {
|
) => {
|
||||||
this.monitorModel.lineEnding = option.value;
|
this.monitorModel.lineEnding = option.value;
|
||||||
};
|
};
|
||||||
|
|
||||||
protected readonly onChangeBaudRate = ({
|
protected readonly onChangeBaudRate = (value: string) => {
|
||||||
value,
|
const { pluggableMonitorSettings } = this.getCurrentSettings();
|
||||||
}: {
|
if (!pluggableMonitorSettings || !pluggableMonitorSettings['baudrate'])
|
||||||
value: string;
|
return;
|
||||||
}): void => {
|
const baudRateSettings = pluggableMonitorSettings['baudrate'];
|
||||||
this.getCurrentSettings().then(({ pluggableMonitorSettings }) => {
|
baudRateSettings.selectedValue = value;
|
||||||
if (!pluggableMonitorSettings || !pluggableMonitorSettings['baudrate'])
|
this.monitorManagerProxy.changeSettings(pluggableMonitorSettings);
|
||||||
return;
|
|
||||||
const baudRateSettings = pluggableMonitorSettings['baudrate'];
|
|
||||||
baudRateSettings.selectedValue = value;
|
|
||||||
this.monitorManagerProxy.changeSettings({ pluggableMonitorSettings });
|
|
||||||
});
|
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
@@ -1,15 +1,16 @@
|
|||||||
import * as React from '@theia/core/shared/react';
|
import * as React from 'react';
|
||||||
import { Key, KeyCode } from '@theia/core/lib/browser/keys';
|
import { Key, KeyCode } from '@theia/core/lib/browser/keys';
|
||||||
import { Board } from '../../../common/protocol/boards-service';
|
import { Board } from '../../../common/protocol/boards-service';
|
||||||
import { isOSX } from '@theia/core/lib/common/os';
|
import { isOSX } from '@theia/core/lib/common/os';
|
||||||
import { DisposableCollection, nls } from '@theia/core/lib/common';
|
import { DisposableCollection, nls } from '@theia/core/lib/common';
|
||||||
|
import { MonitorManagerProxyClient } from '../../../common/protocol';
|
||||||
import { BoardsServiceProvider } from '../../boards/boards-service-provider';
|
import { BoardsServiceProvider } from '../../boards/boards-service-provider';
|
||||||
import { MonitorModel } from '../../monitor-model';
|
import { timeout } from '@theia/core/lib/common/promise-util';
|
||||||
|
|
||||||
export namespace SerialMonitorSendInput {
|
export namespace SerialMonitorSendInput {
|
||||||
export interface Props {
|
export interface Props {
|
||||||
readonly boardsServiceProvider: BoardsServiceProvider;
|
readonly boardsServiceProvider: BoardsServiceProvider;
|
||||||
readonly monitorModel: MonitorModel;
|
readonly monitorManagerProxy: MonitorManagerProxyClient;
|
||||||
readonly onSend: (text: string) => void;
|
readonly onSend: (text: string) => void;
|
||||||
readonly resolveFocus: (element: HTMLElement | undefined) => void;
|
readonly resolveFocus: (element: HTMLElement | undefined) => void;
|
||||||
}
|
}
|
||||||
@@ -33,22 +34,35 @@ export class SerialMonitorSendInput extends React.Component<
|
|||||||
this.onKeyDown = this.onKeyDown.bind(this);
|
this.onKeyDown = this.onKeyDown.bind(this);
|
||||||
}
|
}
|
||||||
|
|
||||||
override componentDidMount(): void {
|
componentDidMount(): void {
|
||||||
this.setState({ connected: this.props.monitorModel.connected });
|
this.setState({ connected: true });
|
||||||
this.toDisposeBeforeUnmount.push(
|
|
||||||
this.props.monitorModel.onChange(({ property }) => {
|
const checkWSConnection = new Promise<boolean>((resolve) => {
|
||||||
if (property === 'connected')
|
this.props.monitorManagerProxy.onWSConnectionChanged((connected) => {
|
||||||
this.setState({ connected: this.props.monitorModel.connected });
|
this.setState({ connected });
|
||||||
})
|
resolve(true);
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
const checkWSTimeout = timeout(1000).then(() => false);
|
||||||
|
|
||||||
|
Promise.race<boolean>([checkWSConnection, checkWSTimeout]).then(
|
||||||
|
async (resolved) => {
|
||||||
|
if (!resolved) {
|
||||||
|
const connected =
|
||||||
|
await this.props.monitorManagerProxy.isWSConnected();
|
||||||
|
this.setState({ connected });
|
||||||
|
}
|
||||||
|
}
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
override componentWillUnmount(): void {
|
componentWillUnmount(): void {
|
||||||
// TODO: "Your preferred browser's local storage is almost full." Discard `content` before saving layout?
|
// TODO: "Your preferred browser's local storage is almost full." Discard `content` before saving layout?
|
||||||
this.toDisposeBeforeUnmount.dispose();
|
this.toDisposeBeforeUnmount.dispose();
|
||||||
}
|
}
|
||||||
|
|
||||||
override render(): React.ReactNode {
|
render(): React.ReactNode {
|
||||||
return (
|
return (
|
||||||
<input
|
<input
|
||||||
ref={this.setRef}
|
ref={this.setRef}
|
||||||
@@ -102,7 +116,7 @@ export class SerialMonitorSendInput extends React.Component<
|
|||||||
}
|
}
|
||||||
|
|
||||||
protected onSend(): void {
|
protected onSend(): void {
|
||||||
this.props.onSend(this.state.text + this.props.monitorModel.lineEnding);
|
this.props.onSend(this.state.text);
|
||||||
this.setState({ text: '' });
|
this.setState({ text: '' });
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@@ -1,4 +1,4 @@
|
|||||||
import * as React from '@theia/core/shared/react';
|
import * as React from 'react';
|
||||||
import { Event } from '@theia/core/lib/common/event';
|
import { Event } from '@theia/core/lib/common/event';
|
||||||
import { DisposableCollection } from '@theia/core/lib/common/disposable';
|
import { DisposableCollection } from '@theia/core/lib/common/disposable';
|
||||||
import { areEqual, FixedSizeList as List } from 'react-window';
|
import { areEqual, FixedSizeList as List } from 'react-window';
|
||||||
@@ -29,7 +29,7 @@ export class SerialMonitorOutput extends React.Component<
|
|||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
override render(): React.ReactNode {
|
render(): React.ReactNode {
|
||||||
return (
|
return (
|
||||||
<List
|
<List
|
||||||
className="serial-monitor-messages"
|
className="serial-monitor-messages"
|
||||||
@@ -51,11 +51,11 @@ export class SerialMonitorOutput extends React.Component<
|
|||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
override shouldComponentUpdate(): boolean {
|
shouldComponentUpdate(): boolean {
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
override componentDidMount(): void {
|
componentDidMount(): void {
|
||||||
this.scrollToBottom();
|
this.scrollToBottom();
|
||||||
this.toDisposeBeforeUnmount.pushAll([
|
this.toDisposeBeforeUnmount.pushAll([
|
||||||
this.props.monitorManagerProxy.onMessagesReceived(({ messages }) => {
|
this.props.monitorManagerProxy.onMessagesReceived(({ messages }) => {
|
||||||
@@ -86,7 +86,7 @@ export class SerialMonitorOutput extends React.Component<
|
|||||||
]);
|
]);
|
||||||
}
|
}
|
||||||
|
|
||||||
override componentWillUnmount(): void {
|
componentWillUnmount(): void {
|
||||||
// TODO: "Your preferred browser's local storage is almost full." Discard `content` before saving layout?
|
// TODO: "Your preferred browser's local storage is almost full." Discard `content` before saving layout?
|
||||||
this.toDisposeBeforeUnmount.dispose();
|
this.toDisposeBeforeUnmount.dispose();
|
||||||
}
|
}
|
||||||
|
@@ -1,5 +1,5 @@
|
|||||||
import { ThemeService } from '@theia/core/lib/browser/theming';
|
import { ThemeService } from '@theia/core/lib/browser/theming';
|
||||||
import { injectable, inject } from '@theia/core/shared/inversify';
|
import { injectable, inject } from 'inversify';
|
||||||
import {
|
import {
|
||||||
Command,
|
Command,
|
||||||
CommandRegistry,
|
CommandRegistry,
|
||||||
@@ -11,9 +11,9 @@ import { Contribution } from '../../contributions/contribution';
|
|||||||
import { Endpoint, FrontendApplication } from '@theia/core/lib/browser';
|
import { Endpoint, FrontendApplication } from '@theia/core/lib/browser';
|
||||||
import { ipcRenderer } from '@theia/electron/shared/electron';
|
import { ipcRenderer } from '@theia/electron/shared/electron';
|
||||||
import { MonitorManagerProxyClient } from '../../../common/protocol';
|
import { MonitorManagerProxyClient } from '../../../common/protocol';
|
||||||
|
import { SerialPlotter } from './protocol';
|
||||||
import { BoardsServiceProvider } from '../../boards/boards-service-provider';
|
import { BoardsServiceProvider } from '../../boards/boards-service-provider';
|
||||||
import { MonitorModel } from '../../monitor-model';
|
import { MonitorModel } from '../../monitor-model';
|
||||||
|
|
||||||
const queryString = require('query-string');
|
const queryString = require('query-string');
|
||||||
|
|
||||||
export namespace SerialPlotterContribution {
|
export namespace SerialPlotterContribution {
|
||||||
@@ -23,11 +23,6 @@ export namespace SerialPlotterContribution {
|
|||||||
label: 'Serial Plotter',
|
label: 'Serial Plotter',
|
||||||
category: 'Arduino',
|
category: 'Arduino',
|
||||||
};
|
};
|
||||||
export const RESET: Command = {
|
|
||||||
id: 'serial-plotter-reset',
|
|
||||||
label: 'Reset Serial Plotter',
|
|
||||||
category: 'Arduino',
|
|
||||||
};
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -49,7 +44,7 @@ export class PlotterFrontendContribution extends Contribution {
|
|||||||
@inject(BoardsServiceProvider)
|
@inject(BoardsServiceProvider)
|
||||||
protected readonly boardsServiceProvider: BoardsServiceProvider;
|
protected readonly boardsServiceProvider: BoardsServiceProvider;
|
||||||
|
|
||||||
override onStart(app: FrontendApplication): MaybePromise<void> {
|
onStart(app: FrontendApplication): MaybePromise<void> {
|
||||||
this.url = new Endpoint({ path: '/plotter' }).getRestUrl().toString();
|
this.url = new Endpoint({ path: '/plotter' }).getRestUrl().toString();
|
||||||
|
|
||||||
ipcRenderer.on('CLOSE_CHILD_WINDOW', async () => {
|
ipcRenderer.on('CLOSE_CHILD_WINDOW', async () => {
|
||||||
@@ -57,21 +52,16 @@ export class PlotterFrontendContribution extends Contribution {
|
|||||||
this.window = null;
|
this.window = null;
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
this.monitorManagerProxy.onMonitorShouldReset(() => this.reset());
|
|
||||||
|
|
||||||
return super.onStart(app);
|
return super.onStart(app);
|
||||||
}
|
}
|
||||||
|
|
||||||
override registerCommands(registry: CommandRegistry): void {
|
registerCommands(registry: CommandRegistry): void {
|
||||||
registry.registerCommand(SerialPlotterContribution.Commands.OPEN, {
|
registry.registerCommand(SerialPlotterContribution.Commands.OPEN, {
|
||||||
execute: this.startPlotter.bind(this),
|
execute: this.connect.bind(this),
|
||||||
});
|
|
||||||
registry.registerCommand(SerialPlotterContribution.Commands.RESET, {
|
|
||||||
execute: () => this.reset(),
|
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
override registerMenus(menus: MenuModelRegistry): void {
|
registerMenus(menus: MenuModelRegistry): void {
|
||||||
menus.registerMenuAction(ArduinoMenus.TOOLS__MAIN_GROUP, {
|
menus.registerMenuAction(ArduinoMenus.TOOLS__MAIN_GROUP, {
|
||||||
commandId: SerialPlotterContribution.Commands.OPEN.id,
|
commandId: SerialPlotterContribution.Commands.OPEN.id,
|
||||||
label: SerialPlotterContribution.Commands.OPEN.label,
|
label: SerialPlotterContribution.Commands.OPEN.label,
|
||||||
@@ -79,8 +69,7 @@ export class PlotterFrontendContribution extends Contribution {
|
|||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
async startPlotter(): Promise<void> {
|
async connect(): Promise<void> {
|
||||||
await this.monitorManagerProxy.startMonitor();
|
|
||||||
if (!!this.window) {
|
if (!!this.window) {
|
||||||
this.window.focus();
|
this.window.focus();
|
||||||
return;
|
return;
|
||||||
@@ -94,10 +83,29 @@ export class PlotterFrontendContribution extends Contribution {
|
|||||||
}
|
}
|
||||||
|
|
||||||
protected async open(wsPort: number): Promise<void> {
|
protected async open(wsPort: number): Promise<void> {
|
||||||
const initConfig = {
|
const board = this.boardsServiceProvider.boardsConfig.selectedBoard;
|
||||||
|
const port = this.boardsServiceProvider.boardsConfig.selectedPort;
|
||||||
|
let baudrates: number[] = [];
|
||||||
|
let currentBaudrate = -1;
|
||||||
|
if (board && port) {
|
||||||
|
const { pluggableMonitorSettings } =
|
||||||
|
this.monitorManagerProxy.getCurrentSettings(board, port);
|
||||||
|
if (pluggableMonitorSettings && 'baudrate' in pluggableMonitorSettings) {
|
||||||
|
// Convert from string to numbers
|
||||||
|
baudrates = pluggableMonitorSettings['baudrate'].values.map((b) => +b);
|
||||||
|
currentBaudrate = +pluggableMonitorSettings['baudrate'].selectedValue;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
const initConfig: Partial<SerialPlotter.Config> = {
|
||||||
|
baudrates,
|
||||||
|
currentBaudrate,
|
||||||
|
currentLineEnding: this.model.lineEnding,
|
||||||
darkTheme: this.themeService.getCurrentTheme().type === 'dark',
|
darkTheme: this.themeService.getCurrentTheme().type === 'dark',
|
||||||
wsPort,
|
wsPort,
|
||||||
serialPort: this.model.serialPort,
|
interpolate: this.model.interpolate,
|
||||||
|
connected: await this.monitorManagerProxy.isWSConnected(),
|
||||||
|
serialPort: this.boardsServiceProvider.boardsConfig.selectedPort?.address,
|
||||||
};
|
};
|
||||||
const urlWithParams = queryString.stringifyUrl(
|
const urlWithParams = queryString.stringifyUrl(
|
||||||
{
|
{
|
||||||
@@ -108,11 +116,4 @@ export class PlotterFrontendContribution extends Contribution {
|
|||||||
);
|
);
|
||||||
this.window = window.open(urlWithParams, 'serialPlotter');
|
this.window = window.open(urlWithParams, 'serialPlotter');
|
||||||
}
|
}
|
||||||
|
|
||||||
protected async reset(): Promise<void> {
|
|
||||||
if (!!this.window) {
|
|
||||||
this.window.close();
|
|
||||||
await this.startPlotter();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
26
arduino-ide-extension/src/browser/serial/plotter/protocol.ts
Normal file
26
arduino-ide-extension/src/browser/serial/plotter/protocol.ts
Normal file
@@ -0,0 +1,26 @@
|
|||||||
|
export namespace SerialPlotter {
|
||||||
|
export type Config = {
|
||||||
|
currentBaudrate: number;
|
||||||
|
baudrates: number[];
|
||||||
|
currentLineEnding: string;
|
||||||
|
darkTheme: boolean;
|
||||||
|
wsPort: number;
|
||||||
|
interpolate: boolean;
|
||||||
|
serialPort: string;
|
||||||
|
connected: boolean;
|
||||||
|
generate?: boolean;
|
||||||
|
};
|
||||||
|
export namespace Protocol {
|
||||||
|
export enum Command {
|
||||||
|
PLOTTER_SET_BAUDRATE = 'PLOTTER_SET_BAUDRATE',
|
||||||
|
PLOTTER_SET_LINE_ENDING = 'PLOTTER_SET_LINE_ENDING',
|
||||||
|
PLOTTER_SET_INTERPOLATE = 'PLOTTER_SET_INTERPOLATE',
|
||||||
|
PLOTTER_SEND_MESSAGE = 'PLOTTER_SEND_MESSAGE',
|
||||||
|
MIDDLEWARE_CONFIG_CHANGED = 'MIDDLEWARE_CONFIG_CHANGED',
|
||||||
|
}
|
||||||
|
export type Message = {
|
||||||
|
command: SerialPlotter.Protocol.Command;
|
||||||
|
data?: any;
|
||||||
|
};
|
||||||
|
}
|
||||||
|
}
|
@@ -1,4 +1,4 @@
|
|||||||
import { injectable, inject } from '@theia/core/shared/inversify';
|
import { injectable, inject } from 'inversify';
|
||||||
import { StorageService } from '@theia/core/lib/browser/storage-service';
|
import { StorageService } from '@theia/core/lib/browser/storage-service';
|
||||||
import {
|
import {
|
||||||
Command,
|
Command,
|
||||||
|
@@ -8,8 +8,3 @@
|
|||||||
.monaco-list-row.show-file-icons.focused {
|
.monaco-list-row.show-file-icons.focused {
|
||||||
background-color: #d6ebff;
|
background-color: #d6ebff;
|
||||||
}
|
}
|
||||||
|
|
||||||
.monaco-editor .view-overlays .compiler-error {
|
|
||||||
background-color: var(--theia-inputValidation-errorBackground);
|
|
||||||
opacity: 0.4 !important;
|
|
||||||
}
|
|
||||||
|
@@ -27,9 +27,8 @@
|
|||||||
}
|
}
|
||||||
|
|
||||||
.ide-updater-dialog .changelog-container {
|
.ide-updater-dialog .changelog-container {
|
||||||
color: var(--theia-dropdown-foreground);
|
background: white;
|
||||||
background-color: var(--theia-dropdown-background);
|
border: 1px solid #dae3e3;
|
||||||
border: 1px solid var(--theia-tree-indentGuidesStroke);
|
|
||||||
border-radius: 2px;
|
border-radius: 2px;
|
||||||
font-size: 12px;
|
font-size: 12px;
|
||||||
height: 180px;
|
height: 180px;
|
||||||
|
@@ -108,21 +108,3 @@ button.theia-button.main {
|
|||||||
.fa-reload {
|
.fa-reload {
|
||||||
font-size: 14px;
|
font-size: 14px;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* restore the old Theia spinner */
|
|
||||||
/* https://github.com/eclipse-theia/theia/pull/10761#issuecomment-1131476318 */
|
|
||||||
.old-theia-preload {
|
|
||||||
position: absolute;
|
|
||||||
top: 0;
|
|
||||||
left: 0;
|
|
||||||
right: 0;
|
|
||||||
bottom: 0;
|
|
||||||
z-index: 50000;
|
|
||||||
background: var(--theia-editor-background);
|
|
||||||
background-image: var(--theia-preloader);
|
|
||||||
background-size: 60px 60px;
|
|
||||||
background-repeat: no-repeat;
|
|
||||||
background-attachment: fixed;
|
|
||||||
background-position: center;
|
|
||||||
transition: opacity 0.8s;
|
|
||||||
}
|
|
@@ -1,10 +0,0 @@
|
|||||||
import { AboutDialog as TheiaAboutDialog } from '@theia/core/lib/browser/about-dialog';
|
|
||||||
import { duration } from '../../../common/decorators';
|
|
||||||
|
|
||||||
export class AboutDialog extends TheiaAboutDialog {
|
|
||||||
@duration({ name: 'theia-about#init' })
|
|
||||||
protected override async init(): Promise<void> {
|
|
||||||
// NOOP
|
|
||||||
// IDE2 has a custom about dialog, so it does not make sense to collect Theia extensions at startup time.
|
|
||||||
}
|
|
||||||
}
|
|
@@ -1,4 +1,4 @@
|
|||||||
import { injectable, inject } from '@theia/core/shared/inversify';
|
import { injectable, inject } from 'inversify';
|
||||||
import { EditorWidget } from '@theia/editor/lib/browser';
|
import { EditorWidget } from '@theia/editor/lib/browser';
|
||||||
import { CommandService } from '@theia/core/lib/common/command';
|
import { CommandService } from '@theia/core/lib/common/command';
|
||||||
import { MessageService } from '@theia/core/lib/common/message-service';
|
import { MessageService } from '@theia/core/lib/common/message-service';
|
||||||
@@ -15,7 +15,7 @@ import {
|
|||||||
} from '@theia/core/lib/browser';
|
} from '@theia/core/lib/browser';
|
||||||
import { Sketch } from '../../../common/protocol';
|
import { Sketch } from '../../../common/protocol';
|
||||||
import { SaveAsSketch } from '../../contributions/save-as-sketch';
|
import { SaveAsSketch } from '../../contributions/save-as-sketch';
|
||||||
import { CurrentSketch, SketchesServiceClientImpl } from '../../../common/protocol/sketches-service-client-impl';
|
import { SketchesServiceClientImpl } from '../../../common/protocol/sketches-service-client-impl';
|
||||||
import { nls } from '@theia/core/lib/common';
|
import { nls } from '@theia/core/lib/common';
|
||||||
import URI from '@theia/core/lib/common/uri';
|
import URI from '@theia/core/lib/common/uri';
|
||||||
|
|
||||||
@@ -33,7 +33,7 @@ export class ApplicationShell extends TheiaApplicationShell {
|
|||||||
@inject(ConnectionStatusService)
|
@inject(ConnectionStatusService)
|
||||||
protected readonly connectionStatusService: ConnectionStatusService;
|
protected readonly connectionStatusService: ConnectionStatusService;
|
||||||
|
|
||||||
protected override track(widget: Widget): void {
|
protected track(widget: Widget): void {
|
||||||
super.track(widget);
|
super.track(widget);
|
||||||
if (widget instanceof OutputWidget) {
|
if (widget instanceof OutputWidget) {
|
||||||
widget.title.closable = false; // TODO: https://arduino.slack.com/archives/C01698YT7S4/p1598011990133700
|
widget.title.closable = false; // TODO: https://arduino.slack.com/archives/C01698YT7S4/p1598011990133700
|
||||||
@@ -41,7 +41,7 @@ export class ApplicationShell extends TheiaApplicationShell {
|
|||||||
if (widget instanceof EditorWidget) {
|
if (widget instanceof EditorWidget) {
|
||||||
// Make the editor un-closeable asynchronously.
|
// Make the editor un-closeable asynchronously.
|
||||||
this.sketchesServiceClient.currentSketch().then((sketch) => {
|
this.sketchesServiceClient.currentSketch().then((sketch) => {
|
||||||
if (CurrentSketch.isValid(sketch)) {
|
if (sketch) {
|
||||||
if (!this.isSketchFile(widget.editor.uri, sketch.uri)) {
|
if (!this.isSketchFile(widget.editor.uri, sketch.uri)) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
@@ -61,7 +61,7 @@ export class ApplicationShell extends TheiaApplicationShell {
|
|||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
override async addWidget(
|
async addWidget(
|
||||||
widget: Widget,
|
widget: Widget,
|
||||||
options: Readonly<TheiaApplicationShell.WidgetOptions> = {}
|
options: Readonly<TheiaApplicationShell.WidgetOptions> = {}
|
||||||
): Promise<void> {
|
): Promise<void> {
|
||||||
@@ -87,19 +87,19 @@ export class ApplicationShell extends TheiaApplicationShell {
|
|||||||
return super.addWidget(widget, { ...options, ref });
|
return super.addWidget(widget, { ...options, ref });
|
||||||
}
|
}
|
||||||
|
|
||||||
override handleEvent(): boolean {
|
handleEvent(): boolean {
|
||||||
// NOOP, dragging has been disabled
|
// NOOP, dragging has been disabled
|
||||||
return false;
|
return false
|
||||||
}
|
}
|
||||||
|
|
||||||
// Avoid hiding top panel as we use it for arduino toolbar
|
// Avoid hiding top panel as we use it for arduino toolbar
|
||||||
protected override createTopPanel(): Panel {
|
protected createTopPanel(): Panel {
|
||||||
const topPanel = super.createTopPanel();
|
const topPanel = super.createTopPanel();
|
||||||
topPanel.show();
|
topPanel.show();
|
||||||
return topPanel;
|
return topPanel;
|
||||||
}
|
}
|
||||||
|
|
||||||
override async saveAll(): Promise<void> {
|
async saveAll(): Promise<void> {
|
||||||
if (
|
if (
|
||||||
this.connectionStatusService.currentStatus === ConnectionStatus.OFFLINE
|
this.connectionStatusService.currentStatus === ConnectionStatus.OFFLINE
|
||||||
) {
|
) {
|
||||||
@@ -130,5 +130,5 @@ DockPanel.prototype.handleEvent = function (event) {
|
|||||||
case 'p-drop':
|
case 'p-drop':
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
originalHandleEvent.bind(this)(event);
|
originalHandleEvent(event);
|
||||||
};
|
};
|
||||||
|
@@ -1,4 +1,4 @@
|
|||||||
import { injectable } from '@theia/core/shared/inversify';
|
import { injectable } from 'inversify';
|
||||||
import {
|
import {
|
||||||
BrowserMainMenuFactory as TheiaBrowserMainMenuFactory,
|
BrowserMainMenuFactory as TheiaBrowserMainMenuFactory,
|
||||||
MenuBarWidget,
|
MenuBarWidget,
|
||||||
@@ -12,12 +12,12 @@ export class BrowserMainMenuFactory
|
|||||||
{
|
{
|
||||||
protected menuBar: MenuBarWidget | undefined;
|
protected menuBar: MenuBarWidget | undefined;
|
||||||
|
|
||||||
override createMenuBar(): MenuBarWidget {
|
createMenuBar(): MenuBarWidget {
|
||||||
this.menuBar = super.createMenuBar();
|
this.menuBar = super.createMenuBar();
|
||||||
return this.menuBar;
|
return this.menuBar;
|
||||||
}
|
}
|
||||||
|
|
||||||
update(): void {
|
update() {
|
||||||
if (this.menuBar) {
|
if (this.menuBar) {
|
||||||
this.menuBar.clearMenus();
|
this.menuBar.clearMenus();
|
||||||
this.fillMenuBar(this.menuBar);
|
this.fillMenuBar(this.menuBar);
|
||||||
|
@@ -1,5 +1,5 @@
|
|||||||
import '../../../../src/browser/style/browser-menu.css';
|
import '../../../../src/browser/style/browser-menu.css';
|
||||||
import { ContainerModule } from '@theia/core/shared/inversify';
|
import { ContainerModule } from 'inversify';
|
||||||
import {
|
import {
|
||||||
BrowserMenuBarContribution,
|
BrowserMenuBarContribution,
|
||||||
BrowserMainMenuFactory as TheiaBrowserMainMenuFactory,
|
BrowserMainMenuFactory as TheiaBrowserMainMenuFactory,
|
||||||
|
@@ -1,10 +1,10 @@
|
|||||||
import { injectable } from '@theia/core/shared/inversify';
|
import { injectable } from 'inversify';
|
||||||
import { FrontendApplication } from '@theia/core/lib/browser';
|
import { FrontendApplication } from '@theia/core/lib/browser';
|
||||||
import { BrowserMenuBarContribution } from '@theia/core/lib/browser/menu/browser-menu-plugin';
|
import { BrowserMenuBarContribution } from '@theia/core/lib/browser/menu/browser-menu-plugin';
|
||||||
|
|
||||||
@injectable()
|
@injectable()
|
||||||
export class ArduinoMenuContribution extends BrowserMenuBarContribution {
|
export class ArduinoMenuContribution extends BrowserMenuBarContribution {
|
||||||
override onStart(app: FrontendApplication): void {
|
onStart(app: FrontendApplication): void {
|
||||||
const menu = this.factory.createMenuBar();
|
const menu = this.factory.createMenuBar();
|
||||||
app.shell.addWidget(menu, { area: 'top' });
|
app.shell.addWidget(menu, { area: 'top' });
|
||||||
}
|
}
|
||||||
|
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user