From adbfdaff4a3c5d44a434cccee063c3561b488342 Mon Sep 17 00:00:00 2001 From: dankeboy36 Date: Sat, 17 Jun 2023 13:03:59 +0200 Subject: [PATCH] feat: can dock the monitor widget to the `"right"` Added a new preference (`arduino.monitor.dockPanel`) to specify the location of the application shell where the _Serial Monitor_ widget resides. The possible values are `"bottom"` and `"right"`. The default\ value is the `"bottom"`. The dock panel is per application and not per workspace or window. However, advanced users can create the `./.vscode/settings.json` and configure per sketch preference. Signed-off-by: dankeboy36 --- .../src/browser/arduino-preferences.ts | 479 ++++++++++-------- .../monitor/monitor-view-contribution.tsx | 60 ++- .../browser/serial/monitor/monitor-widget.tsx | 7 +- .../src/browser/style/monitor.css | 2 +- arduino-ide-extension/src/common/nls.ts | 5 + i18n/en.json | 3 + 6 files changed, 316 insertions(+), 240 deletions(-) diff --git a/arduino-ide-extension/src/browser/arduino-preferences.ts b/arduino-ide-extension/src/browser/arduino-preferences.ts index 5adc8b9c2..ebe525d60 100644 --- a/arduino-ide-extension/src/browser/arduino-preferences.ts +++ b/arduino-ide-extension/src/browser/arduino-preferences.ts @@ -1,12 +1,15 @@ -import { interfaces } from '@theia/core/shared/inversify'; import { - createPreferenceProxy, - PreferenceProxy, - PreferenceService, PreferenceContribution, + PreferenceProxy, PreferenceSchema, + PreferenceService, + createPreferenceProxy, } from '@theia/core/lib/browser/preferences'; -import { nls } from '@theia/core/lib/common'; +import { ApplicationShell } from '@theia/core/lib/browser/shell/application-shell'; +import { nls } from '@theia/core/lib/common/nls'; +import { PreferenceSchemaProperty } from '@theia/core/lib/common/preferences/preference-schema'; +import { interfaces } from '@theia/core/shared/inversify'; +import { serialMonitorWidgetLabel } from '../common/nls'; import { CompilerWarningLiterals, CompilerWarnings } from '../common/protocol'; export enum UpdateChannel { @@ -31,7 +34,7 @@ export const ErrorRevealStrategyLiterals = [ */ 'centerIfOutsideViewport', ] as const; -export type ErrorRevealStrategy = typeof ErrorRevealStrategyLiterals[number]; +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 { @@ -40,225 +43,254 @@ export namespace ErrorRevealStrategy { export const Default: ErrorRevealStrategy = 'centerIfOutsideViewport'; } +export type MonitorWidgetDockPanel = Extract< + ApplicationShell.Area, + 'bottom' | 'right' +>; +export const defaultMonitorWidgetDockPanel: MonitorWidgetDockPanel = 'bottom'; +export function isMonitorWidgetDockPanel( + arg: unknown +): arg is MonitorWidgetDockPanel { + return arg === 'bottom' || arg === 'right'; +} + +type StrictPreferenceSchemaProperties = { + [p in keyof T]: PreferenceSchemaProperty; +}; +type ArduinoPreferenceSchemaProperties = + StrictPreferenceSchemaProperties & { 'arduino.window.zoomLevel': PreferenceSchemaProperty }; + +const properties: ArduinoPreferenceSchemaProperties = { + 'arduino.language.log': { + type: 'boolean', + description: nls.localize( + 'arduino/preferences/language.log', + "True if the Arduino Language Server should generate log files into the sketch folder. Otherwise, false. It's false by default." + ), + default: false, + }, + 'arduino.language.realTimeDiagnostics': { + type: 'boolean', + description: nls.localize( + 'arduino/preferences/language.realTimeDiagnostics', + "If true, the language server provides real-time diagnostics when typing in the editor. It's false by default." + ), + default: false, + }, + 'arduino.compile.verbose': { + type: 'boolean', + description: nls.localize( + 'arduino/preferences/compile.verbose', + 'True for verbose compile output. False by default' + ), + 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': { + enum: [...CompilerWarningLiterals], + description: nls.localize( + 'arduino/preferences/compile.warnings', + "Tells gcc which warning level to use. It's 'None' by default" + ), + default: 'None', + }, + 'arduino.upload.verbose': { + type: 'boolean', + description: nls.localize( + 'arduino/preferences/upload.verbose', + 'True for verbose upload output. False by default.' + ), + default: false, + }, + 'arduino.upload.verify': { + type: 'boolean', + default: false, + }, + 'arduino.window.autoScale': { + type: 'boolean', + description: nls.localize( + 'arduino/preferences/window.autoScale', + 'True if the user interface automatically scales with the font size.' + ), + default: true, + }, + 'arduino.window.zoomLevel': { + type: 'number', + description: '', + default: 0, + deprecationMessage: nls.localize( + 'arduino/preferences/window.zoomLevel/deprecationMessage', + "Deprecated. Use 'window.zoomLevel' instead." + ), + }, + 'arduino.ide.updateChannel': { + type: 'string', + enum: Object.values(UpdateChannel) as UpdateChannel[], + default: UpdateChannel.Stable, + description: nls.localize( + 'arduino/preferences/ide.updateChannel', + "Release channel to get updated from. 'stable' is the stable release, 'nightly' is the latest development build." + ), + }, + 'arduino.ide.updateBaseUrl': { + type: 'string', + default: 'https://downloads.arduino.cc/arduino-ide', + description: nls.localize( + 'arduino/preferences/ide.updateBaseUrl', + "The base URL where to download updates from. Defaults to 'https://downloads.arduino.cc/arduino-ide'" + ), + }, + 'arduino.board.certificates': { + type: 'string', + description: nls.localize( + 'arduino/preferences/board.certificates', + 'List of certificates that can be uploaded to boards' + ), + default: '', + }, + 'arduino.sketchbook.showAllFiles': { + type: 'boolean', + description: nls.localize( + 'arduino/preferences/sketchbook.showAllFiles', + 'True to show all sketch files inside the sketch. It is false by default.' + ), + default: false, + }, + 'arduino.cloud.enabled': { + type: 'boolean', + description: nls.localize( + 'arduino/preferences/cloud.enabled', + 'True if the sketch sync functions are enabled. Defaults to true.' + ), + default: true, + }, + 'arduino.cloud.pull.warn': { + type: 'boolean', + description: nls.localize( + 'arduino/preferences/cloud.pull.warn', + 'True if users should be warned before pulling a cloud sketch. Defaults to true.' + ), + default: true, + }, + 'arduino.cloud.push.warn': { + type: 'boolean', + description: nls.localize( + 'arduino/preferences/cloud.push.warn', + 'True if users should be warned before pushing a cloud sketch. Defaults to true.' + ), + default: true, + }, + 'arduino.cloud.pushpublic.warn': { + type: 'boolean', + description: nls.localize( + 'arduino/preferences/cloud.pushpublic.warn', + 'True if users should be warned before pushing a public sketch to the cloud. Defaults to true.' + ), + default: true, + }, + 'arduino.cloud.sketchSyncEndpoint': { + type: 'string', + description: nls.localize( + 'arduino/preferences/cloud.sketchSyncEndpoint', + 'The endpoint used to push and pull sketches from a backend. By default it points to Arduino Cloud API.' + ), + default: 'https://api2.arduino.cc/create', + }, + 'arduino.auth.clientID': { + type: 'string', + description: nls.localize( + 'arduino/preferences/auth.clientID', + 'The OAuth2 client ID.' + ), + default: 'C34Ya6ex77jTNxyKWj01lCe1vAHIaPIo', + }, + 'arduino.auth.domain': { + type: 'string', + description: nls.localize( + 'arduino/preferences/auth.domain', + 'The OAuth2 domain.' + ), + default: 'login.arduino.cc', + }, + 'arduino.auth.audience': { + type: 'string', + description: nls.localize( + 'arduino/preferences/auth.audience', + 'The OAuth2 audience.' + ), + default: 'https://api.arduino.cc', + }, + 'arduino.auth.registerUri': { + type: 'string', + description: nls.localize( + 'arduino/preferences/auth.registerUri', + 'The URI used to register a new user.' + ), + 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, + }, + 'arduino.checkForUpdates': { + type: 'boolean', + description: nls.localize( + 'arduino/preferences/checkForUpdate', + "Receive notifications of available updates for the IDE, boards, and libraries. Requires an IDE restart after change. It's true by default." + ), + default: true, + }, + 'arduino.sketch.inoBlueprint': { + type: 'string', + markdownDescription: nls.localize( + 'arduino/preferences/sketch/inoBlueprint', + 'Absolute filesystem path to the default `.ino` blueprint file. If specified, the content of the blueprint file will be used for every new sketch created by the IDE. The sketches will be generated with the default Arduino content if not specified. Unaccessible blueprint files are ignored. **A restart of the IDE is needed** for this setting to take effect.' + ), + default: undefined, + }, + 'arduino.monitor.dockPanel': { + type: 'string', + enum: ['bottom', 'right'], + markdownDescription: nls.localize( + 'arduino/preferences/monitor/dockPanel', + 'The area of the application shell where the _{0}_ widget will reside. It is either "bottom" or "right". It defaults to "{1}".', + serialMonitorWidgetLabel, + defaultMonitorWidgetDockPanel + ), + default: defaultMonitorWidgetDockPanel, + }, +}; export const ArduinoConfigSchema: PreferenceSchema = { type: 'object', - properties: { - 'arduino.language.log': { - type: 'boolean', - description: nls.localize( - 'arduino/preferences/language.log', - "True if the Arduino Language Server should generate log files into the sketch folder. Otherwise, false. It's false by default." - ), - default: false, - }, - 'arduino.language.realTimeDiagnostics': { - type: 'boolean', - description: nls.localize( - 'arduino/preferences/language.realTimeDiagnostics', - "If true, the language server provides real-time diagnostics when typing in the editor. It's false by default." - ), - default: false, - }, - 'arduino.compile.verbose': { - type: 'boolean', - description: nls.localize( - 'arduino/preferences/compile.verbose', - 'True for verbose compile output. False by default' - ), - 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': { - enum: [...CompilerWarningLiterals], - description: nls.localize( - 'arduino/preferences/compile.warnings', - "Tells gcc which warning level to use. It's 'None' by default" - ), - default: 'None', - }, - 'arduino.upload.verbose': { - type: 'boolean', - description: nls.localize( - 'arduino/preferences/upload.verbose', - 'True for verbose upload output. False by default.' - ), - default: false, - }, - 'arduino.upload.verify': { - type: 'boolean', - default: false, - }, - 'arduino.window.autoScale': { - type: 'boolean', - description: nls.localize( - 'arduino/preferences/window.autoScale', - 'True if the user interface automatically scales with the font size.' - ), - default: true, - }, - 'arduino.window.zoomLevel': { - type: 'number', - description: '', - default: 0, - deprecationMessage: nls.localize( - 'arduino/preferences/window.zoomLevel/deprecationMessage', - "Deprecated. Use 'window.zoomLevel' instead." - ), - }, - 'arduino.ide.updateChannel': { - type: 'string', - enum: Object.values(UpdateChannel) as UpdateChannel[], - default: UpdateChannel.Stable, - description: nls.localize( - 'arduino/preferences/ide.updateChannel', - "Release channel to get updated from. 'stable' is the stable release, 'nightly' is the latest development build." - ), - }, - 'arduino.ide.updateBaseUrl': { - type: 'string', - default: 'https://downloads.arduino.cc/arduino-ide', - description: nls.localize( - 'arduino/preferences/ide.updateBaseUrl', - "The base URL where to download updates from. Defaults to 'https://downloads.arduino.cc/arduino-ide'" - ), - }, - 'arduino.board.certificates': { - type: 'string', - description: nls.localize( - 'arduino/preferences/board.certificates', - 'List of certificates that can be uploaded to boards' - ), - default: '', - }, - 'arduino.sketchbook.showAllFiles': { - type: 'boolean', - description: nls.localize( - 'arduino/preferences/sketchbook.showAllFiles', - 'True to show all sketch files inside the sketch. It is false by default.' - ), - default: false, - }, - 'arduino.cloud.enabled': { - type: 'boolean', - description: nls.localize( - 'arduino/preferences/cloud.enabled', - 'True if the sketch sync functions are enabled. Defaults to true.' - ), - default: true, - }, - 'arduino.cloud.pull.warn': { - type: 'boolean', - description: nls.localize( - 'arduino/preferences/cloud.pull.warn', - 'True if users should be warned before pulling a cloud sketch. Defaults to true.' - ), - default: true, - }, - 'arduino.cloud.push.warn': { - type: 'boolean', - description: nls.localize( - 'arduino/preferences/cloud.push.warn', - 'True if users should be warned before pushing a cloud sketch. Defaults to true.' - ), - default: true, - }, - 'arduino.cloud.pushpublic.warn': { - type: 'boolean', - description: nls.localize( - 'arduino/preferences/cloud.pushpublic.warn', - 'True if users should be warned before pushing a public sketch to the cloud. Defaults to true.' - ), - default: true, - }, - 'arduino.cloud.sketchSyncEndpoint': { - type: 'string', - description: nls.localize( - 'arduino/preferences/cloud.sketchSyncEndpoint', - 'The endpoint used to push and pull sketches from a backend. By default it points to Arduino Cloud API.' - ), - default: 'https://api2.arduino.cc/create', - }, - 'arduino.auth.clientID': { - type: 'string', - description: nls.localize( - 'arduino/preferences/auth.clientID', - 'The OAuth2 client ID.' - ), - default: 'C34Ya6ex77jTNxyKWj01lCe1vAHIaPIo', - }, - 'arduino.auth.domain': { - type: 'string', - description: nls.localize( - 'arduino/preferences/auth.domain', - 'The OAuth2 domain.' - ), - default: 'login.arduino.cc', - }, - 'arduino.auth.audience': { - type: 'string', - description: nls.localize( - 'arduino/preferences/auth.audience', - 'The OAuth2 audience.' - ), - default: 'https://api.arduino.cc', - }, - 'arduino.auth.registerUri': { - type: 'string', - description: nls.localize( - 'arduino/preferences/auth.registerUri', - 'The URI used to register a new user.' - ), - 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, - }, - 'arduino.checkForUpdates': { - type: 'boolean', - description: nls.localize( - 'arduino/preferences/checkForUpdate', - "Receive notifications of available updates for the IDE, boards, and libraries. Requires an IDE restart after change. It's true by default." - ), - default: true, - }, - 'arduino.sketch.inoBlueprint': { - type: 'string', - markdownDescription: nls.localize( - 'arduino/preferences/sketch/inoBlueprint', - 'Absolute filesystem path to the default `.ino` blueprint file. If specified, the content of the blueprint file will be used for every new sketch created by the IDE. The sketches will be generated with the default Arduino content if not specified. Unaccessible blueprint files are ignored. **A restart of the IDE is needed** for this setting to take effect.' - ), - default: undefined, - }, - }, + properties, }; export interface ArduinoConfiguration { @@ -288,6 +320,7 @@ export interface ArduinoConfiguration { 'arduino.cli.daemon.debug': boolean; 'arduino.sketch.inoBlueprint': string; 'arduino.checkForUpdates': boolean; + 'arduino.monitor.dockPanel': MonitorWidgetDockPanel; } export const ArduinoPreferences = Symbol('ArduinoPreferences'); diff --git a/arduino-ide-extension/src/browser/serial/monitor/monitor-view-contribution.tsx b/arduino-ide-extension/src/browser/serial/monitor/monitor-view-contribution.tsx index 925d221ec..970cf4c54 100644 --- a/arduino-ide-extension/src/browser/serial/monitor/monitor-view-contribution.tsx +++ b/arduino-ide-extension/src/browser/serial/monitor/monitor-view-contribution.tsx @@ -1,6 +1,10 @@ import * as React from '@theia/core/shared/react'; -import { injectable, inject } from '@theia/core/shared/inversify'; -import { AbstractViewContribution, codicon } from '@theia/core/lib/browser'; +import { injectable, inject, postConstruct } from '@theia/core/shared/inversify'; +import { + AbstractViewContribution, + ApplicationShell, + codicon +} from '@theia/core/lib/browser'; import { MonitorWidget } from './monitor-widget'; import { MenuModelRegistry, Command, CommandRegistry } from '@theia/core'; import { @@ -13,6 +17,12 @@ import { nls } from '@theia/core/lib/common'; import { Event } from '@theia/core/lib/common/event'; import { MonitorModel } from '../../monitor-model'; import { MonitorManagerProxyClient } from '../../../common/protocol'; +import { + ArduinoPreferences, + defaultMonitorWidgetDockPanel, + isMonitorWidgetDockPanel +} from '../../arduino-preferences'; +import { serialMonitorWidgetLabel } from '../../../common/nls'; export namespace SerialMonitor { export namespace Commands { @@ -50,31 +60,59 @@ export class MonitorViewContribution static readonly TOGGLE_SERIAL_MONITOR_TOOLBAR = MonitorWidget.ID + ':toggle-toolbar'; static readonly RESET_SERIAL_MONITOR = MonitorWidget.ID + ':reset'; + + @inject(MonitorModel) + private readonly model: MonitorModel; + @inject(MonitorManagerProxyClient) + private readonly monitorManagerProxy: MonitorManagerProxyClient; + @inject(ArduinoPreferences) + private readonly arduinoPreferences: ArduinoPreferences; - constructor( - @inject(MonitorModel) - protected readonly model: MonitorModel, + private _panel: ApplicationShell.Area; - @inject(MonitorManagerProxyClient) - protected readonly monitorManagerProxy: MonitorManagerProxyClient - ) { + constructor() { super({ widgetId: MonitorWidget.ID, - widgetName: MonitorWidget.LABEL, + widgetName: serialMonitorWidgetLabel, defaultWidgetOptions: { - area: 'bottom', + area: defaultMonitorWidgetDockPanel, }, toggleCommandId: MonitorViewContribution.TOGGLE_SERIAL_MONITOR, toggleKeybinding: 'CtrlCmd+Shift+M', }); + this._panel = defaultMonitorWidgetDockPanel; + } + + @postConstruct() + protected init(): void { + this._panel = this.arduinoPreferences['arduino.monitor.dockPanel'] ?? defaultMonitorWidgetDockPanel; this.monitorManagerProxy.onMonitorShouldReset(() => this.reset()); + this.arduinoPreferences.onPreferenceChanged((event) => { + if (event.preferenceName === 'arduino.monitor.dockPanel' && isMonitorWidgetDockPanel(event.newValue) && event.newValue !== this._panel) { + this._panel = event.newValue; + const widget = this.tryGetWidget(); + // reopen at the new position if opened + if (widget) { + widget.close(); + this.openView({ activate: true, reveal: true }); + } + } + }) + } + + override get defaultViewOptions(): ApplicationShell.WidgetOptions { + const viewOptions = super.defaultViewOptions; + return { + ...viewOptions, + area: this._panel + }; } override registerMenus(menus: MenuModelRegistry): void { if (this.toggleCommand) { menus.registerMenuAction(ArduinoMenus.TOOLS__MAIN_GROUP, { commandId: this.toggleCommand.id, - label: MonitorWidget.LABEL, + label: serialMonitorWidgetLabel, order: '5', }); } diff --git a/arduino-ide-extension/src/browser/serial/monitor/monitor-widget.tsx b/arduino-ide-extension/src/browser/serial/monitor/monitor-widget.tsx index 0e790706b..7f2e6d02c 100644 --- a/arduino-ide-extension/src/browser/serial/monitor/monitor-widget.tsx +++ b/arduino-ide-extension/src/browser/serial/monitor/monitor-widget.tsx @@ -27,13 +27,10 @@ import { } from '../../../common/protocol'; import { MonitorModel } from '../../monitor-model'; import { FrontendApplicationStateService } from '@theia/core/lib/browser/frontend-application-state'; +import { serialMonitorWidgetLabel } from '../../../common/nls'; @injectable() export class MonitorWidget extends ReactWidget { - static readonly LABEL = nls.localize( - 'arduino/common/serialMonitor', - 'Serial Monitor' - ); static readonly ID = 'serial-monitor'; protected settings: MonitorSettings = {}; @@ -65,7 +62,7 @@ export class MonitorWidget extends ReactWidget { constructor() { super(); this.id = MonitorWidget.ID; - this.title.label = MonitorWidget.LABEL; + this.title.label = serialMonitorWidgetLabel; this.title.iconClass = 'monitor-tab-icon'; this.title.closable = true; this.scrollOptions = undefined; diff --git a/arduino-ide-extension/src/browser/style/monitor.css b/arduino-ide-extension/src/browser/style/monitor.css index 6787ea4cb..dfbed12aa 100644 --- a/arduino-ide-extension/src/browser/style/monitor.css +++ b/arduino-ide-extension/src/browser/style/monitor.css @@ -20,7 +20,7 @@ .serial-monitor .head { display: flex; - padding: 0px 5px 5px 0px; + padding: 0px 5px 5px 5px; height: 27px; background-color: var(--theia-activityBar-background); } diff --git a/arduino-ide-extension/src/common/nls.ts b/arduino-ide-extension/src/common/nls.ts index a2e58b86a..29ab5604f 100644 --- a/arduino-ide-extension/src/common/nls.ts +++ b/arduino-ide-extension/src/common/nls.ts @@ -19,3 +19,8 @@ export const InstallManually = nls.localize( 'arduino/common/installManually', 'Install Manually' ); + +export const serialMonitorWidgetLabel = nls.localize( + 'arduino/common/serialMonitor', + 'Serial Monitor' +); diff --git a/i18n/en.json b/i18n/en.json index ecd94c757..9a5b38eda 100644 --- a/i18n/en.json +++ b/i18n/en.json @@ -381,6 +381,9 @@ "language.log": "True if the Arduino Language Server should generate log files into the sketch folder. Otherwise, false. It's false by default.", "language.realTimeDiagnostics": "If true, the language server provides real-time diagnostics when typing in the editor. It's false by default.", "manualProxy": "Manual proxy configuration", + "monitor": { + "dockPanel": "The area of the application shell where the _{0}_ widget will reside. It is either \"bottom\" or \"right\". It defaults to \"{1}\"." + }, "network": "Network", "newSketchbookLocation": "Select new sketchbook location", "noCliConfig": "Could not load the CLI configuration",