Reputation: 43
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.
Upvotes: 0
Views: 72
Reputation: 66478
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(' '));
}
}));
Upvotes: 1