Cleaner implementation of HistoryList

- The implementation has been taken from @kittaakos repo
d10de01736/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.
This commit is contained in:
Muhammad Zaheer 2022-10-21 00:05:55 +05:30 committed by Akos Kitta
parent cdaaa5584d
commit 3b2d12eff9

View File

@ -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;
private readonly items: string[] = [];
private index = -1;
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);
constructor(private readonly size = 100) {}
push(val: string): void {
if (val !== this.items[this.items.length - 1]) {
this.items.push(val);
}
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;
while (this.items.length > this.size) {
this.items.shift();
}
this.index = -1;
}
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;
previous(): string {
if (this.index === -1) {
this.index = this.items.length - 1;
return this.items[this.index];
}
if (this.hasPrevious) {
return this.items[--this.index];
}
this.ring[this.end] = val;
this.index = this.end;
this.traverse = false;
return this.index;
return this.items[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];
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];
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,21 +158,16 @@ 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();
if (text) {
this.state.history.push(text);
}
else if (key === Key.ARROW_UP) {
this.setState({ text: this.state.history.prev()});
}
else if (key === Key.ARROW_DOWN) {
} 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) {
} else if (key === Key.ESCAPE) {
this.setState({ text: '' });
}
}