1let display_pwd = "~" 2let home_direcotry = "/home/Tess" 3let real_pwd = "/home/Tess" 4let currentShellEntry = "" 5let inCommand = false 6let commandBuffer = [] 7let lastResult = true; 8 9 10let commands = { 11 "cd": cdCommand, 12 "help": helpCommand, 13 "clear": clearCommand, 14 "ls": lsCommand, 15 "rm": rmCommand, 16 "pwd": pwdCommand 17} 18 19 20onmessage = (e) => { 21 let key = e.data.key; 22 let cols = e.data.cols - 2; 23 let os = e.data.os; 24 let version = e.data.version; 25 26 if (!inCommand) { 27 if (key == "\r") { 28 if (currentShellEntry.trim() != "") { 29 let command = currentShellEntry.split(" ")[0]; 30 let args = currentShellEntry.split(" "); 31 args.shift(); 32 currentShellEntry = ""; 33 inCommand = true; 34 35 postMessage("\r\n\x1b[0m"); 36 37 executeCommand(command, args).then(() => { 38 postMessage("\r\n\x1b[1m\x1b[36mTess\x1b[0m\x1b[2m at \x1b[0m\x1b[1m\x1b[32m" + display_pwd +"\x1b[0m\x1b[2m on \x1b[0m" + os + "\x1b[0m\x1b[2m with \x1b[0m\x1b[1m\x1b[91mv" + version + "\n\r\x1b[1m\x1b[32m⯠") 39 lastResult = true; 40 }).catch(() => { 41 postMessage("\r\n\x1b[1m\x1b[36mTess\x1b[0m\x1b[2m at \x1b[0m\x1b[1m\x1b[32m" + display_pwd + "\x1b[0m\x1b[2m on \x1b[0m" + os + "\x1b[0m\x1b[2m with \x1b[0m\x1b[1m\x1b[91mv" + version + "\n\r\x1b[1m\x1b[31m⯠") 42 lastResult = false;
43 }).finally(() => { 44 inCommand = false; 45 }) 46 } else { 47 let colorCode = lastResult ? "\x1b[32m" : "\x1b[31m" 48 postMessage("\r\n\n\x1b[1m\x1b[36mTess\x1b[0m\x1b[2m at \x1b[0m\x1b[1m\x1b[32m" + display_pwd +"\x1b[0m\x1b[2m on \x1b[0m" + os + "\x1b[0m\x1b[2m with \x1b[0m\x1b[1m\x1b[91mv" + version + "\n\r\x1b[1m" + colorCode + "⯠") 49 } 50 } else { 51 if (key == "\x7F") { 52 currentShellEntry = currentShellEntry.slice(0, -1) 53 } else if (key == " " || !encodeURI(key).startsWith("%")) { 54 currentShellEntry += key 55 } 56 57 let command = currentShellEntry.split(" ")[0] 58 let args = currentShellEntry.split(" ") 59 args.shift(); 60 61 let argsString; 62 if (args.length == 0) { 63 argsString = "" 64 } else { 65 argsString = " " + args.join(" "); 66 } 67 68 let colorCode = lastResult ? "\x1b[32m" : "\x1b[31m" 69 70 postMessage("\r\x1b[1m" + colorCode + "⯠" + "\x1b[0m\x1b[1m" + command + "\x1b[0m" + argsString + " ".repeat(cols - currentShellEntry.length) + "\x1B[D".repeat(cols - currentShellEntry.length - 1)) 71 } 72 } else { 73 commandBuffer.push(key) 74 } 75} 76 77 78function executeCommand(command, args) { 79 return new Promise((resolve, reject) => { 80 let commandFunction = commands[command]; 81 if (commandFunction != undefined) { 82 commandFunction(args).then(() => { 83 resolve() 84 }).catch(() => { 85 reject() 86 }) 87 } else { 88 postMessage("Unknown command: " + command + "\r\n") 89 reject() 90 } 91 }) 92} 93 94function cdCommand(args) { 95 return new Promise((resolve, reject) => { 96 if (args[0] == undefined) { 97 postMessage("Missing path\r\n") 98 reject() 99 } else { 100 if (args[0] == "~") { 101 display_pwd = args[0]; 102 real_pwd = "/home/Tess"; 103 resolve(); 104 } else if ((args[0] == ".." || args[0] == "../")) { 105 let tmp = real_pwd.split("").reverse() 106 107 let i = 1; 108 for (const c of tmp) { 109 if (c != "/") { 110 i++; 111 } else { 112 break; 113 } 114 } 115 116 display_pwd = tmp.reverse().slice(0, -i).join(""); 117 if (display_pwd == "") { 118 display_pwd = "/"; 119 } 120 121 real_pwd = display_pwd; 122 123 resolve(); 124 } else { 125 if (!args[0].startsWith("/") && !args[0].startsWith("./") ) { 126 args[0] = "./" + args[0]; 127 } 128 129 if (args[0].match(/^\/|\/\/|(\/[\w-]+)+$/)) { 130 if (args[0].startsWith("/")) { 131 display_pwd = args[0]; 132 real_pwd = args[0] 133 resolve(); 134 } else if (args[0].startsWith("./")) { 135 if (real_pwd.endsWith("/")) { 136 real_pwd += args[0].split("").slice(2).join("");; 137 } else { 138 real_pwd += "/" + args[0].split("").slice(2).join("");; 139 } 140 141 display_pwd = real_pwd; 142 resolve(); 143 } else { 144 postMessage("Invalid path\r\n") 145 reject(); 146 } 147 } else { 148 postMessage("Invalid path\r\n") 149 reject(); 150 } 151 } 152 153 154 155 } 156 }) 157} 158 159 160function testCommand() { 161 return new Promise((resolve, _) => { 162 postMessage("enter somethings pls: ") 163 let i = 0; 164 165 setInterval(() => { 166 let tmp = commandBuffer.shift() 167 if (tmp != undefined) { 168 i++ 169 let key = tmp 170 postMessage(key) 171 } 172 173 if (i > 5 ) { 174 resolve() 175 } 176 }, 20) 177 }) 178} 179 180function helpCommand() { 181 return new Promise((resolve, _) => { 182 postMessage("Tess Demo Shell, inspired by https://starship.rs interfaces\n\r\n\x1b[1mCommands:\r\n\x1b[0m cd: change current dir\r\n help: show this help\r\n pwd: show current directory\r\n clear: clear the screen\r\n rm: delete a file\r\n"); 183 resolve(); 184 }) 185} 186 187function clearCommand() { 188 return new Promise((resolve, _) => { 189 postMessage("\x1bc"); 190 resolve(); 191 }) 192} 193 194function lsCommand() { 195 return new Promise((resolve, _) => { 196 let count = 0;
197 display_pwd.split().forEach((el) => { 198 count += el.charCodeAt(0); 199 }); 200 201 if (count % 2 == 0) { 202 postMessage("Looks like there is nothing to see here!\n"); 203 } else { 204 postMessage("This directory is empty\n"); 205 } 206 207 resolve(); 208 }) 209} 210 211function rmCommand(args) { 212 return new Promise((resolve, reject) => { 213 if (args[0] == "-rf" && args[1] == "/" && args[2] == "--no-preserve-root") { 214 postMessage("\x1b[33mDeleting the system root, you may lose all of your data. We are sorry for the inconvenience\n"); 215 resolve(); 216 } else { 217 postMessage("We are unable to delete this file\n"); 218 reject(); 219 } 220 221 }) 222} 223 224function pwdCommand() { 225 return new Promise((resolve, _) => { 226 postMessage(real_pwd + "\n"); 227 resolve(); 228 }) 229}
Line numbers count LF bytes from the start of the resource, as the search results do. Vendor segments are library code the classifier recognised; they are stored but not indexed. Bytes are shown as Latin1 characters, one per byte.