11//script.js
22import { Terminal } from '@xterm/xterm' ;
33import { FitAddon } from '@xterm/addon-fit' ;
4+ import { WebLinksAddon } from 'xterm-addon-web-links' ;
45import '@xterm/xterm/css/xterm.css' ;
56
7+ // Custom beep function using Web Audio API
8+ function squareBeep ( freq = 440 , duration = 0.1 ) {
9+ const audioCtx = new ( window . AudioContext || window . webkitAudioContext ) ( ) ;
10+ const oscillator = audioCtx . createOscillator ( ) ;
11+ const gainNode = audioCtx . createGain ( ) ;
12+
13+ oscillator . type = 'square' ;
14+ oscillator . frequency . value = freq ; // in Hz
15+
16+ oscillator . connect ( gainNode ) ;
17+ gainNode . connect ( audioCtx . destination ) ;
18+
19+ oscillator . start ( ) ;
20+ oscillator . stop ( audioCtx . currentTime + duration ) ;
21+ }
22+
23+ // ANSI color codes for terminal formatting
24+ const colors = {
25+ reset : '\x1B[0m' ,
26+ bold : '\x1B[1m' ,
27+ italic : '\x1B[3m' ,
28+ green : '\x1B[1;32m' ,
29+ blue : '\x1B[1;34m' ,
30+ yellow : '\x1B[1;33m' ,
31+ red : '\x1B[1;3;31m'
32+ } ;
33+
634var term = new Terminal ( ) ;
735term . open ( document . getElementById ( 'terminal' ) ) ;
836
37+ // Fit terminal to container
938let fitAddon = new FitAddon ( ) ;
1039term . loadAddon ( fitAddon ) ;
1140fitAddon . fit ( ) ;
12-
13- // Resize the terminal when the window resizes
1441window . addEventListener ( 'resize' , ( ) => {
1542 fitAddon . fit ( ) ;
1643} ) ;
1744
45+ term . open ( document . getElementById ( 'terminal' ) ) ;
46+ term . loadAddon ( new WebLinksAddon ( ) ) ;
47+
48+
49+
1850let currentInput = '' ;
1951let currentLine = '' ;
2052let cursorPosition = 0 ;
2153
2254// Available commands
55+
56+ // --- Virtual File System ---
57+ let vfs = { } ;
58+ const VFS_KEY = 'miaoshell-vfs' ;
59+
60+ function loadVFS ( ) {
61+ try {
62+ const data = localStorage . getItem ( VFS_KEY ) ;
63+ if ( data ) vfs = JSON . parse ( data ) ;
64+ else vfs = { } ;
65+ } catch ( e ) {
66+ vfs = { } ;
67+ }
68+ }
69+
70+ function saveVFS ( ) {
71+ localStorage . setItem ( VFS_KEY , JSON . stringify ( vfs ) ) ;
72+ }
73+
74+ // Load VFS on startup
75+ loadVFS ( ) ;
76+
2377const commands = {
2478 help : ( ) => {
2579 term . writeln ( '\r\nAvailable commands:' ) ;
2680 term . writeln ( ' help - Show this help message' ) ;
2781 term . writeln ( ' clear - Clear the terminal' ) ;
2882 term . writeln ( ' echo - Echo back your message' ) ;
29- term . writeln ( ' date - Show current date and time' )
83+ term . writeln ( ' date - Show current date and time' ) ;
84+ term . writeln ( ' beep - Make a beep sound' ) ;
85+ term . writeln ( ' ls - List files in the virtual file system' ) ;
86+ term . writeln ( ' cat - Show file contents: cat filename' ) ;
87+ term . writeln ( ' write - Write to a file: write filename content' ) ;
88+ term . writeln ( ' rm - Remove a file: rm filename' ) ;
89+ term . writeln ( ' save - Save VFS to browser storage' ) ;
90+ term . writeln ( ' load - Load VFS from browser storage' ) ;
91+ term . writeln ( ' about - About this terminal' ) ;
3092 } ,
3193 clear : ( ) => {
32- term . clear ( ) ;
94+ setTimeout ( ( ) => {
95+ term . clear ( ) ;
96+ } , 0 ) ;
3397 } ,
3498 echo : ( args ) => {
3599 term . writeln ( '\r\n' + args . join ( ' ' ) ) ;
36100 } ,
37101 date : ( ) => {
38102 term . writeln ( '\r\n' + new Date ( ) . toString ( ) ) ;
103+ } ,
104+ beep : ( ) => {
105+ squareBeep ( ) ;
106+ term . writeln ( '\r\n🔊 Beep!' ) ;
107+ } ,
108+ ls : ( ) => {
109+ const files = Object . keys ( vfs ) ;
110+ if ( files . length === 0 ) term . writeln ( '\r\n(no files)' ) ;
111+ else term . writeln ( '\r\n' + files . join ( ' ' ) ) ;
112+ } ,
113+ cat : ( args ) => {
114+ if ( ! args [ 0 ] ) {
115+ term . writeln ( '\r\nUsage: cat filename' ) ;
116+ return ;
117+ }
118+ const file = args [ 0 ] ;
119+ if ( vfs [ file ] !== undefined ) {
120+ term . writeln ( '\r\n' + vfs [ file ] ) ;
121+ } else {
122+ term . writeln ( `\r\nFile not found: ${ file } ` ) ;
123+ }
124+ } ,
125+ write : ( args ) => {
126+ if ( ! args [ 0 ] ) {
127+ term . writeln ( '\r\nUsage: write filename content' ) ;
128+ return ;
129+ }
130+ const file = args [ 0 ] ;
131+ const content = args . slice ( 1 ) . join ( ' ' ) ;
132+ vfs [ file ] = content ;
133+ term . writeln ( `\r\nWrote to ${ file } ` ) ;
134+ } ,
135+ rm : ( args ) => {
136+ if ( ! args [ 0 ] ) {
137+ term . writeln ( '\r\nUsage: rm filename' ) ;
138+ return ;
139+ }
140+ const file = args [ 0 ] ;
141+ if ( vfs [ file ] !== undefined ) {
142+ delete vfs [ file ] ;
143+ term . writeln ( `\r\nDeleted ${ file } ` ) ;
144+ } else {
145+ term . writeln ( `\r\nFile not found: ${ file } ` ) ;
146+ }
147+ } ,
148+ save : ( ) => {
149+ saveVFS ( ) ;
150+ term . writeln ( '\r\nVFS saved to browser storage.' ) ;
151+ } ,
152+ load : ( ) => {
153+ loadVFS ( ) ;
154+ term . writeln ( '\r\nVFS loaded from browser storage.' ) ;
155+ } ,
156+ about : ( ) => {
157+ term . writeln ( '\r\n' + colors . bold + 'MiaoShell' + colors . reset + ' - A Useless Terminal' ) ;
158+ term . writeln ( 'Version: 1.0.0' ) ;
159+ term . writeln ( 'https://github.com/daniel4-scratch/xtermtest' ) ;
39160 }
40161} ;
41162
@@ -57,7 +178,7 @@ function executeCommand(input) {
57178}
58179
59180function prompt ( ) {
60- term . write ( ' \r\n\x1B[1;32muser@xterm-demo\x1B[0m:\x1B[1;34m~\x1B[0m$ ' ) ;
181+ term . write ( ` \r\n${ colors . green } user@miaoshell ${ colors . reset } : ${ colors . blue } ~ ${ colors . reset } $ ` ) ;
61182}
62183
63184// Handle user input
@@ -76,10 +197,28 @@ term.onData(data => {
76197 } else if ( code >= 32 ) { // Printable characters
77198 currentInput += data ;
78199 term . write ( data ) ;
200+ } else if ( code === 27 ) { // Escape key
201+ // Handle escape sequences if needed
79202 }
80203} ) ;
81204
82- // Initialize terminal
83- term . writeln ( 'Welcome to \x1B[1;3;31mXterm.js\x1B[0m Terminal Demo!' ) ;
84- term . writeln ( 'Type \x1B[1;33mhelp\x1B[0m to see available commands.' ) ;
85- prompt ( ) ;
205+ async function init ( ) {
206+ // Initialize terminal
207+ //print ./assets/miao.txt
208+ await fetch ( './assets/miao.txt' )
209+ . then ( response => response . text ( ) )
210+ . then ( text => {
211+ text . split ( / \r ? \n / ) . forEach ( line => term . writeln ( line ) ) ;
212+ } )
213+ . catch ( error => {
214+ term . writeln ( 'Error loading file: ' + error ) ;
215+ } ) ;
216+ term . writeln ( `Welcome to ${ colors . red } MiaoShell${ colors . reset } - A Useless Terminal!` ) ;
217+ term . writeln ( `Type ${ colors . yellow } help${ colors . reset } to see available commands.` ) ;
218+ prompt ( ) ;
219+ } ;
220+
221+ init ( ) . catch ( err => {
222+ console . error ( 'Error initializing terminal:' , err ) ;
223+ term . writeln ( 'Error initializing terminal. Check console for details.' ) ;
224+ } ) ;
0 commit comments