From df49032f95b63053dacfbd586c9bd73d84065e69 Mon Sep 17 00:00:00 2001 From: Muhammad Zaheer Date: Sun, 16 Oct 2022 13:31:20 +0530 Subject: [PATCH 1/4] Added Message History to Serial Monitor --- .../monitor/serial-monitor-send-input.tsx | 102 +++++++++++++++++- 1 file changed, 100 insertions(+), 2 deletions(-) diff --git a/arduino-ide-extension/src/browser/serial/monitor/serial-monitor-send-input.tsx b/arduino-ide-extension/src/browser/serial/monitor/serial-monitor-send-input.tsx index f96636455..e3f2871e7 100644 --- a/arduino-ide-extension/src/browser/serial/monitor/serial-monitor-send-input.tsx +++ b/arduino-ide-extension/src/browser/serial/monitor/serial-monitor-send-input.tsx @@ -6,6 +6,88 @@ import { BoardsServiceProvider } from '../../boards/boards-service-provider'; import { MonitorModel } from '../../monitor-model'; import { Unknown } from '../../../common/nls'; +class HistoryList { + private ring: string[]; + private size: number; + private begin: number; + private index: number; + private end: number; + private traverse: boolean; + + constructor(size: number = 100) { + this.init = this.init.bind(this); + this.push = this.push.bind(this); + this.prev = this.prev.bind(this); + this.next = this.next.bind(this); + this.init(size); + } + private init(size: number = 100) { + this.ring = []; + this.size = (size > 0) ? size : 1; + this.begin = 0; + this.index = 0; + this.end = -1; + this.traverse = false; + } + + push(val: string): number { + this.end++; + if (this.ring.length >= this.size) { + if (this.end >= this.size) + this.end = 0; + if (this.end === this.begin) { + this.begin++; + if (this.begin >= this.size) + this.begin = 0; + } + } + this.ring[this.end] = val; + this.index = this.end; + this.traverse = false; + return this.index; + } + + prev(): string { + if (this.ring.length < 1) { + return ''; + } + if (this.index === this.end) { + this.traverse = true; + this.index--; + return this.ring[this.end]; + } + if (this.index !== this.begin) { + if (this.traverse) { + this.traverse = false; + } + else + this.index = (this.index > 0) ? --this.index : this.size - 1; + } + + return this.ring[this.index]; + } + + next(): string { + if (this.ring.length < 1) { + return ''; + } + if (this.index !== this.end) { + this.traverse = true; + this.index = (++this.index < this.size) ? this.index : 0; + return this.ring[this.index]; + } + else { + if (!this.traverse) { + return ''; + } + else { + this.traverse = false; + return this.ring[this.index]; + } + } + } +} + export namespace SerialMonitorSendInput { export interface Props { readonly boardsServiceProvider: BoardsServiceProvider; @@ -16,6 +98,7 @@ export namespace SerialMonitorSendInput { export interface State { text: string; connected: boolean; + history: HistoryList; } } @@ -27,7 +110,7 @@ export class SerialMonitorSendInput extends React.Component< constructor(props: Readonly) { super(props); - this.state = { text: '', connected: true }; + this.state = { text: '', connected: true, history: new HistoryList() }; this.onChange = this.onChange.bind(this); this.onSend = this.onSend.bind(this); this.onKeyDown = this.onKeyDown.bind(this); @@ -110,8 +193,23 @@ export class SerialMonitorSendInput extends React.Component< if (keyCode) { const { key } = keyCode; if (key === Key.ENTER) { + // NOTE: order of operations is critical here. Push the current state.text + // onto the history stack before sending. After sending, state.text is empty + // and you'd end up pushing '' onto the history stack. + if (this.state.text.length > 0) { + this.state.history.push(this.state.text); + } this.onSend(); + } + else if (key === Key.ARROW_UP) { + this.setState({ text: this.state.history.prev()}); + } + else if (key === Key.ARROW_DOWN) { + this.setState({ text: this.state.history.next()}); + } + else if (key === Key.ESCAPE) { + this.setState({ text: ''}); } } } -} +} \ No newline at end of file From c85bba8e99a2b3d25ea34493af72f909d80b165b Mon Sep 17 00:00:00 2001 From: Muhammad Zaheer Date: Sun, 16 Oct 2022 16:53:14 +0530 Subject: [PATCH 2/4] Changed logic to avoid end value being shown twice --- .../browser/serial/monitor/serial-monitor-send-input.tsx | 8 +++----- 1 file changed, 3 insertions(+), 5 deletions(-) diff --git a/arduino-ide-extension/src/browser/serial/monitor/serial-monitor-send-input.tsx b/arduino-ide-extension/src/browser/serial/monitor/serial-monitor-send-input.tsx index e3f2871e7..6650a8377 100644 --- a/arduino-ide-extension/src/browser/serial/monitor/serial-monitor-send-input.tsx +++ b/arduino-ide-extension/src/browser/serial/monitor/serial-monitor-send-input.tsx @@ -74,17 +74,15 @@ class HistoryList { if (this.index !== this.end) { this.traverse = true; this.index = (++this.index < this.size) ? this.index : 0; - return this.ring[this.index]; + if(this.index === this.end) + this.traverse = false; } else { if (!this.traverse) { return ''; } - else { - this.traverse = false; - return this.ring[this.index]; - } } + return this.ring[this.index]; } } From 3740f0b55706e9495a52db0a3aff43f0ef924a0f Mon Sep 17 00:00:00 2001 From: Muhammad Zaheer Date: Fri, 21 Oct 2022 00:05:55 +0530 Subject: [PATCH 3/4] Cleaner implementation of HistoryList - The implementation has been taken from @kittaakos repo https://github.com/kittaakos/arduino-ide/blob/d10de017362989b62d01991a33eaef9e71a6aec4/arduino-ide-extension/src/browser/serial/monitor/serial-monitor-send-input.tsx - The previous method has been modified to ensure the first element instead of an empty string is returned if the index is at the beginning of the list. - The push method has been modified to check if the current command is same as the last command. If same then, it is not added to the list else it is added. --- .../monitor/serial-monitor-send-input.tsx | 122 ++++++------------ 1 file changed, 42 insertions(+), 80 deletions(-) diff --git a/arduino-ide-extension/src/browser/serial/monitor/serial-monitor-send-input.tsx b/arduino-ide-extension/src/browser/serial/monitor/serial-monitor-send-input.tsx index 6650a8377..427aec1f7 100644 --- a/arduino-ide-extension/src/browser/serial/monitor/serial-monitor-send-input.tsx +++ b/arduino-ide-extension/src/browser/serial/monitor/serial-monitor-send-input.tsx @@ -7,82 +7,49 @@ import { MonitorModel } from '../../monitor-model'; import { Unknown } from '../../../common/nls'; class HistoryList { - private ring: string[]; - private size: number; - private begin: number; - private index: number; - private end: number; - private traverse: boolean; - - constructor(size: number = 100) { - this.init = this.init.bind(this); - this.push = this.push.bind(this); - this.prev = this.prev.bind(this); - this.next = this.next.bind(this); - this.init(size); - } - private init(size: number = 100) { - this.ring = []; - this.size = (size > 0) ? size : 1; - this.begin = 0; - this.index = 0; - this.end = -1; - this.traverse = false; - } - - push(val: string): number { - this.end++; - if (this.ring.length >= this.size) { - if (this.end >= this.size) - this.end = 0; - if (this.end === this.begin) { - this.begin++; - if (this.begin >= this.size) - this.begin = 0; - } + private readonly items: string[] = []; + private index = -1; + + constructor(private readonly size = 100) {} + + push(val: string): void { + if (val !== this.items[this.items.length - 1]) { + this.items.push(val); + } + while (this.items.length > this.size) { + this.items.shift(); } - this.ring[this.end] = val; - this.index = this.end; - this.traverse = false; - return this.index; + this.index = -1; } - prev(): string { - if (this.ring.length < 1) { - return ''; - } - if (this.index === this.end) { - this.traverse = true; - this.index--; - return this.ring[this.end]; + previous(): string { + if (this.index === -1) { + this.index = this.items.length - 1; + return this.items[this.index]; } - if (this.index !== this.begin) { - if (this.traverse) { - this.traverse = false; - } - else - this.index = (this.index > 0) ? --this.index : this.size - 1; + if (this.hasPrevious) { + return this.items[--this.index]; } + return this.items[this.index]; + } - return this.ring[this.index]; + private get hasPrevious(): boolean { + return this.index >= 1; } next(): string { - if (this.ring.length < 1) { + if (this.index === this.items.length - 1) { + this.index = -1; return ''; } - if (this.index !== this.end) { - this.traverse = true; - this.index = (++this.index < this.size) ? this.index : 0; - if(this.index === this.end) - this.traverse = false; + if (this.hasNext) { + return this.items[++this.index]; } - else { - if (!this.traverse) { - return ''; - } - } - return this.ring[this.index]; + return ''; + } + + private get hasNext(): boolean { + return this.index >= 0 && this.index !== this.items.length - 1; } } @@ -171,7 +138,7 @@ export class SerialMonitorSendInput extends React.Component< ); } - protected setRef = (element: HTMLElement | null) => { + protected setRef = (element: HTMLElement | null): void => { if (this.props.resolveFocus) { this.props.resolveFocus(element || undefined); } @@ -191,22 +158,17 @@ export class SerialMonitorSendInput extends React.Component< if (keyCode) { const { key } = keyCode; if (key === Key.ENTER) { - // NOTE: order of operations is critical here. Push the current state.text - // onto the history stack before sending. After sending, state.text is empty - // and you'd end up pushing '' onto the history stack. - if (this.state.text.length > 0) { - this.state.history.push(this.state.text); - } + const { text } = this.state; this.onSend(); - } - else if (key === Key.ARROW_UP) { - this.setState({ text: this.state.history.prev()}); - } - else if (key === Key.ARROW_DOWN) { - this.setState({ text: this.state.history.next()}); - } - else if (key === Key.ESCAPE) { - this.setState({ text: ''}); + if (text) { + this.state.history.push(text); + } + } else if (key === Key.ARROW_UP) { + this.setState({ text: this.state.history.previous() }); + } else if (key === Key.ARROW_DOWN) { + this.setState({ text: this.state.history.next() }); + } else if (key === Key.ESCAPE) { + this.setState({ text: '' }); } } } From fcd0f03975e0831506c1df5d0d0057624f2ab262 Mon Sep 17 00:00:00 2001 From: Muhammad Zaheer Date: Fri, 21 Oct 2022 13:02:58 +0530 Subject: [PATCH 4/4] Coding style fix - newline added --- .../src/browser/serial/monitor/serial-monitor-send-input.tsx | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/arduino-ide-extension/src/browser/serial/monitor/serial-monitor-send-input.tsx b/arduino-ide-extension/src/browser/serial/monitor/serial-monitor-send-input.tsx index 427aec1f7..163fdbafd 100644 --- a/arduino-ide-extension/src/browser/serial/monitor/serial-monitor-send-input.tsx +++ b/arduino-ide-extension/src/browser/serial/monitor/serial-monitor-send-input.tsx @@ -172,4 +172,4 @@ export class SerialMonitorSendInput extends React.Component< } } } -} \ No newline at end of file +}