1+ /**
2+ * Constants for ANSI escape sequences.
3+ */
14const ESC = "\x1B[" ;
25
36const SAVE = "\x1B7" ; // "\x1B[s"
@@ -12,18 +15,47 @@ const HOME = "H";
1215
1316const isTTY = Deno . stdout . isTerminal ;
1417
18+ /**
19+ * Interface representing the size of the terminal.
20+ */
1521interface Size {
1622 columns : number ;
1723 rows : number ;
1824}
1925
26+ /**
27+ * A class for managing terminal operations using ANSI escape sequences.
28+ */
2029export default class TermBox {
30+ /**
31+ * Encoder for converting strings to Uint8Array.
32+ */
2133 private encoder = new TextEncoder ( ) ;
34+
35+ /**
36+ * Writer for writing to the terminal.
37+ */
2238 private writer = Deno . stdout . writable . getWriter ( ) ;
39+
40+ /**
41+ * Two-dimensional array representing the terminal cells.
42+ */
2343 private cells : string [ ] [ ] ;
44+
45+ /**
46+ * Number of columns in the terminal.
47+ */
2448 private columns : number ;
49+
50+ /**
51+ * Number of rows in the terminal.
52+ */
2553 private rows : number ;
2654
55+ /**
56+ * Constructs a new TermBox instance.
57+ * @param size Optional size of the terminal. If not provided, it will be determined automatically.
58+ */
2759 constructor ( size ?: Size ) {
2860 const { columns, rows } = size ?? this . size ( ) ;
2961 this . columns = columns ;
@@ -33,19 +65,39 @@ export default class TermBox {
3365 . map ( ( ) => new Array ( columns ) . fill ( null ) . map ( ( ) => " " ) ) ;
3466 }
3567
68+ /**
69+ * Moves the cursor to a specified position.
70+ * @param action The ANSI escape sequence for cursor movement.
71+ * @returns A promise that resolves when the operation is complete.
72+ */
3673 private cursor ( action : string ) : Promise < void > {
3774 return this . write ( ESC + action ) ;
3875 }
3976
77+ /**
78+ * Writes a message to the terminal.
79+ * @param msg The message to write.
80+ * @returns A promise that resolves when the operation is complete.
81+ */
4082 private write ( msg : string ) : Promise < void > {
4183 return this . writer . write ( this . encoder . encode ( msg ) ) ;
4284 }
4385
86+ /**
87+ * Flushes the current state of the terminal cells to the terminal.
88+ * @returns A promise that resolves when the operation is complete.
89+ */
4490 async flush ( ) : Promise < void > {
4591 await this . cursorTo ( 0 , 0 ) ;
4692 return this . write ( this . cells . map ( ( v ) => v . join ( "" ) ) . join ( "\n" ) ) ;
4793 }
4894
95+ /**
96+ * Sets the content of a specific cell in the terminal grid.
97+ * @param x The column index.
98+ * @param y The row index.
99+ * @param char The character to set.
100+ */
49101 setCell ( x : number , y : number , char : string ) : void {
50102 if ( x >= this . columns || x < 0 ) return ;
51103 if ( y >= this . rows || y < 0 ) return ;
@@ -55,26 +107,52 @@ export default class TermBox {
55107 this . cells [ y ] [ x ] = char ;
56108 }
57109
110+ /**
111+ * Hides the cursor.
112+ * @returns A promise that resolves when the operation is complete.
113+ */
58114 cursorHide ( ) : Promise < void > {
59115 return this . cursor ( HIDE ) ;
60116 }
61117
118+ /**
119+ * Shows the cursor.
120+ * @returns A promise that resolves when the operation is complete.
121+ */
62122 cursorShow ( ) : Promise < void > {
63123 return this . cursor ( SHOW ) ;
64124 }
65125
126+ /**
127+ * Saves the current cursor position.
128+ * @returns A promise that resolves when the operation is complete.
129+ */
66130 cursorSave ( ) : Promise < void > {
67131 return this . write ( SAVE ) ;
68132 }
69133
134+ /**
135+ * Restores the saved cursor position.
136+ * @returns A promise that resolves when the operation is complete.
137+ */
70138 cursorRestore ( ) : Promise < void > {
71139 return this . write ( RESTORE ) ;
72140 }
73141
142+ /**
143+ * Moves the cursor to a specific position.
144+ * @param x The column index.
145+ * @param y The row index.
146+ * @returns A promise that resolves when the operation is complete.
147+ */
74148 cursorTo ( x : number , y : number ) : Promise < void > {
75149 return this . cursor ( `${ y } ;${ x } ${ HOME } ` ) ;
76150 }
77151
152+ /**
153+ * Gets the current cursor position.
154+ * @returns A promise that resolves with the cursor position.
155+ */
78156 async cursorPosition ( ) : Promise < Size > {
79157 if ( ! isTTY ) {
80158 return { columns : 0 , rows : 0 } ;
@@ -101,14 +179,26 @@ export default class TermBox {
101179 }
102180 }
103181
182+ /**
183+ * Clears the screen.
184+ * @returns A promise that resolves when the operation is complete.
185+ */
104186 screenClear ( ) : Promise < void > {
105187 return this . cursor ( CLEAR_SCREEN ) ;
106188 }
107189
190+ /**
191+ * Resets the screen to its initial state.
192+ * @returns A promise that resolves when the operation is complete.
193+ */
108194 screenReset ( ) : Promise < void > {
109195 return this . write ( ESC + ( this . rows - 1 ) + "A\r\x1b[?0J" ) ;
110196 }
111197
198+ /**
199+ * Gets the size of the terminal.
200+ * @returns The size of the terminal.
201+ */
112202 size ( ) : Size {
113203 if ( ! isTTY ) return { columns : 100 , rows : 50 } ;
114204 return {
@@ -117,11 +207,17 @@ export default class TermBox {
117207 } ;
118208 }
119209
210+ /**
211+ * Ends the session and releases any resources.
212+ */
120213 end ( ) : void {
121214 this . writer . releaseLock ( ) ;
122215 }
123216}
124217
218+ /**
219+ * Regular expression pattern for matching ANSI escape codes.
220+ */
125221// https://github.com/chalk/ansi-regex/blob/02fa893d619d3da85411acc8fd4e2eea0e95a9d9/index.js
126222const ANSI_PATTERN = new RegExp (
127223 [
@@ -131,6 +227,11 @@ const ANSI_PATTERN = new RegExp(
131227 "g" ,
132228) ;
133229
230+ /**
231+ * Strips ANSI escape codes from a string.
232+ * @param string The string to strip.
233+ * @returns The stripped string.
234+ */
134235function stripAnsiCode ( string : string ) : string {
135236 return string . replace ( ANSI_PATTERN , "" ) ;
136- }
237+ }
0 commit comments