Skip to content

Javascript Command Line Interface

I was playing with a minor project and wanted to simulate a command line interface, like the old April Fools xkcd, and realized that their code was far more complicated than what you need if you use jQuery and contenteditable.

My quick jQuery plugin to turn any <div> into a terminal emulator is:

	$.fn.cli = function(handler, prompt, effect){
		if (!prompt) prompt = '&gt;&nbsp;';
		if (!effect) effect = $.fn.text;
		return this.each(function(){
			var self = $(this);
			function newline(){
				 append('<p class=input><span class=prompt>'+prompt+'</span><span  style=outline:none contenteditable></span>').
				 find('[contenteditable]')[0].focus(); // focus only works on the element, not the jQuery object
			self.on('keydown', '[contenteditable]', function(evt){
				if (evt.keyCode == 13){
					this.removeAttribute('contenteditable'); // the old input line should not be editable
					// standards use textContent, IE uses innerText$('<p class=response>').appendTo(self),handler(this.textContent || this.innerText));
					return false;

And you use it like:

  return 'You wrote: '+text;

See the demo. The font there is Peter Hull's VT323.

handler is a function that is passed the text in the input line and should return the text to output. prompt is the prompt string. effect is the function that lets you do fancy things to the output. It is called with this set to a <p> element that is to contain the text, and is passed one parameter, the text to output. It defaults to jQuery.fn.text, just showing the text.

It's not fancy; any actual processing of the text is up to you. Catching special characters like the up-arrow for history is also up to you. It doesn't have the old-fashioned blinking block cursor, since the insertion point caret is not styleable, and faking it is not worth the effort.

If you want a mind-blowingly cool terminal emulator, see mass:werk's termlib. And check out their cool Space Invaders game on their 404 page.

Post a Comment

Your email is never published nor shared. Required fields are marked *