User:Slaporte/vi.js

//http://www.netlobo.com/url_query_string_javascript.html function gup( name ) { name = name.replace(/[\[]/,"\\\[").replace(/[\]]/,"\\\]"); var regexS = "[\\?&]"+name+"=([^&#]*)"; var regex = new RegExp( regexS ); var results = regex.exec( window.location.href ); if( results == null ) return null; else return unescape(results[1]); }

/*    JSVI - VI in JavaScript. Copyright (C) 2006-2008 Internet Connection, Inc.

This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by   the Free Software Foundation; either version 3 of the License, or    (at your option) any later version.

This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details.

You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307  USA var emacsen = false;

/* TODO

sortof bugs: the toolbar is kind of ugly- possibly replace with an image-version- or more likely- replace with styled buttons

ideas: uneditable sections?

a ruler at the 72 character mark? possibly word-wrapping?

want to switch between vi/emacs modes?

var term_cols; var term_rows; var term_win_width; var term_win_height; var term_cur_width;

var tools; var suggest; var backing;

var tagstyle = 0; var line_height = 0; var cclick = undefined;

var mode = 0; var accum = 0; var lastaccum = 0; var marks = new Object; var registers = new Object; var lastreg = '';

var lastcommand; var lastmotion; var cursoriv; var drawiv;

var printer; var term; var base = 0; var left = 0;

var vselm = 0; var vselx = undefined; var vsely = undefined; var vseld = false;

var lastkey = undefined;

var statustext = ''; var command = ''; var oldcommand = ''; var commandleft = 0; var savex, savey; var once = true;

var cursorx, cursory; var file = new Array; var tags = new Array; var palette; var cursor;

var yank_buffer = undefined;

var term_save_h = new Array;

var term_save_ss; var term_save_mc; var term_save_kd; var term_save_kp; var term_save_rs; var term_save_op;

var lastsearch; var lastsubst; var lastflags;

var undoset = undefined; var undoline = undefined; var undoy = -1;

var term_ex_motion; var vi_ft_reg; var viflags = ''; var lastinsert = '';

var spelling = false; var spellcheck = new Object; var safewords = new Object; var brokenwords = new Object; var suggestions = new Object;

safewords['jsvi']=true; safewords['javascript']=true; safewords['URL']=true; safewords['hyperlinks']=true; safewords['HTML']=true; safewords['UNIX']=true; safewords['Firefox']=true; safewords['MSIE']=true; safewords['Ctrl']=true; safewords['vi']=true; safewords['vi-keys']=true; safewords[':hardcopy']=true; safewords['unicode-aware']=true; safewords['developer-centric']=true;

var doing_backing_paste = false;

function _true { return true; } function _false { return false; }

function _cbrestore { var i;	for (i = 0; i < term_save_h.length; i++) { var z = term_save_h[i]; z; }	term_save_h = new Array; } function _cbw(nx,ny) { var nz = window['on'+nx]; (function(x,y,z) {		term_save_h[term_save_h.length] = function {			window['on'+x] = z;		};	})(nx,ny,nz); window['on'+nx]=ny; } function _cbd(nx,ny) { var nz = document['on'+nx]; (function(x,y,z) {		term_save_h[term_save_h.length] = function {			document['on'+x] = z;		};	})(nx, ny, nz); document['on'+nx]=ny; } function _rer(re,t,aa) { if (RegExp.rightContext != undefined) return RegExp.rightContext; // emulate rightContext var s = re.toString; if ((s.substr(0,2) == '/^' && s.substr(s.length-1,1) == '/') || s.substr(0,1) == '^') { // bound at beginning return t.substr(aa[0].length, t.length - aa[0].length); }	if ((s.substr(0,1) == '/' && s.substr(s.length-2,2) == '$/') || s.substr(s.length-1,1) == '$') { // bound at end return ""; }	var j = t.lastIndexOf(aa[0]); if (j != -1) return t.substr(j.t.length-j); return t;

} function _rel(re,t,aa) { if (RegExp.leftContext != undefined) return RegExp.leftContext; // emulate leftContext var s = re.toString; if ((s.substr(0,2) == '/^' && s.substr(s.length-1,1) == '/') || s.substr(0,1) == '^') { // bound at beginning return ""; }	if ((s.substr(0,1) == '/' && s.substr(s.length-2,2) == '$/') || s.substr(s.length-1,1) == '$') { // bound at end return t.substr(0, t.length - aa[0].length); }	var j = t.indexOf(aa[0]); if (j != -1) return t.substr(0,j); return ""; } function _hra(x) { var i;	var cx = 0; var t = ''; var g = ''; for (i = 0; i < x.length; i++) { var x3 = x.substr(i,3); var gx = String.fromCharCode(cx); if (x3 == '') { cx = cx | 1; i += 2; } else if (x3 == '') { cx = cx | 16; i += 2; } else if (x3 == '</i') { cx = (cx | 16) ^ 16; i += 3; } else if (x3 == '<sp') { // cx = cx | 4; i += 16; } else if (x3 == '</s') { // cx = (cx | 4) ^ 4; i += 6; } else if (x3 == '&am') { // &amp; t += '&'; g += gx; i += 4; } else if (x3 == '&lt') { // &lt; t += '<'; g += gx; i += 3; } else { t += x.substr(i,1); g += gx; }	}	var aa = new Array; aa[0] = t;	aa[1] = g;	return aa; } function _rtf(t,g) { var cx = 0; var i;	var o = ''; if (t == undefined) { t = ''; g = ''; }	for (i = 0; i < t.length; i++) { var gx = g.substr(i, 1).charCodeAt(0); var tx = t.substr(i, 1); o += tx; }	return o; } function _rtfl(y) { return _rtf(file[y],tags[y]); } function _dfx(q) { /*@cc_on @*/ /*@if (1) return @end @*/ q.style.position = 'fixed'; } function term_freeze { var i;	var o = ''; for (i = 0; i < file.length; i++) { o += _rtfl(i)+"\n"; }	return o; } function _term_update_printer { var i;	var o = ''; for (i = 0; i < file.length; i++) { o += _rtfl(i)+" "; }	printer.innerHTML = o; } function term_thaw(s) { var a = s.split("\n"); var i;	var aa; file = new Array; tags = new Array; var o = ''; for (i = 0; i < a.length; i++) { o += a[i] + " "; aa = _hra(a[i]); file[i] = aa[0]; tags[i] = aa[1]; }	printer.innerHTML = o; }

function _mxo(z,y) { var i;	var o = ''; for (i = 0; i < z.length; i++) { o += String.fromCharCode(z.substr(i, 1).charCodeAt(0) | y); }	return o; } function _mxs(n,y) { var z = String.fromCharCode(y); var i;	var o = ''; for (i = 0; i < n; i++) { o += z;	} return o; } function _zeros(n) { return _mxs(n,0); } function _fauc { var d = document.getElementsByTagName('A'); var i;	for (i = 0; i < d.length; i++) { var j = d[i]; if (j._len && j._term) { if (j._row == (base+cursory) && (left+cursorx) >= j._col && (left+cursorx) <= (j._col+j._len)) { return j;			} }	}	return undefined; } function _pass_click(e) { var z = _fauc; if (z && z.onclick) return z.onclick; return false; } function _pass_dblclick(e) { var z = _fauc; if (z && z.ondblclick) return z.ondblclick; return false; }

