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": { "dependencies": {
"@parcel/fs": "^2.8.3", "@parcel/fs": "^2.8.3",
"copy-to-clipboard": "^3.3.3",
"memfs": "^3.4.13", "memfs": "^3.4.13",
"react": "^18.2.0", "react": "^18.2.0",
"react-dom": "^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('-') }); let files = argv.filter(x => { return !x.startsWith('-') });
files.shift(); files.shift();
files.forEach(file => { 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'); const lines = fs.readFileSync(file).toString().split('\n');
if (numbers) { 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`); terminal.writeln(`${argv[0]}: missing output file`);
return; return;
} }
filepath = argv[argv.indexOf('-O') + 1] filepath = argv[argv.indexOf('-O') + 1];
return;
} }
function progress(p) { function progress(p) {
@ -35,11 +34,15 @@ Usage: ${argv[0]} [URL] [-O out.file] [-V] [-Q] [-s]
if (total == 0) if (total == 0)
total = '?' total = '?'
terminal.write(`\rDownloading... ${p.loaded}/${total}`); // terminal.write(`\rDownloading... ${p.loaded}/${total}`);
} }
function write(file) { function write(file) {
if (filepath == '-') {
terminal.write(file);
} else {
fs.writeFileSync(filepath, file);
}
} }
let file; let file;
@ -50,8 +53,7 @@ Usage: ${argv[0]} [URL] [-O out.file] [-V] [-Q] [-s]
req.onprogress = progress; req.onprogress = progress;
req.onload = (e) => { req.onload = (e) => {
if (e.type == 'load') { if (e.type == 'load') {
let enc = new TextDecoder("utf-8"); write(e.response);
terminal.write(enc.decode(req.response));
} }
}; };
req.send(); req.send();

View File

@ -3,7 +3,9 @@ module.exports = (dom) => {
terminal.writeln('Welcome to my online resume!') terminal.writeln('Welcome to my online resume!')
terminal.writeln('Type \033[1;32mhelp\033[0m for list of commands') 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(''); terminal.writeln('');
require('./zsh')(terminal, dom); 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'); const cmds = require('./commands');
/** /**
* @type {Terminal} * @type { Terminal }
*/ */
let 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, ''); 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; cmd += char;
terminal.write(char); terminal.write(char);
} }
@ -47,7 +54,7 @@ function exec_file(f) {
return; return;
} }
function exec_cmd() { async function exec_cmd() {
let c = cmd; let c = cmd;
const command = c.split(' ')[0]; const command = c.split(' ')[0];
reset_cmd(c); reset_cmd(c);
@ -68,8 +75,13 @@ function exec_cmd() {
} }
if (cmds[command] != undefined) { if (cmds[command] != undefined) {
cmds[command](c.split(' '), terminal); const startY = terminal.buffer.normal.cursorY
if (terminal.buffer.active.cursorX != 0) {
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'); terminal.write('\033[30;47m%\033[0m\n');
} }
print_prompt(); print_prompt();
@ -94,20 +106,41 @@ function reset_cmd() {
terminal.writeln(''); 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 */ /** @param { KeyboardEvent } dom */
function control_char(id, 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) { switch (id) {
// backspace // backspace
case 8: case 8:
backspace(); backspace(dom.ctrlKey);
break; break;
// enter // enter
@ -130,13 +163,16 @@ function control_char(id, dom) {
print_prompt(); print_prompt();
break; break;
} }
case 37:
backspace();
break;
case 86:
if (dom.altKey) break;
default: default:
if (dom.ctrlKey && (dom.key.length == 1)) {
terminal.write('^' + dom.key.toUpperCase());
break;
}
terminal.write('<'); terminal.write('<');
if (dom.ctrlKey) terminal.write('C'); if (dom.ctrlKey) terminal.write('C');
if (dom.altKey) terminal.write('A'); if (dom.altKey) terminal.write('A');
@ -150,16 +186,20 @@ function key(e) {
/** @type {KeyboardEvent} */ /** @type {KeyboardEvent} */
const dom = e.domEvent; const dom = e.domEvent;
if (dom.key.length == 1 && !(dom.ctrlKey || dom.altKey)) { if (dom.key.length == 1 && !(dom.ctrlKey || dom.altKey)) {
pr_char(e.domEvent.key); pr_char(e.domEvent.key, dom);
} else { } else {
control_char(e.domEvent.keyCode, dom) control_char(e.domEvent.keyCode, dom)
} }
} }
module.exports = (t, d) => { function register(t, d) {
terminal = t; terminal = t;
dom = d; dom = d;
terminal.onKey(key); terminal.onKey(key);
terminal.write(prompt); terminal.write(prompt);
} }
register.pr_char = pr_char;
module.exports = register;