@@ -6,6 +6,88 @@ import { BoardsServiceProvider } from '../../boards/boards-service-provider';
66import { MonitorModel } from '../../monitor-model' ;
77import { Unknown } from '../../../common/nls' ;
88
9+ class HistoryList {
10+ private ring : string [ ] ;
11+ private size : number ;
12+ private begin : number ;
13+ private index : number ;
14+ private end : number ;
15+ private traverse : boolean ;
16+
17+ constructor ( size : number = 100 ) {
18+ this . init = this . init . bind ( this ) ;
19+ this . push = this . push . bind ( this ) ;
20+ this . prev = this . prev . bind ( this ) ;
21+ this . next = this . next . bind ( this ) ;
22+ this . init ( size ) ;
23+ }
24+ private init ( size : number = 100 ) {
25+ this . ring = [ ] ;
26+ this . size = ( size > 0 ) ? size : 1 ;
27+ this . begin = 0 ;
28+ this . index = 0 ;
29+ this . end = - 1 ;
30+ this . traverse = false ;
31+ }
32+
33+ push ( val : string ) : number {
34+ this . end ++ ;
35+ if ( this . ring . length >= this . size ) {
36+ if ( this . end >= this . size )
37+ this . end = 0 ;
38+ if ( this . end === this . begin ) {
39+ this . begin ++ ;
40+ if ( this . begin >= this . size )
41+ this . begin = 0 ;
42+ }
43+ }
44+ this . ring [ this . end ] = val ;
45+ this . index = this . end ;
46+ this . traverse = false ;
47+ return this . index ;
48+ }
49+
50+ prev ( ) : string {
51+ if ( this . ring . length < 1 ) {
52+ return '' ;
53+ }
54+ if ( this . index === this . end ) {
55+ this . traverse = true ;
56+ this . index -- ;
57+ return this . ring [ this . end ] ;
58+ }
59+ if ( this . index !== this . begin ) {
60+ if ( this . traverse ) {
61+ this . traverse = false ;
62+ }
63+ else
64+ this . index = ( this . index > 0 ) ? -- this . index : this . size - 1 ;
65+ }
66+
67+ return this . ring [ this . index ] ;
68+ }
69+
70+ next ( ) : string {
71+ if ( this . ring . length < 1 ) {
72+ return '' ;
73+ }
74+ if ( this . index !== this . end ) {
75+ this . traverse = true ;
76+ this . index = ( ++ this . index < this . size ) ? this . index : 0 ;
77+ return this . ring [ this . index ] ;
78+ }
79+ else {
80+ if ( ! this . traverse ) {
81+ return '' ;
82+ }
83+ else {
84+ this . traverse = false ;
85+ return this . ring [ this . index ] ;
86+ }
87+ }
88+ }
89+ }
90+
991export namespace SerialMonitorSendInput {
1092 export interface Props {
1193 readonly boardsServiceProvider : BoardsServiceProvider ;
@@ -16,6 +98,7 @@ export namespace SerialMonitorSendInput {
1698 export interface State {
1799 text : string ;
18100 connected : boolean ;
101+ history : HistoryList ;
19102 }
20103}
21104
@@ -27,7 +110,7 @@ export class SerialMonitorSendInput extends React.Component<
27110
28111 constructor ( props : Readonly < SerialMonitorSendInput . Props > ) {
29112 super ( props ) ;
30- this . state = { text : '' , connected : true } ;
113+ this . state = { text : '' , connected : true , history : new HistoryList ( ) } ;
31114 this . onChange = this . onChange . bind ( this ) ;
32115 this . onSend = this . onSend . bind ( this ) ;
33116 this . onKeyDown = this . onKeyDown . bind ( this ) ;
@@ -110,8 +193,23 @@ export class SerialMonitorSendInput extends React.Component<
110193 if ( keyCode ) {
111194 const { key } = keyCode ;
112195 if ( key === Key . ENTER ) {
196+ // NOTE: order of operations is critical here. Push the current state.text
197+ // onto the history stack before sending. After sending, state.text is empty
198+ // and you'd end up pushing '' onto the history stack.
199+ if ( this . state . text . length > 0 ) {
200+ this . state . history . push ( this . state . text ) ;
201+ }
113202 this . onSend ( ) ;
203+ }
204+ else if ( key === Key . ARROW_UP ) {
205+ this . setState ( { text : this . state . history . prev ( ) } ) ;
206+ }
207+ else if ( key === Key . ARROW_DOWN ) {
208+ this . setState ( { text : this . state . history . next ( ) } ) ;
209+ }
210+ else if ( key === Key . ESCAPE ) {
211+ this . setState ( { text : '' } ) ;
114212 }
115213 }
116214 }
117- }
215+ }
0 commit comments