-
Notifications
You must be signed in to change notification settings - Fork 0
/
readme.txt
2410 lines (1715 loc) · 87.6 KB
/
readme.txt
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
513
514
515
516
517
518
519
520
521
522
523
524
525
526
527
528
529
530
531
532
533
534
535
536
537
538
539
540
541
542
543
544
545
546
547
548
549
550
551
552
553
554
555
556
557
558
559
560
561
562
563
564
565
566
567
568
569
570
571
572
573
574
575
576
577
578
579
580
581
582
583
584
585
586
587
588
589
590
591
592
593
594
595
596
597
598
599
600
601
602
603
604
605
606
607
608
609
610
611
612
613
614
615
616
617
618
619
620
621
622
623
624
625
626
627
628
629
630
631
632
633
634
635
636
637
638
639
640
641
642
643
644
645
646
647
648
649
650
651
652
653
654
655
656
657
658
659
660
661
662
663
664
665
666
667
668
669
670
671
672
673
674
675
676
677
678
679
680
681
682
683
684
685
686
687
688
689
690
691
692
693
694
695
696
697
698
699
700
701
702
703
704
705
706
707
708
709
710
711
712
713
714
715
716
717
718
719
720
721
722
723
724
725
726
727
728
729
730
731
732
733
734
735
736
737
738
739
740
741
742
743
744
745
746
747
748
749
750
751
752
753
754
755
756
757
758
759
760
761
762
763
764
765
766
767
768
769
770
771
772
773
774
775
776
777
778
779
780
781
782
783
784
785
786
787
788
789
790
791
792
793
794
795
796
797
798
799
800
801
802
803
804
805
806
807
808
809
810
811
812
813
814
815
816
817
818
819
820
821
822
823
824
825
826
827
828
829
830
831
832
833
834
835
836
837
838
839
840
841
842
843
844
845
846
847
848
849
850
851
852
853
854
855
856
857
858
859
860
861
862
863
864
865
866
867
868
869
870
871
872
873
874
875
876
877
878
879
880
881
882
883
884
885
886
887
888
889
890
891
892
893
894
895
896
897
898
899
900
901
902
903
904
905
906
907
908
909
910
911
912
913
914
915
916
917
918
919
920
921
922
923
924
925
926
927
928
929
930
931
932
933
934
935
936
937
938
939
940
941
942
943
944
945
946
947
948
949
950
951
952
953
954
955
956
957
958
959
960
961
962
963
964
965
966
967
968
969
970
971
972
973
974
975
976
977
978
979
980
981
982
983
984
985
986
987
988
989
990
991
992
993
994
995
996
997
998
999
1000
**** mass:werk termlib.js - JS-WebTerminal Object v1.66 ****
(c) Norbert Landsteiner 2003-2015
mass:werk - media environments
<http://www.masswerk.at>
### COMPATIBILITY WARNING ###
Dropped support of Netscape 4 (layers) with version 1.5!
Netscape 4 is now outdated for more than 10 years. Any further support of this browser
would be of academic nature. As a benefit this step allows us to include the socket
extension in the main library, so there are no additional files to load anymore.
For the first time there is a backward compatibility issue from version 1.3 to version 1.4:
The following applies to the style vector for the `type()' method while using colors:
while with version 1.3 a color was encoded using the color code times 16 (0xf), e.g.:
myTerm.type( 'This is red.', 2*16 );
this changed with version 1.4 to the color code times 256 (0xff), e.g.:
myTerm.type( 'This is red.', 2*256 );
All other style encodings or color API remain unchanged.
Since this feature was only introduced in version 1.3 and there are no known applications
that would use a statement like the above (since you would usually use the `write()' method
for complex output), this seems to be good bargain for some codes for custom styles.
C.f.: sect 7.5 "TermGlobals.assignStyle()"
### Mac OS X Dead-Keys ###
(Dead-keys: combinations of accents and characters that are built by two consecutively pressed keys.)
Mac OS X 10.5 and later doesn't fire a keyboard event for dead keys anymore.
It's possible to fix this for Safari by a custom dead keys emulation, but not for Chrome or Firefox.
"termlib.js" provides automatic translations of common dead-keys for Safari in German (de-de).
In case you would need dead-keys for another language, please contact me via http://www.masswerk.at/.
Contents:
1 About
2 Creating a new Terminal Instance
2.1 Configuration Values
3 Using the Terminal
3.1 The Default Handler
3.2 Input Modes
3.2.1 Normal Line Input (Command Line Mode)
3.2.1.2 Special Keys (ctrlHandler)
3.2.2 Raw Mode
3.2.3 Character Mode
3.3 Other Handlers
3.3.1 initHandler
3.3.2 exitHandler
3.4 Flags for Behaviour Control
4 Output Methods
4.1 Terminal.type()
4.2 Terminal.write()
4.3 Terminal.typeAt()
4.4 Terminal.setChar()
4.5 Terminal.newLine()
4.6 Terminal.clear()
4.7 Terminal.statusLine()
4.8 Terminal.printRowFromString()
4.9 Terminal.redraw()
4.10 Using Color
4.11 Text Wrap - Terminal.wrapOn(), Terminal.wrapOff()
4.12 ANSI Support
5 Cursor Methods and Editing
5.1 Terminal.cursorOn()
5.2 Terminal.cursorOff()
5.3 Terminal.cursorSet()
5.4 Terminal.cursorLeft()
5.5 Terminal.cursorRight()
5.6 Terminal.backspace()
5.7 Terminal.fwdDelete()
5.8 Terminal.isPrintable()
6 Other Methods of the Terminal Object
6.1 Terminal.prompt()
6.2 Terminal.reset()
6.3 Terminal.open()
6.4 Terminal.close()
6.5 Terminal.focus()
6.6 Terminal.moveTo()
6.7 Terminal.resizeTo()
6.8 Terminal.getDimensions()
6.9 Terminal.rebuild()
6.10 Terminal.backupScreen()
6.11 Terminal.restoreScreen()
6.12 Terminal.swapBackup()
6.13 Terminal.setTextColor()
6.14 Terminal.setTextBlur()
7 Global Static Methods (TermGlobals)
7.1 TermGlobals.setFocus()
7.2 TermGlobals.keylock (Global Locking Flag)
7.3 TermGlobals Text Methods
7.3.1 TermGlobals.normalize()
7.3.2 TermGlobals.fillLeft()
7.3.3 TermGlobals.center()
7.3.4 TermGlobals.stringReplace()
7.4 TermGlobals Import Methods
7.4.1 TermGlobals.insertText()
7.4.2 TermGlobals.importEachLine()
7.4.3 TermGlobals.importMultiLine()
7.5 TermGlobals.assignStyle()
8 Localization
9 The Socket Extension (Remote Communication)
9.1 A First Example
9.2 The send() API
9.3 Global Config Settings
9.4 The Callback (Response Handling)
9.5 Error Codes
9.6 Note on Compatibly / Browser Requirements
9.7 termlib_socket.js Version History
10 Cross Browser Functions
11 Architecture, Internals
11.1 Global Entities
11.2 I/O Architecture
11.3 Compatibility
12 History
13 Example for a Command Line Parser
14 License
15 Disclaimer
16 Donations
17 References
1 About
The Terminal library "termlib.js" provides an object oriented constructor and control
methods for a terminal-like DHTML interface.
"termlib.js" features direct keyboard input and powerful output methods for multiple
instances of the `Terminal' object (including focus control).
"termlib.js" also comprises methods for a transparent handling of client-server com-
munications via XMLHttpRequests (see sect. 9 "The Socket Extension").
The library was written with the aim of simple usage and a maximum of compatibility with
minimal foot print in the global namespace.
A simple example:
// creating a terminal and using it
var term = new Terminal( {handler: termHandler} );
term.open();
function termHandler() {
var line = this.lineBuffer;
this.newLine();
if (line == "help") {
this.write(helpPage)
}
else if (line == "exit") {
this.close();
return;
}
else if (line != "") {
this.write("You typed: "+line);
}
this.prompt();
}
var helpPage = [
"This is the monstrous help page for my groovy terminal.",
"Commands available:",
" help ... print this monstrous help page",
" exit ... leave this groovy terminal",
" ",
"Have fun!"
];
You should provide CSS font definitions for the classes ".term" (normal video) and
".termReverse" (reverse video) in a monospaced font.
A sample stylesheet "term_styles.css" comes with this library.
See the sample application "multiterm_test.html" for a demo of multiple terminals.
v.1.01: If you configure to use another font class (see 2.1 Configuration Values),
you must provide a subclass ".termReverse" for reversed video.
p.e.: .myFontClass .termReverse {
/* your definitions for reverse video here */
}
With the addition of `conf.fontClass' you can now create multiple
instances with independend appearences.
2 Creating a new Terminal Instance
Use the `new' constructor to create a new instance of the Terminal object. You will want
to supply a configuration object as an argument to the constructor. If the `new'
constructor is called without an object as its first argument, default values are used.
p.e.:
// creating a new instance of Terminal
var conf= {
x: 100,
y: 100,
cols: 80,
rows: 24
}
var term = new Term(conf);
term.open();
`Terminal.open()' initializes the terminal and makes it visible to the user.
This is handled in by separate method to allow the re-initilization of instances
previously closed.
NOTE:
The division or HTML-element that holds the terminal must be present when calling
`Terminal.open()'. So you must not call this method from the header of a HTML-document at
compile time.
2.1 Configuration Values
Set any of these values in your configuration object to override:
LABEL DEFAULT VALUE COMMENT
x 100 terminal's position x in px
y 100 terminal's position y in px
termDiv 'termDiv' id of terminals CSS division
bgColor '#181818' background color (HTML hex value)
frameColor '#555555' frame color (HTML hex value)
frameWidth 1 frame border width in px
fontClass 'term' class name of CSS font definition to use
cols 80 number of cols per row
rows 24 number of rows
rowHeight 15 a row's line-height in px
blinkDelay 500 delay for cursor blinking in milliseconds
crsrBlinkMode false true for blinking cursor
crsrBlockMode true true for block-cursor else underscore
DELisBS false handle <DEL> as <BACKSPACE>
printTab true handle <TAB> as printable (prints as space)
printEuro true handle unicode 0x20AC (Euro sign) as printable
catchCtrlH true handle ^H as <BACKSPACE>
closeOnESC true close terminal on <ESC>
historyUnique false prevent consecutive and identical entries in history
id 0 terminal id
ps '>' prompt string
greeting '%+r Terminal ready. %-r' string for greeting if no initHandler is used
handler defaultHandler reference to handler for command interpretation
ctrlHandler null reference to handler called on uncatched special keys
initHandler null reference to handler called at end of init()
exitHandler null reference to handler called on close()
wrapping false text wrapping for `write()' on/off
mapANSI false enable mapping of ANSI escape sequences (SGR only)
ANSItrueBlack false force ANSI 30m to be rendered as black (default: fg color)
textColor '' String, default text color (color 0), overrides any CSS rules
textBlur 0 Number, if set, adds a CSS text-shadow with the given number of px
("text-shadow: 0 0 <textBlur>px <color>"), use this with textColor
If the value is an array of numbers, multiple text-shadows will
be applied.
At least you will want to specify `handler' to implement your own command parser.
Note: While `id' is not used by the Termninal object, it provides an easy way to identify
multiple terminals by the use of "this.id". (e.g.: "if (this.id == 1) startupterm = true;")
p.e.:
// creating two individual Terminal instances
var term1 = new Terminal(
{
id: 1,
x: 200,
y: 10,
cols: 80,
rows: 12,
greeting: "*** This is Terminal 1 ***",
handler: myTerminalHandler
}
);
term1.open();
var term2 = new Terminal(
{
id: 2,
x, 200,
y: 220,
cols: 80
rows: 12,
greeting: "*** This is Terminal 2 ***",
handler: myTerminalHandler
}
);
term2.open();
3 Using the Terminal
There are 4 different handlers that are called by a Terminal instance to process input and
some flags to control the input mode and behaviour.
3.1 The Default Handler (a simlple example for input handling)
If no handlers are defined in the configuration object, a default handler is called to
handle a line of user input. The default command line handler `defaultHandler' just
closes the command line with a new line and echos the input back to the user:
function termDefaultHandler() {
this.newLine();
if (this.lineBuffer != '') {
this.type('You typed: '+this.lineBuffer);
this.newLine();
}
this.prompt();
}
// Note: This used to be top level function. With version 1.4 `termDefaultHandler' became
// a reference to the method `Terminal.prototype.defaultHandler'.
First you may note that the instance is refered to as `this'. So you need not worry about
which Terminal instance is calling your handler. As the handler is entered, the terminal
is locked for user input and the cursor is off. The current input is available as a string
value in `this.lineBuffer'.
The method `type(<text>)' just does what it says and types a string at the current cursor
position to the terminal screen.
`newLine()' moves the cursor to a new line.
The method `prompt()' adds a new line if the cursor isn't at the start of a line, outputs
the prompt string (as specified in the configuration), activates the cursor, and unlocks
the terminal for further input. While you're doing normal command line processing, always
call `prompt()' when leaving your handler.
In fact this is all you need to create your own terminal application. Please see at least
the method `write()' for a more powerful output method.
Below we will refer to all methods of the Terminal object as `Terminal.<method>()'.
You can call them as `this.<method>()' in a handler or as methods of your named instance
in other context (e.g.: "myTerminal.close()").
[In technical terms these methods are methods of the Terminal's prototype object, while
the properties are properties of a Termninal instance. Since this doesn't make any
difference to your script, we'll refer to both as `Terminal.<method-or-property>'.]
3.2 Input Modes
3.2.1 Normal Line Input (Command Line Mode)
By default the terminal is in normal input mode. Any printable characters in the range of
ASCII 0x20 - 0xff are echoed to the terminal and may be edited with the use of the cursor
keys and the <BACKSPACE> key.
The cursor keys UP and DOWN let the user browse in the command line history (the list of
all commands issued previously in this Terminal instance).
If the user presses <CR> or <ENTER>, the line is read from the terminal buffer, converted
to a string, and placed in `Terminal.lineBuffer' (-> `this.lineBuffer') for further use.
The terminal is then locked for further input and the specified handler
(`Terminal.handler') is called.
3.2.1.2 Special Keys (ctrlHandler)
If a special character (ASCII<0x20) or an according combination of <CTRL> and a key is
pressed, which is not caught for editing or "enter", and a handler for `ctrlHandler' is
specified, this handler is called.
The ASCII value of the special character is available in `Terminal.inputChar'. Please note
that the terminal is neither locked, nor is the cursor off - all further actions have to
be controlled by `ctrlHandler'. (The tracking of <CTRL>-<key> combinations as "^C" usually
works but cannot be taken for granted.)
A named reference of the special control values in POSIX form (as well as the values of
the cursor keys [LEFT, RIGHT, UP, DOWN]) is available in the `termKey' object.
Note:
With version 1.4 `termKey' is a reference to `Terminal.prototype.globals.termKey'.
This object is also mapped to `Terminal.prototype.termKey', so you may also access it as
"this.termKey" inside handlers.
p.e.:
// a simple ctrlHandler
function myCtrlHandler() {
if (this.inputChar == termKey.ETX) {
// exit on ^C (^C == ASCII 0x03 == <ETX>)
this.close();
}
}
If no `ctrlHandler' is specified, control keys are ignored (default).
3.2.2 Raw Mode
If the flag `Terminal.rawMode' is set to a value evaluating to `true', no special keys are
tracked but <CR> and <ENTER> (and <ESC>, if the flag `Terminal.closeOnESC' is set).
The input is NOT echoed to the terminal. All printable key values [0x20-0xff] are
transformed to characters and added to `Terminal.lineBuffer' sequentially. The command
line input is NOT added to the history.
This mode is especially suitable for password input.
p.e.:
// using raw mode for password input
function myTermHandler() {
this.newLine();
// we stored a flag in Terminal.env to track the status
if (this.env.getpassword) {
// leave raw mode
this.rawMode = false;
if (passwords[this.env.user] == this.lineBuffer) {
// matched
this.type('Welcome '+this.env.user);
this.env.loggedin = true;
}
else {
this.type('Sorry.');
}
this.env.getpassword = false;
}
else {
// simple parsing
var args = this.lineBuffer.split(' ');
var cmd = args[0];
if (cmd == 'login') {
var user = args[1];
if (!user) {
this.type('usage: login <username>');
}
else {
this.env.user = user;
this.env.getpassword = true;
this.type('password? ');
// enter raw mode
this.rawMode = true;
// leave without prompt so we must unlock first
this.lock = false;
return;
}
}
/*
other actions ...
*/
}
this.prompt();
}
In this example a handler is set up to process the command "login <username>" and ask for
a password for the given user name in raw mode. Note the use of the object `Terminal.env'
which is just an empty object set up at the creation of the Terminal instance. Its only
purpose is to provide an individual namespace for private data to be stored by a Terminal
instance.
NOTE: The flag `Terminal.lock' is used to control the keyboard locking. If we would not
set this to `false' before leaving in raw mode, we would be caught in dead-lock, since no
input could be entered and our handler wouldn't be called again. - A dreadful end of our
terminal session.
NOTE: Raw mode utilizes the property `Terminal.lastLine' to collect the input string.
This is normally emty, when a handler is called. This is not the case if your script left
the input process on a call of ctrlHandler. You should clear `Terminal.lastLine' in such
a case, if you're going to enter raw mode immediatly after this.
3.2.3 Character Mode
If the flag `Terminal.charMode' is set to a value evaluating to `true', the terminal is in
character mode. In this mode the numeric ASCII value of the next key typed is stored in
`Terminal.inputChar'. The input is NOT echoed to the terminal. NO locking or cursor
control is performed and left to the handler.
You can use this mode to implement your editor or a console game.
`Terminal.charMode' takes precedence over `Terminal.rawMode'.
p.e.:
// using char mode
function myTermHandler() {
// this is the normal handler
this.newLine();
// simple parsing
var args = this.lineBuffer.split(' ');
var cmd = args[0];
if (cmd == 'edit') {
// init the editor
myEditor(this);
// redirect the handler to editor
this.handler = myEditor;
// leave in char mode
this.charMode = true;
// show cursor
this.cursorOn();
// don't forget unlocking
this.lock = false;
return;
}
/*
other actions ...
*/
this.prompt();
}
function myEditor(initterm) {
// our dummy editor (featuring modal behaviour)
if (initterm) {
// perform initialization tasks
initterm.clear();
initterm.write('this is a simple test editor; leave with <ESC> then "q"%n%n');
initterm.env.mode = '';
// store a reference of the calling handler
initterm.env.handler = initterm.handler;
return;
}
// called as handler -> lock first
this.lock=true;
// hide cursor
this.cursorOff();
var key = this.inputChar;
if (this.env.mode == 'ctrl') {
// control mode
if (key == 113) {
// "q" => quit
// leave charMode and reset the handler to normal
this.charMode = false;
this.handler = this.env.handler;
// clear the screen
this.clear();
// prompt and return
this.prompt();
return;
}
else {
// leave control mode
this.env.mode = '';
}
}
else {
// edit mode
if (key == termKey.ESC) {
// enter control mode
// we'd better indicate this in a status line ...
this.env.mode = 'ctrl';
}
else if (key == termKey.LEFT) {
// cursor left
}
else if (key == termKey.RIGHT) {
// cursor right
}
if (key == termKey.UP) {
// cursor up
}
else if (key == termKey.DOWN) {
// cursor down
}
else if (key == termKey.CR) {
// cr or enter
}
else if (key == termKey.BS) {
// backspace
}
else if (key == termKey.DEL) {
// fwd delete
// conf.DELisBS is not evaluated in charMode!
}
else if (this.isPrintable(key)) {
// printable char - just type it
var ch = String.fromCharCode(key);
this.type(ch);
}
}
// leave unlocked with cursor
this.lock = false;
this.cursorOn();
}
Note the redirecting of the input handler to replace the command line handler by the
editor. The method `Terminal.clear()' clears the terminal.
`Terminal.cursorOn()' and `Terminal.cursorOff()' are used to show and hide the cursor.
3.3 Other Handlers
There are two more handlers that can be specified in the configuration object:
3.3.1 initHandler
`initHandler' is called at the end of the initialization triggered by `Terminal.open()'.
The default action - if no `initHandler' is specified - is:
// default initilization
this.write(this.conf.greeting);
this.newLine();
this.prompt();
Use `initHandler' to perform your own start up tasks (e.g. show a start up screen). Keep
in mind that you should unlock the terminal and possibly show a cursor to give the
impression of a usable terminal.
3.3.2 exitHandler
`exitHandler' is called by `Terminal.close()' just before hiding the terminal. You can use
this handler to implement any tasks to be performed on exit. Note that this handler is
called even if the terminal is closed on <ESC> outside of your inputHandlers control.
See the file "multiterm_test.html" for an example.
3.4 Overview: Flags for Behaviour Control
These falgs are accessible as `Terminal.<flag>' at runtime. If not stated else, the
initial value may be specified in the configuration object.
The configuration object and its properties are accessible at runtime via `Terminal.conf'.
NAME DEFAULT VALUE MEANING
blink_delay 500 delay for cursor blinking in milliseconds.
crsrBlinkMode false true for blinking cursor.
if false, cursor is static.
crsrBlockMode true true for block-cursor else underscore.
DELisBS false handle <DEL> as <BACKSPACE>.
printTab true handle <TAB> as printable (prints as space)
if false <TAB> is handled as a control character
printEuro true handle the euro sign as valid input char.
if false char 0x20AC is printed, but not accepted
in the command line
catchCtrlH true handle ^H as <BACKSPACE>.
if false, ^H must be tracked by a custom
ctrlHandler.
closeOnESC true close terminal on <ESC>.
if true, <ESC> is not available for ctrHandler.
historyUnique false unique history entries.
if true, entries that are identical to the last
entry in the user history will not be added.
charMode false terminal in character mode (tracks next key-code).
(runtime only)
rawMode false terminal in raw mode (no echo, no editing).
(runtime only)
wrapping false text wrapping on/off
mapANSI false filter ANSI escape sequences and apply SGR styles
and color codes for write()
ANSItrueBlack false force output of ANSI code 30m (black) as black
(default: render color 0 as foreground color)
Not exactly a flag but useful:
ps '>' prompt string.
4 Output Methods
Please note that any output to the terminal implies an advance of the cursor. This means,
that if your output reaches the last column of your terminal, the cursor is advanced and
a new line is opened automatically. This procedure may include scrolling to make room for
the new line. While this is not of much interest for most purposes, please note that, if
you output a string of length 80 to a 80-columns-terminal, and a new line, and another
string, this will result in an empty line between the two strings.
4.1 Terminal.type( <text> [,<stylevector>] )
Types the string <text> at the current cursor position to the terminal. Long lines are
broken where the last column of the terminal is reached and continued in the next line.
`Terminal.write()' does not support any kind of arbitrary line breaks. (This is just a
basic output routine. See `Terminal.write()' for a more powerful output method.)
A bitvector may be supplied as an optional second argument to represent a style or a
combination of styles. The meanings of the bits set are interpreted as follows:
<stylevector>:
1 ... reverse (2 power 0)
2 ... underline (2 power 1)
4 ... italics (2 power 2)
8 ... strike (2 power 3)
16 ... bold (2 power 4) *displayed as italics, used internally for ANSI-mapping*
So "Terminal.type( 'text', 5 )" types "text" in italics and reverse video.
Note:
There is no bold, for most monospaced fonts (including Courier) tend to render wider in
bold. Since this would bring the terminal's layout out of balance, we just can't use bold
as a style. - Sorry.
The HTML-representation of this styles are defined in "TermGlobals.termStyleOpen" and
"TermGlobals.termStyleClose".
(Version 1.4: "TermGlobals" is now a reference to "Terminal.prototype.globals".)
Version 1.2 introduces additional styles for colors.
Please read also sect. 4.10 "Using Color" for the extended color values.
4.2 Terminal.write( <text> [,<usemore>] )
Writes a text with markup to the terminal. If an optional second argument evaluates to
true, a UN*X-style utility like `more' is used to page the text. The text may be supplied
as a single string (with newline character "\n") or as an array of lines. Any other input
is transformed to a string value before output.
4.2.1 Mark-up:
`Terminal.write()' employs a simple mark-up with the following syntax:
<markup>: %((+|-)<style>|n|CS|%)
where "+" and '-' are used to switch on and off a style, where
<style>:
"i" ... italics
"r" ... reverse
"s" ... strike
"u" ... underline
"p" ... reset to plain ("%+p" == "%-p")
styles may be combined and may overlap. (e.g. "This is %+rREVERSE%-r, %+uUNDER%+iSCORE%-u%-i.")
"%n" represents a new line (in fact "\n" is translated to "%n" before processing)
"%CS" clears the terminal screen
"%%" represents the percent character ('%')
Version 1.2 introduces an additional syntax for colors:
<color-style> ::= %c(<value>|"("<color-label>")")
Please read also sect. 4.10 "Using Color" for the extended color syntax.
Version 1.51 introduces the mapping of ANSI escape sequences. To use this option you must supply
the flag `mapANSI' with a true value in the config-object or set `this.mapANSI' to `true' at run-
time. Currently supported are SGR codes foreground colors and type styles. Other sequences are
just filtered out. See section 4.12 "ANSI Support" for more.
4.2.2 Buffering:
`Terminal.write()' writes via buffered output to the terminal. This means that the
provided text is rendered to a buffer first and then only the visible parts are transfered
to the terminal display buffers. This avoids scrolling delays for long output.
4.2.3 UseMore Mode:
The buffering of `Terminal.write()' allows for pagewise output, which may be specified by
a second boolean argument. If <usemore> evaluates to `true' and the output exceeds the
range of empty rows on the terminal screen, `Terminal.write()' performs like the UN*X
utility `more'. The next page may be accessed by hitting <SPACE> while <q> terminates
paging and returns with the prompt (-> `Terminal.prompt()').
To use this facillity make sure to return immediatly after calling `Terminal.write()' in
order to allow the more-routine to track the user input.
The terminal is set to "charMode == false" afterwards.
p.e.:
// using Terminal.write as a pager
function myTermHandler() {
this.newLine();
var args = this.lineBuffer.split(' ');
var cmd = args[0];
if (cmd == 'more') {
var page = args[1];
if (myPages[page]) {
// Terminal.write as a pager
this.write(myPages[page], true);
return;
}
else {
// Terminal.write for simple output
this.write('no such page.');
}
}
/*
other actions ...
*/
this.prompt();
}
4.2.4 Text Wrap
Starting with version 1.3 "termlib.js" supports automatic text wrapping with
`Terminal.write()'. (Text wrapping is off by default.)
Use `Terminal.wrapOn()' to enable wrapping, use `Terminal.wrapOff()' to turn it off again.
Use the property "wrapping" of the configuration object to turn wrapping globaly on.
For details see sect. 4.11 "Text Wrap - Terminal.wrapOn(), Terminal.wrapOff()"
4.3 Terminal.typeAt( <r>, <c>, <text> [,<stylevector>] )
Output the string <text> at row <r>, col <c>.
For <stylevector> see `Terminal.type()'.
`Terminal.typeAt()' does not move the cursor.
4.4 Terminal.setChar( <charcode>, <r>, <c> [,<stylevector>] )
Output a single character represented by the ASCII value of <charcode> at row <r>, col <c>.
For <stylevector> see `Terminal.type()'.
4.5 Terminal.newLine()
Moves the cursor to the first column of the next line and performs scrolling, if needed.
4.6 Terminal.clear()
Clears the terminal screen. (Returns with cursor off.)
4.7 Terminal.statusLine( <text> [,<stylevector> [,<lineoffset>]] )
All output acts on a logical screen with the origin at row 0 / col 0. While the origin is
fixed, the logical width and height of the terminal are defined by `Terminal.maxCols' and
`Terminal.maxLines'. These are set to the configuration dimensions at initilization and by
`Terminal.reset()', but may be altered at any moment. Please note that there are no bounds
checked, so make sure that `Terminal.maxCols' and `Terminal.maxLines' are less or equal
to the configuration dimensions.
You may want to decrement `Terminal.maxLines' to keep space for a reserved status line.
`Terminal.statusLine( <text>, <style> )' offers a simple way to type a text to the last
line of the screen as defined by the configuration dimensions.
// using statusLine()
function myHandler() {
// ...
// reserve last line
this.maxLines = term.conf.rows-1;
// print to status line in reverse video
this.statusLine("Status: <none>", 1);
// ...
}
For multiple status lines the optional argument <lineoffset> specifies the addressed row,
where 1 is the line closest to the bottom, 2 the second line from the bottom and so on.
(default: 1)
4.8 Terminal.printRowFromString( <r> , <text> [,<stylevector>] )
Outputs the string <text> to row <r> in the style of an optional <stylevector>.
If the string's length exceeds the length of the row (up to `Terminal.conf.cols'), extra
characteres are ignored, else any extra space is filled with character code 0 (prints as
<SPACE>).
The valid range for <row> is: 0 >= <row> < `Terminal.maxLines'.
`Terminal.printRowFromString()' does not set the cursor.
You could, for example, use this method to output a line of a text editor's buffer.
p.e.:
// page refresh function of a text editor
function myEditorRefresh(termref, topline) {
// termref: reference to Terminal instance
// topline: index of first line to print
// lines of text are stored in termref.env.lines
for (var r=0; r<termref.maxLines; r++) {
var i = topline + r;
if (i < termref.env.lines.length) {
// output stored line
termref.printRowFromString(r, termref.env.lines[i]);
}
else {
// output <tilde> for empty line
termref.printRowFromString(r, '~');
}
}
// set cursor to origin
termref.r = termref.c = 0; // same as termref.cursorSet(0, 0);
}
4.9 Terminal.redraw( <row> )
Basic function to redraw a terminal row <row> according to screen buffer values.
For hackers only. (e.g.: for a console game, hack screen buffers first and redraw all
changed rows at once.)
4.10 Using Color
With version 1.2 termlib.js introduces support for colors.
Colors are controlled using the styles interface of the type() and write() methods.
Usage:
As any style settings colors are controlled by the "%<style>" markup of the write() method,
where <style> starts with a "c" for "color".
"termlib.js" supports 3 different color systems:
1) The first approach mimics the ANSI color approach as known from most terminals:
There is a set of 16 colors (1 default color and 15 configurable colors):
color name code color string synonyms
----------------------------------------------------------------
default 0 *empty* clear, ""
black 1 #000000
red 2 #ff0000 red1
green 3 #00ff00 green1
yellow 4 #ffff00 yellow1
blue 5 #0066ff blue1
magenta 6 #ff00ff magenta1
cyan 7 #00ffff cyan1
white 8 #ffffff
grey 9 #808080 gray
darkred A #990000 red2
darkgreen B #009900 green2
darkyellow C #999900 yellow2
darkblue D #003399 blue2
darkmagenta E #990099 magenta2
darkcyan F #009999 cyan2
"default" or "clear" refers always to the configured default color.
Code values from "A" to "F" (may be lower case) indicate hex values from 10 to 15.
You may change the color string using the method
`TermGlobals.setColor( <label>, <colorstring> )', where <label> is the name or code
of a color and <colorstring> a valid CSS color value.
Examples:
// changing the color string used for "red"
TermGlobals.setColor( "red", "#880000" );
TermGlobals.setColor( "2", "#880000" );
TermGlobals.setColor( 2, "#880000" );
// changing darkred
TermGlobals.setColor( "darkred", "#440000" );
TermGlobals.setColor( "A", "#440000" );
TermGlobals.setColor( 10, "#440000" );
You may also access the currently used color string using the method
`TermGlobals.getColorString( <label> )' or look up a color's code using
`TermGlobals.getColorCode( <label> )'.
Note on `TermGlobals' and version 1.4 or higher:
`TermGlobals' is now a reference to `Terminal.prototype.globals', so you may also use the
following inside a handler: "this.globals.setColor( 'red', '#880000' );".