@@ -34,70 +34,110 @@ export const cursorCodes = {
34
34
show : "?25h" ,
35
35
} as const
36
36
37
- /**
38
- * For storing bookmarks
39
- */
40
- const positions : { [ key : string ] : CursorPos } = { }
41
-
42
- /**
43
- * For chaining cursor methods.
44
- */
45
- const c = ( s : string , esc : string = ESC ) => {
46
- write ( esc + s )
47
- return cursor
48
- }
49
-
50
37
/**
51
38
* Moving the cursor around the terminal. Needs testing on Windows.
52
39
*/
53
- export const cursor = {
54
- write : ( s : string ) => c ( s , "" ) ,
55
- up : ( count : number = 1 ) => c ( `${ count } ${ cursorCodes . up } ` ) ,
56
- down : ( count : number = 1 ) => c ( `${ count } ${ cursorCodes . down } ` ) ,
57
- forward : ( count : number = 1 ) => c ( `${ count } ${ cursorCodes . forward } ` ) ,
58
- back : ( count : number = 1 ) => c ( `${ count } ${ cursorCodes . back } ` ) ,
59
- moveDown : ( count : number = 1 ) => c ( `${ count } ${ cursorCodes . nextLine } ` ) ,
60
- moveUp : ( count : number = 1 ) => c ( `${ count } ${ cursorCodes . previousLine } ` ) ,
61
- backToStart : ( ) => c ( `${ cursorCodes . horizontalAbsolute } ` ) ,
62
- horizontalAbsolute : ( count = 1 ) => c ( `${ count } ${ cursorCodes . horizontalAbsolute } ` ) ,
63
- eraseBefore : ( count = 1 ) => c ( `${ count } ${ cursorCodes . eraseData } ` ) ,
64
- eraseLine : ( ) => c ( `${ cursorCodes . eraseLine } ` ) ,
65
- erase : ( count = 1 ) => c ( `${ count } ${ cursorCodes . eraseCharacter } ` ) ,
66
- clearScreen : ( ) => c ( `${ cursorCodes . clearScreen } ` ) ,
67
- scrollUp : ( count = 1 ) => c ( `${ count } ${ cursorCodes . scrollUp } ` ) ,
68
- scrollDown : ( count = 1 ) => c ( `${ count } ${ cursorCodes . scrollDown } ` ) ,
69
- goto : ( pos : CursorPos ) => c ( cursorCodes . goToPosition ( pos . cols , pos . rows ) , "" ) ,
40
+ export class Cursor {
41
+ bookmarks : { [ key : string ] : CursorPos } = { }
42
+
43
+ // for chaining easily
44
+ c ( s : string , esc : string = ESC ) {
45
+ write ( esc + s )
46
+ return this
47
+ }
48
+
49
+ write ( s : string ) {
50
+ return this . c ( s , "" )
51
+ }
52
+ up ( count : number = 1 ) {
53
+ return this . c ( `${ count } ${ cursorCodes . up } ` )
54
+ }
55
+ down ( count : number = 1 ) {
56
+ return this . c ( `${ count } ${ cursorCodes . down } ` )
57
+ }
58
+ forward ( count : number = 1 ) {
59
+ return this . c ( `${ count } ${ cursorCodes . forward } ` )
60
+ }
61
+ back ( count : number = 1 ) {
62
+ return this . c ( `${ count } ${ cursorCodes . back } ` )
63
+ }
64
+ moveDown ( count : number = 1 ) {
65
+ return this . c ( `${ count } ${ cursorCodes . nextLine } ` )
66
+ }
67
+ moveUp ( count : number = 1 ) {
68
+ return this . c ( `${ count } ${ cursorCodes . previousLine } ` )
69
+ }
70
+ backToStart ( ) {
71
+ return this . c ( `${ cursorCodes . horizontalAbsolute } ` )
72
+ }
73
+ horizontalAbsolute ( count = 1 ) {
74
+ return this . c ( `${ count } ${ cursorCodes . horizontalAbsolute } ` )
75
+ }
76
+ eraseBefore ( count = 1 ) {
77
+ return this . c ( `${ count } ${ cursorCodes . eraseData } ` )
78
+ }
79
+ eraseLine ( ) {
80
+ return this . c ( `${ cursorCodes . eraseLine } ` )
81
+ }
82
+ erase ( count = 1 ) {
83
+ return this . c ( `${ count } ${ cursorCodes . eraseCharacter } ` )
84
+ }
85
+ clearScreen ( ) {
86
+ return this . c ( `${ cursorCodes . clearScreen } ` )
87
+ }
88
+ scrollUp ( count = 1 ) {
89
+ return this . c ( `${ count } ${ cursorCodes . scrollUp } ` )
90
+ }
91
+ scrollDown ( count = 1 ) {
92
+ return this . c ( `${ count } ${ cursorCodes . scrollDown } ` )
93
+ }
94
+ goto ( pos : CursorPos ) {
95
+ return this . c ( cursorCodes . goToPosition ( pos . cols , pos . rows ) , "" )
96
+ }
70
97
71
98
// basic save & restore position
72
- savePosition : ( ) => c ( `${ cursorCodes . savePosition } ` , "" ) ,
73
- restorePosition : ( ) => c ( `${ cursorCodes . restorePosition } ` , "" ) ,
74
-
75
- hide : ( ) => c ( `${ cursorCodes . hide } ` ) ,
76
- show : ( ) => c ( `${ cursorCodes . show } ` ) ,
77
-
78
- backspace : ( count = 1 ) => cursor . back ( count ) . erase ( count ) ,
79
-
80
- alternate : ( enabled : boolean ) =>
81
- c ( `${ enabled ? cursorCodes . enterAlternativeScreen : cursorCodes . exitAlternativeScreen } ` ) ,
82
-
83
- // advanced save & restore positions -- these can't be chained
84
- queryPosition,
85
- bookmark : async ( name : string , pos ?: CursorPos ) => {
99
+ savePosition ( ) {
100
+ return this . c ( `${ cursorCodes . savePosition } ` , "" )
101
+ }
102
+ restorePosition ( ) {
103
+ return this . c ( `${ cursorCodes . restorePosition } ` , "" )
104
+ }
105
+
106
+ hide ( ) {
107
+ return this . c ( `${ cursorCodes . hide } ` )
108
+ }
109
+ show ( ) {
110
+ return this . c ( `${ cursorCodes . show } ` )
111
+ }
112
+
113
+ backspace ( count = 1 ) {
114
+ return this . back ( count ) . erase ( count )
115
+ }
116
+
117
+ alternate ( enabled : boolean ) {
118
+ return this . c ( `${ enabled ? cursorCodes . enterAlternativeScreen : cursorCodes . exitAlternativeScreen } ` )
119
+ }
120
+
121
+ // advanced save & restore bookmarks -- these can't be chained
122
+ queryPosition ( ) {
123
+ return queryPosition ( )
124
+ }
125
+ async bookmark ( name : string , pos ?: CursorPos ) {
86
126
const cpos = pos || ( await queryPosition ( ) )
87
- positions [ name ] = cpos
127
+ this . bookmarks [ name ] = cpos
88
128
return cpos
89
- } ,
90
- getBookmark : ( name : string ) => positions [ name ] ,
129
+ }
91
130
92
131
// can be chained, since we don't have to wait for the queryPosition
93
- jump : ( name : string ) => {
94
- const pos = positions [ name ]
132
+ jump ( name : string ) {
133
+ const pos = this . bookmarks [ name ]
95
134
if ( ! pos ) throw new Error ( `No cursor bookmark found with name ${ name } ` )
96
- cursor . goto ( pos )
97
- return cursor
98
- } ,
135
+ return this . goto ( pos )
136
+ }
99
137
}
100
138
139
+ export const cursor = new Cursor ( )
140
+
101
141
// this is how we use the ansi queryPosition escape code.
102
142
// it returns the cursor position, which we can then parse
103
143
// and use to position the cursor.
0 commit comments