Compare commits

...

5 Commits

Author SHA1 Message Date
b1ek b41f37efa7
wget can write to file 2023-03-17 16:09:14 +10:00
b1ek 34aaa678b1
Ctrl+backspace, register clipboard 2023-03-17 16:08:49 +10:00
b1ek 747b94f103
clipboard support 2023-03-17 16:08:13 +10:00
b1ek 1e90b97973
fix eof not detected (resume) 2023-03-16 17:31:37 +10:00
b1ek 89acd8a4a6
cat dont throw exception on file not found 2023-03-16 17:17:11 +10:00
6 changed files with 111 additions and 25 deletions

View File

@ -20,6 +20,7 @@
},
"dependencies": {
"@parcel/fs": "^2.8.3",
"copy-to-clipboard": "^3.3.3",
"memfs": "^3.4.13",
"react": "^18.2.0",
"react-dom": "^18.2.0",

View File

@ -19,6 +19,10 @@ module.exports = (argv, terminal) => {
let files = argv.filter(x => { return !x.startsWith('-') });
files.shift();
files.forEach(file => {
if (!fs.existsSync(file)) {
terminal.writeln(`${argv[0]}: ${file}: no such file or directory`);
return;
}
const lines = fs.readFileSync(file).toString().split('\n');
if (numbers) {

View File

@ -26,8 +26,7 @@ Usage: ${argv[0]} [URL] [-O out.file] [-V] [-Q] [-s]
terminal.writeln(`${argv[0]}: missing output file`);
return;
}
filepath = argv[argv.indexOf('-O') + 1]
return;
filepath = argv[argv.indexOf('-O') + 1];
}
function progress(p) {
@ -35,11 +34,15 @@ Usage: ${argv[0]} [URL] [-O out.file] [-V] [-Q] [-s]
if (total == 0)
total = '?'
terminal.write(`\rDownloading... ${p.loaded}/${total}`);
// terminal.write(`\rDownloading... ${p.loaded}/${total}`);
}
function write(file) {
if (filepath == '-') {
terminal.write(file);
} else {
fs.writeFileSync(filepath, file);
}
}
let file;
@ -50,8 +53,7 @@ Usage: ${argv[0]} [URL] [-O out.file] [-V] [-Q] [-s]
req.onprogress = progress;
req.onload = (e) => {
if (e.type == 'load') {
let enc = new TextDecoder("utf-8");
terminal.write(enc.decode(req.response));
write(e.response);
}
};
req.send();

View File

@ -3,7 +3,9 @@ module.exports = (dom) => {
terminal.writeln('Welcome to my online resume!')
terminal.writeln('Type \033[1;32mhelp\033[0m for list of commands')
terminal.writeln('Use \033[1;33mAlt+C/V\033[0m to copy or paste');
terminal.writeln('');
require('./zsh')(terminal, dom);
require('./pastebuffer')(terminal, dom);
}

View File

@ -0,0 +1,37 @@
import { Terminal } from "xterm"
import copy from 'copy-to-clipboard';
/** @type { Terminal } */
let terminal;
const zsh = require('./zsh');
/**
*
* @param {{ key: string, domEvent: KeyboardEvent }} e
*/
async function keyHandler(e) {
const dom = e.domEvent;
if (!dom.altKey)
return;
if (dom.key.length != 1)
return;
switch (dom.key.toLowerCase()) {
case 'c':
if (!terminal.hasSelection()) break;
copy(terminal.getSelection())
break;
case 'v':
zsh.pr_char(prompt("Paste your text:"), {key: 'a'})
}
}
module.exports = (t, d) => {
terminal = t;
terminal.onKey(keyHandler);
}

View File

@ -7,7 +7,7 @@ global.fs = fs;
const cmds = require('./commands');
/**
* @type {Terminal}
* @type { Terminal }
*/
let terminal;
@ -24,7 +24,14 @@ function text_prompt() {
return prompt.replace(/[\u001b\u009b][[()#;?]*(?:[0-9]{1,4}(?:;[0-9]{0,4})*)?[0-9A-ORZcf-nqry=><]/g, '');
}
function pr_char(char) {
/**
*
* @param { string } char
* @param { KeyboardEvent } dom
*/
function pr_char(char, dom) {
if (dom.key.length != 1) return;
cmd += char;
terminal.write(char);
}
@ -47,7 +54,7 @@ function exec_file(f) {
return;
}
function exec_cmd() {
async function exec_cmd() {
let c = cmd;
const command = c.split(' ')[0];
reset_cmd(c);
@ -68,8 +75,13 @@ function exec_cmd() {
}
if (cmds[command] != undefined) {
cmds[command](c.split(' '), terminal);
if (terminal.buffer.active.cursorX != 0) {
const startY = terminal.buffer.normal.cursorY
await cmds[command](c.split(' '), terminal);
await (new Promise(resolve => setTimeout(resolve, 10)));
if (terminal.buffer.active.cursorX != 0 && startY != terminal.buffer.active.cursorY) {
terminal.write('\033[30;47m%\033[0m\n');
}
print_prompt();
@ -94,20 +106,41 @@ function reset_cmd() {
terminal.writeln('');
}
function cbackspace() {
let exploded = cmd.split(' ');
if (exploded.length >= 1) {
reprint_prompt();
cmd = '';
return;
}
exploded.pop();
cmd = exploded.join(' ') + ' ';
reprint_prompt();
terminal.write(cmd);
return;
}
function backspace(isCtrl) {
if (terminal.buffer.active.cursorX <= text_prompt().length) return;
if (isCtrl) {
return cbackspace();
}
terminal.write('\b \b');
cmd = cmd.substring(0, cmd.length - 1);
}
/** @param { KeyboardEvent } dom */
function control_char(id, dom) {
const backspace = () => {
if (terminal.buffer.active.cursorX <= text_prompt().length) return;
terminal.write('\b \b');
cmd = cmd.substring(0, cmd.length - 1);
}
switch (id) {
// backspace
case 8:
backspace();
backspace(dom.ctrlKey);
break;
// enter
@ -131,12 +164,15 @@ function control_char(id, dom) {
break;
}
case 37:
backspace();
break;
case 86:
if (dom.altKey) break;
default:
if (dom.ctrlKey && (dom.key.length == 1)) {
terminal.write('^' + dom.key.toUpperCase());
break;
}
terminal.write('<');
if (dom.ctrlKey) terminal.write('C');
if (dom.altKey) terminal.write('A');
@ -150,16 +186,20 @@ function key(e) {
/** @type {KeyboardEvent} */
const dom = e.domEvent;
if (dom.key.length == 1 && !(dom.ctrlKey || dom.altKey)) {
pr_char(e.domEvent.key);
pr_char(e.domEvent.key, dom);
} else {
control_char(e.domEvent.keyCode, dom)
}
}
module.exports = (t, d) => {
function register(t, d) {
terminal = t;
dom = d;
terminal.onKey(key);
terminal.write(prompt);
}
register.pr_char = pr_char;
module.exports = register;