function _cancel_ev(e) { if (!e) e = window.event; if (!e) return false; if (e.preventDefault) e.preventDefault; if (e.stopPropagation) e.stopPropagation; return false; } function _willclick(e) { if (window.event) { if (!e) e = window.event; }	if (!e) return true; if (cclick != undefined) window.clearTimeout(cclick); var x = e.clientX; var y = e.clientY; cclick = window.setTimeout(function {			cclick=undefined;			_cursortoxy(x,y);		}, 200); return false; } function _subclick(e) { return _willclick(e); } function _srep(e) { if (!e) e = window.event; if (e.preventDefault) e.preventDefault; if (e.stopPropagation) e.stopPropagation; e.cancelBubble=true; var y = this._row; var x = this._col; var len = this._len; var rep = this._word; var t = (file[y]); var g = (tags[y]); var w = (t.substr(x, len)); var st = (g.substr(x, len)); while (st.length < rep.length) { st = st + st; }	if (st.length > rep.length) { st = st.substr(0, rep.length); }

term_save_undo; // save undo! file[y] = t.substr(0, x) + rep + t.substr(x+len, t.length-(x+len)); tags[y] = g.substr(0, x) + st + g.substr(x+len, t.length-(x+len)); suggest.style.display = 'none'; suggest._visible = false; while (suggest.firstChild) suggest.removeChild(suggest.firstChild); if (w == rep) { statustext = ''; } else { statustext = 'Replaced "' + w + '" with "' + rep + '"'; }	term_redraw; return false; } function _rl(w,h) { var x = document.createElement('DIV'); x.style.overflow = 'hidden'; x.style.height = h + 'px'; x.style.marginLeft = w + 'px'; x.style.marginRight = w + 'px'; x.style.backgroundColor = palette[0]; x.style.display = 'block'; x.style.innerHTML = ' '; x.style.fontFamily = 'monospace'; return x; } function _ruo(t) { this.style.color = palette[0]; this.style.backgroundColor = palette[1]; } function _rux(t) { this.style.color = palette[1]; this.style.backgroundColor = palette[0]; } function _openurl(e) { var u = this._term; window.open(u,'_new'); return true; } function _suggest(e) { var z = this; if (window.event) { if (!e) e = window.event; }	if (e) { if (e.preventDefault) e.preventDefault; if (e.stopPropagation) e.stopPropagation; e.cancelBubble=true; }	(function(q) {		window.setTimeout(function{ _dosuggest(q); }, 10);	})(z); return false; } function _dosuggest(z) { var x = 0; var y = 0; var xt = z._term; var wrow = z._row; var wcol = z._col; var wlen = z._len; while (z && z != document.body) { x += z.offsetLeft; y += z.offsetTop; z = z.offsetParent; }

suggest._visible = true; suggest.style.top = y + 'px'; suggest.style.left = x + 'px'; suggest.style.display = 'block'; suggest.style.zIndex = '3'; suggest.style.padding = '2px';

while (suggest.firstChild) suggest.removeChild(suggest.firstChild);

var sg = document.createElement('DIV'); sg.style.backgroundColor = palette[0]; sg.style.color = palette[1]; sg.style.fontSize = '100%'; sg.style.padding = '2px'; sg.style.textAlign = 'center'; sg.style.cursor = 'default';

var sa = suggestions[xt]; var i;	var fs = 200; var fd = parseInt((100 / sa.length) * 1.5); var bf; for (i = 0; i < sa.length; i++) { var da = document.createElement('A'); da.href = 'javascript:void(0)'; da.onclick = _srep; da._word = sa[i]; da._row = wrow; da._col = wcol; da._len = wlen; da.onmouseover = _ruo; da.onmouseout = _rux; da.style.margin = '4px'; da.style.textDecoration = 'none'; da.style.display = 'block'; da.style.color = palette[1]; da.style.backgroundColor = palette[0]; da.style.fontSize = fs + '%'; fs -= fd; if (fs <= 100) fs = 100; da.appendChild(document.createTextNode(sa[i])); // err... da.appendChild(document.createElement('BR')); if ((wrow-base) > term_rows-(sa.length+1)) { sg.insertBefore(da, sg.firstChild); bf = true; } else if (((i % 2) == 0) || (wrow < (sa.length+1))) { sg.appendChild(da); } else { sg.insertBefore(da, sg.firstChild); }		da = undefined; // break }	if (sa.length == 0) { sg.appendChild(document.createTextNode('No matches')); }	var da = document.createElement('A'); da.href = 'javascript:void(0)'; da.onclick = _srep; da._word = xt; da._row = wrow; da._col = wcol; da._len = wlen; da.style.margin= '4px'; da.style.textDecoration = 'none'; da.style.color = palette[1]; da.style.backgroundColor = palette[0]; da.style.borderBottom = '1px dashed red'; da.style.fontSize = '100%'; da.onmouseover = _ruo; da.onmouseout = _rux; da.appendChild(document.createTextNode(xt)); if (wrow > term_rows-(sa.length+1)) { sg.insertBefore(da, sg.firstChild); } else { sg.appendChild(da); }

// rounded top and bottom suggest.appendChild(_rl(3,1)); suggest.appendChild(_rl(2,1)); suggest.appendChild(_rl(1,2)); suggest.appendChild(sg); suggest.appendChild(_rl(1,2)); suggest.appendChild(_rl(2,1)); suggest.appendChild(_rl(3,1));

// msie needs to recalculate these things manually... grr... // this doesn't work because msie doesn't calculate offsetwidth (thtphtpht) var zq; var mw = 11; if (mw < xt.length) mw = xt.length; for (i = 0; i < sa.length; i++) { if (mw < sa[i].length) mw = sa[i].length; }

if (mw) { mw *= (term_cur_width*2); mw += 16; suggest.style.width = mw + 'px'; }

var sx = parseInt(sg.offsetWidth / 4); if (x < sx) { x = 0; } else { x -= sx; suggest.style.left = x + 'px'; }	var sy = parseInt(sg.offsetHeight / 4); if (bf) { suggest.style.top = ''; suggest.style.bottom = '0px'; } else if (y < sy) { y = 0; suggest.style.top = '0px'; suggest.style.bottom = ''; } else { y -= sy; suggest.style.top = y + 'px'; suggest.style.bottom = ''; }

statustext = 'Suggestions for: ' + xt; term_redraw;

da = undefined; // break sg = undefined; // break }

function _backing_paste_real { doing_backing_paste = false; term_redraw; if (!backing.value) return; if (backing._lastvalue == backing.value) { return; }	backing._lastvalue = backing.value; term_paste(false, backing.value); term_redraw; } function _msie_paste { var chunk = "new content associated with this object"; event.returnValue = false; term_paste(false, window.clipboardData.getData("Text", chunk)); } function _backing_paste { _update_backing; if (!doing_backing_paste) { doing_backing_paste = true; window.setTimeout(_backing_paste_real, 10); } } function _update_backing { if (!backing) return; /*@cc_on @*/ /*@if (1) return @end @*/ backing.focus; backing.select; } function _yaty(y) { if (line_height) return parseInt(y/line_height); var zx; var qx = term.firstChild; var nh = 0; while (qx && qx != document.body) { nh += qx.offsetTop; qx = qx.offsetParent; }

var ny = 0; var cy = 0; for (zx = term.firstChild; zx; zx = zx.nextSibling) { nh += (zx.offsetHeight + 4); if (y <= nh) { cy = ny; break; }		ny++; }	return cy; } function _cursortoxy(x,y) { // this is a little gross... var sx = cursorx; cursorx = parseInt(x / term_cur_width); term_redraw;

var sy = cursory; cursory = _yaty(y);

if (cursory >= (term_rows-1)) { cursory = sy; cursorx = sx; sy = 0; }

term_scrollto; term_calcx; if (cursory != sy) { term_redraw; } else { term_calcy; }	_update_backing; return true; } function _mousescroll(e) { if (!e) e = window.event; var d = 0; if (e.wheelDelta) { d = e.wheelDelta; if (d < 0) d = 1; else d = -1; } else if (e.detail) { d = e.detail; } else { return true; }	if (d < 0) { if (base > 0) base--; } else if (d > 0) { if (base < (file.length - (term_rows-1))) base++; }	term_redraw; return false; }

function _mousedown(e) { if (suggest._visible) return true; if (!e) e = window.event; var y = _yaty(e.clientY); if (y >= (term_rows-1)) return true; _willclick(e); vseld = true; vselm = 0; vselx = undefined; vsely = undefined; return false; } function _mousemove(e) { if (!e) e = window.event; if (e) { if (e.preventDefault) e.preventDefault; if (e.stopPropagation) e.stopPropagation; e.cancelBubble=true; }	if (window.getSelection) { var s = window.getSelection; if (s.removeAllRanges) s.removeAllRanges; }	if (document.selection && document.selection.empty) { eval('try{document.selection.empty;}catch(e){}'); }	// fixup selection _update_backing;

if (suggest._visible || !vseld) return true; if (vseld) { if (vselx == undefined && vsely == undefined) { // turn on v here vselm = 1; vselx = cursorx+left; vsely = cursory+base; }		_willclick(e); return true; }	return true; } function _mouseup(e) { if (suggest._visible || !vseld) return true; vseld = false; if (vselm && vselx != undefined && vsely != undefined) { // okay, we HAVE selection var rr = lastreg; lastreg = '*'; term_vi_set('y'); term_vi_unset('d'); term_select; term_operate; lastreg = rr; } else { vselm = 0; }	_willclick(e); return false; } function _mouseclick(e) { if (!e) e = window.event; var y = _yaty(e.clientY); if (y >= (term_rows-1)) return true; vselm = 0; _cursorto(e); return true; } function _cursorto(e) { if (!e) e = window.event; var x = e.clientX; var y = e.clientY; if (suggest._visible) { suggest.style.display = 'none'; suggest._visible = false; statustext = ''; }	return _cursortoxy(x,y); }

function _word(s) { var t = s.replace(/[.?!,:]*$/,""); if (t) s = t;	t = s.replace(/[ \r\n\t]/,""); if (t) s = t;	return s; } function _safe(s) { if (s.match(/^[ \r\n\t]*<.*>[ \r\n\t]*$/)) return true; return false; } function _xhttp { var xmlhttp=false; /*@cc_on @*/ /*@if (@_jscript_version >= 5) try { xmlhttp = new ActiveXObject("Msxml2.XMLHTTP"); } catch (e) { try { xmlhttp = new ActiveXObject("Microsoft.XMLHTTP"); } catch (E) { xmlhttp = false; } } @end @*/ if (!xmlhttp && typeof XMLHttpRequest!='undefined') { xmlhttp = new XMLHttpRequest; }	if (!xmlhttp) return new Object; // fake out caller return xmlhttp; }

function term_setmode(n) { mode = n;	lastinsert = ''; }

function term_roll_yank { registers["9"] = registers["8"]; registers["8"] = registers["7"]; registers["7"] = registers["6"]; registers["6"] = registers["5"]; registers["5"] = registers["4"]; registers["4"] = registers["3"]; registers["3"] = registers["2"]; registers["2"] = registers["1"]; registers["1"] = registers["0"];

if (lastreg == '0') { registers[""] = yank_buffer; }	if (lastreg == "" || lastreg == "*") { backing._lastvalue = yank_buffer; backing.value = yank_buffer; }	registers["0"] = yank_buffer; }

function term_justify { var y = cursory+base; var i;	if (!accum) accum = 1; var t = (file[y]); file[p] = t.replace(/[ ][ ]*$/,""); tags[p] = tags[p].substr(0, file[p].length); for (i = 0; i < accum; i++) { var t = file[i+y+1]; var g = tags[i+y+1]; term_delete(i+y+1); // ignore return

t = t.replace(/^[ ][ ]*/,""); g = g.substr(g.length - t.length, t.length); if (t != '') { file[y] = file[y] + " " + t;			tags[y] = tags[y] + "\0" + g;		} }	file[y] = file[y].replace(/^[ ][ ]*/,""); tags[y] = tags[y].substr(tags[y].length - file[y].length, file[y].length); accum = 0; }

function term_vi_bb { return term_skipbackward(/[ ][^ ][^ ]*[ ]*$/); } function term_vi_b { return term_skipbackward(/[^a-zA-Z0-9_][a-zA-Z0-9_][a-zA-Z0-9_]*[^a-zA-Z0-9_]*$/); } function term_vi_tt { var t = (file[cursory+base]); var i;	var w = term_cols; for (i = (cursorx+left)-1; i >= 0; i--) { var c = (t.substr(i, 1)); if (c == vi_ft_reg) { cursorx = (i - left)+1; if (cursorx >= w) { left = 0; cursorx = i+1; }			return true; }	}	return false; } function term_vi_t { var t = (file[cursory+base]); var i;	for (i = (cursorx+left)+1; i < t.length; i++) { var c = (t.substr(i, 1)); if (c == vi_ft_reg) { cursorx = (i - left)-1; if (term_vi_flag('d') || term_vi_flag('c') || term_vi_flag('y')) cursorx++; if (cursorx < 0) { left = 0; cursorx = i-1; }			return true; }	}	return false; } function term_vi_ff { var t = (file[cursory+base]); var i;	for (i = (cursorx+left)-1; i >= 0; i--) { var c = (t.substr(i, 1)); if (c == vi_ft_reg) { cursorx = i - left; if (cursorx < 0) { left = 0; cursorx = i;			} return true; }	}	return false; } function term_vi_f { var t = (file[cursory+base]); var i;	var w = term_cols; for (i = (cursorx+left)+1; i < t.length; i++) { var c = (t.substr(i, 1)); if (c == vi_ft_reg) { cursorx = i - left; if (term_vi_flag('d') || term_vi_flag('c') || term_vi_flag('y')) cursorx++; if (cursorx >= w) { left = 0; cursorx = i;			} return true; }	}	return false; } function term_vi_eof { cursorx = 0; left = 0; base = 0; if (accum) { cursory = accum-1; return false; } else { base = file.length - (term_rows-1); cursory = term_rows-1; if (base < 0) { base = 0; cursory = file.length-1; }	}	term_redraw; return true; } function term_vi_top { cursorx = 0; base = 0; left = 0; if (accum) { cursory = accum-1; return false; } else { cursory = 0; }	return true; } function term_vi_h { cursorx--; term_scrollto; return true; } function term_vi_j { cursory++; term_scrollto; return true; } function term_vi_k { cursory--; term_scrollto; return true; } function term_vi_l { cursorx++; // hack var a = mode; mode = 1; term_scrollto; mode = a;	return true; } function term_vi_ll { cursory = term_rows-2; return true; } function term_vi_mm { cursory = parseInt((term_rows-2) / 2); cursorx = 0; left = 0; return true; } function term_vi_hh { cursory = 0; return true; } function term_vi_ob { cursory--; return term_skipreverse2(/^[ ]*$/, 0); } function term_vi_cb { cursory++; return term_skipforward(/^[ ]*$/, 0); } function term_vi_ww { return term_skipforward(/[ ][^ ]/, 0); } function term_vi_w { return term_skipforward(/[^a-zA-Z0-9_{}<>][a-zA-Z0-9_{}<>]/, 0); }

function term_vi_flag(f) { return (viflags.indexOf(f) == -1) ? false : true; } function term_vi_unset(f) { var j = viflags.indexOf(f); if (j == -1) return; viflags = viflags.substr(0, j) + viflags.substr(j+1, (viflags.length-j)-1); } function term_vi_set(f) { if (viflags.indexOf(f) == -1) viflags += ''+f; } function term_vi_bounce { var y = cursory+base; var t = (file[y]); var x = cursorx+left; var z1 = '[{}]'; var z2 = ']})({['; while (x < t.length) { var z = z1.indexOf(t.substr(x,1)); if (z == -1) { x++; continue; }		var d = (z > 2) ? -1 : 1;		var c=z2.substr(z,1); while (y >= 0 && y < file.length) { while (x > 0 && x < t.length) { if (t.substr(x,1) == c) { cursorx = x-left; cursory = y;					base = 0; term_scrollto; return true; }				x += d;			} if (d == -1) { y--; t = file[y]; x = (t.length-1) } else { y++; t = file[y]; x = 0; }		}	}	return false; } function term_vi_eol { var t = (file[cursory+base]); cursorx = (t.length)-left; if (cursorx < 0) { left = 0; cursorx = (t.length); }	return true; } function term_vi_line { var t = (file[cursory+base]); left = 0; cursorx = t.length+1; return true; } function term_vi_ee { return term_skipforward(/[^ ][ ]/, 1); } function term_vi_e { if (term_skipforward(/[a-zA-Z0-9_{}<>][^a-zA-Z0-9_{}<>]/, 1)) { if (term_vi_flag('d') || term_vi_flag('c') || term_vi_flag('y')) cursorx++; return true; }	return false; }

function term_vi_v { cursorx = vselx - left; if (cursorx < 0) { left = 0; cursorx = vselx; }	cursory = vsely - base; if (cursory < 0) { base = 0; cursory = vsely; } } function term_vi_vv { term_vi_v; term_vi_line; }

function term_select { if (vselm == 1) { term_ex_motion = term_vi_v; } else if (vselm == 2) { term_ex_motion = term_vi_vv; cursorx = 0; left = 0; } } function term_indent(y,amount) { if (file[y] == undefined) { file[y] = ''; tags[y] = ''; }	file[y] = _mxs(amount*4,32)+file[y]; tags[y] = _mxs(amount*4,tagstyle)+tags[y]; } function term_unindent(y,amount) { amount*=4; while (amount > 0 && file[y].substr(0, 1) == ' ') { file[y] = file[y].substr(1, file[y].length-1); amount--; } }

function term_operate { term_save_undo;

var fa = accum; if (!fa) fa = 1; var sx = cursorx+left; var sy = cursory+base; while (fa > 0) { var t = file[base+cursory]; if (t == undefined) break; if (fa > 1 && ((cursorx+left) >= t.length)) { cursory++; cursorx = 0; left = 0; }

term_ex_motion; fa--; }	fa = accum; if (!fa) fa = 1; accum = 0; var ex = cursorx+left; var ey = cursory+base; var i;	if (ey < sy) { i = ey; ey = sy; sy = i;	} if (ex < sx) { i = ex; ex = sx; sx = i;	} var t = file[ey]; var g = tags[ey]; var restore = false; if (term_vi_flag('c')) term_vi_set('d'); if (vselm != 2 && ey == sy && ex <= t.length) { if (vselm) ex++; if (ex != sx) { if (term_vi_flag('F')) { // styling tags[ey] = (g.substr(0, sx)) + _mxs(ex-sx, tagstyle) + (g.substr(ex, g.length-ex)); } else if (term_vi_flag('d') || term_vi_flag('y')) { yank_buffer = _rtf(t.substr(sx, ex-sx),						g.substr(sx,ex-sx)); }			if (term_vi_flag('d')) { file[ey] = (t.substr(0, sx)) + (t.substr(ex, t.length-ex)); tags[ey] = (g.substr(0, sx)) + (g.substr(ex, g.length-ex)); if (lastreg != '_') { registers[lastreg] = yank_buffer; term_roll_yank; }			} else if (term_vi_flag('y')) { registers[lastreg] = yank_buffer; term_roll_yank; }			if (term_vi_flag('>')) { term_indent(ey,fa); } else if (term_vi_flag('<')) { term_unindent(ey,fa); }		}	} else if (vselm == 1) { if (term_vi_flag('d') || term_vi_flag('y') || term_vi_flag('F')) { yank_buffer = ''; var al, bl; for (i = sy; i <= ey; i++) { t = file[i]; g = tags[i]; if (i == sy) { if ((sy == vsely && sx == vselx) || (sy != vsely && sx != vselx)) { al = sx; } else { al = ex; }					bl = t.length; } else if (i == ey) { al = 0; if ((sy == vsely && sx == vselx) || (sy != vsely && sx != vselx)) { al = ex; } else { al = sx; }				} else { al = 0; bl = t.length; }				yank_buffer += _rtf(t.substr(al, bl-al),						g.substr(al,bl-al)); if (sy != ey || vselm == 2) yank_buffer += "\n"; if (term_vi_flag('d')) { file[i] = t.substr(0, al) + t.substr(bl, t.length-bl); tags[i] = g.substr(0, al) + g.substr(bl, g.length-bl); } else if (term_vi_flag('F')) { tags[i] = g.substr(0, al) + _mxs(bl-al, tagstyle) + g.substr(bl, g.length-bl); }				if (term_vi_flag('>')) { term_indent(i,fa); } else if (term_vi_flag('<')) { term_unindent(i,fa); }			}			if (lastreg != '_' && !term_vi_flag('F')) { registers[lastreg] = yank_buffer; term_roll_yank; }		}	} else { if (term_vi_flag('F')) { for (i = sy; i <= ey; i++) { tags[i] = _mxs(file[i].length, tagstyle); }		} else if (term_vi_flag('d')) { yank_buffer = ''; for (i = sy; i <= ey; i++) { yank_buffer += term_delete(sy); }			if (lastreg != '_') { registers[lastreg] = yank_buffer; term_roll_yank; }		} else if (term_vi_flag('y')) { yank_buffer = ''; for (i = sy; i <= ey; i++) { yank_buffer += _rtfl(sy) + "\n"; }			registers[lastreg] = yank_buffer; term_roll_yank; } else if (term_vi_flag('>')) { for (i = sy; i <= ey; i++) { term_indent(i,fa); }		} else if (term_vi_flag('<')) { for (i = sy; i <= ey; i++) { term_unindent(i,fa); }		}	}

if (term_vi_flag('d') || term_vi_flag('F') || term_vi_flag('c')) { _term_update_printer; }	if (term_vi_flag('d')) { term_vi_unset('d'); lastcommand = 'd'; lastmotion = term_ex_motion; restore = true; }	if (term_vi_flag('y')) { term_vi_unset('y'); restore = true; }	if (term_vi_flag('F')) { term_vi_unset('F'); restore = true; }	lastaccum = accum; if (restore) { cursorx = sx - left; if (cursorx < 0) { cursorx = sx; left = 0; }		cursory = sy - base; if (cursory < 0) { cursory = sy; base = 0; }		term_scrollto; }	if (term_vi_flag('c')) { term_vi_unset('c'); term_setmode(1); }	accum = 0; }

function term_save_undo_line { if ((base+cursory) != undoy) { undoy = base+cursory; undoline = _rtfl(undoy); } } function term_save_undo { undoset = term_freeze; }

function term_delete(i) { if (i > file.length) return ''; var j;	var z = file[i]; var g = tags[i]; for (j = i+1; j < file.length; j++) { file[j-1] = file[j]; tags[j-1] = tags[j]; }	file=_pop(file); return _rtf(z,g) + "\n"; }

function term_skipreverse2(re, fuzz) { var y = cursory+base; var x = (cursorx+left)+(1+fuzz); for { var t = file[y]; if (t == undefined) { // beep cursory = y - base; return false; }		if (fuzz) t += " "; else t = " " + t;		t = (t.substr(x, t.length-x)); var aa = re.exec(t); if (!aa) { y--; x = 0; } else { x += _rel(re,t,aa).length; cursorx = x - left; cursory = y - base; return true; }	}	return false; } function term_skipforward(re, fuzz) { var y = cursory+base; var x = (cursorx+left)+(1+fuzz); for { var t = file[y]; if (t == undefined) { // beep cursory = y - base; return false; }		if (fuzz) t += " "; else t = " " + t;		t = (t.substr(x, t.length-x)); var aa = re.exec(t); if (!aa) { y++; x = 0; } else { x += _rel(re,t,aa).length; cursorx = x - left; cursory = y - base; return true; }	}	return false; } function term_skipbackward(re) { var y = cursory+base; var x = (cursorx+left)+1; for { var t = file[y]; if (t == undefined) { // beep cursory = 0; cursorx = 0; return false; }		t = " " + t.substr(0, x-1); if (t == '') { y--; t = file[y]; if (t == undefined) continue; x = (t.length); continue; }		var aa = re.exec(t); if (!aa) { left = 0; cursorx = 0; cursory = y - base; return true; } else { x = _rel(re,t,aa).length; cursorx = x - left; cursory = y - base; return true; }	}	return false; }

function term_search(s, top, start, bottom) { var re = new RegExp(s.substr(1)); var i;	if (s.substr(0, 1) == '/') { statustext=''; re.lastIndex = cursorx+left+1; for (i = start; i < bottom; i++) { var t = (file[i]); if (i == start) { t = t.substr(cursorx+left+1, t.length-(cursorx+left+1)); }			aa = re.exec(t); if (!aa) continue; var tx = _rel(re,t,aa).length; if (i == start) { tx += cursorx+left+1; }			left = 0; base = 0; cursorx = tx; cursory = i;			term_scrollto; return true; }		statustext = 'search hit BOTTOM, continuing at TOP'; for (i = top; i <= start; i++) { var aa = re.exec(file[i]); if (!aa) continue; left = 0; base = 0; cursorx = _rel(re,file[i],aa).length; cursory = i;			term_scrollto; return true; }		statustext = 'Pattern not found: ' + s.substr(1); } else { statustext=''; for (i = start; i >= top; i--) { var t = file[i]; if (t == undefined) continue; var tail = 0; if (i == start) { tail = (cursorx+left); } else { tail = t.length; }			var right = tail; while (tail > 0) { tail--; var xj = t.substr(tail, right-tail); var aa = re.exec(xj); if (!aa) continue;

var tx = tail+_rel(re,xj,aa).length; left = 0; base = 0; cursorx = tx; cursory = i;				term_scrollto; return true; }		}		statustext = 'search hit TOP, continuing at BOTTOM'; for (i = bottom; i >= start; i--) { var t = file[i]; if (t == undefined) continue; var tail = t.length; while (tail > 0) { tail--; var xj = t.substr(tail, t.length-tail); var aa = re.exec(xj); if (!aa) continue;

cursorx = tail+_rel(re,xj,aa).length; cursory = i;				left = 0; base = 0; term_scrollto; return true; }		}		statustext = 'Pattern not found: ' + s.substr(1); }	return false; } function term_rsearch(s, top, start, bottom) { var cx = s.substr(0, 1); cx = (cx == '/') ? '?' : "/";	return term_search(cx+s.substr(1,s.length-1), top, start, bottom); }

function _pop(q) { var a = new Array; var i;	for (i = 0; i < q.length-1; i++) { a[i] = q[i]; }	return a; } function _addr(q) { if (q == '.') { return cursory+base; }	if (q == '$') { return file.length-1; }	if (q.substr(0, 1) == "'") { return marks[ q.substr(1, 1) ]; }	if (q == "\\/" || q == "\\&") { var a=cursory; var b=base; term_search(lastsearch, 0, cursory+base, file.length); var c=cursory+base; cursory=a; base=b; return c;	} if (q == "\\?") { var a=cursory; var b=base; term_rsearch(lastsearch, 0, cursory+base, file.length); var c=cursory+base; cursory=a; base=b; return c;	} if (q.substr(0, 1) == "/" || q.substr(0,1) == "?") { var a=cursory; var b=base; term_search(q, 0, cursory+base, file.length); var c=cursory+base; cursory=a; base=b; return c;	} q=parseInt(q)-1; if (q >= file.length-1) q=file.length-1; if (q < 0) q=0; return q; } function term_command(s) { var top, start,bottom; if (s && s.length > 0 && s.substr(0,1) == ':') { s = s.substr(1, s.length-1); top = cursory+base; start = top; bottom = top; } else { top = 0; start = cursory+base; bottom = file.length; }

// okay, this is kind of tricky var i;	var tok = ''; var tc = 0; var ng = new Array; var lastre = undefined; var nf = false; /// xxx todo implement ! with nf	for (i = 0; i < s.length; i++) { var c = s.substr(i, 1); if ((tc==0 || tc==1) && "0123456789".indexOf(c) > -1) { tc = 1; tok = +tok++c; continue;

} else if (tc == 1) { tc = 0; ng[ng.length] = parseInt(tok)-1; tok = ''; }

if (c == '%') { top = 0; bottom = file.length; start = cursory+base; } else if (c == '!') { nf = !nf; } else if (c == ',') { // do nothing while (ng.length > 2) { ng=_pop(ng); }		} else if (c == ';') { start = ng[ng.length-1]; ng = _pop(ng); cursory=start; base=0; ng = _pop(ng); } else if (c == '$') { ng[ng.length] = file.length; } else if (c == '.') { ng[ng.length] = cursory+base; } else if (c == "'") { // mark ng[ng.length] = marks[s.substr(i+1,1)]; i++;

} else if (c == "\\") { i++; c = s.substr(i, 1); var qq; if (c == '?') { qq=term_rsearch; } else { qq=term_search; }			if (ng.length == 1) { top = ng[0]; ng = _pop(ng); } else if (ng.length >= 2) { top = ng[ng.length-2]; bottom = ng[ng.length-1]; ng = _pop(_pop(ng)); }			if (!qq(lastsearch,top,start,bottom)) { return; }			ng[ng.length] = cursory+base; } else if (c == "/" || c == "?") { var j = i;			for (i++; i < s.length; i++) { var tc = s.substr(i, 1); if (tc == "\\") i++; else if (tc == c) break; }			lastre = s.substr(j, i-j); if (ng.length == 1) { top = ng[0]; ng = _pop(ng); } else if (ng.length >= 2) { top = ng[ng.length-2]; bottom = ng[ng.length-1]; ng = _pop(_pop(ng)); }			if (!term_search(lastre,top,start,bottom)) { return; }			ng[ng.length] = cursory+base; } else if (c == " " || c == "\t") { continue; } else { break; }	}	if (tc == 1) { ng[ng.length] = parseInt(tok)-1; tok = ''; i++; }	if (ng.length == 1) { top = ng[0]; bottom = ng[0]; } else if (ng.length >= 2) { top = ng[ng.length-2]; bottom = ng[ng.length-1]; }	if (lastre != undefined) { lastsearch = lastre; registers["/"] = lastsearch.substr(1, lastsearch.length-1); }

var cmd2 = s.substr(i,2); var cmd = s.substr(i, 1);

if (cmd2 == 'wq' || cmd == 'x') { $('#wpTextbox1').val(term_freeze); $('#editform').submit; } else if (cmd == '=') { statustext = '' + bottom; return; } else if (cmd2 == 'ha') { window.print; return; } else if (cmd == 'w') { $('#wpTextbox1').val(term_freeze) } else if (!emacsen && s.substr(i,(s.length-i)) == 'emacs') { statustext = 'EMACS mode enabled. Press M-x vi to use vi mode'; emacsen = true; mode = 1;

} else if (emacsen && cmd2 == 'vi') { statustext = 'VI mode enabled. Press ESC :emacs to use EMACS mode'; mode = 0; emacsen = false;

} else if (cmd == 'e' && term._formelement) { var zx = term_freeze; if (cmd2 != 'e!') { if (cmd2 == 'e?') { if (!confirm("Your changes will be lost\nAre you sure?")) { return; }			} else if (term._formelement.value != zx) { statustext = 'No write since last change (use ! to override)'; return; }		}		//term_thaw(term._formelement.value); filepicker.getFile('*/*', {'modal': true}, function (url, data) {			term.filePickerHandle = url;			$.ajax({url: url, success: function(data) { term._formelement.value = data; term_thaw(term._formelement.value); term_redraw; }});		});	} else if (cmd == 'f') { var zx = term_freeze; statustext = '"/tmp/mess4XbCXM"'; if (term._formelement.value != zx) { statustext += ' [Modified]'; }		statustext += ' line ' + (cursory+base+1) + ' of ' + file.length + ' col ' + (cursorx+left+1);

} else if (cmd == 'h' || s.substr(i,5) == 'about') { statustext = "jsvi \xa9 2006 Internet Connection, Inc";

} else if (s.substr(i,4) == 'kwak') { term.style.backgroundImage = 'url(ducky.jpg)'; statustext = 'kwak kwak kwak...'; } else if (s.substr(i,3) == 'moo') { statustext = 'This editor does not have Super Cow Powers';

} else if (cmd == 'b') { // only one buffer

} else if (cmd == 'n' || cmd == 'N') { statustext = 'There is only one file to edit';

} else if (cmd == 'q') { $('#editform').submit; } else if (cmd == 'd') { // delete lines yank_buffer = term_delete(top); while (top < bottom) { yank_buffer += term_delete(top); bottom--; }		if (lastreg != '_') { registers[lastreg] = yank_buffer; term_roll_yank; }		term_scrollto; } else if (cmd == 'u') { var z = term_freeze; term_thaw(undoset); undoset = z;

} else if (cmd == 'y') { yank_buffer = ''; for (i = top; i < bottom; i++) { yank_buffer += (file[i])+"\n"; }		registers[lastreg] = yank_buffer; term_roll_yank;

} else if (cmd == 'F') { // styling! var y;		var tadd = 0; var tsub = 0; var tset = undefined; var otc = tagstyle; var tg = '='; for (y = i+1; y < s.length; y++) { var cy = s.substr(y, 1); if (cy == '=' || cy == '+' || cy == '-' || cy == '!') { tg = cy; } else { var fl = 0; if (cy == 'b') { fl = 1; } else if (cy == 'i') { fl = 16; } else if (cy == 'u') { fl = 2; } else if (cy == 'o') { fl = 4; } else { statustext = 'Unrecognized formatting specifier: ' + cy; return; }				if (tg == '!') { if (tset != undefined) tagstyle = tset; tagstyle = tagstyle ^ fl; } else if (tg == '=') { if (tset == undefined) tset = 0; tset = tset + fl; } else if (tg == '+') { tadd |= fl; } else if (tg == '-') { tsub |= fl; }			}		}		if (tset == undefined) { tagstyle = ((tagstyle | tadd) | tsub) ^ tsub; } else { tagstyle = tset; }		// okay, we've set tagstyle if (i != 0) { // if this happened, then we were given a range(!) for (y = top; y <= bottom; y++) { if (file[y] == undefined) continue; tags[y] = _mxs(file[y].length, tagstyle); }			tagstyle = otc;

} else if (vselm) { term_select; term_vi_unset('d'); term_vi_unset('y'); term_vi_unset('c'); term_vi_set('F'); term_operate; tagstyle = otc; }

} else if (cmd == 'g' || cmd == 'v') { // okay then var y;		var ng = s.substr(i+1,(s.length-i)-1); if (cmd == 'v') ng = '!' + ng; for (y = 0; y < file.length; y++) { base = 0; cursory = y;			term_command(ng); }

} else if (cmd == 't' || cmd2 == 'co') { // copy- need address var t = s.substr(i, s.length-i).replace(/^[a-z]*[ ]*/); var x;		yank_buffer = ""; for (x = top; x <= bottom; x++) { if (file[x] != undefined) { yank_buffer += (file[x]) + "\n"; }		}		var a = cursory; var b = base; base = 0; cursorx = 0; left = 0; cursory = _addr(t); if (cursory < 0) cursory = 0; term_paste(false, yank_buffer); cursory = a;		base = b;

} else if (cmd == 'm') { // move- need address i++; if (s.substr(i, 3) == 'ove') { i += 3; }		var t = s.substr(i, s.length-i); yank_buffer = term_delete(top); while (top < bottom) { yank_buffer += term_delete(top); bottom--; }		var a = cursory; var b = base; base = 0; cursorx = 0; left = 0; cursory = _addr(t); if (cursory < 0) cursory = 0; term_paste(false, yank_buffer); cursory = a;		base = b;

} else if (cmd == 's') { // substitute i++; // extract regex var q = s.substr(i,1); while (q == ' ') { i++; q = s.substr(i,1); }		var sep = s.substr(i,1); i++;

var lr, ls, lf; if (sep == '') { if (!lastsearch || !lastsubst) { statustext = 'No previous substitute regular expression'; return; }			lr = lastsearch.substr(1, lastsearch.length-1); ls = lastsubst; lf = lastflags; } else { var jj = i;			var zj; for (i < s.length; i++) { zj = s.substr(i,1); if (zj == "\\") { i++; } else if (zj == sep) { break; }			}			lastsearch = "/" + s.substr(jj, i-jj); registers["/"] = lastsearch.substr(1, lastsearch.length-1); i++; // sep jj=i; for (i < s.length; i++) { zj = s.substr(i,1); if (zj == "\\") { i++; } else if (zj == sep) { break; }			}			lastsubst = s.substr(jj, i-jj); lastflags = ''; i++; var count = -1; for (i < s.length; i++) { zj = s.substr(i,1); if (zj == 'i' || zj == 'g') { lastflags += zj; } else { count = parseInt(s.substr(i,s.length-i)); if (count > 0) { break; } else { statustext = "Trailing characters"; return; }				}			}			var re = new RegExp; re.compile(lastsearch.substr(1, lastsearch.length-1),					(lastflags.indexOf('i') > -1) ? 'i' : ''); var hit = false; for (i = top; i < bottom; i++) { var t = file[i]; var g = tags[i]; var aa; var st = t;				aa = re.exec(t); if (!aa || aa.length == 0) continue; file[i] = ''; tags[i] = ''; // okay got a hit, do this vi style for { t = _rer(re,st,aa); var lt = _rel(re,st,aa); var lg = _resubst(lastsubst,aa); file[i] += lt + lg; tags[i] += g.substr(0, lt.length) + _zeros(lg.length);

if (lastflags.indexOf('g') > -1) { st = t;						aa = re.exec(t); if (aa && aa.length > 0) continue; }					file[i] += t;					tags[i] += g.substr(g.length - t.length, t.length); break; }				hit = true; if (count > -1) { count--; if (count == 0) break; }			}			if (!hit) { statustext = 'Pattern not found: ' + lastsearch.substr(1, lastsearch.length-1); }		}

} else if (cmd == '' && ng.length > 0) { base = 0; cursory = top; } else { statustext = "Not an editor command: " + s.substr(i,s.length-i); }

} function _resubst(s, aa) { var i;	var out = ''; for (i = 0; i < s.length; i++) { var zq = s.substr(i, 1); if (zq == "\\") { zq = s.substr(i, 2); if (zq == "\\1") { zq = aa[1]; } else if (zq == "\\2") { zq = aa[2]; } else if (zq == "\\3") { zq = aa[3]; } else if (zq == "\\4") { zq = aa[4]; } else if (zq == "\\5") { zq = aa[5]; } else if (zq == "\\6") { zq = aa[6]; } else if (zq == "\\7") { zq = aa[7]; } else if (zq == "\\8") { zq = aa[8]; } else if (zq == "\\9") { zq = aa[9]; } else { zq = s.substr(i+1, 1); }			i++; } else if (zq == "&") { zq = aa[0]; }		out += zq; }	return out; } function _calcy(zx, x, g) { if (zx && cursor._lasty != cursory) { cursor._lasty = cursory; var nh = 0; while (zx && zx != document.body) { nh += zx.offsetTop; zx = zx.offsetParent; }		cursor.style.top = nh + 'px'; }

var z = x.substr(cursorx, 1); var q = g.substr(cursorx, 1).charCodeAt(0); if (cursorx >= x.length || z == undefined || z == "\240" || z == '') z = ' '; if (cursor._lastch != z || cursor._lastgh != q) { if (z == ' ') { z = "\240"; q = 0; }		while (cursor.firstChild) cursor.removeChild(cursor.firstChild); cursor.appendChild(document.createTextNode(z));

cursor._lastch = z;		cursor._lastgh = q;

if (q & 1) { cursor.style.fontWeight = 'bold'; } else { cursor.style.fontWeight = 'normal'; }		if (q & 2) { cursor.style.textDecoration = 'underline'; } else { cursor.style.textDecoration = 'none'; }		if (q & 16) { cursor.style.fontStyle = 'italic'; } else { cursor.style.fontStyle = 'normal'; }	} } function term_calcy { // fixup character inside... burrr var xx = file[cursory+base]; var xg = tags[cursory+base]; var zleft = left; if (cursory == (term_rows-1)) { xx = command + " "; zleft = commandleft; xg = _mxs(xx.length+1,0); }	var gg = term.childNodes; if (gg.length > cursory) { gg = term.childNodes[cursory]; } else { gg = undefined; }	_calcy(gg, xx.substr(zleft, xx.length-zleft), xg.substr(zleft, xg.length-zleft)); } function term_calcx { if (cursorx != cursor._lastx) { cursor.style.left = (cursorx * (term_cur_width)) + 'px'; cursor._lastx = cursorx; term_calcy; } } function term_scrollto {

var h = term_rows; var w = term_cols; var x = cursorx+left; var y = cursory+base; var t = file[y];

if (command == '') h--;

var ex = parseInt((w/8)); if (ex < 4) ex = 4; var ey = parseInt((h/8)); if (ey < 4) ey = 4;

while (t == undefined && y > 0) { y--; t = file[y]; }	if (t == undefined) t = ''; if (x >= t.length) { if (mode) x = t.length; else x = t.length-1; }	if (x < 0) x = 0; if (y < 0) y = 0;

if (x < left) { left = (x - ex); cursorx = ex; if (left < 0) { left = 0; cursorx = 0; }	} else if (x >= left+w) { left = (x - w) + ex; cursorx = w - ex; } else { cursorx = x - left; }	if (y < base) { base = (y - ey); cursory = ey; if (base < 0) { base = 0; cursory = 0; }	} else if (y >= base+h) { base = ((y - h) + ey); cursory = (h - ey); } else { cursory = y - base; }	term_calcx; term_calcy; }

function term_insert(y, str) { var z = file.length; file[z] = ''; tags[z] = ''; var i;	for (i = z; i > y; i--) { file[i] = (file[i-1]); tags[i] = (tags[i-1]); }	file[y] = ''; tags[y] = ''; } function term_paste(after, ign) { if (ign != undefined) { yank_buffer = ign; } else { registers['.'] = lastinsert; registers[':'] = oldcommand; registers['%'] = "/tmp/mess4XbCXM"; registers['#'] = ""; yank_buffer = registers[lastreg]; }	if (yank_buffer == undefined) return false; if (yank_buffer.indexOf("\n") > -1) { // insert after this line if (after) cursory++; var nq = yank_buffer.split("\n"); var nj; for (nj = 0; nj < nq.length; nj++) { if (nj == (nq.length-1)) { if (nq[nj] == undefined) break; if (nq[nj] == '') break; // handled specially var aa = _hra(nq[nj]); file[cursory+base+nj] = aa[0] + (file[cursory+base+nj]); tags[cursory+base+nj] = aa[1] + (tags[cursory+base+nj]); break; }			term_insert(cursory+base+nj); var aa = _hra(nq[nj]); file[cursory+base+nj] = aa[0]; tags[cursory+base+nj] = aa[1]; }	} else { var t = (file[cursory+base]); var g = (tags[cursory+base]); var aa = _hra(yank_buffer); if (after) cursorx++; file[cursory+base] = t.substr(0, cursorx+left) + aa[0] + t.substr(cursorx+left, t.length-(cursorx+left)); tags[cursory+base] = g.substr(0, cursorx+left) + aa[1] + g.substr(cursorx+left, g.length-(cursorx+left)); }	return true; } function term_keyfix(e) { if (!e) e = window.event;

var ch = e.keyCode; if (!ch) ch = e.which;

if (e.DOM_VK_UP) { if (e.DOM_VK_UP == ch) ch = 57373; else if (e.DOM_VK_DOWN == ch) ch = 57374; else if (e.DOM_VK_LEFT == ch) ch = 57375; else if (e.DOM_VK_RIGHT == ch) ch = 57376; }

if (ch == 8 || ch == 9 || ch == 37 || ch == 39	|| ch == 38 || ch == 40 || ch == 127	|| ch == 33 || ch == 34 || ch == 36	|| ch == 35 || ch == 45 || ch == 46	|| ch == 57373	|| ch == 57374	|| ch == 57375	|| ch == 57376) { if (e.preventDefault) e.preventDefault; if (e.stopPropagation) e.stopPropagation; term_keypress_inner(e, true); e.cancelBubble=true; return false; } else { e.cancelBubble=false; return true; }

} function term_keypress(e) { if (!e) e = window.event; if (e.preventDefault) e.preventDefault; if (e.stopPropagation) e.stopPropagation; if (suggest._visible) { suggest.style.display = 'none'; suggest._visible = false; }	e.cancelBubble=true; term_keypress_inner(e, false); return false; } function term_keypress_inner(e, synth) { var k = e.which; var kc; if (e.charCode) { if (e.charCode == 27 || e.charCode == 13 || e.charCode == 10				|| e.charCode == 8				|| e.charCode == 9) { k = e.charCode; kc = String.fromCharCode(e.charCode); } else if (e.charCode == 63232) { k = 57373; } else if (e.charCode == 63233) { k = 57374; } else if (e.charCode == 63234) { k = 57375; } else if (e.charCode == 63235) { k = 57376; } else { if (e.charCode == 191) return; // wtf? kc = String.fromCharCode(e.charCode); k = 0; }	} else if (e.keyCode) { k = e.keyCode; if (e.DOM_VK_UP) { if (e.DOM_VK_UP == k) k = 57373; else if (e.DOM_VK_DOWN == k) k = 57374; else if (e.DOM_VK_LEFT == k) k = 57375; else if (e.DOM_VK_RIGHT == k) k = 57376; } else { kc = String.fromCharCode(e.keyCode); }		if (k == 191) return; // unicode i think } else { if (!k || k == 191) return; kc = String.fromCharCode(k); var i;	} var mod; if (e.modifiers) mod = e.modifiers; else mod = 0; var ctrl = e.ctrlKey | (mod & 2); var shift = e.shiftKey | (mod & 4); var meta = e.altKey | e.metaKey | (mod & 1); var lk = lastkey; lastkey = kc;

if (kc == undefined) kc = '';

if (!emacsen && mode == 0) { if (kc == 'U') { if ((base+cursory) == undoy) { var aa = _hra(undoline); file[undoy] = aa[0]; tags[undoy] = aa[1]; }		} else if (kc == 'u' && undoset) { var z = term_freeze; term_thaw(undoset); undoset = z;		}

if (kc == 'u' || kc == 'U') { term_scrollto; term_redraw; lastkey = undefined; return; }	}

var fakemode = false;

// emacsen if (emacsen && meta && (kc == 'x' || kc == 'X')) { kc = ':' fakemode = true; lk = undefined; lastkey = undefined; } else if (ctrl && (kc == 't' || kc == 'T')) { kc = '?' fakemode = true; lk = undefined; lastkey = undefined; } else if (ctrl && (kc == 's' || kc == 'S')) { kc = '/' fakemode = true; lk = undefined; lastkey = undefined; } else if (ctrl && (kc == 'k' || kc == 'K')) { term_command(':d'); lastkey = undefined; return; } else if (emacsen && meta && (kc == 'd' || kc == 'D')) { kc = 'D'; fakemode = true; lk = undefined; lastkey = undefined; } else if (ctrl && (kc == 'a' || kc == 'A')) { kc = '0'; fakemode = true; lk = undefined; lastkey = undefined; } else if (ctrl && (kc == 'd' || kc == 'D')) { if (emacsen) { kc = 'x'; } else { // err... if (!accum) accum=term_rows+1; cursory += parseInt(accum/2)+2; accum=0; term_scrollto; term_redraw; lk = undefined; lastkey = undefined; return; }		fakemode = true; lk = undefined; lastkey = undefined; } else if (ctrl && (kc == 'g' || kc == 'G')) { term_command(':f'); lastkey = undefined; return; } else if (ctrl && (kc == 'e' || kc == 'E')) { if (emacsen) { kc = '$'; } else { if (!accum) accum = 1; cursory += accum; accum = 0; term_scrollto; term_redraw; lk = undefined; lastkey = undefined; return; }		fakemode = true; lk = undefined; lastkey = undefined; } else if (emacsen && meta && (kc == 'b' || kc == 'B')) { kc = 'b'; fakemode = true; lk = undefined; lastkey = undefined; } else if (emacsen && meta && (kc == 'l' || kc == 'L')) { kc = 'e'; fakemode = true; lk = undefined; lastkey = undefined; } else if (emacsen && meta && (kc == 'f' || kc == 'F')) { kc = 'w'; fakemode = true; lk = undefined; lastkey = undefined; } else if (ctrl && (kc == 'f' || kc == 'F')) { if (emacsen) { kc = 'l'; } else { // vi pagedown if (!accum) accum = 0; cursory += (term_rows*accum); accum = 0; term_scrollto; term_redraw; lk = undefined; lastkey = undefined; return; }		fakemode = true; lk = undefined; lastkey = undefined; } else if (ctrl && (kc == 'y' || kc == 'Y')) { if (emacsen) { term_command(':y'); lastkey = undefined; return; } else { if (!accum) accum = 1; cursory -= accum; accum = 0; term_scrollto; term_redraw; lk = undefined; lastkey = undefined; return; }	} else if (ctrl && (kc == 'l' || kc == 'L')) { term_redraw; lk = undefined; lastkey = undefined; return; } else if (ctrl && (kc == 'u' || kc == 'U')) { if (emacsen) { // emacs undo kc = 'u'; } else { // vi pageup if (!accum) accum=term_rows+1; cursory -= parseInt(accum/2)+2; accum=0; term_scrollto; term_redraw; lk = undefined; lastkey = undefined; return; }		fakemode = true; lk = undefined; lastkey = undefined; } else if (ctrl && (kc == 'w' || kc == 'W')) { // vim uses this for window control; this is actually useful fakemode = true; term_vi_set('d'); kc = 'b'; lk = undefined; lastkey = undefined;

} else if (ctrl && (kc == 'b' || kc == 'B')) { if (emacsen) { kc = 'h'; } else { // vi pageup if (!accum) accum=1; cursory -= (term_rows*accum); accum=0; term_scrollto; term_redraw; lk = undefined; lastkey = undefined; return; }		fakemode = true; lk = undefined; lastkey = undefined; }

if (k >= 57373 && k <= 57376 && !synth) { // bail return } else if (!synth && (k < 57373 || k > 57376)) { // no touching... } else if (k == 31 || k == 40 || k == 57374) { // down if (!synth) return; fakemode = true; kc = 'j'; lk = undefined; lastkey = undefined; } else if (k == 30 || k == 38 || k == 57373) { // up		if (!synth) return; fakemode = true; kc = 'k'; lk = undefined; lastkey = undefined; } else if (k == 28 || k == 37 || k == 57375) { // left if (!synth) return; fakemode = true; kc = ctrl ? 'B' : 'h'; lk = undefined; lastkey = undefined; } else if (k == 29 || k == 39 || k == 57376) { // right if (!synth) return; fakemode = true; kc = ctrl ? 'W' : 'l'; lk = undefined; lastkey = undefined; } else if (k == 33) { // pageup cursory -= term_rows; term_scrollto; term_redraw; lk = undefined; lastkey = undefined; return; } else if (k == 34) { // pagedown cursory += term_rows; term_scrollto; term_redraw; lk = undefined; lastkey = undefined; return; } else if (k == 36) { // home if (ctrl) { lk = 'g'; kc = 'g'; } else { kc = '0'; }		fakemode = true; lk = undefined; lastkey = undefined; accum = 0; } else if (k == 35) { // end fakemode = true; accum = 0; if (ctrl) { kc = 'G'; } else { kc = '$'; }		lk = undefined; lastkey = undefined; } else if (k == 45) { // insert fakemode = true; if (mode == 1) { mode = 2; } else if (mode == 2) { mode = 1; } else { term_setmode(1); }		lk = undefined; lastkey = undefined; term_redraw; return; } else if (k == 46) { // delete fakemode = true; kc = 'x'; lk = undefined; lastkey = undefined; } else if (synth && k != 8) { return; }

term_save_undo_line;

if (fakemode || mode == 0) { if (!fakemode && ctrl) return; if (lk == 'F' || lk == 'T' || lk == 'f' || lk == 't') { vi_ft_reg = kc; if (lk == 'F') { term_ex_motion = term_vi_ff; } else if (lk == 'T') { term_ex_motion = term_vi_tt; } else if (lk == 'f') { term_ex_motion = term_vi_f; } else if (lk == 't') { term_ex_motion = term_vi_t; }			term_operate; lastkey = undefined; term_scrollto; term_redraw; _update_backing; return; } else if (lk == 'm') { // set mark marks[kc] = cursory+base; lastkey = undefined; accum = 0; return;

} else if (lk == "'") { term_ex_motion = function { cursory = marks[kc]; base = 0; term_scrollto; term_redraw; return true; };			if (!accum) accum = 1; term_operate; return;

} else if (lk == '"') {			// set last register			lastreg = kc;			lastkey = undefined;			accum = 0;			return;

} else if (lk == 'r') { var p = cursorx + left; var t = (file[cursory+base]); if (!accum) accum = 1; var ng = ''; var i;			for (i = 0; i < accum; i++) ng += kc; term_save_undo; file[cursory+base] = (t.substr(0, p)) + (ng) + (t.substr(p+accum, t.length-(p+accum))); // tags remains unchanged (same length) accum = 0; lastkey = undefined; term_scrollto; term_redraw; _update_backing; _term_update_printer; return; }

if (kc == ':' || kc == '/' || kc == '?') { command = kc; commandleft = 0; savex = cursorx; savey = cursory; cursorx = 1; cursory = term_rows-1; mode=1; term_redraw; term_calcx; return; } else if (kc == "'") { // jump to mark (ick) } else if (kc == '"') {			// do nothing for now

} else if (kc == '.') { term_vi_set(lastcommand); term_ex_motion = lastmotion; term_operate;

} else if (kc == '$') { term_ex_motion = term_vi_eol; term_operate;

} else if (kc == '^') { //term_ex_motion = term_vi_eol; cursorx = left-1; term_operate;

} else if (kc == '%') { if (accum <= 0) { term_ex_motion = term_vi_bounce; term_operate; } else if (file.length > 0) { base = 0; cursorx = 0; left = 0; cursory = parseInt(accum * (term_rows / (file.length+1.0))); accum = 0; }

} else if (kc == '0') { if (accum) { accum *= 10; } else { cursorx = 0; left = 0; }		} else if (kc == '1') { accum *= 10; accum++; } else if (kc == '2') { accum *= 10; accum += 2; } else if (kc == '3') { accum *= 10; accum += 3; } else if (kc == '4') { accum *= 10; accum += 4; } else if (kc == '5') { accum *= 10; accum += 5; } else if (kc == '6') { accum *= 10; accum += 6; } else if (kc == '7') { accum *= 10; accum += 7; } else if (kc == '8') { accum *= 10; accum += 8; } else if (kc == '9') { accum *= 10; accum += 9; } else if (kc == 'A') { var t = (file[cursory+base]); cursorx = t.length; // will be fixed up... term_setmode(1); term_save_undo; } else if (kc == 'a') { term_setmode(1); cursorx++; term_save_undo; } else if (kc == 'B') { term_ex_motion = term_vi_bb; term_operate; } else if (kc == 'b') { term_ex_motion = term_vi_b; term_operate; } else if (kc == 'c') { if (term_vi_flag('c')) { term_vi_set('d'); term_vi_unset('c'); savex = cursorx+left; savey = cursory+base; cursorx = 0; left = 0; term_ex_motion = term_vi_line; term_operate; cursorx = savex-left; cursory = savey-base; term_setmode(1); } else { term_vi_set('c'); }		} else if (kc == 'C') { term_ex_motion = term_vi_eol; term_vi_set('d'); term_operate; term_setmode(1); //hack from hn comment cursorx = 1; term_operate; } else if (kc == 'D') { term_ex_motion = term_vi_eol; term_vi_set('d'); term_operate; } else if (kc == 'd') { if (vselm) { term_vi_set('d'); term_vi_unset('y'); term_select; term_operate; vselm = 0; } else if (term_vi_flag('d')) { accum++; savex = cursorx+left; savey = cursory+base; cursorx = 0; left = 0; term_ex_motion = term_vi_line; term_operate; cursorx = savex-left; cursory = savey-base; } else { term_vi_set('d'); term_vi_unset('y'); }		} else if (kc == '>' || kc == '<') { if (vselm) { term_vi_unset('<'); term_vi_unset('>'); term_vi_set(kc); term_vi_unset('d'); term_vi_unset('y'); term_operate; vselm = 0; } else if (term_vi_flag(kc)) { accum++; savex = cursorx+left; savey = cursory+base; cursorx = 0; left = 0; term_ex_motion = term_vi_line; term_operate; cursorx = savex-left; cursory = savey-base; term_vi_unset('<'); term_vi_unset('>'); } else { term_vi_unset('<'); term_vi_unset('>'); term_vi_set(kc); term_vi_unset('d'); term_vi_unset('y'); }

} else if (kc == 'E') { term_ex_motion = term_vi_ee; term_operate; } else if (kc == 'e') { term_ex_motion = term_vi_e; term_operate;

} else if (kc == 'F' || kc == 'f') { // does nothing here } else if (kc == 'G') { term_ex_motion = term_vi_eof; term_operate;

} else if (kc == 'g' && lk == 'g') { term_ex_motion = term_vi_top; term_operate;

} else if (kc == 'H') { term_ex_motion = term_vi_hh; term_operate;

} else if (kc == 'h') { term_ex_motion = term_vi_h; term_operate;

} else if (kc == 'I') { term_save_undo; if (vselm) { term_vi_set('d'); term_vi_unset('y'); term_select; term_operate; vselm = 0; }			term_setmode(1); cursorx = 0; left = 0; } else if (kc == 'i') { term_save_undo; if (vselm) { term_vi_set('d'); term_vi_unset('y'); term_select; term_operate; vselm = 0; }			term_setmode(1); } else if (kc == 'J') { term_save_undo; term_justify; } else if (kc == 'j') { term_ex_motion = term_vi_j; term_operate; } else if (kc == 'K') { // err.. } else if (kc == 'k') { term_ex_motion = term_vi_k; term_operate; } else if (kc == 'L') { term_ex_motion = term_vi_ll; term_operate; } else if (kc == 'l') { term_ex_motion = term_vi_l; term_operate; } else if (kc == 'M') { term_ex_motion = term_vi_mm; term_operate; } else if (kc == 'm') { // set mark } else if (kc == 'N') { if (lastsearch == '') { statustext = 'No previous regular expression'; } else { if (!accum) accum = 1; var sl = lastsearch; var cx = lastsearch.substr(0, 1); cx = (cx == '?') ? '/' : '?';				var i;				for (i = 0; i < accum; i++) { term_command(cx+(sl.substr(1, sl.length-1))); }				lastsearch = sl; accum = 0; }		} else if (kc == 'n') { if (lastsearch == '') { statustext = 'No previous regular expression'; } else { if (!accum) accum = 1; var i;				for (i = 0; i < accum; i++) term_command(lastsearch); accum = 0; }		} else if (kc == 'O') { cursorx = 0; left = 0; term_insert(cursory+base); term_setmode(1); } else if (kc == 'o') { cursory++; cursorx = 0; left = 0; term_insert(cursory+base); term_setmode(1); term_save_undo; } else if (kc == 'P' || kc == 'p') { term_save_undo; term_paste(kc == 'P' ? false : true); accum = 0;

} else if (kc == 'R') { term_save_undo; if (vselm) { term_vi_set('d'); term_vi_unset('y'); term_select; term_operate; vselm = 0; }			term_setmode(2);

} else if (kc == 'S') { term_vi_set('d'); term_vi_unset('c'); savex = cursorx+left; savey = cursory+base; cursorx = 0; left = 0; term_ex_motion = term_vi_line; term_operate; cursorx = savex-left; cursory = savey-base; term_setmode(1);

} else if (kc == 's') { term_vi_set('d'); term_vi_unset('c'); savex = cursorx+left; savey = cursory+base; term_ex_motion = term_vi_l; term_operate; cursorx = savex-left; cursory = savey-base; term_setmode(1);

} else if (kc == 'T' || kc == 't') { // nothing here } else if (kc == 'V' || kc == 'v') { if (vselm) { vselm = 0; vselx = undefined; vsely = undefined; } else { vselm = (kc == 'v') ? 1 : 2;				vselx = cursorx+left; vsely = cursory+base; }

} else if (kc == 'W') { term_ex_motion = term_vi_ww; term_operate; } else if (kc == '{') { term_ex_motion = term_vi_ob; term_operate; } else if (kc == '}') { term_ex_motion = term_vi_cb; term_operate; } else if (kc == 'w') { term_ex_motion = term_vi_w; term_operate; } else if (kc == 'x' || kc == 'X') { if (term_vi_set('d')) { term_vi_unset('d'); } else { term_vi_set('d'); if (kc == 'x') { term_ex_motion = term_vi_l; } else { term_ex_motion = term_vi_h; }				term_operate; }		} else if (kc == 'y') { if (vselm) { term_vi_set('y'); term_vi_unset('d'); term_select; term_operate; vselm = 0; } else if (term_vi_flag('y')) { accum++; savex = cursorx+left; savey = cursory+base; cursorx = 0; left = 0; term_ex_motion = term_vi_line; term_operate; cursorx = savex-left; cursory = savey-base; } else { term_vi_set('y'); term_vi_unset('d'); }		} else if (kc == 'Z' && lk == 'Z') { editor_disable(true); accum = 0; } else if (k == 27 || (k == 91 && ctrl)) { // escape or ^[ vselm = 0; statustext = ''; mode = 0; } else { accum = 0; }		term_scrollto; } else if ((k == 27 || (k == 91 && ctrl))) { // escape or ^[ vselm = 0; statustext = ''; if (command != '') { cursorx = savex; cursory = savey; } else { if (mode) _term_update_printer; if (accum > 1) { var i, j;				j = lastreg; lastreg = '.'; for (i = 1; i < accum; i++) { term_paste(false); }				lastreg = j;				accum = 0; }			cursorx--; term_scrollto; }		mode = emacsen ? 1 : 0;		command = ''; commandleft = 0; } else if (command != '') { if (k == 10 || k == 13) { // cr and execute command cursorx = savex; cursory = savey; if (emacsen) { mode = 1; } else { mode = 0; }			var cy = command;

command = ''; commandleft = 0;

term_command(cy); var cx = command.substr(0,1); if (cx == '/' || cx == '?') lastsearch = cy; else oldcommand = cy; // incase its needed term_scrollto; } else if (k == 8) { if (!synth) return; command = command.substr(command, command.length-1); cursorx--; if (cursorx <= 0) { var w = term_cols; commandleft -= (w-16); cursorx = w - 8; if (commandleft < 0) { cursorx = savex; cursory = savey; if (emacsen) { mode = 1; } else { mode = 0; }				}			}		} else { command = command + kc; cursorx++; var w = term_cols; if (cursorx >= (w-8)) { cursorx = 8; commandleft += w-16; }		}		term_redraw; term_calcx; _update_backing; return; } else { var t = (file[cursory+base]); var lx = (t.substr(0, cursorx+left)); var ly = (t.substr(cursorx+left+(mode-1))); var lz = (t.substr(cursorx+left)); var g = (tags[cursory+base]); var gx = (g.substr(0, cursorx+left)); var gy = (g.substr(cursorx+left+(mode-1))); var gz = (g.substr(cursorx+left)); if (!lx) lx = ''; if (k == 9) kc = '       '; if (k == 10 || k == 13) { // CR			if (!lz) lz = ''; file[cursory+base] = lx; tags[cursory+base] = gx; cursory++; cursorx=0; left=0; term_insert(cursory+base); file[cursory+base] = lz; tags[cursory+base] = gz; lastinsert += "\n"; } else if (k == 8) { if (!synth) return; // backspace file[cursory+base] = lx.substr(0,lx.length-1)+lz; tags[cursory+base] = gx.substr(0,lx.length-1)+gz; lastinsert = lastinsert.substr(0,lastinsert.length-1); cursorx--; } else { if (kc == '') return; file[cursory+base] = lx+kc+ly; tags[cursory+base] = gx+String.fromCharCode(tagstyle)+gy; lastinsert += kc; cursorx+=kc.length; }		term_scrollto; }

term_redraw; _update_backing; return; }

function do_escape { vselm = 0; statustext = ''; mode = 0; term_redraw; _update_backing; return; }

$(document).keyup(function(e) {        if(e.keyCode== 27) {	do_escape;    } });

function _redraw_cursor { term_draw_cursor(true); _update_backing; }

function term_draw_cursor(tf) { // maybe use vertical bar if mode==1 hrm? if (!tf || !cursor._opaque) { cursor._opaque = true; cursor.style.color = palette[1]; cursor.style.backgroundColor = palette[0]; } else { cursor._opaque = false; cursor.style.color = palette[0]; cursor.style.backgroundColor = palette[1]; } }

function _redraw_term_force { while (term.firstChild) term.removeChild(term.firstChild); } function _redraw_term {

var h = term_rows; var w = term_cols;

var ka, kb; var tospell = 0; var osp = ''; var y;	var tago = new Array; var isurl = new Array; var ca, cb; var sa, sb; var qp; if (vselm) { sa = vsely-base; sb = cursory; if (sa > sb) { zx = sa; sa = sb; sb = zx; }		ca = vselx-left; cb = cursorx; if (ca > cb) { zx = ca; ca = cb; cb = zx; }	}	for (y = 0; y < h; y++) { ka = ; kb = ; var x = file[y+base]; var g;

var zleft = 0; var cx; var j, vj; if (y == (h-1)) { if (cursory == y) { zleft = commandleft; x = command; cx = 0; statustext = ''; } else if (emacsen) { x = '[' + (mode == 1 ? 'Ins' : 'Ovr') + '] ' + statustext; while (x.length < w) { x += ' '; }				cx = 4; } else if (vselm == 1) { cx = 1; x = '-- VISUAL --'; statustext = ''; } else if (vselm == 2) { cx = 1; x = '-- VISUAL LINE --'; statustext = ''; } else if (mode == 0) { x = statustext; cx = 16; } else if (mode == 1) { cx = 1; x = '-- INSERT --'; statustext = ''; } else if (mode == 2) { cx = 1; x = '-- REPLACE --'; statustext = ''; }			g = _mxs(x.length, cx); } else if (x == undefined) { x = '~'; g = "\010"; } else { zleft = left; g = tags[y+base]; // do spellchecking var p = 0; vj = x.split(/[ ,;]+/); for (j = 0; j < vj.length; j++) { var vx = vj[j]; var vm = _word(vx); if (j != 0) p++;

if (vx.match(/^(https?|ftp):\/\//)) { g = g.substr(0, p)						+ _mxo(g.substr(p, vx.length), ((1+tago.length)*256)) + g.substr(p+vx.length); isurl[tago.length] = true; tago[tago.length] = vx;

} else if (brokenwords[vm] && !safewords[vm]) { g = g.substr(0, p)						+ _mxo(g.substr(p, vx.length), ((1+tago.length)*256)) + g.substr(p+vx.length); isurl[tago.length] = false; tago[tago.length] = vx; } else { if (vm.length > 3 && !_safe(vm) && !safewords[vm] && !spelling) { tospell++; osp += escape("c"+tospell) + "=" + escape(vm) + "&"; spellcheck[tospell] = vm; }				}				p += vx.length; }		}		if (x == undefined) { x = ''; g = ''; }

var zx; vx = 0;

// truncate as necessary x = x.substr(zleft, x.length-zleft); g = g.substr(zleft, g.length-zleft); if (x.length >= w) { x = x.substr(0, w); g = g.substr(0, w); }

if (vselm) { if (vselm == 1 && sa == sb && sa == y) { // middle of line between ca->cb is selected g = g.substr(0,ca) + _mxo(g.substr(ca,(cb-ca)+1), 4) + g.substr(cb,(g.length-cb)-1); } else if ((sa < y && sb > y) || (vselm == 2 && (sa <= y && sb >= y))) { // entire line selected g = _mxo(g, 4); } else if (sa < y && sb == y) { // beginning of line selected (up to q)				// if (sb is cursory) then q = cursorx otherwise vselx qp = (sb == cursory) ? cursorx : (vselx-left); g = _mxo(g.substr(0, qp+1), 4) + g.substr(qp, (g.length-qp)-1); } else if (sa == y && sb > y) { // end of line selected (beginning at q)				// if (sa is cursory) then q = cursorx otherwise vselx qp = (sa == cursory) ? cursorx : (vselx-left); g = g.substr(0, qp) + _mxo(g.substr(qp, g.length-qp), 4); }		}

vj = 0; g += "\377"; // terminate x += " "; x = x.replace(/ /g, "\240");

if (term.childNodes.length > y) { zx = term.childNodes[y]; if (zx._cachex == x && zx._cacheg == g) { if (y == cursory) _calcy(zx, x, g); continue; }

// as a last ditch effort- to accelerate deletions... // and inserts... if (term.childNodes.length > (y+1)) { var zy = term.childNodes[y+1]; if (zy._cachex == x && zy._cacheg == g) { // okay then, so the NEXT line is the winner // copy its nodes term.removeChild(zy); term.replaceChild(zy, zx); if (zy.nextSibling) { term.insertBefore(zx, zy.nextSibling); } else { term.appendChild(zx); }					if (y == cursory) _calcy(zy, x, g); continue; }			}

// update while (zx.firstChild) zx.removeChild(zx.firstChild); } else { zx = document.createElement('PRE'); zx.style.display='block'; zx.style.fontFamily = 'monospace'; zx.style.fontSize = '100%'; _zmp(zx); zx.style.marginBottom = '1px'; }

cx = 255; var ax = zx;

for (j = 0; j < x.length; j++) { var gx = g.charCodeAt(j);

if (gx != cx) { if (j != vj && ax) { var t = x.substr(vj, (j-vj)); if (!t) t = ''; ax.appendChild(document.createTextNode(t)); if (zx != ax) zx.appendChild(ax); vj = j;				}

if (gx > 255) { var wx = parseInt(gx / 256)-1;

ax = document.createElement('A'); if (isurl[wx]) { ax.style.borderBottom = '1px double blue'; ax.href = tago[wx]; ax.target = '_new'; ax.ondblclick = _openurl; } else { ax.style.borderBottom = '1px dashed red'; ax.href = 'javascript:void(0)'; ax.ondblclick = _suggest; }					ax._term = _word(tago[wx]); ax._len = tago[wx].length; ax._row = y+base; ax._col = j+zleft; ax.onclick = _subclick; } else { ax = document.createElement('SPAN'); }				if (gx == 255) gx = 0; if (gx & 1) { ax.style.fontWeight = 'bold'; } else { ax.style.fontWeight = 'normal'; }				if (gx & 2) { ax.style.textDecoration = 'underline'; } else { ax.style.textDecoration = 'none'; }				if (gx & 4) { // reverse video ax.style.color = palette[1]; ax.style.backgroundColor = palette[0]; } else { ax.style.color = palette[0]; ax.style.backgroundColor = palette[1]; }				if (gx & 8) { // unselectable ax.unselectable = true; if (ax.setAttribute) ax.setAttribute('unselectable', 'on'); ax.style.color = palette[0]; ax.style.backgroundColor = palette[1]; ax.style.userSelect = 'none'; ax.style['-moz-user-select'] = 'none'; }				if (gx & 16) { ax.style.fontStyle = 'italic'; } else { ax.style.fontStyle = 'normal'; }				cx = gx; }		}		if (j != vj) { var t = x.substr(vj, (j-vj)-1); ax.appendChild(document.createTextNode(t)); if (zx != ax) zx.appendChild(ax); vj = j;		} ax.appendChild(document.createTextNode("\240")); zx._cachex = x;		zx._cacheg = g;		if (term.childNodes.length <= y) { term.appendChild(zx); }

if (y == 1) { var qx = zx; var nh = 0; while (qx && qx != document.body) { nh += qx.offsetTop; qx = qx.offsetParent; }			if (nh != line_height) { line_height = nh; term_resize; }		}

if (y == cursory) { _calcy(zx, x, g); }

ax = undefined; // break; }	while (term.childNodes.length > h) { term.removeChild(term.lastChild); }	zx = undefined; // break

if (!spelling && tospell > 0 && false) { spelling = true; var xh = _xhttp; osp=osp.substr(0,osp.length-1); xh.open("GET", "spell.cgi?"+osp, true); xh.onreadystatechange = function { if (xh.readyState == 4) { var j;				var a = xh.responseText.split("\n"); for (j = 0; j < a.length; j++) { var kp = a[j].split("=", 2); var k, v;					if (kp.length == 2) { k = kp[0]; v = kp[1]; } else if (kp.length == 1) { k = kp[0]; v = ''; } else { k = a[j]; v = ''; }					if (k.substr(0,1) != 'c') continue; k = k.substr(1, k.length-1); var term = spellcheck[k]; if (v == undefined || v == '') { brokenwords[term] = true; suggestions[term] = new Array; } else if (v == term) { safewords[term] = true; } else { safewords[v] = true; if (!suggestions[term]) { suggestions[term] = new Array; }						suggestions[term][ suggestions[term].length ] = v;						brokenwords[term] = true; }				}				spelling=false; window.setTimeout(term_redraw,10); xh = undefined; // break (deferred) }		};		xh.send(undefined); }	if (cursory == (h-1)) { tools.style.display = 'none'; } else { tools.style.display = 'block'; }	_update_backing; }

function _redraw_term_back { drawiv = undefined; _redraw_term; term_draw_cursor; } function term_redraw { if (drawiv) window.clearTimeout(drawiv); drawiv = window.setTimeout(_redraw_term_back, 10); }

function term_resize { var h = term.offsetHeight; var r = line_height; if (!line_height) r = cursor.offsetHeight-1; // 1 px overlap var nh = (h/r); term_rows = parseInt(nh); term_win_height = h;	h = term.offsetWidth; r = (term_cur_width+1); // 1 px padding nh = (h/r); term_cols = parseInt(nh); term_win_width = h;

term_redraw; } function editor_disable(sav) { self.close; //close the window statustext = "Can't close the window"; term_redraw; location.reload(true); return; //rest isn't needed

if (cursoriv) { window.clearInterval(cursoriv); cursoriv = undefined; }

_cbrestore;

if (term._formelement) { if (sav) term._formelement.value = term_freeze;

// disconnect term._formelement = undefined; }

if (backing.removeEventListener) { backing.removeEventListener('DOMAttrModified',_backing_paste,false); backing.removeEventListener('Input',_backing_paste,false); backing.removeEventListener('input',_backing_paste,false); }	backing.oninput = undefined; backing.onInput = undefined;

document.body.removeChild(suggest); document.body.removeChild(term); document.body.removeChild(printer); document.body.removeChild(tools); document.body.removeChild(cursor);

var z;	for (z = document.body.firstChild; z; z = z.nextSibling) { if (z.tagName && z._flipe) z.style.display = z._orige; }

// bug in firefox: can't remove this //document.body.removeChild(backing); if (backing.blur) backing.blur; backing.style.display = 'none'; if (document.body.focus) document.body.focus; if (document.focus) document.focus;

document.body.style.overflow = ''; } function _cursor_fix { term_cur_width = cursor.offsetWidth; } function _zmp(o) { o.style.marginTop='0px'; o.style.marginLeft='0px'; o.style.marginRight='0px'; o.style.marginBottom='0px'; o.style.paddingTop='0px'; o.style.paddingLeft='0px'; o.style.paddingRight='0px'; o.style.paddingBottom='0px'; } function editor(t) { if (term && term._formelement && term._formelement != t) { editor_disable(false); }

// okay, find EVERYTHING inside body and display none it	var z;	for (z = document.body.firstChild; z; z = z.nextSibling) { if (z.tagName) { z._orige = z.style.display; z._flipe = true; z.style.display = 'none'; }	}

if (!term) { term = document.createElement('DIV'); printer = document.createElement('DIV'); suggest = document.createElement('DIV'); backing = document.createElement('TEXTAREA'); tools = document.createElement('DIV'); cursor = document.createElement('DIV'); }

//	if (document.documentElement) { //		_zmp(document.documentElement); //		document.documentElement.height = '100%'; //		_zmp(document.body); //		document.body.height = '100%'; //	}

printer.className = 'print'; cursor.className = 'editorcursor'; term.className = 'editor';

suggest.style.position = 'absolute'; suggest.style.display = 'none';

backing.tabIndex = -1; backing.style.position = 'absolute'; backing.style.bottom = '0px'; backing.style.right = '0px'; backing.style.width = '1px'; backing.style.height = '1px'; backing.style.visibility = 'hidden'; backing.oninput = _backing_paste; backing.onInput = _backing_paste; if (backing.addEventListener) { backing.addEventListener('DOMAttrModified',_backing_paste,false); backing.addEventListener('Input',_backing_paste,false); backing.addEventListener('input',_backing_paste,false); }	if (window.addEventListener) { window.addEventListener('DOMMouseScroll',_mousescroll,false); }	tools.className = 'editortools'; tools.style.position = 'absolute'; tools.style.right = '0px'; tools.style.bottom = '0px'; tools.innerHTML = ''; cursor.onclick = _pass_click; cursor.ondblclick = _pass_dblclick;

document.body.appendChild(suggest); document.body.appendChild(term); document.body.appendChild(printer); document.body.appendChild(tools); // firefox bug if (once) document.body.appendChild(backing); document.body.appendChild(cursor);

cursoriv = window.setInterval(_redraw_cursor, 300);

term.style.position = 'absolute'; term.style.top = '0px'; term.style.left = '0px'; term.style.display = 'block'; term.style.overflow = 'hidden'; term.style.width = '100%'; term.style.height = '100%'; term.style.cursor = 'default'; term.style.fontFamily = 'monospace'; term.style.fontSize = '100%'; _zmp(term); term._formelement = t;

//load from filepicker var f = gup('f'); if (f) { term.filePickerHandle = f;		$.ajax({url: f,			success: function(data) {				term._formelement.value = data;				term_thaw(term._formelement.value);				term._formelement.value = term_freeze;				term_redraw;			}}); }	document.body.style.overflow = 'hidden'; tools.style.display = 'block';

_cbd('select', _cancel_ev); _cbd('selectstart', _cancel_ev); _cbd('keydown', term_keyfix); _cbd('keypress', term_keypress); _cbd('paste', _msie_paste); _cbd('click', _mouseclick); _cbd('mousedown', _mousedown); _cbd('mousemove', _mousemove); _cbd('mouseup', _mouseup); _cbd('mousewheel', _mousescroll);

vselm = 0; vseld = false; vselx = undefined; vsely = undefined;

t.blur; cursorx = 0; cursory = 0; cursor.style.position = 'absolute'; cursor.style.top = 0; cursor.style.left = 0; cursor.style.fontFamily = 'monospace'; cursor.style.fontSize = '100%'; cursor.style.width = 'auto'; cursor.style.cursor = 'default'; _zmp(cursor); cursor.style.overflow = 'hidden'; cursor.innerHTML = 'X'; cursor._opaque = false; cursor._lasty = -1; cursor._lastx = -1; cursor._lastch = '-xyz-'; cursor._lastgh = 0; palette = undefined;

if (document.defaultView && document.defaultView.getComputedStyle) { palette = new Array; var cs = document.defaultView.getComputedStyle(term, null); palette[0] = cs.color; palette[1] = cs.backgroundColor; } else if (window.getComputedStyle) { palette = new Array; var cs = window.getComputedStyle(term, null); palette[0] = cs.color; palette[1] = cs.backgroundColor; } else if (term.currentStyle) { palette = new Array; palette[0] = term.currentStyle.color; palette[1] = term.currentStyle.backgroundColor; }

if (emacsen) { mode = 1; } else { mode = 0; }

once = false;

backing._lastvalue = ''; backing.value = ''; backing.defaultValue = ''; suggest._visible = false; suggest.display = 'none';

tools.style.backgroundColor = palette[0]; _dfx(tools);

// degrading... file = new Array; tags = new Array; var st = t.value.split("\n"); var j;	for (j = 0; j < st.length; j++) { if (st[j].substr(st[j].length-1, 1) == "\r") { st[j] = st[j].substr(0, st[j].length-1); }		var aa = _hra(st[j]); file[j] = aa[0]; tags[j] = aa[1]; }	// fix t.value = term_freeze; _term_update_printer;

cursor.style.display = 'inline'; _cursor_fix; window.setTimeout(term_redraw,1); term_resize;

_cbw('resize', term_resize); _cbw('beforeprint', _term_update_printer); _update_backing; }

/* enter edit mode */

if(mw.config.get('wgAction') === 'edit') { editor(document.forms[0].elements.wpTextbox1); }