I have a JQuery terminal that i'm trying to make it similar to the MacOS terminal. When using the MacOS terminal, I noticed that whenever you press enter, the prompt will disappear for a sec, the reappear very quickly. Im trying to find out how I can make the same thing in my Jquery terminal, but work just like it, but without one problem that I have, here is the code so far:
<!DOCTYPE html>
<html>
<head>
<script src="https://cdn.jsdelivr.net/npm/jquery"></script>
<script src="https://cdn.jsdelivr.net/npm/jquery.terminal/js/jquery.terminal.min.js"></script>
<link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/jquery.terminal/css/jquery.terminal.min.css"/>
</head>
<body>
<script>
$('body').terminal({
echo: function(...args) {
this.echo(args.join(" "))
}
}, {
keydown: function(e) {
if(e.key === 'Enter' || e.keyCode === 13) {
var checkit = this.get_prompt();
setTimeout(() => {
this.set_prompt('')
}, 10);
setTimeout(() => {
this.set_prompt(checkit)
}, 200);
} else {
}
},
greetings: '',
checkArity: false,
prompt: 'MyNormalPrompt>'
});
</script>
</body>
</html>
Problem: as you can see if you try the demo, the prompt does disappear and then reappear just how I wanted, but if you try to press enter too quick, or hold it down, the prompt will just disappear completely.
What I tried: I took a look at this: Detect Long Press on Enter/OK Key on a caph-list Item which gave information of how to detect a long enter key press in javascript, and when implementing some of the code there to my jquery terminal, it sorta helped, but still wouldnt make the prompt stop disappearing.
You can use pause/resume:
echo: function(...args) {
term.pause();
this.echo(args.join(" "));
setTimeout(() => {
this.resume();
}, 200);
}
pause/resume is the same as returning a promise and resolving after a delay:
const delay = time => new Promise(resolve => setTimeout(resolve, time));
echo: async function(...args) {
this.echo(args.join(" "))
await delay(200);
}
I don't think there is a way to do this globally for all commands. But you can create a function that abstracts this away:
const timeout = 200;
const delayed = (fn) {
return function(...args) {
term.pause();
fn.apply(this, args);
setTimeout(() => {
this.resume();
}, timeout);
};
};
echo: delayed(function(...args) {
this.echo(args.join(" "));
})
You can do the same with the async approach.
const timeout = 200;
const delayed = (fn) {
return async function(...args) {
await fn.apply(this, args);
await delay(timeout);
};
};
In this case the function echo can be async or normal function:
echo: delayed(async function(...args) {
this.echo(args.join(" "));
})
You can also delay every method of an object, it's best to use a function as the interpreter where you can parse the command yourself and handle it on your own.
const timeout = 200;
const delay = time => new Promise(resolve => setTimeout(resolve, time));
const delayed = obj => {
return async function(command) {
if (!command) {
return;
}
const cmd = $.terminal.parse_command(command);
if (obj[cmd.name]) {
obj[cmd.name].apply(this, cmd.args);
} else {
this.error(`Wrong command: ${cmd.name}`);
}
await delay(timeout);
}
};
const term = $('body').terminal(delayed({
echo(...args) {
this.echo(args.join(' '));
}
}));