1- //script.js
1+ //script.js - main logic for miao shell
22import { Terminal } from '@xterm/xterm' ;
33import { FitAddon } from '@xterm/addon-fit' ;
44import { WebLinksAddon } from 'xterm-addon-web-links' ;
@@ -7,6 +7,7 @@ import '@xterm/xterm/css/xterm.css';
77
88import * as vfs from './commands/vfs.js' ; // Import all VFS commands
99import * as jsC from './commands/js.js' ; // Import JavaScript commands
10+ import * as curl from './commands/curl.js' ; // Import curl commands
1011
1112// ANSI color codes for terminal formatting
1213const colors = {
@@ -66,6 +67,8 @@ let currentLine = '';
6667let cursorPosition = 0 ;
6768let commandHistory = [ ] ;
6869let historyIndex = - 1 ;
70+ let undoStack = [ ] ;
71+ let redoStack = [ ] ;
6972
7073// Load VFS on startup
7174vfs . loadVFS ( ) ;
@@ -104,7 +107,7 @@ const commands = {
104107 term . writeln ( 'Version: 1.0.0' ) ;
105108 term . writeln ( 'https://github.com/daniel4-scratch/miaoshell' ) ;
106109 } ,
107- ...vfs . commands , ...jsC . commands
110+ ...vfs . commands , ...jsC . commands , ... curl . commands
108111} ;
109112
110113function executeCommand ( input ) {
@@ -153,12 +156,24 @@ function prompt() {
153156// Handle terminal input
154157term . onKey ( e => {
155158 const { key, domEvent } = e ;
159+
160+ // Save state for undo before any input-changing action
161+ function saveUndoState ( ) {
162+ undoStack . push ( { input : currentInput , cursor : cursorPosition } ) ;
163+ // Clear redo stack on new input
164+ redoStack = [ ] ;
165+ // Limit undo stack size
166+ if ( undoStack . length > 100 ) undoStack . shift ( ) ;
167+ }
168+
156169 if ( domEvent . key === 'Enter' ) {
170+ saveUndoState ( ) ;
157171 executeCommand ( currentInput ) ;
158172 currentInput = '' ;
159173 cursorPosition = 0 ; // Reset cursor position
160174 } else if ( domEvent . key === 'Backspace' ) {
161175 if ( currentInput . length > 0 && cursorPosition > 0 ) {
176+ saveUndoState ( ) ;
162177 // Remove character at cursor position
163178 currentInput = currentInput . slice ( 0 , cursorPosition - 1 ) + currentInput . slice ( cursorPosition ) ;
164179 cursorPosition -- ;
@@ -223,7 +238,42 @@ term.onKey(e => {
223238 cursorPosition = 0 ; // Reset cursor position
224239 }
225240 }
241+ } else if ( domEvent . ctrlKey && domEvent . key === 'z' ) {
242+ // Undo (Ctrl+Z)
243+ if ( undoStack . length > 0 ) {
244+ redoStack . push ( { input : currentInput , cursor : cursorPosition } ) ;
245+ const prev = undoStack . pop ( ) ;
246+ currentInput = prev . input ;
247+ cursorPosition = prev . cursor ;
248+ // Clear line and redraw
249+ term . write ( '\x1b[2K' ) ;
250+ term . write ( '\r' ) ;
251+ term . write ( '\x1b[1A' ) ;
252+ prompt ( ) ;
253+ term . write ( currentInput ) ;
254+ // Move cursor to correct position
255+ if ( cursorPosition < currentInput . length ) {
256+ term . write ( `\x1b[${ currentInput . length - cursorPosition } D` ) ;
257+ }
258+ }
259+ } else if ( domEvent . ctrlKey && domEvent . key === 'y' ) {
260+ // Redo (Ctrl+Y)
261+ if ( redoStack . length > 0 ) {
262+ undoStack . push ( { input : currentInput , cursor : cursorPosition } ) ;
263+ const next = redoStack . pop ( ) ;
264+ currentInput = next . input ;
265+ cursorPosition = next . cursor ;
266+ term . write ( '\x1b[2K' ) ;
267+ term . write ( '\r' ) ;
268+ term . write ( '\x1b[1A' ) ;
269+ prompt ( ) ;
270+ term . write ( currentInput ) ;
271+ if ( cursorPosition < currentInput . length ) {
272+ term . write ( `\x1b[${ currentInput . length - cursorPosition } D` ) ;
273+ }
274+ }
226275 } else if ( typeof key === 'string' && key . length === 1 ) {
276+ saveUndoState ( ) ;
227277 // Insert character at cursor position
228278 currentInput = currentInput . slice ( 0 , cursorPosition ) + key + currentInput . slice ( cursorPosition ) ;
229279
@@ -233,6 +283,29 @@ term.onKey(e => {
233283 cursorPosition ++ ; // Update cursor position
234284 }
235285} ) ;
286+ // Paste support: handle paste event and insert clipboard text at cursor position
287+ if ( term . textarea ) {
288+ term . textarea . addEventListener ( 'paste' , async ( event ) => {
289+ event . preventDefault ( ) ;
290+ let pasteText = '' ;
291+ if ( event . clipboardData ) {
292+ pasteText = event . clipboardData . getData ( 'text' ) ;
293+ } else if ( window . clipboardData ) {
294+ pasteText = window . clipboardData . getData ( 'Text' ) ;
295+ }
296+ if ( pasteText ) {
297+ // Save undo state before paste
298+ undoStack . push ( { input : currentInput , cursor : cursorPosition } ) ;
299+ redoStack = [ ] ;
300+ if ( undoStack . length > 100 ) undoStack . shift ( ) ;
301+
302+ // Insert pasted text at cursor position
303+ currentInput = currentInput . slice ( 0 , cursorPosition ) + pasteText + currentInput . slice ( cursorPosition ) ;
304+ term . write ( pasteText ) ;
305+ cursorPosition += pasteText . length ;
306+ }
307+ } ) ;
308+ }
236309
237310async function init ( ) {
238311 // Initialize terminal
0 commit comments