/vi.js
JavaScript | 3883 lines | 3671 code | 136 blank | 76 comment | 674 complexity | c1ae2ce7d6cb1908c44538eecb70e1fa MD5 | raw file
Large files files are truncated, but you can click here to view the full file
- /*
- 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 jsvi = (function () {
- var version = '1.0',
- emacsen = false,
- term_cols,
- term_rows,
- term_win_width,
- term_win_height,
- term_cur_width,
- tools,
- suggest,
- backing,
- tagstyle = 0,
- line_height = 0,
- cclick,
- mode = 0,
- accum = 0,
- lastaccum = 0,
- marks = {},
- registers = {},
- lastreg = '',
- lastcommand,
- lastmotion,
- cursoriv,
- drawiv,
- printer,
- term,
- base = 0,
- left = 0,
- vselm = 0,
- vselx,
- vsely,
- vseld = false,
- lastkey,
- statustext = '',
- command = '',
- oldcommand = '',
- commandleft = 0,
- savex, savey,
- once = true,
- cursorx, cursory,
- file = [],
- tags = [],
- palette,
- cursor,
- yank_buffer,
- term_save_h = [],
- term_save_ss,
- term_save_mc,
- term_save_kd,
- term_save_kp,
- term_save_rs,
- term_save_op,
- lastsearch,
- lastsubst,
- lastflags,
- undoset,
- undoline,
- undoy = -1,
- term_ex_motion,
- vi_ft_reg,
- viflags = '',
- lastinsert = '',
- spelling = false,
- spellcheck = {},
- safewords = {},
- brokenwords = {},
- suggestions = {},
- doing_backing_paste = false;
- 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;
- function _cbrestore() {
- var i, z;
- for (i = 0; i < term_save_h.length; i++) {
- z = term_save_h[i];
- z();
- }
- term_save_h = [];
- }
- 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;
- }
- var s, j;
- // emulate rightContext
- 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 "";
- }
- 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;
- }
- var s, j;
- // emulate leftContext
- 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);
- }
- j = t.indexOf(aa[0]);
- if (j !== -1) {
- return t.substr(0, j);
- }
- return "";
- }
- function _hra(x) {
- var i,
- cx = 0,
- t = '',
- g = '',
- x3, gx,
- aa = [];
- for (i = 0; i < x.length; i++) {
- x3 = x.substr(i, 3);
- gx = String.fromCharCode(cx);
- if (x3 === '<b>') {
- cx = cx | 1;
- i += 2;
- } else if (x3 === '</b') {
- cx = (cx | 1) ^ 1;
- i += 3;
- } else if (x3 === '<u>') {
- cx = cx | 2;
- i += 2;
- } else if (x3 === '</u') {
- cx = (cx | 2) ^ 2;
- i += 3;
- } else if (x3 === '<i>') {
- cx = cx | 16;
- i += 2;
- } else if (x3 === '</i') {
- cx = (cx | 16) ^ 16;
- i += 3;
- } else if (x3 === '<sp') { // <span class="rv">
- cx = cx | 4;
- i += 16;
- } else if (x3 === '</s') { // </span>
- cx = (cx | 4) ^ 4;
- i += 6;
- } else if (x3 === '&am') { // &
- t += '&';
- g += gx;
- i += 4;
- } else if (x3 === '<') { // <
- t += '<';
- g += gx;
- i += 3;
- } else {
- t += x.substr(i, 1);
- g += gx;
- }
- }
- aa[0] = t;
- aa[1] = g;
- return aa;
- }
- function _rtf(t, g) {
- var cx = 0,
- i,
- o = '',
- gx, tx;
- if (t === undefined) {
- t = '';
- g = '';
- }
- for (i = 0; i < t.length; i++) {
- gx = g.substr(i, 1).charCodeAt(0);
- tx = t.substr(i, 1);
- if (tx === "<") {
- tx = "<";
- }
- else if (tx === '&') {
- tx = '&';
- }
- if (gx !== cx) {
- if ((gx & 1) && !(cx & 1)) {
- o += "<b>";
- } else if (!(gx & 1) && (cx & 1)) {
- o += "</b>";
- }
- if ((gx & 2) && !(cx & 2)) {
- o += "<u>";
- } else if (!(gx & 2) && (cx & 2)) {
- o += "</u>";
- }
- if ((gx & 4) && !(cx & 4)) {
- o += "<span class=\"rv\">";
- } else if (!(gx & 4) && (cx & 4)) {
- o += "</span>";
- }
- if ((gx & 16) && !(cx & 16)) {
- o += "<i>";
- } else if (!(gx & 16) && (cx & 16)) {
- o += "</i>";
- }
- cx = gx;
- }
- 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,
- o = '';
- for (i = 0; i < file.length; i++) {
- o += _rtfl(i) + "\n";
- }
- return o;
- }
- function _term_update_printer() {
- var i,
- o = '';
- for (i = 0; i < file.length; i++) {
- o += _rtfl(i) + "<br/>";
- }
- printer.innerHTML = o;
- }
- function term_thaw(s) {
- var a = s.split("\n"),
- i,
- aa,
- o = '';
- file = [];
- tags = [];
- for (i = 0; i < a.length; i++) {
- o += a[i] + "<br/>";
- aa = _hra(a[i]);
- file[i] = aa[0];
- tags[i] = aa[1];
- }
- printer.innerHTML = o;
- }
- function _mxo(z, y) {
- var i,
- 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),
- i,
- 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'),
- i, j;
- for (i = 0; i < d.length; i++) {
- 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 _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 _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 _redraw_term() {
- var h = term_rows,
- w = term_cols,
- ka, kb,
- tospell = 0,
- osp = '',
- y,
- tago = [],
- isurl = [],
- ca, cb,
- sa, sb,
- qp, zx;
- 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],
- g,
- zleft = 0,
- cx,
- 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 = '';
- }
- // 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) {
- spelling = true;
- var xh = new XMLHttpRequest();
- 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] = [];
- } else if (v === term) {
- safewords[term] = true;
- } else {
- safewords[v] = true;
- if (!suggestions[term]) {
- suggestions[term] = [];
- }
- suggestions[term][ suggestions[term].length ] = v;
- brokenwords[term] = true;
- }
- }
- spelling = false;
- window.setTimeout(term_redraw, 10);
- xh = undefined; // break (deferred)
- }
- };
- //HACK: Too this out, replace with an actual app :)
- //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 _cursortoxy(x, y) {
- // this is a little gross...
- var sx = cursorx,
- sy = cursory;
- cursorx = parseInt(x / term_cur_width, 10);
- term_redraw();
- 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 _willclick(e) {
- if (window.event) {
- if (!e) {
- e = window.event;
- }
- }
- if (!e) {
- return true;
- }
- if (cclick !== undefined) {
- window.clearTimeout(cclick);
- }
- var x = e.clientX,
- y = e.clientY;
- cclick = window.setTimeout(function () {
- cclick = undefined;
- _cursortoxy(x, y);
- }, 200);
- return false;
- }
- function _subclick(e) {
- return _willclick(e);
- }
- function term_save_undo() {
- undoset = term_freeze();
- }
- 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,
- x = this._col,
- len = this._len,
- rep = this._word,
- t = (file[y]),
- g = (tags[y]),
- w = (t.substr(x, len)),
- 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,
- y = 0,
- xt = z._term,
- wrow = z._row,
- wcol = z._col,
- wlen = z._len,
- sg, sa, i, fs, fd, bf, da;
- 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);
- }
- 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';
- sa = suggestions[xt];
- fs = 200;
- fd = parseInt((100 / sa.length) * 1.5);
- for (i = 0; i < sa.length; i++) {
- 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 _mousescroll(e) {
- if (!e) {
- e = window.event;
- }
- var d = 0;
- if (e.wheelDelta) {
- d = e.wheelDelta;
- d = d < 0 ? 1 : -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) {
- 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) {
- 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 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;
- …
Large files files are truncated, but you can click here to view the full file