PageRenderTime 41ms CodeModel.GetById 31ms RepoModel.GetById 0ms app.codeStats 1ms

/vi/vi.js

https://github.com/10gen/external
JavaScript | 3799 lines | 3619 code | 93 blank | 87 comment | 740 complexity | 775a4d065f9b0a74ceac66f1a6152e71 MD5 | raw file
Possible License(s): LGPL-2.1, BSD-3-Clause, LGPL-2.0, MIT, Unlicense
  1. /*
  2. JSVI - VI in JavaScript.
  3. Copyright (C) 2006-2008 Internet Connection, Inc.
  4. This program is free software; you can redistribute it and/or modify
  5. it under the terms of the GNU General Public License as published by
  6. the Free Software Foundation; either version 3 of the License, or
  7. (at your option) any later version.
  8. This program is distributed in the hope that it will be useful,
  9. but WITHOUT ANY WARRANTY; without even the implied warranty of
  10. MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  11. GNU General Public License for more details.
  12. You should have received a copy of the GNU General Public License
  13. along with this program; if not, write to the Free Software
  14. Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
  15. */
  16. var emacsen = false;
  17. /* TODO
  18. sortof bugs:
  19. the toolbar is kind of ugly- possibly replace with an image-version-
  20. or more likely- replace with styled buttons
  21. ideas:
  22. uneditable sections?
  23. a ruler at the 72 character mark? possibly word-wrapping?
  24. want to switch between vi/emacs modes?
  25. */
  26. var term_cols;
  27. var term_rows;
  28. var term_win_width;
  29. var term_win_height;
  30. var term_cur_width;
  31. var tools;
  32. var suggest;
  33. var backing;
  34. var tagstyle = 0;
  35. var line_height = 0;
  36. var cclick = undefined;
  37. var mode = 0;
  38. var accum = 0;
  39. var lastaccum = 0;
  40. var marks = new Object();
  41. var registers = new Object();
  42. var lastreg = '';
  43. var lastcommand;
  44. var lastmotion;
  45. var cursoriv;
  46. var drawiv;
  47. var printer;
  48. var term;
  49. var base = 0;
  50. var left = 0;
  51. var vselm = 0;
  52. var vselx = undefined;
  53. var vsely = undefined;
  54. var vseld = false;
  55. var lastkey = undefined;
  56. var statustext = '';
  57. var command = '';
  58. var oldcommand = '';
  59. var commandleft = 0;
  60. var savex, savey;
  61. var once = true;
  62. var cursorx, cursory;
  63. var file = new Array();
  64. var tags = new Array();
  65. var palette;
  66. var cursor;
  67. var yank_buffer = undefined;
  68. var term_save_h = new Array();
  69. var term_save_ss;
  70. var term_save_mc;
  71. var term_save_kd;
  72. var term_save_kp;
  73. var term_save_rs;
  74. var term_save_op;
  75. var lastsearch;
  76. var lastsubst;
  77. var lastflags;
  78. var undoset = undefined;
  79. var undoline = undefined;
  80. var undoy = -1;
  81. var term_ex_motion;
  82. var vi_ft_reg;
  83. var viflags = '';
  84. var lastinsert = '';
  85. var spelling = false;
  86. var spellcheck = new Object();
  87. var safewords = new Object();
  88. var brokenwords = new Object();
  89. var suggestions = new Object();
  90. safewords['jsvi']=true;
  91. safewords['javascript']=true;
  92. safewords['URL']=true;
  93. safewords['hyperlinks']=true;
  94. safewords['HTML']=true;
  95. safewords['UNIX']=true;
  96. safewords['Firefox']=true;
  97. safewords['MSIE']=true;
  98. safewords['Ctrl']=true;
  99. safewords['vi']=true;
  100. safewords['vi-keys']=true;
  101. safewords[':hardcopy']=true;
  102. safewords['unicode-aware']=true;
  103. safewords['developer-centric']=true;
  104. var doing_backing_paste = false;
  105. function _true() { return true; }
  106. function _false() { return false; }
  107. function _cbrestore() {
  108. var i;
  109. for (i = 0; i < term_save_h.length; i++) {
  110. var z = term_save_h[i];
  111. z();
  112. }
  113. term_save_h = new Array();
  114. }
  115. function _cbw(nx,ny) {
  116. var nz = window['on'+nx];
  117. (function(x,y,z) {
  118. term_save_h[term_save_h.length] = function() {
  119. window['on'+x] = z;
  120. };
  121. })(nx,ny,nz);
  122. window['on'+nx]=ny;
  123. }
  124. function _cbd(nx,ny) {
  125. var nz = document['on'+nx];
  126. (function(x,y,z) {
  127. term_save_h[term_save_h.length] = function() {
  128. document['on'+x] = z;
  129. };
  130. })(nx, ny, nz);
  131. document['on'+nx]=ny;
  132. }
  133. function _rer(re,t,aa) {
  134. if (RegExp.rightContext != undefined) return RegExp.rightContext;
  135. // emulate rightContext
  136. var s = re.toString();
  137. if ((s.substr(0,2) == '/^' && s.substr(s.length-1,1) == '/') || s.substr(0,1) == '^') {
  138. // bound at beginning
  139. return t.substr(aa[0].length, t.length - aa[0].length);
  140. }
  141. if ((s.substr(0,1) == '/' && s.substr(s.length-2,2) == '$/') || s.substr(s.length-1,1) == '$') {
  142. // bound at end
  143. return "";
  144. }
  145. var j = t.lastIndexOf(aa[0]);
  146. if (j != -1) return t.substr(j.t.length-j);
  147. return t;
  148. }
  149. function _rel(re,t,aa) {
  150. if (RegExp.leftContext != undefined) return RegExp.leftContext;
  151. // emulate leftContext
  152. var s = re.toString();
  153. if ((s.substr(0,2) == '/^' && s.substr(s.length-1,1) == '/') || s.substr(0,1) == '^') {
  154. // bound at beginning
  155. return "";
  156. }
  157. if ((s.substr(0,1) == '/' && s.substr(s.length-2,2) == '$/') || s.substr(s.length-1,1) == '$') {
  158. // bound at end
  159. return t.substr(0, t.length - aa[0].length);
  160. }
  161. var j = t.indexOf(aa[0]);
  162. if (j != -1) return t.substr(0,j);
  163. return "";
  164. }
  165. function _hra(x) {
  166. var i;
  167. var cx = 0;
  168. var t = '';
  169. var g = '';
  170. for (i = 0; i < x.length; i++) {
  171. var x3 = x.substr(i,3);
  172. var gx = String.fromCharCode(cx);
  173. if (x3 == '<b>') {
  174. cx = cx | 1;
  175. i += 2;
  176. } else if (x3 == '</b') {
  177. cx = (cx | 1) ^ 1;
  178. i += 3;
  179. } else if (x3 == '<u>') {
  180. cx = cx | 2;
  181. i += 2;
  182. } else if (x3 == '</u') {
  183. cx = (cx | 2) ^ 2;
  184. i += 3;
  185. } else if (x3 == '<i>') {
  186. cx = cx | 16;
  187. i += 2;
  188. } else if (x3 == '</i') {
  189. cx = (cx | 16) ^ 16;
  190. i += 3;
  191. } else if (x3 == '<sp') { // <span class="rv">
  192. cx = cx | 4;
  193. i += 16;
  194. } else if (x3 == '</s') { // </span>
  195. cx = (cx | 4) ^ 4;
  196. i += 6;
  197. } else if (x3 == '&am') { // &amp;
  198. t += '&';
  199. g += gx;
  200. i += 4;
  201. } else if (x3 == '&lt') { // &lt;
  202. t += '<';
  203. g += gx;
  204. i += 3;
  205. } else {
  206. t += x.substr(i,1);
  207. g += gx;
  208. }
  209. }
  210. var aa = new Array();
  211. aa[0] = t;
  212. aa[1] = g;
  213. return aa;
  214. }
  215. function _rtf(t,g) {
  216. var cx = 0;
  217. var i;
  218. var o = '';
  219. if (t == undefined) {
  220. t = '';
  221. g = '';
  222. }
  223. for (i = 0; i < t.length; i++) {
  224. var gx = g.substr(i, 1).charCodeAt(0);
  225. var tx = t.substr(i, 1);
  226. if (tx == "<") tx = "&lt;";
  227. else if (tx == '&') tx = '&amp;';
  228. if (gx != cx) {
  229. if ((gx & 1) && !(cx & 1)) {
  230. o += "<b>";
  231. } else if (!(gx & 1) && (cx & 1)) {
  232. o += "</b>";
  233. }
  234. if ((gx & 2) && !(cx & 2)) {
  235. o += "<u>";
  236. } else if (!(gx & 2) && (cx & 2)) {
  237. o += "</u>";
  238. }
  239. if ((gx & 4) && !(cx & 4)) {
  240. o += "<span class=\"rv\">";
  241. } else if (!(gx & 4) && (cx & 4)) {
  242. o += "</span>";
  243. }
  244. if ((gx & 16) && !(cx & 16)) {
  245. o += "<i>";
  246. } else if (!(gx & 16) && (cx & 16)) {
  247. o += "</i>";
  248. }
  249. cx = gx;
  250. }
  251. o += tx;
  252. }
  253. return o;
  254. }
  255. function _rtfl(y) {
  256. return _rtf(file[y],tags[y]);
  257. }
  258. function _dfx(q) {
  259. /*@cc_on @*/
  260. /*@if (1) return
  261. @end @*/
  262. q.style.position = 'fixed';
  263. }
  264. function term_freeze() {
  265. var i;
  266. var o = '';
  267. for (i = 0; i < file.length; i++) {
  268. o += _rtfl(i)+"\n";
  269. }
  270. return o;
  271. }
  272. function _term_update_printer() {
  273. var i;
  274. var o = '';
  275. for (i = 0; i < file.length; i++) {
  276. o += _rtfl(i)+"<br/>";
  277. }
  278. printer.innerHTML = o;
  279. }
  280. function term_thaw(s) {
  281. var a = s.split("\n");
  282. var i;
  283. var aa;
  284. file = new Array();
  285. tags = new Array();
  286. var o = '';
  287. for (i = 0; i < a.length; i++) {
  288. o += a[i] + "<br/>";
  289. aa = _hra(a[i]);
  290. file[i] = aa[0];
  291. tags[i] = aa[1];
  292. }
  293. printer.innerHTML = o;
  294. }
  295. function _mxo(z,y) {
  296. var i;
  297. var o = '';
  298. for (i = 0; i < z.length; i++) {
  299. o += String.fromCharCode(z.substr(i, 1).charCodeAt(0) | y);
  300. }
  301. return o;
  302. }
  303. function _mxs(n,y) {
  304. var z = String.fromCharCode(y);
  305. var i;
  306. var o = '';
  307. for (i = 0; i < n; i++) {
  308. o += z;
  309. }
  310. return o;
  311. }
  312. function _zeros(n) {
  313. return _mxs(n,0);
  314. }
  315. function _fauc() {
  316. var d = document.getElementsByTagName('A');
  317. var i;
  318. for (i = 0; i < d.length; i++) {
  319. var j = d[i];
  320. if (j._len && j._term) {
  321. if (j._row == (base+cursory) && (left+cursorx) >= j._col && (left+cursorx) <= (j._col+j._len)) {
  322. return j;
  323. }
  324. }
  325. }
  326. return undefined;
  327. }
  328. function _pass_click(e) {
  329. var z = _fauc();
  330. if (z && z.onclick) return z.onclick();
  331. return false;
  332. }
  333. function _pass_dblclick(e) {
  334. var z = _fauc();
  335. if (z && z.ondblclick) return z.ondblclick();
  336. return false;
  337. }
  338. function _cancel_ev(e) {
  339. if (!e) e = window.event;
  340. if (!e) return false;
  341. if (e.preventDefault) e.preventDefault();
  342. if (e.stopPropagation) e.stopPropagation();
  343. return false;
  344. }
  345. function _willclick(e) {
  346. if (window.event) {
  347. if (!e) e = window.event;
  348. }
  349. if (!e) return true;
  350. if (cclick != undefined) window.clearTimeout(cclick);
  351. var x = e.clientX;
  352. var y = e.clientY;
  353. cclick = window.setTimeout(function() {
  354. cclick=undefined;
  355. _cursortoxy(x,y);
  356. }, 200);
  357. return false;
  358. }
  359. function _subclick(e) {
  360. return _willclick(e);
  361. }
  362. function _srep(e) {
  363. if (!e) e = window.event;
  364. if (e.preventDefault) e.preventDefault();
  365. if (e.stopPropagation) e.stopPropagation();
  366. e.cancelBubble=true;
  367. var y = this._row;
  368. var x = this._col;
  369. var len = this._len;
  370. var rep = this._word;
  371. var t = (file[y]);
  372. var g = (tags[y]);
  373. var w = (t.substr(x, len));
  374. var st = (g.substr(x, len));
  375. while (st.length < rep.length) {
  376. st = st + st;
  377. }
  378. if (st.length > rep.length) {
  379. st = st.substr(0, rep.length);
  380. }
  381. term_save_undo(); // save undo!
  382. file[y] = t.substr(0, x) + rep + t.substr(x+len, t.length-(x+len));
  383. tags[y] = g.substr(0, x) + st + g.substr(x+len, t.length-(x+len));
  384. suggest.style.display = 'none';
  385. suggest._visible = false;
  386. while (suggest.firstChild) suggest.removeChild(suggest.firstChild);
  387. if (w == rep) {
  388. statustext = '';
  389. } else {
  390. statustext = 'Replaced "' + w + '" with "' + rep + '"';
  391. }
  392. term_redraw();
  393. return false;
  394. }
  395. function _rl(w,h) {
  396. var x = document.createElement('DIV');
  397. x.style.overflow = 'hidden';
  398. x.style.height = h + 'px';
  399. x.style.marginLeft = w + 'px';
  400. x.style.marginRight = w + 'px';
  401. x.style.backgroundColor = palette[0];
  402. x.style.display = 'block';
  403. x.style.innerHTML = '&nbsp;';
  404. x.style.fontFamily = 'monospace';
  405. return x;
  406. }
  407. function _ruo(t) {
  408. this.style.color = palette[0];
  409. this.style.backgroundColor = palette[1];
  410. }
  411. function _rux(t) {
  412. this.style.color = palette[1];
  413. this.style.backgroundColor = palette[0];
  414. }
  415. function _openurl(e) {
  416. var u = this._term;
  417. window.open(u,'_new');
  418. return true;
  419. }
  420. function _suggest(e) {
  421. var z = this;
  422. if (window.event) {
  423. if (!e) e = window.event;
  424. }
  425. if (e) {
  426. if (e.preventDefault) e.preventDefault();
  427. if (e.stopPropagation) e.stopPropagation();
  428. e.cancelBubble=true;
  429. }
  430. (function(q) {
  431. window.setTimeout(function(){
  432. _dosuggest(q);
  433. }, 10);
  434. })(z);
  435. return false;
  436. }
  437. function _dosuggest(z) {
  438. var x = 0;
  439. var y = 0;
  440. var xt = z._term;
  441. var wrow = z._row;
  442. var wcol = z._col;
  443. var wlen = z._len;
  444. while (z && z != document.body) {
  445. x += z.offsetLeft;
  446. y += z.offsetTop;
  447. z = z.offsetParent;
  448. }
  449. suggest._visible = true;
  450. suggest.style.top = y + 'px';
  451. suggest.style.left = x + 'px';
  452. suggest.style.display = 'block';
  453. suggest.style.zIndex = '3';
  454. suggest.style.padding = '2px';
  455. while (suggest.firstChild) suggest.removeChild(suggest.firstChild);
  456. var sg = document.createElement('DIV');
  457. sg.style.backgroundColor = palette[0];
  458. sg.style.color = palette[1];
  459. sg.style.fontSize = '100%';
  460. sg.style.padding = '2px';
  461. sg.style.textAlign = 'center';
  462. sg.style.cursor = 'default';
  463. var sa = suggestions[xt];
  464. var i;
  465. var fs = 200;
  466. var fd = parseInt((100 / sa.length) * 1.5);
  467. var bf;
  468. for (i = 0; i < sa.length; i++) {
  469. var da = document.createElement('A');
  470. da.href = 'javascript:void(0)';
  471. da.onclick = _srep;
  472. da._word = sa[i];
  473. da._row = wrow;
  474. da._col = wcol;
  475. da._len = wlen;
  476. da.onmouseover = _ruo;
  477. da.onmouseout = _rux;
  478. da.style.margin = '4px';
  479. da.style.textDecoration = 'none';
  480. da.style.display = 'block';
  481. da.style.color = palette[1];
  482. da.style.backgroundColor = palette[0];
  483. da.style.fontSize = fs + '%';
  484. fs -= fd;
  485. if (fs <= 100) fs = 100;
  486. da.appendChild(document.createTextNode(sa[i]));
  487. // err...
  488. da.appendChild(document.createElement('BR'));
  489. if ((wrow-base) > term_rows-(sa.length+1)) {
  490. sg.insertBefore(da, sg.firstChild);
  491. bf = true;
  492. } else if (((i % 2) == 0) || (wrow < (sa.length+1))) {
  493. sg.appendChild(da);
  494. } else {
  495. sg.insertBefore(da, sg.firstChild);
  496. }
  497. da = undefined; // break
  498. }
  499. if (sa.length == 0) {
  500. sg.appendChild(document.createTextNode('No matches'));
  501. }
  502. var da = document.createElement('A');
  503. da.href = 'javascript:void(0)';
  504. da.onclick = _srep;
  505. da._word = xt;
  506. da._row = wrow;
  507. da._col = wcol;
  508. da._len = wlen;
  509. da.style.margin= '4px';
  510. da.style.textDecoration = 'none';
  511. da.style.color = palette[1];
  512. da.style.backgroundColor = palette[0];
  513. da.style.borderBottom = '1px dashed red';
  514. da.style.fontSize = '100%';
  515. da.onmouseover = _ruo;
  516. da.onmouseout = _rux;
  517. da.appendChild(document.createTextNode(xt));
  518. if (wrow > term_rows-(sa.length+1)) {
  519. sg.insertBefore(da, sg.firstChild);
  520. } else {
  521. sg.appendChild(da);
  522. }
  523. // rounded top and bottom
  524. suggest.appendChild(_rl(3,1));
  525. suggest.appendChild(_rl(2,1));
  526. suggest.appendChild(_rl(1,2));
  527. suggest.appendChild(sg);
  528. suggest.appendChild(_rl(1,2));
  529. suggest.appendChild(_rl(2,1));
  530. suggest.appendChild(_rl(3,1));
  531. // msie needs to recalculate these things manually... grr...
  532. // this doesn't work because msie doesn't calculate offsetwidth (thtphtpht)
  533. var zq;
  534. var mw = 11;
  535. if (mw < xt.length) mw = xt.length;
  536. for (i = 0; i < sa.length; i++) {
  537. if (mw < sa[i].length) mw = sa[i].length;
  538. }
  539. if (mw) {
  540. mw *= (term_cur_width*2);
  541. mw += 16;
  542. suggest.style.width = mw + 'px';
  543. }
  544. var sx = parseInt(sg.offsetWidth / 4);
  545. if (x < sx) {
  546. x = 0;
  547. } else {
  548. x -= sx;
  549. suggest.style.left = x + 'px';
  550. }
  551. var sy = parseInt(sg.offsetHeight / 4);
  552. if (bf) {
  553. suggest.style.top = '';
  554. suggest.style.bottom = '0px';
  555. } else if (y < sy) {
  556. y = 0;
  557. suggest.style.top = '0px';
  558. suggest.style.bottom = '';
  559. } else {
  560. y -= sy;
  561. suggest.style.top = y + 'px';
  562. suggest.style.bottom = '';
  563. }
  564. statustext = 'Suggestions for: ' + xt;
  565. term_redraw();
  566. da = undefined; // break
  567. sg = undefined; // break
  568. }
  569. function _backing_paste_real() {
  570. doing_backing_paste = false;
  571. term_redraw();
  572. if (!backing.value) return;
  573. if (backing._lastvalue == backing.value) {
  574. return;
  575. }
  576. backing._lastvalue = backing.value;
  577. term_paste(false, backing.value);
  578. term_redraw();
  579. }
  580. function _msie_paste() {
  581. var chunk = "new content associated with this object";
  582. event.returnValue = false;
  583. term_paste(false, window.clipboardData.getData("Text", chunk));
  584. }
  585. function _backing_paste() {
  586. _update_backing();
  587. if (!doing_backing_paste) {
  588. doing_backing_paste = true;
  589. window.setTimeout(_backing_paste_real, 10);
  590. }
  591. }
  592. function _update_backing() {
  593. if (!backing) return;
  594. /*@cc_on @*/
  595. /*@if (1) return
  596. @end @*/
  597. backing.focus();
  598. backing.select();
  599. }
  600. function _yaty(y) {
  601. if (line_height) return parseInt(y/line_height);
  602. var zx;
  603. var qx = term.firstChild;
  604. var nh = 0;
  605. while (qx && qx != document.body) {
  606. nh += qx.offsetTop;
  607. qx = qx.offsetParent;
  608. }
  609. var ny = 0;
  610. var cy = 0;
  611. for (zx = term.firstChild; zx; zx = zx.nextSibling) {
  612. nh += (zx.offsetHeight + 4);
  613. if (y <= nh) {
  614. cy = ny;
  615. break;
  616. }
  617. ny++;
  618. }
  619. return cy;
  620. }
  621. function _cursortoxy(x,y) {
  622. // this is a little gross...
  623. var sx = cursorx;
  624. cursorx = parseInt(x / term_cur_width);
  625. term_redraw();
  626. var sy = cursory;
  627. cursory = _yaty(y);
  628. if (cursory >= (term_rows-1)) {
  629. cursory = sy;
  630. cursorx = sx;
  631. sy = 0;
  632. }
  633. term_scrollto();
  634. term_calcx();
  635. if (cursory != sy) {
  636. term_redraw();
  637. } else {
  638. term_calcy();
  639. }
  640. _update_backing();
  641. return true;
  642. }
  643. function _mousescroll(e) {
  644. if (!e) e = window.event;
  645. var d = 0;
  646. if (e.wheelDelta) {
  647. d = e.wheelDelta;
  648. if (d < 0) d = 1; else d = -1;
  649. } else if (e.detail) {
  650. d = e.detail;
  651. } else {
  652. return true;
  653. }
  654. if (d < 0) {
  655. if (base > 0) base--;
  656. } else if (d > 0) {
  657. if (base < (file.length - (term_rows-1))) base++;
  658. }
  659. term_redraw();
  660. return false;
  661. }
  662. function _mousedown(e) {
  663. if (suggest._visible) return true;
  664. if (!e) e = window.event;
  665. var y = _yaty(e.clientY);
  666. if (y >= (term_rows-1)) return true;
  667. _willclick(e);
  668. vseld = true;
  669. vselm = 0;
  670. vselx = undefined;
  671. vsely = undefined;
  672. return false;
  673. }
  674. function _mousemove(e) {
  675. if (!e) e = window.event;
  676. if (e) {
  677. if (e.preventDefault) e.preventDefault();
  678. if (e.stopPropagation) e.stopPropagation();
  679. e.cancelBubble=true;
  680. }
  681. if (window.getSelection) {
  682. var s = window.getSelection();
  683. if (s.removeAllRanges) s.removeAllRanges();
  684. }
  685. if (document.selection && document.selection.empty) {
  686. eval('try{document.selection.empty();}catch(e){}');
  687. }
  688. // fixup selection
  689. _update_backing();
  690. if (suggest._visible || !vseld) return true;
  691. if (vseld) {
  692. if (vselx == undefined && vsely == undefined) {
  693. // turn on v here
  694. vselm = 1;
  695. vselx = cursorx+left;
  696. vsely = cursory+base;
  697. }
  698. _willclick(e);
  699. return true;
  700. }
  701. return true;
  702. }
  703. function _mouseup(e) {
  704. if (suggest._visible || !vseld) return true;
  705. vseld = false;
  706. if (vselm && vselx != undefined && vsely != undefined) {
  707. // okay, we HAVE selection
  708. var rr = lastreg;
  709. lastreg = '*';
  710. term_vi_set('y');
  711. term_vi_unset('d');
  712. term_select();
  713. term_operate();
  714. lastreg = rr;
  715. } else {
  716. vselm = 0;
  717. }
  718. _willclick(e);
  719. return false;
  720. }
  721. function _mouseclick(e) {
  722. if (!e) e = window.event;
  723. var y = _yaty(e.clientY);
  724. if (y >= (term_rows-1)) return true;
  725. vselm = 0;
  726. _cursorto(e);
  727. return true;
  728. }
  729. function _cursorto(e) {
  730. if (!e) e = window.event;
  731. var x = e.clientX;
  732. var y = e.clientY;
  733. if (suggest._visible) {
  734. suggest.style.display = 'none';
  735. suggest._visible = false;
  736. statustext = '';
  737. }
  738. return _cursortoxy(x,y);
  739. }
  740. function _word(s) {
  741. var t = s.replace(/[.?!,:]*$/,"");
  742. if (t) s = t;
  743. t = s.replace(/[ \r\n\t]/,"");
  744. if (t) s = t;
  745. return s;
  746. }
  747. function _safe(s) {
  748. if (s.match(/^[ \r\n\t]*<.*>[ \r\n\t]*$/)) return true;
  749. return false;
  750. }
  751. function _xhttp() {
  752. var xmlhttp=false;
  753. /*@cc_on @*/
  754. /*@if (@_jscript_version >= 5)
  755. try {
  756. xmlhttp = new ActiveXObject("Msxml2.XMLHTTP");
  757. } catch (e) {
  758. try {
  759. xmlhttp = new ActiveXObject("Microsoft.XMLHTTP");
  760. } catch (E) {
  761. xmlhttp = false;
  762. }
  763. }
  764. @end @*/
  765. if (!xmlhttp && typeof XMLHttpRequest!='undefined') {
  766. xmlhttp = new XMLHttpRequest();
  767. }
  768. if (!xmlhttp) return new Object(); // fake out caller
  769. return xmlhttp;
  770. }
  771. function term_setmode(n) {
  772. mode = n;
  773. lastinsert = '';
  774. }
  775. function term_roll_yank() {
  776. registers["9"] = registers["8"];
  777. registers["8"] = registers["7"];
  778. registers["7"] = registers["6"];
  779. registers["6"] = registers["5"];
  780. registers["5"] = registers["4"];
  781. registers["4"] = registers["3"];
  782. registers["3"] = registers["2"];
  783. registers["2"] = registers["1"];
  784. registers["1"] = registers["0"];
  785. if (lastreg == '0') {
  786. registers[""] = yank_buffer;
  787. }
  788. if (lastreg == "" || lastreg == "*") {
  789. backing._lastvalue = yank_buffer;
  790. backing.value = yank_buffer;
  791. }
  792. registers["0"] = yank_buffer;
  793. }
  794. function term_justify() {
  795. var y = cursory+base;
  796. var i;
  797. if (!accum) accum = 1;
  798. var t = (file[y]);
  799. file[p] = t.replace(/[ ][ ]*$/,"");
  800. tags[p] = tags[p].substr(0, file[p].length);
  801. for (i = 0; i < accum; i++) {
  802. var t = file[i+y+1];
  803. var g = tags[i+y+1];
  804. term_delete(i+y+1); // ignore return
  805. t = t.replace(/^[ ][ ]*/,"");
  806. g = g.substr(g.length - t.length, t.length);
  807. if (t != '') {
  808. file[y] = file[y] + " " + t;
  809. tags[y] = tags[y] + "\0" + g;
  810. }
  811. }
  812. file[y] = file[y].replace(/^[ ][ ]*/,"");
  813. tags[y] = tags[y].substr(tags[y].length - file[y].length, file[y].length);
  814. accum = 0;
  815. }
  816. function term_vi_bb() {
  817. return term_skipbackward(/[ ][^ ][^ ]*[ ]*$/);
  818. }
  819. function term_vi_b() {
  820. return term_skipbackward(/[^a-zA-Z0-9_][a-zA-Z0-9_][a-zA-Z0-9_]*[^a-zA-Z0-9_]*$/);
  821. }
  822. function term_vi_tt() {
  823. var t = (file[cursory+base]);
  824. var i;
  825. var w = term_cols;
  826. for (i = (cursorx+left)-1; i >= 0; i--) {
  827. var c = (t.substr(i, 1));
  828. if (c == vi_ft_reg) {
  829. cursorx = (i - left)+1;
  830. if (cursorx >= w) {
  831. left = 0;
  832. cursorx = i+1;
  833. }
  834. return true;
  835. }
  836. }
  837. return false;
  838. }
  839. function term_vi_t() {
  840. var t = (file[cursory+base]);
  841. var i;
  842. for (i = (cursorx+left)+1; i < t.length; i++) {
  843. var c = (t.substr(i, 1));
  844. if (c == vi_ft_reg) {
  845. cursorx = (i - left)-1;
  846. if (term_vi_flag('d') || term_vi_flag('c') || term_vi_flag('y')) cursorx++;
  847. if (cursorx < 0) {
  848. left = 0;
  849. cursorx = i-1;
  850. }
  851. return true;
  852. }
  853. }
  854. return false;
  855. }
  856. function term_vi_ff() {
  857. var t = (file[cursory+base]);
  858. var i;
  859. for (i = (cursorx+left)-1; i >= 0; i--) {
  860. var c = (t.substr(i, 1));
  861. if (c == vi_ft_reg) {
  862. cursorx = i - left;
  863. if (cursorx < 0) {
  864. left = 0;
  865. cursorx = i;
  866. }
  867. return true;
  868. }
  869. }
  870. return false;
  871. }
  872. function term_vi_f() {
  873. var t = (file[cursory+base]);
  874. var i;
  875. var w = term_cols;
  876. for (i = (cursorx+left)+1; i < t.length; i++) {
  877. var c = (t.substr(i, 1));
  878. if (c == vi_ft_reg) {
  879. cursorx = i - left;
  880. if (term_vi_flag('d') || term_vi_flag('c') || term_vi_flag('y')) cursorx++;
  881. if (cursorx >= w) {
  882. left = 0;
  883. cursorx = i;
  884. }
  885. return true;
  886. }
  887. }
  888. return false;
  889. }
  890. function term_vi_eof() {
  891. cursorx = 0;
  892. left = 0;
  893. base = 0;
  894. if (accum) {
  895. cursory = accum-1;
  896. return false;
  897. } else {
  898. base = file.length - (term_rows-1);
  899. cursory = term_rows-1;
  900. if (base < 0) {
  901. base = 0;
  902. cursory = file.length-1;
  903. }
  904. }
  905. term_redraw();
  906. return true;
  907. }
  908. function term_vi_top() {
  909. cursorx = 0;
  910. base = 0;
  911. left = 0;
  912. if (accum) {
  913. cursory = accum-1;
  914. return false;
  915. } else {
  916. cursory = 0;
  917. }
  918. return true;
  919. }
  920. function term_vi_h() { cursorx--; term_scrollto(); return true; }
  921. function term_vi_j() { cursory++; term_scrollto(); return true; }
  922. function term_vi_k() { cursory--; term_scrollto(); return true; }
  923. function term_vi_l() {
  924. cursorx++;
  925. // hack
  926. var a = mode;
  927. mode = 1;
  928. term_scrollto();
  929. mode = a;
  930. return true;
  931. }
  932. function term_vi_ll() {
  933. cursory = term_rows-2;
  934. return true;
  935. }
  936. function term_vi_mm() {
  937. cursory = parseInt((term_rows-2) / 2);
  938. cursorx = 0; left = 0;
  939. return true;
  940. }
  941. function term_vi_hh() {
  942. cursory = 0;
  943. return true;
  944. }
  945. function term_vi_ob() {
  946. cursory--;
  947. return term_skipreverse2(/^[ ]*$/, 0);
  948. }
  949. function term_vi_cb() {
  950. cursory++;
  951. return term_skipforward(/^[ ]*$/, 0);
  952. }
  953. function term_vi_ww() {
  954. return term_skipforward(/[ ][^ ]/, 0);
  955. }
  956. function term_vi_w() {
  957. return term_skipforward(/[^a-zA-Z0-9_(){}<>][a-zA-Z0-9_(){}<>]/, 0);
  958. }
  959. function term_vi_flag(f) {
  960. return (viflags.indexOf(f) == -1) ? false : true;
  961. }
  962. function term_vi_unset(f) {
  963. var j = viflags.indexOf(f);
  964. if (j == -1) return;
  965. viflags = viflags.substr(0, j) + viflags.substr(j+1, (viflags.length-j)-1);
  966. }
  967. function term_vi_set(f) {
  968. if (viflags.indexOf(f) == -1) viflags += ''+f;
  969. }
  970. function term_vi_bounce() {
  971. var y = cursory+base;
  972. var t = (file[y]);
  973. var x = cursorx+left;
  974. var z1 = '[{()}]';
  975. var z2 = ']})({[';
  976. while (x < t.length) {
  977. var z = z1.indexOf(t.substr(x,1));
  978. if (z == -1) {
  979. x++;
  980. continue;
  981. }
  982. var d = (z > 2) ? -1 : 1;
  983. var c=z2.substr(z,1);
  984. while (y >= 0 && y < file.length) {
  985. while (x > 0 && x < t.length) {
  986. if (t.substr(x,1) == c) {
  987. cursorx = x-left;
  988. cursory = y;
  989. base = 0;
  990. term_scrollto();
  991. return true;
  992. }
  993. x += d;
  994. }
  995. if (d == -1) {
  996. y--;
  997. t = file[y];
  998. x = (t.length-1)
  999. } else {
  1000. y++;
  1001. t = file[y];
  1002. x = 0;
  1003. }
  1004. }
  1005. }
  1006. return false;
  1007. }
  1008. function term_vi_eol() {
  1009. var t = (file[cursory+base]);
  1010. cursorx = (t.length)-left;
  1011. if (cursorx < 0) {
  1012. left = 0;
  1013. cursorx = (t.length);
  1014. }
  1015. return true;
  1016. }
  1017. function term_vi_line() {
  1018. var t = (file[cursory+base]);
  1019. left = 0;
  1020. cursorx = t.length+1;
  1021. return true;
  1022. }
  1023. function term_vi_ee() {
  1024. return term_skipforward(/[^ ][ ]/, 1);
  1025. }
  1026. function term_vi_e() {
  1027. if (term_skipforward(/[a-zA-Z0-9_(){}<>][^a-zA-Z0-9_(){}<>]/, 1)) {
  1028. if (term_vi_flag('d') || term_vi_flag('c') || term_vi_flag('y')) cursorx++;
  1029. return true;
  1030. }
  1031. return false;
  1032. }
  1033. function term_vi_v() {
  1034. cursorx = vselx - left;
  1035. if (cursorx < 0) {
  1036. left = 0;
  1037. cursorx = vselx;
  1038. }
  1039. cursory = vsely - base;
  1040. if (cursory < 0) {
  1041. base = 0;
  1042. cursory = vsely;
  1043. }
  1044. }
  1045. function term_vi_vv() {
  1046. term_vi_v();
  1047. term_vi_line();
  1048. }
  1049. function term_select() {
  1050. if (vselm == 1) {
  1051. term_ex_motion = term_vi_v;
  1052. } else if (vselm == 2) {
  1053. term_ex_motion = term_vi_vv;
  1054. cursorx = 0;
  1055. left = 0;
  1056. }
  1057. }
  1058. function term_indent(y,amount) {
  1059. if (file[y] == undefined) {
  1060. file[y] = '';
  1061. tags[y] = '';
  1062. }
  1063. file[y] = _mxs(amount*4,32)+file[y];
  1064. tags[y] = _mxs(amount*4,tagstyle)+tags[y];
  1065. }
  1066. function term_unindent(y,amount) {
  1067. amount*=4;
  1068. while (amount > 0 && file[y].substr(0, 1) == ' ') {
  1069. file[y] = file[y].substr(1, file[y].length-1);
  1070. amount--;
  1071. }
  1072. }
  1073. function term_operate() {
  1074. term_save_undo();
  1075. var fa = accum;
  1076. if (!fa) fa = 1;
  1077. var sx = cursorx+left;
  1078. var sy = cursory+base;
  1079. while (fa > 0) {
  1080. var t = file[base+cursory];
  1081. if (t == undefined) break;
  1082. if (fa > 1 && ((cursorx+left) >= t.length)) {
  1083. cursory++;
  1084. cursorx = 0;
  1085. left = 0;
  1086. }
  1087. term_ex_motion();
  1088. fa--;
  1089. }
  1090. fa = accum;
  1091. if (!fa) fa = 1;
  1092. accum = 0;
  1093. var ex = cursorx+left;
  1094. var ey = cursory+base;
  1095. var i;
  1096. if (ey < sy) {
  1097. i = ey;
  1098. ey = sy;
  1099. sy = i;
  1100. }
  1101. if (ex < sx) {
  1102. i = ex;
  1103. ex = sx;
  1104. sx = i;
  1105. }
  1106. var t = file[ey];
  1107. var g = tags[ey];
  1108. var restore = false;
  1109. if (term_vi_flag('c')) term_vi_set('d');
  1110. if (vselm != 2 && ey == sy && ex <= t.length) {
  1111. if (vselm) ex++;
  1112. if (ex != sx) {
  1113. if (term_vi_flag('F')) {
  1114. // styling
  1115. tags[ey] = (g.substr(0, sx)) + _mxs(ex-sx, tagstyle) + (g.substr(ex, g.length-ex));
  1116. } else if (term_vi_flag('d') || term_vi_flag('y')) {
  1117. yank_buffer = _rtf(t.substr(sx, ex-sx),
  1118. g.substr(sx,ex-sx));
  1119. }
  1120. if (term_vi_flag('d')) {
  1121. file[ey] = (t.substr(0, sx)) + (t.substr(ex, t.length-ex));
  1122. tags[ey] = (g.substr(0, sx)) + (g.substr(ex, g.length-ex));
  1123. if (lastreg != '_') {
  1124. registers[lastreg] = yank_buffer;
  1125. term_roll_yank();
  1126. }
  1127. } else if (term_vi_flag('y')) {
  1128. registers[lastreg] = yank_buffer;
  1129. term_roll_yank();
  1130. }
  1131. if (term_vi_flag('>')) {
  1132. term_indent(ey,fa);
  1133. } else if (term_vi_flag('<')) {
  1134. term_unindent(ey,fa);
  1135. }
  1136. }
  1137. } else if (vselm == 1) {
  1138. if (term_vi_flag('d') || term_vi_flag('y') || term_vi_flag('F')) {
  1139. yank_buffer = '';
  1140. var al, bl;
  1141. for (i = sy; i <= ey; i++) {
  1142. t = file[i];
  1143. g = tags[i];
  1144. if (i == sy) {
  1145. if ((sy == vsely && sx == vselx) || (sy != vsely && sx != vselx)) {
  1146. al = sx;
  1147. } else {
  1148. al = ex;
  1149. }
  1150. bl = t.length;
  1151. } else if (i == ey) {
  1152. al = 0;
  1153. if ((sy == vsely && sx == vselx) || (sy != vsely && sx != vselx)) {
  1154. al = ex;
  1155. } else {
  1156. al = sx;
  1157. }
  1158. } else {
  1159. al = 0;
  1160. bl = t.length;
  1161. }
  1162. yank_buffer += _rtf(t.substr(al, bl-al),
  1163. g.substr(al,bl-al));
  1164. if (sy != ey || vselm == 2) yank_buffer += "\n";
  1165. if (term_vi_flag('d')) {
  1166. file[i] = t.substr(0, al) + t.substr(bl, t.length-bl);
  1167. tags[i] = g.substr(0, al) + g.substr(bl, g.length-bl);
  1168. } else if (term_vi_flag('F')) {
  1169. tags[i] = g.substr(0, al) + _mxs(bl-al, tagstyle)
  1170. + g.substr(bl, g.length-bl);
  1171. }
  1172. if (term_vi_flag('>')) {
  1173. term_indent(i,fa);
  1174. } else if (term_vi_flag('<')) {
  1175. term_unindent(i,fa);
  1176. }
  1177. }
  1178. if (lastreg != '_' && !term_vi_flag('F')) {
  1179. registers[lastreg] = yank_buffer;
  1180. term_roll_yank();
  1181. }
  1182. }
  1183. } else {
  1184. if (term_vi_flag('F')) {
  1185. for (i = sy; i <= ey; i++) {
  1186. tags[i] = _mxs(file[i].length, tagstyle);
  1187. }
  1188. } else if (term_vi_flag('d')) {
  1189. yank_buffer = '';
  1190. for (i = sy; i <= ey; i++) {
  1191. yank_buffer += term_delete(sy);
  1192. }
  1193. if (lastreg != '_') {
  1194. registers[lastreg] = yank_buffer;
  1195. term_roll_yank();
  1196. }
  1197. } else if (term_vi_flag('y')) {
  1198. yank_buffer = '';
  1199. for (i = sy; i <= ey; i++) {
  1200. yank_buffer += _rtfl(sy) + "\n";
  1201. }
  1202. registers[lastreg] = yank_buffer;
  1203. term_roll_yank();
  1204. } else if (term_vi_flag('>')) {
  1205. for (i = sy; i <= ey; i++) {
  1206. term_indent(i,fa);
  1207. }
  1208. } else if (term_vi_flag('<')) {
  1209. for (i = sy; i <= ey; i++) {
  1210. term_unindent(i,fa);
  1211. }
  1212. }
  1213. }
  1214. if (term_vi_flag('d') || term_vi_flag('F') || term_vi_flag('c')) {
  1215. _term_update_printer();
  1216. }
  1217. if (term_vi_flag('d')) {
  1218. term_vi_unset('d');
  1219. lastcommand = 'd';
  1220. lastmotion = term_ex_motion;
  1221. restore = true;
  1222. }
  1223. if (term_vi_flag('y')) {
  1224. term_vi_unset('y');
  1225. restore = true;
  1226. }
  1227. if (term_vi_flag('F')) {
  1228. term_vi_unset('F');
  1229. restore = true;
  1230. }
  1231. lastaccum = accum;
  1232. if (restore) {
  1233. cursorx = sx - left;
  1234. if (cursorx < 0) {
  1235. cursorx = sx;
  1236. left = 0;
  1237. }
  1238. cursory = sy - base;
  1239. if (cursory < 0) {
  1240. cursory = sy;
  1241. base = 0;
  1242. }
  1243. term_scrollto();
  1244. }
  1245. if (term_vi_flag('c')) {
  1246. term_vi_unset('c');
  1247. term_setmode(1);
  1248. }
  1249. accum = 0;
  1250. }
  1251. function term_save_undo_line() {
  1252. if ((base+cursory) != undoy) {
  1253. undoy = base+cursory;
  1254. undoline = _rtfl(undoy);
  1255. }
  1256. }
  1257. function term_save_undo() {
  1258. undoset = term_freeze();
  1259. }
  1260. function term_delete(i) {
  1261. if (i > file.length) return '';
  1262. var j;
  1263. var z = file[i];
  1264. var g = tags[i];
  1265. for (j = i+1; j < file.length; j++) {
  1266. file[j-1] = file[j];
  1267. tags[j-1] = tags[j];
  1268. }
  1269. file=_pop(file);
  1270. return _rtf(z,g) + "\n";
  1271. }
  1272. function term_skipreverse2(re, fuzz) {
  1273. var y = cursory+base;
  1274. var x = (cursorx+left)+(1+fuzz);
  1275. for (;;) {
  1276. var t = file[y];
  1277. if (t == undefined) {
  1278. // beep
  1279. cursory = y - base;
  1280. return false;
  1281. }
  1282. if (fuzz) t += " "; else t = " " + t;
  1283. t = (t.substr(x, t.length-x));
  1284. var aa = re.exec(t);
  1285. if (!aa) {
  1286. y--;
  1287. x = 0;
  1288. } else {
  1289. x += _rel(re,t,aa).length;
  1290. cursorx = x - left;
  1291. cursory = y - base;
  1292. return true;
  1293. }
  1294. }
  1295. return false;
  1296. }
  1297. function term_skipforward(re, fuzz) {
  1298. var y = cursory+base;
  1299. var x = (cursorx+left)+(1+fuzz);
  1300. for (;;) {
  1301. var t = file[y];
  1302. if (t == undefined) {
  1303. // beep
  1304. cursory = y - base;
  1305. return false;
  1306. }
  1307. if (fuzz) t += " "; else t = " " + t;
  1308. t = (t.substr(x, t.length-x));
  1309. var aa = re.exec(t);
  1310. if (!aa) {
  1311. y++;
  1312. x = 0;
  1313. } else {
  1314. x += _rel(re,t,aa).length;
  1315. cursorx = x - left;
  1316. cursory = y - base;
  1317. return true;
  1318. }
  1319. }
  1320. return false;
  1321. }
  1322. function term_skipbackward(re) {
  1323. var y = cursory+base;
  1324. var x = (cursorx+left)+1;
  1325. for (;;) {
  1326. var t = file[y];
  1327. if (t == undefined) {
  1328. // beep
  1329. cursory = 0;
  1330. cursorx = 0;
  1331. return false;
  1332. }
  1333. t = " " + t.substr(0, x-1);
  1334. if (t == '') {
  1335. y--;
  1336. t = file[y];
  1337. if (t == undefined) continue;
  1338. x = (t.length);
  1339. continue;
  1340. }
  1341. var aa = re.exec(t);
  1342. if (!aa) {
  1343. left = 0;
  1344. cursorx = 0;
  1345. cursory = y - base;
  1346. return true;
  1347. } else {
  1348. x = _rel(re,t,aa).length;
  1349. cursorx = x - left;
  1350. cursory = y - base;
  1351. return true;
  1352. }
  1353. }
  1354. return false;
  1355. }
  1356. function term_search(s, top, start, bottom) {
  1357. var re = new RegExp(s.substr(1));
  1358. var i;
  1359. if (s.substr(0, 1) == '/') {
  1360. statustext='';
  1361. re.lastIndex = cursorx+left+1;
  1362. for (i = start; i < bottom; i++) {
  1363. var t = (file[i]);
  1364. if (i == start) {
  1365. t = t.substr(cursorx+left+1, t.length-(cursorx+left+1));
  1366. }
  1367. aa = re.exec(t);
  1368. if (!aa) continue;
  1369. var tx = _rel(re,t,aa).length;
  1370. if (i == start) {
  1371. tx += cursorx+left+1;
  1372. }
  1373. left = 0;
  1374. base = 0;
  1375. cursorx = tx;
  1376. cursory = i;
  1377. term_scrollto();
  1378. return true;
  1379. }
  1380. statustext = 'search hit BOTTOM, continuing at TOP';
  1381. for (i = top; i <= start; i++) {
  1382. var aa = re.exec(file[i]);
  1383. if (!aa) continue;
  1384. left = 0;
  1385. base = 0;
  1386. cursorx = _rel(re,file[i],aa).length;
  1387. cursory = i;
  1388. term_scrollto();
  1389. return true;
  1390. }
  1391. statustext = 'Pattern not found: ' + s.substr(1);
  1392. } else {
  1393. statustext='';
  1394. for (i = start; i >= top; i--) {
  1395. var t = file[i];
  1396. if (t == undefined) continue;
  1397. var tail = 0;
  1398. if (i == start) {
  1399. tail = (cursorx+left);
  1400. } else {
  1401. tail = t.length;
  1402. }
  1403. var right = tail;
  1404. while (tail > 0) {
  1405. tail--;
  1406. var xj = t.substr(tail, right-tail);
  1407. var aa = re.exec(xj);
  1408. if (!aa) continue;
  1409. var tx = tail+_rel(re,xj,aa).length;
  1410. left = 0;
  1411. base = 0;
  1412. cursorx = tx;
  1413. cursory = i;
  1414. term_scrollto();
  1415. return true;
  1416. }
  1417. }
  1418. statustext = 'search hit TOP, continuing at BOTTOM';
  1419. for (i = bottom; i >= start; i--) {
  1420. var t = file[i];
  1421. if (t == undefined) continue;
  1422. var tail = t.length;
  1423. while (tail > 0) {
  1424. tail--;
  1425. var xj = t.substr(tail, t.length-tail);
  1426. var aa = re.exec(xj);
  1427. if (!aa) continue;
  1428. cursorx = tail+_rel(re,xj,aa).length;
  1429. cursory = i;
  1430. left = 0;
  1431. base = 0;
  1432. term_scrollto();
  1433. return true;
  1434. }
  1435. }
  1436. statustext = 'Pattern not found: ' + s.substr(1);
  1437. }
  1438. return false;
  1439. }
  1440. function term_rsearch(s, top, start, bottom) {
  1441. var cx = s.substr(0, 1);
  1442. cx = (cx == '/') ? '?' : "/";
  1443. return term_search(cx+s.substr(1,s.length-1), top, start, bottom);
  1444. }
  1445. function _pop(q) {
  1446. var a = new Array();
  1447. var i;
  1448. for (i = 0; i < q.length-1; i++) {
  1449. a[i] = q[i];
  1450. }
  1451. return a;
  1452. }
  1453. function _addr(q) {
  1454. if (q == '.') {
  1455. return cursory+base;
  1456. }
  1457. if (q == '$') {
  1458. return file.length-1;
  1459. }
  1460. if (q.substr(0, 1) == "'") {
  1461. return marks[ q.substr(1, 1) ];
  1462. }
  1463. if (q == "\\/" || q == "\\&") {
  1464. var a=cursory;
  1465. var b=base;
  1466. term_search(lastsearch, 0, cursory+base, file.length);
  1467. var c=cursory+base;
  1468. cursory=a;
  1469. base=b;
  1470. return c;
  1471. }
  1472. if (q == "\\?") {
  1473. var a=cursory;
  1474. var b=base;
  1475. term_rsearch(lastsearch, 0, cursory+base, file.length);
  1476. var c=cursory+base;
  1477. cursory=a;
  1478. base=b;
  1479. return c;
  1480. }
  1481. if (q.substr(0, 1) == "/" || q.substr(0,1) == "?") {
  1482. var a=cursory;
  1483. var b=base;
  1484. term_search(q, 0, cursory+base, file.length);
  1485. var c=cursory+base;
  1486. cursory=a;
  1487. base=b;
  1488. return c;
  1489. }
  1490. q=parseInt(q)-1;
  1491. if (q >= file.length-1) q=file.length-1;
  1492. if (q < 0) q=0;
  1493. return q;
  1494. }
  1495. function term_command(s) {
  1496. var top, start,bottom;
  1497. if (s && s.length > 0 && s.substr(0,1) == ':') {
  1498. s = s.substr(1, s.length-1);
  1499. top = cursory+base;
  1500. start = top;
  1501. bottom = top;
  1502. } else {
  1503. top = 0;
  1504. start = cursory+base;
  1505. bottom = file.length;
  1506. }
  1507. // okay, this is kind of tricky
  1508. var i;
  1509. var tok = '';
  1510. var tc = 0;
  1511. var ng = new Array();
  1512. var lastre = undefined;
  1513. var nf = false;
  1514. /// xxx todo implement ! with nf
  1515. for (i = 0; i < s.length; i++) {
  1516. var c = s.substr(i, 1);
  1517. if ((tc==0 || tc==1) && "0123456789".indexOf(c) > -1) {
  1518. tc = 1;
  1519. tok = ''+tok+''+c;
  1520. continue;
  1521. } else if (tc == 1) {
  1522. tc = 0;
  1523. ng[ng.length] = parseInt(tok)-1;
  1524. tok = '';
  1525. }
  1526. if (c == '%') {
  1527. top = 0;
  1528. bottom = file.length;
  1529. start = cursory+base;
  1530. } else if (c == '!') {
  1531. nf = !nf;
  1532. } else if (c == ',') {
  1533. // do nothing
  1534. while (ng.length > 2) {
  1535. ng=_pop(ng);
  1536. }
  1537. } else if (c == ';') {
  1538. start = ng[ng.length-1];
  1539. ng = _pop(ng);
  1540. cursory=start;
  1541. base=0;
  1542. ng = _pop(ng);
  1543. } else if (c == '$') {
  1544. ng[ng.length] = file.length;
  1545. } else if (c == '.') {
  1546. ng[ng.length] = cursory+base;
  1547. } else if (c == "'") {
  1548. // mark
  1549. ng[ng.length] = marks[s.substr(i+1,1)];
  1550. i++;
  1551. } else if (c == "\\") {
  1552. i++;
  1553. c = s.substr(i, 1);
  1554. var qq;
  1555. if (c == '?') {
  1556. qq=term_rsearch;
  1557. } else {
  1558. qq=term_search;
  1559. }
  1560. if (ng.length == 1) {
  1561. top = ng[0];
  1562. ng = _pop(ng);
  1563. } else if (ng.length >= 2) {
  1564. top = ng[ng.length-2];
  1565. bottom = ng[ng.length-1];
  1566. ng = _pop(_pop(ng));
  1567. }
  1568. if (!qq(lastsearch,top,start,bottom)) {
  1569. return;
  1570. }
  1571. ng[ng.length] = cursory+base;
  1572. } else if (c == "/" || c == "?") {
  1573. var j = i;
  1574. for (i++; i < s.length; i++) {
  1575. var tc = s.substr(i, 1);
  1576. if (tc == "\\") i++;
  1577. else if (tc == c) break;
  1578. }
  1579. lastre = s.substr(j, i-j);
  1580. if (ng.length == 1) {
  1581. top = ng[0];
  1582. ng = _pop(ng);
  1583. } else if (ng.length >= 2) {
  1584. top = ng[ng.length-2];
  1585. bottom = ng[ng.length-1];
  1586. ng = _pop(_pop(ng));
  1587. }
  1588. if (!term_search(lastre,top,start,bottom)) {
  1589. return;
  1590. }
  1591. ng[ng.length] = cursory+base;
  1592. } else if (c == " " || c == "\t") {
  1593. continue;
  1594. } else {
  1595. break;
  1596. }
  1597. }
  1598. if (tc == 1) {
  1599. ng[ng.length] = parseInt(tok)-1;
  1600. tok = '';
  1601. i++;
  1602. }
  1603. if (ng.length == 1) {
  1604. top = ng[0];
  1605. bottom = ng[0];
  1606. } else if (ng.length >= 2) {
  1607. top = ng[ng.length-2];
  1608. bottom = ng[ng.length-1];
  1609. }
  1610. if (lastre != undefined) {
  1611. lastsearch = lastre;
  1612. registers["/"] = lastsearch.substr(1, lastsearch.length-1);
  1613. }
  1614. var cmd2 = s.substr(i,2);
  1615. var cmd = s.substr(i, 1);
  1616. if (cmd2 == 'wq' || cmd == 'x') {
  1617. editor_disable(true);
  1618. } else if (cmd == '=') {
  1619. statustext = '' + bottom;
  1620. return;
  1621. } else if (cmd2 == 'ha') {
  1622. window.print();
  1623. return;
  1624. } else if (cmd == 'w') {
  1625. var zx = term_freeze();
  1626. if (term._formelement) term._formelement.value=zx;
  1627. statustext = '"/tmp/mess4XbCXM" ' + file.length + 'L, '
  1628. + zx.length + 'C written';
  1629. } else if (!emacsen && s.substr(i,(s.length-i)) == 'emacs') {
  1630. statustext = 'EMACS mode enabled. Press M-x vi to use vi mode';
  1631. emacsen = true;
  1632. mode = 1;
  1633. } else if (emacsen && cmd2 == 'vi') {
  1634. statustext = 'VI mode enabled. Press ESC :emacs to use EMACS mode';
  1635. mode = 0;
  1636. emacsen = false;
  1637. } else if (cmd == 'e' && term._formelement) {
  1638. var zx = term_freeze();
  1639. if (cmd2 != 'e!') {
  1640. if (cmd2 == 'e?') {
  1641. if (!confirm("Your changes will be lost\nAre you sure?")) {
  1642. return;
  1643. }
  1644. } else if (term._formelement.value != zx) {
  1645. statustext = 'No write since last change (use ! to override)';
  1646. return;
  1647. }
  1648. }
  1649. term_thaw(term._formelement.value);
  1650. } else if (cmd == 'f') {
  1651. var zx = term_freeze();
  1652. statustext = '"/tmp/mess4XbCXM"';
  1653. if (term._formelement.value != zx) {
  1654. statustext += ' [Modified]';
  1655. }
  1656. statustext += ' line ' + (cursory+base+1) + ' of '
  1657. + file.length + ' col ' + (cursorx+left+1);
  1658. } else if (cmd == 'h' || s.substr(i,5) == 'about') {
  1659. statustext = "jsvi \xa9 2006 Internet Connection, Inc";
  1660. } else if (s.substr(i,4) == 'kwak') {
  1661. term.style.backgroundImage = 'url(ducky.jpg)';
  1662. statustext = 'kwak kwak kwak...';
  1663. } else if (s.substr(i,3) == 'moo') {
  1664. statustext = 'This editor does not have Super Cow Powers';
  1665. } else if (cmd == 'b') {
  1666. // only one buffer
  1667. } else if (cmd == 'n' || cmd == 'N') {
  1668. statustext = 'There is only one file to edit';
  1669. } else if (cmd == 'q') {
  1670. var zx = term_freeze();
  1671. if (cmd2 != 'q!') {
  1672. if (term._formelement.value != zx) {
  1673. if (cmd2 == 'q?') {
  1674. if (confirm("Your changes will be lost\nAre you sure?")) {
  1675. editor_disable(false);
  1676. return;
  1677. } else {
  1678. return;
  1679. }
  1680. }
  1681. statustext = 'No write since last change (use ! to override)';
  1682. return;
  1683. }
  1684. }
  1685. editor_disable(false);
  1686. } else if (cmd == 'd') {
  1687. // delete lines
  1688. yank_buffer = term_delete(top);
  1689. while (top < bottom) {
  1690. yank_buffer += term_delete(top);
  1691. bottom--;
  1692. }
  1693. if (lastreg != '_') {
  1694. registers[lastreg] = yank_buffer;
  1695. term_roll_yank();
  1696. }
  1697. term_scrollto();
  1698. } else if (cmd == 'u') {
  1699. var z = term_freeze();
  1700. term_thaw(undoset);
  1701. undoset = z;
  1702. } else if (cmd == 'y') {
  1703. yank_buffer = '';
  1704. for (i = top; i < bottom; i++) {
  1705. yank_buffer += (file[i])+"\n";
  1706. }
  1707. registers[lastreg] = yank_buffer;
  1708. term_roll_yank();
  1709. } else if (cmd == 'F') {
  1710. // styling!
  1711. var y;
  1712. var tadd = 0;
  1713. var tsub = 0;
  1714. var tset = undefined;
  1715. var otc = tagstyle;
  1716. var tg = '=';
  1717. for (y = i+1; y < s.length; y++) {
  1718. var cy = s.substr(y, 1);
  1719. if (cy == '=' || cy == '+' || cy == '-' || cy == '!') {
  1720. tg = cy;
  1721. } else {
  1722. var fl = 0;
  1723. if (cy == 'b') {
  1724. fl = 1;
  1725. } else if (cy == 'i') {
  1726. fl = 16;
  1727. } else if (cy == 'u') {
  1728. fl = 2;
  1729. } else if (cy == 'o') {
  1730. fl = 4;
  1731. } else {
  1732. statustext = 'Unrecognized formatting specifier: ' + cy;
  1733. return;
  1734. }
  1735. if (tg == '!') {
  1736. if (tset != undefined) tagstyle = tset;
  1737. tagstyle = tagstyle ^ fl;
  1738. } else if (tg == '=') {
  1739. if (tset == undefined) tset = 0;
  1740. tset = tset + fl;
  1741. } else if (tg == '+') {
  1742. tadd |= fl;
  1743. } else if (tg == '-') {
  1744. tsub |= fl;
  1745. }
  1746. }
  1747. }
  1748. if (tset == undefined) {
  1749. tagstyle = ((tagstyle | tadd) | tsub) ^ tsub;
  1750. } else {
  1751. tagstyle = tset;
  1752. }
  1753. // okay, we've set tagstyle
  1754. if (i != 0) {
  1755. // if this happened, then we were given a range(!)
  1756. for (y = top; y <= bottom; y++) {
  1757. if (file[y] == undefined) continue;
  1758. tags[y] = _mxs(file[y].length, tagstyle);
  1759. }
  1760. tagstyle = otc;
  1761. } else if (vselm) {
  1762. term_select();
  1763. term_vi_unset('d');
  1764. term_vi_unset('y');
  1765. term_vi_unset('c');
  1766. term_vi_set('F');
  1767. term_operate();
  1768. tagstyle = otc;
  1769. }
  1770. } else if (cmd == 'g' || cmd == 'v') {
  1771. // okay then
  1772. var y;
  1773. var ng = s.substr(i+1,(s.length-i)-1);
  1774. if (cmd == 'v') ng = '!' + ng;
  1775. for (y = 0; y < file.length; y++) {
  1776. base = 0;
  1777. cursory = y;
  1778. term_command(ng);
  1779. }
  1780. } else if (cmd == 't' || cmd2 == 'co') {
  1781. // copy- need address
  1782. var t = s.substr(i, s.length-i).replace(/^[a-z]*[ ]*/);
  1783. var x;
  1784. yank_buffer = "";
  1785. for (x = top; x <= bottom; x++) {
  1786. if (file[x] != undefined) {
  1787. yank_buffer += (file[x]) + "\n";
  1788. }
  1789. }
  1790. var a = cursory;
  1791. var b = base;
  1792. base = 0;
  1793. cursorx = 0;
  1794. left = 0;
  1795. cursory = _addr(t);
  1796. if (cursory < 0) cursory = 0;
  1797. term_paste(false, yank_buffer);
  1798. cursory = a;
  1799. base = b;
  1800. } else if (cmd == 'm') {
  1801. // move- need address
  1802. i++;
  1803. if (s.substr(i, 3) == 'ove') {
  1804. i += 3;
  1805. }
  1806. var t = s.substr(i, s.length-i);
  1807. yank_buffer = term_delete(top);
  1808. while (top < bottom) {
  1809. yank_buffer += term_delete(top);
  1810. bottom--;
  1811. }
  1812. var a = cursory;
  1813. var b = base;
  1814. base = 0;
  1815. cursorx = 0;
  1816. left = 0;
  1817. cursory = _addr(t);
  1818. if (cursory < 0) cursory = 0;
  1819. term_paste(false, yank_buffer);
  1820. cursory = a;
  1821. base = b;
  1822. } else if (cmd == 's') {
  1823. // substitute
  1824. i++;
  1825. // extract regex
  1826. var q = s.substr(i,1);
  1827. while (q == ' ') {
  1828. i++;
  1829. q = s.substr(i,1);
  1830. }
  1831. var sep = s.substr(i,1);
  1832. i++;
  1833. var lr, ls, lf;
  1834. if (sep == '') {
  1835. if (!lastsearch || !lastsubst) {
  1836. statustext = 'No previous substitute regular expression';
  1837. return;
  1838. }
  1839. lr = lastsearch.substr(1, lastsearch.length-1);
  1840. ls = lastsubst;
  1841. lf = lastflags;
  1842. } else {
  1843. var jj = i;
  1844. var zj;
  1845. for (; i < s.length; i++) {
  1846. zj = s.substr(i,1);
  1847. if (zj == "\\") {
  1848. i++;
  1849. } else if (zj == sep) {
  1850. break;
  1851. }
  1852. }
  1853. lastsearch = "/" + s.substr(jj, i-jj);
  1854. registers["/"] = lastsearch.substr(1, lastsearch.length-1);
  1855. i++; // sep
  1856. jj=i;
  1857. for (; i < s.length; i++) {
  1858. zj = s.substr(i,1);
  1859. if (zj == "\\") {
  1860. i++;
  1861. } else if (zj == sep) {
  1862. break;
  1863. }
  1864. }
  1865. lastsubst = s.substr(jj, i-jj);
  1866. lastflags = '';
  1867. i++;
  1868. var count = -1;
  1869. for (; i < s.length; i++) {
  1870. zj = s.substr(i,1);
  1871. if (zj == 'i' || zj == 'g') {
  1872. lastflags += zj;
  1873. } else {
  1874. count = parseInt(s.substr(i,s.length-i));
  1875. if (count > 0) {
  1876. break;
  1877. } else {
  1878. statustext = "Trailing characters";
  1879. return;
  1880. }
  1881. }
  1882. }
  1883. var re = new RegExp;
  1884. re.compile(lastsearch.substr(1, lastsearch.length-1),
  1885. (lastflags.indexOf('i') > -1) ? 'i' : '');
  1886. var hit = false;
  1887. for (i = top; i < bottom; i++) {
  1888. var t = file[i];
  1889. var g = tags[i];
  1890. var aa;
  1891. var st = t;
  1892. aa = re.exec(t);
  1893. if (!aa || aa.length == 0) continue;
  1894. file[i] = '';
  1895. tags[i] = '';
  1896. // okay got a hit, do this vi style
  1897. for (;;) {
  1898. t = _rer(re,st,aa);
  1899. var lt = _rel(re,st,aa);
  1900. var lg = _resubst(lastsubst,aa);
  1901. file[i] += lt + lg;
  1902. tags[i] += g.substr(0, lt.length) + _zeros(lg.length);
  1903. if (lastflags.indexOf('g') > -1) {
  1904. st = t;
  1905. aa = re.exec(t);
  1906. if (aa && aa.length > 0) continue;
  1907. }
  1908. file[i] += t;
  1909. tags[i] += g.substr(g.length - t.length, t.length);
  1910. break;
  1911. }
  1912. hit = true;
  1913. if (count > -1) {
  1914. count--;
  1915. if (count == 0) break;
  1916. }
  1917. }
  1918. if (!hit) {
  1919. statustext = 'Pattern not found: ' + lastsearch.substr(1, lastsearch.length-1);
  1920. }
  1921. }
  1922. } else if (cmd == '' && ng.length > 0) {
  1923. base = 0;
  1924. cursory = top;
  1925. } else {
  1926. statustext = "Not an editor command: " + s.substr(i,s.length-i);
  1927. }
  1928. }
  1929. function _resubst(s, aa) {
  1930. var i;
  1931. var out = '';
  1932. for (i = 0; i < s.length; i++) {
  1933. var zq = s.substr(i, 1);
  1934. if (zq == "\\") {
  1935. zq = s.substr(i, 2);
  1936. if (zq == "\\1") {
  1937. zq = aa[1];
  1938. } else if (zq == "\\2") {
  1939. zq = aa[2];
  1940. } else if (zq == "\\3") {
  1941. zq = aa[3];
  1942. } else if (zq == "\\4") {
  1943. zq = aa[4];
  1944. } else if (zq == "\\5") {
  1945. zq = aa[5];
  1946. } else if (zq == "\\6") {
  1947. zq = aa[6];
  1948. } else if (zq == "\\7") {
  1949. zq = aa[7];
  1950. } else if (zq == "\\8") {
  1951. zq = aa[8];
  1952. } else if (zq == "\\9") {
  1953. zq = aa[9];
  1954. } else {
  1955. zq = s.substr(i+1, 1);
  1956. }
  1957. i++;
  1958. } else if (zq == "&") {
  1959. zq = aa[0];
  1960. }
  1961. out += zq;
  1962. }
  1963. return out;
  1964. }
  1965. function _calcy(zx, x, g) {
  1966. if (zx && cursor._lasty != cursory) {
  1967. cursor._lasty = cursory;
  1968. var nh = 0;
  1969. while (zx && zx != document.body) {
  1970. nh += zx.offsetTop;
  1971. zx = zx.offsetParent;
  1972. }
  1973. cursor.style.top = nh + 'px';
  1974. }
  1975. var z = x.substr(cursorx, 1);
  1976. var q = g.substr(cursorx, 1).charCodeAt(0);
  1977. if (cursorx >= x.length || z == undefined || z == "\240" || z == '')
  1978. z = ' ';
  1979. if (cursor._lastch != z || cursor._lastgh != q) {
  1980. if (z == ' ') {
  1981. z = "\240";
  1982. q = 0;
  1983. }
  1984. while (cursor.firstChild)
  1985. cursor.removeChild(cursor.firstChild);
  1986. cursor.appendChild(document.createTextNode(z));
  1987. cursor._lastch = z;
  1988. cursor._lastgh = q;
  1989. if (q & 1) {
  1990. cursor.style.fontWeight = 'bold';
  1991. } else {
  1992. cursor.style.fontWeight = 'normal';
  1993. }
  1994. if (q & 2) {
  1995. cursor.style.textDecoration = 'underline';
  1996. } else {
  1997. cursor.style.textDecoration = 'none';
  1998. }
  1999. if (q & 16) {
  2000. cursor.style.fontStyle = 'italic';
  2001. } else {
  2002. cursor.style.fontStyle = 'normal';
  2003. }
  2004. }
  2005. }
  2006. function term_calcy() {
  2007. // fixup character inside... burrr
  2008. var xx = file[cursory+base];
  2009. var xg = tags[cursory+base];
  2010. var zleft = left;
  2011. if (cursory == (term_rows-1)) {
  2012. xx = command + " ";
  2013. zleft = commandleft;
  2014. xg = _mxs(xx.length+1,0);
  2015. }
  2016. var gg = term.childNodes;
  2017. if (gg.length > cursory) {
  2018. gg = term.childNodes[cursory];
  2019. } else {
  2020. gg = undefined;
  2021. }
  2022. _calcy(gg, xx.substr(zleft, xx.length-zleft), xg.substr(zleft, xg.length-zleft));
  2023. }
  2024. function term_calcx() {
  2025. if (cursorx != cursor._lastx) {
  2026. cursor.style.left = (cursorx * (term_cur_width)) + 'px';
  2027. cursor._lastx = cursorx;
  2028. term_calcy();
  2029. }
  2030. }
  2031. function term_scrollto() {
  2032. var h = term_rows;
  2033. var w = term_cols;
  2034. var x = cursorx+left;
  2035. var y = cursory+base;
  2036. var t = file[y];
  2037. if (command == '') h--;
  2038. var ex = parseInt((w/8));
  2039. if (ex < 4) ex = 4;
  2040. var ey = parseInt((h/8));
  2041. if (ey < 4) ey = 4;
  2042. while (t == undefined && y > 0) {
  2043. y--;
  2044. t = file[y];
  2045. }
  2046. if (t == undefined) t = '';
  2047. if (x >= t.length) {
  2048. if (mode) x = t.length;
  2049. else x = t.length-1;
  2050. }
  2051. if (x < 0) x = 0;
  2052. if (y < 0) y = 0;
  2053. if (x < left) {
  2054. left = (x - ex);
  2055. cursorx = ex;
  2056. if (left < 0) {
  2057. left = 0;
  2058. cursorx = 0;
  2059. }
  2060. } else if (x >= left+w) {
  2061. left = (x - w) + ex;
  2062. cursorx = w - ex;
  2063. } else {
  2064. cursorx = x - left;
  2065. }
  2066. if (y < base) {
  2067. base = (y - ey);
  2068. cursory = ey;
  2069. if (base < 0) {
  2070. base = 0;
  2071. cursory = 0;
  2072. }
  2073. } else if (y >= base+h) {
  2074. base = ((y - h) + ey);
  2075. cursory = (h - ey);
  2076. } else {
  2077. cursory = y - base;
  2078. }
  2079. term_calcx();
  2080. term_calcy();
  2081. }
  2082. function term_insert(y, str) {
  2083. var z = file.length;
  2084. file[z] = '';
  2085. tags[z] = '';
  2086. var i;
  2087. for (i = z; i > y; i--) {
  2088. file[i] = (file[i-1]);
  2089. tags[i] = (tags[i-1]);
  2090. }
  2091. file[y] = '';
  2092. tags[y] = '';
  2093. }
  2094. function term_paste(after, ign) {
  2095. if (ign != undefined) {
  2096. yank_buffer = ign;
  2097. } else {
  2098. registers['.'] = lastinsert;
  2099. registers[':'] = oldcommand;
  2100. registers['%'] = "/tmp/mess4XbCXM";
  2101. registers['#'] = "";
  2102. yank_buffer = registers[lastreg];
  2103. }
  2104. if (yank_buffer == undefined) return false;
  2105. if (yank_buffer.indexOf("\n") > -1) {
  2106. // insert after this line
  2107. if (after) cursory++;
  2108. var nq = yank_buffer.split("\n");
  2109. var nj;
  2110. for (nj = 0; nj < nq.length; nj++) {
  2111. if (nj == (nq.length-1)) {
  2112. if (nq[nj] == undefined) break;
  2113. if (nq[nj] == '') break;
  2114. // handled specially
  2115. var aa = _hra(nq[nj]);
  2116. file[cursory+base+nj] = aa[0] + (file[cursory+base+nj]);
  2117. tags[cursory+base+nj] = aa[1] + (tags[cursory+base+nj]);
  2118. break;
  2119. }
  2120. term_insert(cursory+base+nj);
  2121. var aa = _hra(nq[nj]);
  2122. file[cursory+base+nj] = aa[0];
  2123. tags[cursory+base+nj] = aa[1];
  2124. }
  2125. } else {
  2126. var t = (file[cursory+base]);
  2127. var g = (tags[cursory+base]);
  2128. var aa = _hra(yank_buffer);
  2129. if (after) cursorx++;
  2130. file[cursory+base] = t.substr(0, cursorx+left)
  2131. + aa[0] + t.substr(cursorx+left, t.length-(cursorx+left));
  2132. tags[cursory+base] = g.substr(0, cursorx+left)
  2133. + aa[1] + g.substr(cursorx+left, g.length-(cursorx+left));
  2134. }
  2135. return true;
  2136. }
  2137. function term_keyfix(e) {
  2138. if (!e) e = window.event;
  2139. var ch = e.keyCode;
  2140. if (!ch) ch = e.which;
  2141. if (e.DOM_VK_UP) {
  2142. if (e.DOM_VK_UP == ch) ch = 57373;
  2143. else if (e.DOM_VK_DOWN == ch) ch = 57374;
  2144. else if (e.DOM_VK_LEFT == ch) ch = 57375;
  2145. else if (e.DOM_VK_RIGHT == ch) ch = 57376;
  2146. }
  2147. if (ch == 8 || ch == 9 || ch == 37 || ch == 39
  2148. || ch == 38 || ch == 40 || ch == 127
  2149. || ch == 33 || ch == 34 || ch == 36
  2150. || ch == 35 || ch == 45 || ch == 46
  2151. || ch == 57373
  2152. || ch == 57374
  2153. || ch == 57375
  2154. || ch == 57376) {
  2155. if (e.preventDefault) e.preventDefault();
  2156. if (e.stopPropagation) e.stopPropagation();
  2157. term_keypress_inner(e, true);
  2158. e.cancelBubble=true;
  2159. return false;
  2160. } else {
  2161. e.cancelBubble=false;
  2162. return true;
  2163. }
  2164. }
  2165. function term_keypress(e) {
  2166. if (!e) e = window.event;
  2167. if (e.preventDefault) e.preventDefault();
  2168. if (e.stopPropagation) e.stopPropagation();
  2169. if (suggest._visible) {
  2170. suggest.style.display = 'none';
  2171. suggest._visible = false;
  2172. }
  2173. e.cancelBubble=true;
  2174. term_keypress_inner(e, false);
  2175. return false;
  2176. }
  2177. function term_keypress_inner(e, synth) {
  2178. var k = e.which;
  2179. var kc;
  2180. if (e.charCode) {
  2181. if (e.charCode == 27 || e.charCode == 13 || e.charCode == 10
  2182. || e.charCode == 8
  2183. || e.charCode == 9) {
  2184. k = e.charCode;
  2185. kc = String.fromCharCode(e.charCode);
  2186. } else if (e.charCode == 63232) {
  2187. k = 57373;
  2188. } else if (e.charCode == 63233) {
  2189. k = 57374;
  2190. } else if (e.charCode == 63234) {
  2191. k = 57375;
  2192. } else if (e.charCode == 63235) {
  2193. k = 57376;
  2194. } else {
  2195. if (e.charCode == 191) return; // wtf?
  2196. kc = String.fromCharCode(e.charCode);
  2197. k = 0;
  2198. }
  2199. } else if (e.keyCode) {
  2200. k = e.keyCode;
  2201. if (e.DOM_VK_UP) {
  2202. if (e.DOM_VK_UP == k) k = 57373;
  2203. else if (e.DOM_VK_DOWN == k) k = 57374;
  2204. else if (e.DOM_VK_LEFT == k) k = 57375;
  2205. else if (e.DOM_VK_RIGHT == k) k = 57376;
  2206. } else {
  2207. kc = String.fromCharCode(e.keyCode);
  2208. }
  2209. if (k == 191) return; // unicode i think
  2210. } else {
  2211. if (!k || k == 191) return;
  2212. kc = String.fromCharCode(k);
  2213. var i;
  2214. }
  2215. var mod;
  2216. if (e.modifiers) mod = e.modifiers; else mod = 0;
  2217. var ctrl = e.ctrlKey | (mod & 2);
  2218. var shift = e.shiftKey | (mod & 4);
  2219. var meta = e.altKey | e.metaKey | (mod & 1);
  2220. var lk = lastkey;
  2221. lastkey = kc;
  2222. if (kc == undefined) kc = '';
  2223. if (!emacsen && mode == 0) {
  2224. if (kc == 'U') {
  2225. if ((base+cursory) == undoy) {
  2226. var aa = _hra(undoline);
  2227. file[undoy] = aa[0];
  2228. tags[undoy] = aa[1];
  2229. }
  2230. } else if (kc == 'u' && undoset) {
  2231. var z = term_freeze();
  2232. term_thaw(undoset);
  2233. undoset = z;
  2234. }
  2235. if (kc == 'u' || kc == 'U') {
  2236. term_scrollto();
  2237. term_redraw();
  2238. lastkey = undefined;
  2239. return;
  2240. }
  2241. }
  2242. var fakemode = false;
  2243. // emacsen
  2244. if (emacsen && meta && (kc == 'x' || kc == 'X')) {
  2245. kc = ':'
  2246. fakemode = true;
  2247. lk = undefined;
  2248. lastkey = undefined;
  2249. } else if (ctrl && (kc == 't' || kc == 'T')) {
  2250. kc = '?'
  2251. fakemode = true;
  2252. lk = undefined;
  2253. lastkey = undefined;
  2254. } else if (ctrl && (kc == 's' || kc == 'S')) {
  2255. kc = '/'
  2256. fakemode = true;
  2257. lk = undefined;
  2258. lastkey = undefined;
  2259. } else if (ctrl && (kc == 'k' || kc == 'K')) {
  2260. term_command(':d');
  2261. lastkey = undefined;
  2262. return;
  2263. } else if (emacsen && meta && (kc == 'd' || kc == 'D')) {
  2264. kc = 'D';
  2265. fakemode = true;
  2266. lk = undefined;
  2267. lastkey = undefined;
  2268. } else if (ctrl && (kc == 'a' || kc == 'A')) {
  2269. kc = '0';
  2270. fakemode = true;
  2271. lk = undefined;
  2272. lastkey = undefined;
  2273. } else if (ctrl && (kc == 'd' || kc == 'D')) {
  2274. if (emacsen) {
  2275. kc = 'x';
  2276. } else {
  2277. // err...
  2278. if (!accum) accum=term_rows+1;
  2279. cursory += parseInt(accum/2)+2;
  2280. accum=0;
  2281. term_scrollto();
  2282. term_redraw();
  2283. lk = undefined;
  2284. lastkey = undefined;
  2285. return;
  2286. }
  2287. fakemode = true;
  2288. lk = undefined;
  2289. lastkey = undefined;
  2290. } else if (ctrl && (kc == 'g' || kc == 'G')) {
  2291. term_command(':f');
  2292. lastkey = undefined;
  2293. return;
  2294. } else if (ctrl && (kc == 'e' || kc == 'E')) {
  2295. if (emacsen) {
  2296. kc = '$';
  2297. } else {
  2298. if (!accum) accum = 1;
  2299. cursory += accum;
  2300. accum = 0;
  2301. term_scrollto();
  2302. term_redraw();
  2303. lk = undefined;
  2304. lastkey = undefined;
  2305. return;
  2306. }
  2307. fakemode = true;
  2308. lk = undefined;
  2309. lastkey = undefined;
  2310. } else if (emacsen && meta && (kc == 'b' || kc == 'B')) {
  2311. kc = 'b';
  2312. fakemode = true;
  2313. lk = undefined;
  2314. lastkey = undefined;
  2315. } else if (emacsen && meta && (kc == 'l' || kc == 'L')) {
  2316. kc = 'e';
  2317. fakemode = true;
  2318. lk = undefined;
  2319. lastkey = undefined;
  2320. } else if (emacsen && meta && (kc == 'f' || kc == 'F')) {
  2321. kc = 'w';
  2322. fakemode = true;
  2323. lk = undefined;
  2324. lastkey = undefined;
  2325. } else if (ctrl && (kc == 'f' || kc == 'F')) {
  2326. if (emacsen) {
  2327. kc = 'l';
  2328. } else {
  2329. // vi pagedown
  2330. if (!accum) accum = 0;
  2331. cursory += (term_rows*accum);
  2332. accum = 0;
  2333. term_scrollto();
  2334. term_redraw();
  2335. lk = undefined;
  2336. lastkey = undefined;
  2337. return;
  2338. }
  2339. fakemode = true;
  2340. lk = undefined;
  2341. lastkey = undefined;
  2342. } else if (ctrl && (kc == 'y' || kc == 'Y')) {
  2343. if (emacsen) {
  2344. term_command(':y');
  2345. lastkey = undefined;
  2346. return;
  2347. } else {
  2348. if (!accum) accum = 1;
  2349. cursory -= accum;
  2350. accum = 0;
  2351. term_scrollto();
  2352. term_redraw();
  2353. lk = undefined;
  2354. lastkey = undefined;
  2355. return;
  2356. }
  2357. } else if (ctrl && (kc == 'l' || kc == 'L')) {
  2358. term_redraw();
  2359. lk = undefined;
  2360. lastkey = undefined;
  2361. return;
  2362. } else if (ctrl && (kc == 'u' || kc == 'U')) {
  2363. if (emacsen) {
  2364. // emacs undo
  2365. kc = 'u';
  2366. } else {
  2367. // vi pageup
  2368. if (!accum) accum=term_rows+1;
  2369. cursory -= parseInt(accum/2)+2;
  2370. accum=0;
  2371. term_scrollto();
  2372. term_redraw();
  2373. lk = undefined;
  2374. lastkey = undefined;
  2375. return;
  2376. }
  2377. fakemode = true;
  2378. lk = undefined;
  2379. lastkey = undefined;
  2380. } else if (ctrl && (kc == 'w' || kc == 'W')) {
  2381. // vim uses this for window control; this is actually useful
  2382. fakemode = true;
  2383. term_vi_set('d');
  2384. kc = 'b';
  2385. lk = undefined;
  2386. lastkey = undefined;
  2387. } else if (ctrl && (kc == 'b' || kc == 'B')) {
  2388. if (emacsen) {
  2389. kc = 'h';
  2390. } else {
  2391. // vi pageup
  2392. if (!accum) accum=1;
  2393. cursory -= (term_rows*accum);
  2394. accum=0;
  2395. term_scrollto();
  2396. term_redraw();
  2397. lk = undefined;
  2398. lastkey = undefined;
  2399. return;
  2400. }
  2401. fakemode = true;
  2402. lk = undefined;
  2403. lastkey = undefined;
  2404. }
  2405. if (k >= 57373 && k <= 57376 && !synth) {
  2406. // bail
  2407. return
  2408. } else if (!synth && (k < 57373 || k > 57376)) {
  2409. // no touching...
  2410. } else if (k == 31 || k == 40 || k == 57374) { // down
  2411. if (!synth) return;
  2412. fakemode = true;
  2413. kc = 'j';
  2414. lk = undefined;
  2415. lastkey = undefined;
  2416. } else if (k == 30 || k == 38 || k == 57373) { // up
  2417. if (!synth) return;
  2418. fakemode = true;
  2419. kc = 'k';
  2420. lk = undefined;
  2421. lastkey = undefined;
  2422. } else if (k == 28 || k == 37 || k == 57375) { // left
  2423. if (!synth) return;
  2424. fakemode = true;
  2425. kc = ctrl ? 'B' : 'h';
  2426. lk = undefined;
  2427. lastkey = undefined;
  2428. } else if (k == 29 || k == 39 || k == 57376) { // right
  2429. if (!synth) return;
  2430. fakemode = true;
  2431. kc = ctrl ? 'W' : 'l';
  2432. lk = undefined;
  2433. lastkey = undefined;
  2434. } else if (k == 33) { // pageup
  2435. cursory -= term_rows;
  2436. term_scrollto();
  2437. term_redraw();
  2438. lk = undefined;
  2439. lastkey = undefined;
  2440. return;
  2441. } else if (k == 34) { // pagedown
  2442. cursory += term_rows;
  2443. term_scrollto();
  2444. term_redraw();
  2445. lk = undefined;
  2446. lastkey = undefined;
  2447. return;
  2448. } else if (k == 36) { // home
  2449. if (ctrl) {
  2450. lk = 'g';
  2451. kc = 'g';
  2452. } else {
  2453. kc = '0';
  2454. }
  2455. fakemode = true;
  2456. lk = undefined;
  2457. lastkey = undefined;
  2458. accum = 0;
  2459. } else if (k == 35) { // end
  2460. fakemode = true;
  2461. accum = 0;
  2462. if (ctrl) {
  2463. kc = 'G';
  2464. } else {
  2465. kc = '$';
  2466. }
  2467. lk = undefined;
  2468. lastkey = undefined;
  2469. } else if (k == 45) { // insert
  2470. fakemode = true;
  2471. if (mode == 1) {
  2472. mode = 2;
  2473. } else if (mode == 2) {
  2474. mode = 1;
  2475. } else {
  2476. term_setmode(1);
  2477. }
  2478. lk = undefined;
  2479. lastkey = undefined;
  2480. term_redraw();
  2481. return;
  2482. } else if (k == 46) { // delete
  2483. fakemode = true;
  2484. kc = 'x';
  2485. lk = undefined;
  2486. lastkey = undefined;
  2487. } else if (synth && k != 8) {
  2488. return;
  2489. }
  2490. term_save_undo_line();
  2491. if (fakemode || mode == 0) {
  2492. if (!fakemode && ctrl) return;
  2493. if (lk == 'F' || lk == 'T' || lk == 'f' || lk == 't') {
  2494. vi_ft_reg = kc;
  2495. if (lk == 'F') {
  2496. term_ex_motion = term_vi_ff;
  2497. } else if (lk == 'T') {
  2498. term_ex_motion = term_vi_tt;
  2499. } else if (lk == 'f') {
  2500. term_ex_motion = term_vi_f;
  2501. } else if (lk == 't') {
  2502. term_ex_motion = term_vi_t;
  2503. }
  2504. term_operate();
  2505. lastkey = undefined;
  2506. term_scrollto();
  2507. term_redraw();
  2508. _update_backing();
  2509. return;
  2510. } else if (lk == 'm') {
  2511. // set mark
  2512. marks[kc] = cursory+base;
  2513. lastkey = undefined;
  2514. accum = 0;
  2515. return;
  2516. } else if (lk == "'") {
  2517. term_ex_motion = function() {
  2518. cursory = marks[kc];
  2519. base = 0;
  2520. term_scrollto();
  2521. term_redraw();
  2522. return true;
  2523. };
  2524. if (!accum) accum = 1;
  2525. term_operate();
  2526. return;
  2527. } else if (lk == '"') {
  2528. // set last register
  2529. lastreg = kc;
  2530. lastkey = undefined;
  2531. accum = 0;
  2532. return;
  2533. } else if (lk == 'r') {
  2534. var p = cursorx + left;
  2535. var t = (file[cursory+base]);
  2536. if (!accum) accum = 1;
  2537. var ng = '';
  2538. var i;
  2539. for (i = 0; i < accum; i++) ng += kc;
  2540. term_save_undo();
  2541. file[cursory+base] = (t.substr(0, p))
  2542. + (ng) + (t.substr(p+accum, t.length-(p+accum)));
  2543. // tags remains unchanged (same length)
  2544. accum = 0;
  2545. lastkey = undefined;
  2546. term_scrollto();
  2547. term_redraw();
  2548. _update_backing();
  2549. _term_update_printer();
  2550. return;
  2551. }
  2552. if (kc == ':' || kc == '/' || kc == '?') {
  2553. command = kc;
  2554. commandleft = 0;
  2555. savex = cursorx;
  2556. savey = cursory;
  2557. cursorx = 1;
  2558. cursory = term_rows-1;
  2559. mode=1;
  2560. term_redraw();
  2561. term_calcx();
  2562. return;
  2563. } else if (kc == "'") {
  2564. // jump to mark (ick)
  2565. } else if (kc == '"') {
  2566. // do nothing for now
  2567. } else if (kc == '.') {
  2568. term_vi_set(lastcommand);
  2569. term_ex_motion = lastmotion;
  2570. term_operate();
  2571. } else if (kc == '$') {
  2572. term_ex_motion = term_vi_eol;
  2573. term_operate();
  2574. } else if (kc == '%') {
  2575. if (accum <= 0) {
  2576. term_ex_motion = term_vi_bounce;
  2577. term_operate();
  2578. } else if (file.length > 0) {
  2579. base = 0;
  2580. cursorx = 0;
  2581. left = 0;
  2582. cursory = parseInt(accum * (term_rows / (file.length+1.0)));
  2583. accum = 0;
  2584. }
  2585. } else if (kc == '0') {
  2586. if (accum) {
  2587. accum *= 10;
  2588. } else {
  2589. cursorx = 0;
  2590. left = 0;
  2591. }
  2592. } else if (kc == '1') {
  2593. accum *= 10; accum++;
  2594. } else if (kc == '2') {
  2595. accum *= 10; accum += 2;
  2596. } else if (kc == '3') {
  2597. accum *= 10; accum += 3;
  2598. } else if (kc == '4') {
  2599. accum *= 10; accum += 4;
  2600. } else if (kc == '5') {
  2601. accum *= 10; accum += 5;
  2602. } else if (kc == '6') {
  2603. accum *= 10; accum += 6;
  2604. } else if (kc == '7') {
  2605. accum *= 10; accum += 7;
  2606. } else if (kc == '8') {
  2607. accum *= 10; accum += 8;
  2608. } else if (kc == '9') {
  2609. accum *= 10; accum += 9;
  2610. } else if (kc == 'A') {
  2611. var t = (file[cursory+base]);
  2612. cursorx = t.length; // will be fixed up...
  2613. term_setmode(1);
  2614. term_save_undo();
  2615. } else if (kc == 'a') {
  2616. term_setmode(1);
  2617. cursorx++;
  2618. term_save_undo();
  2619. } else if (kc == 'B') {
  2620. term_ex_motion = term_vi_bb;
  2621. term_operate();
  2622. } else if (kc == 'b') {
  2623. term_ex_motion = term_vi_b;
  2624. term_operate();
  2625. } else if (kc == 'c') {
  2626. if (term_vi_flag('c')) {
  2627. term_vi_set('d');
  2628. term_vi_unset('c');
  2629. savex = cursorx+left;
  2630. savey = cursory+base;
  2631. cursorx = 0; left = 0;
  2632. term_ex_motion = term_vi_line;
  2633. term_operate();
  2634. cursorx = savex-left;
  2635. cursory = savey-base;
  2636. term_setmode(1);
  2637. } else {
  2638. term_vi_set('c');
  2639. }
  2640. } else if (kc == 'C') {
  2641. term_ex_motion = term_vi_eol;
  2642. term_vi_set('d');
  2643. term_operate();
  2644. term_setmode(1);
  2645. } else if (kc == 'D') {
  2646. term_ex_motion = term_vi_eol;
  2647. term_vi_set('d');
  2648. term_operate();
  2649. } else if (kc == 'd') {
  2650. if (vselm) {
  2651. term_vi_set('d');
  2652. term_vi_unset('y');
  2653. term_select();
  2654. term_operate();
  2655. vselm = 0;
  2656. } else if (term_vi_flag('d')) {
  2657. accum++;
  2658. savex = cursorx+left;
  2659. savey = cursory+base;
  2660. cursorx = 0; left = 0;
  2661. term_ex_motion = term_vi_line;
  2662. term_operate();
  2663. cursorx = savex-left;
  2664. cursory = savey-base;
  2665. } else {
  2666. term_vi_set('d');
  2667. term_vi_unset('y');
  2668. }
  2669. } else if (kc == '>' || kc == '<') {
  2670. if (vselm) {
  2671. term_vi_unset('<');
  2672. term_vi_unset('>');
  2673. term_vi_set(kc);
  2674. term_vi_unset('d');
  2675. term_vi_unset('y');
  2676. term_operate();
  2677. vselm = 0;
  2678. } else if (term_vi_flag(kc)) {
  2679. accum++;
  2680. savex = cursorx+left;
  2681. savey = cursory+base;
  2682. cursorx = 0; left = 0;
  2683. term_ex_motion = term_vi_line;
  2684. term_operate();
  2685. cursorx = savex-left;
  2686. cursory = savey-base;
  2687. term_vi_unset('<');
  2688. term_vi_unset('>');
  2689. } else {
  2690. term_vi_unset('<');
  2691. term_vi_unset('>');
  2692. term_vi_set(kc);
  2693. term_vi_unset('d');
  2694. term_vi_unset('y');
  2695. }
  2696. } else if (kc == 'E') {
  2697. term_ex_motion = term_vi_ee;
  2698. term_operate();
  2699. } else if (kc == 'e') {
  2700. term_ex_motion = term_vi_e;
  2701. term_operate();
  2702. } else if (kc == 'F' || kc == 'f') {
  2703. // does nothing here
  2704. } else if (kc == 'G') {
  2705. term_ex_motion = term_vi_eof;
  2706. term_operate();
  2707. } else if (kc == 'g' && lk == 'g') {
  2708. term_ex_motion = term_vi_top;
  2709. term_operate();
  2710. } else if (kc == 'H') {
  2711. term_ex_motion = term_vi_hh;
  2712. term_operate();
  2713. } else if (kc == 'h') {
  2714. term_ex_motion = term_vi_h;
  2715. term_operate();
  2716. } else if (kc == 'I') {
  2717. term_save_undo();
  2718. if (vselm) {
  2719. term_vi_set('d');
  2720. term_vi_unset('y');
  2721. term_select();
  2722. term_operate();
  2723. vselm = 0;
  2724. }
  2725. term_setmode(1);
  2726. cursorx = 0;
  2727. left = 0;
  2728. } else if (kc == 'i') {
  2729. term_save_undo();
  2730. if (vselm) {
  2731. term_vi_set('d');
  2732. term_vi_unset('y');
  2733. term_select();
  2734. term_operate();
  2735. vselm = 0;
  2736. }
  2737. term_setmode(1);
  2738. } else if (kc == 'J') {
  2739. term_save_undo();
  2740. term_justify();
  2741. } else if (kc == 'j') {
  2742. term_ex_motion = term_vi_j;
  2743. term_operate();
  2744. } else if (kc == 'K') {
  2745. // err..
  2746. } else if (kc == 'k') {
  2747. term_ex_motion = term_vi_k;
  2748. term_operate();
  2749. } else if (kc == 'L') {
  2750. term_ex_motion = term_vi_ll;
  2751. term_operate();
  2752. } else if (kc == 'l') {
  2753. term_ex_motion = term_vi_l;
  2754. term_operate();
  2755. } else if (kc == 'M') {
  2756. term_ex_motion = term_vi_mm;
  2757. term_operate();
  2758. } else if (kc == 'm') {
  2759. // set mark
  2760. } else if (kc == 'N') {
  2761. if (lastsearch == '') {
  2762. statustext = 'No previous regular expression';
  2763. } else {
  2764. if (!accum) accum = 1;
  2765. var sl = lastsearch;
  2766. var cx = lastsearch.substr(0, 1);
  2767. cx = (cx == '?') ? '/' : '?';
  2768. var i;
  2769. for (i = 0; i < accum; i++) {
  2770. term_command(cx+(sl.substr(1, sl.length-1)));
  2771. }
  2772. lastsearch = sl;
  2773. accum = 0;
  2774. }
  2775. } else if (kc == 'n') {
  2776. if (lastsearch == '') {
  2777. statustext = 'No previous regular expression';
  2778. } else {
  2779. if (!accum) accum = 1;
  2780. var i;
  2781. for (i = 0; i < accum; i++)
  2782. term_command(lastsearch);
  2783. accum = 0;
  2784. }
  2785. } else if (kc == 'O') {
  2786. cursorx = 0;
  2787. left = 0;
  2788. term_insert(cursory+base);
  2789. term_setmode(1);
  2790. } else if (kc == 'o') {
  2791. cursory++;
  2792. cursorx = 0;
  2793. left = 0;
  2794. term_insert(cursory+base);
  2795. term_setmode(1);
  2796. term_save_undo();
  2797. } else if (kc == 'P' || kc == 'p') {
  2798. term_save_undo();
  2799. term_paste(kc == 'P' ? false : true);
  2800. accum = 0;
  2801. } else if (kc == 'R') {
  2802. term_save_undo();
  2803. if (vselm) {
  2804. term_vi_set('d');
  2805. term_vi_unset('y');
  2806. term_select();
  2807. term_operate();
  2808. vselm = 0;
  2809. }
  2810. term_setmode(2);
  2811. } else if (kc == 'S') {
  2812. term_vi_set('d');
  2813. term_vi_unset('c');
  2814. savex = cursorx+left;
  2815. savey = cursory+base;
  2816. cursorx = 0; left = 0;
  2817. term_ex_motion = term_vi_line;
  2818. term_operate();
  2819. cursorx = savex-left;
  2820. cursory = savey-base;
  2821. term_setmode(1);
  2822. } else if (kc == 's') {
  2823. term_vi_set('d');
  2824. term_vi_unset('c');
  2825. savex = cursorx+left;
  2826. savey = cursory+base;
  2827. term_ex_motion = term_vi_l;
  2828. term_operate();
  2829. cursorx = savex-left;
  2830. cursory = savey-base;
  2831. term_setmode(1);
  2832. } else if (kc == 'T' || kc == 't') {
  2833. // nothing here
  2834. } else if (kc == 'V' || kc == 'v') {
  2835. if (vselm) {
  2836. vselm = 0;
  2837. vselx = undefined;
  2838. vsely = undefined;
  2839. } else {
  2840. vselm = (kc == 'v') ? 1 : 2;
  2841. vselx = cursorx+left;
  2842. vsely = cursory+base;
  2843. }
  2844. } else if (kc == 'W') {
  2845. term_ex_motion = term_vi_ww;
  2846. term_operate();
  2847. } else if (kc == '{') {
  2848. term_ex_motion = term_vi_ob;
  2849. term_operate();
  2850. } else if (kc == '}') {
  2851. term_ex_motion = term_vi_cb;
  2852. term_operate();
  2853. } else if (kc == 'w') {
  2854. term_ex_motion = term_vi_w;
  2855. term_operate();
  2856. } else if (kc == 'x' || kc == 'X') {
  2857. if (term_vi_set('d')) {
  2858. term_vi_unset('d');
  2859. } else {
  2860. term_vi_set('d');
  2861. if (kc == 'x') {
  2862. term_ex_motion = term_vi_l;
  2863. } else {
  2864. term_ex_motion = term_vi_h;
  2865. }
  2866. term_operate();
  2867. }
  2868. } else if (kc == 'y') {
  2869. if (vselm) {
  2870. term_vi_set('y');
  2871. term_vi_unset('d');
  2872. term_select();
  2873. term_operate();
  2874. vselm = 0;
  2875. } else if (term_vi_flag('y')) {
  2876. accum++;
  2877. savex = cursorx+left;
  2878. savey = cursory+base;
  2879. cursorx = 0; left = 0;
  2880. term_ex_motion = term_vi_line;
  2881. term_operate();
  2882. cursorx = savex-left;
  2883. cursory = savey-base;
  2884. } else {
  2885. term_vi_set('y');
  2886. term_vi_unset('d');
  2887. }
  2888. } else if (kc == 'Z' && lk == 'Z') {
  2889. editor_disable(true);
  2890. accum = 0;
  2891. } else if (k == 27 || (k == 91 && ctrl)) { // escape or ^[
  2892. vselm = 0;
  2893. statustext = '';
  2894. mode = 0;
  2895. } else {
  2896. accum = 0;
  2897. }
  2898. term_scrollto();
  2899. } else if ((k == 27 || (k == 91 && ctrl))) { // escape or ^[
  2900. vselm = 0;
  2901. statustext = '';
  2902. if (command != '') {
  2903. cursorx = savex;
  2904. cursory = savey;
  2905. } else {
  2906. if (mode) _term_update_printer();
  2907. if (accum > 1) {
  2908. var i, j;
  2909. j = lastreg;
  2910. lastreg = '.';
  2911. for (i = 1; i < accum; i++) {
  2912. term_paste(false);
  2913. }
  2914. lastreg = j;
  2915. accum = 0;
  2916. }
  2917. cursorx--;
  2918. term_scrollto();
  2919. }
  2920. mode = emacsen ? 1 : 0;
  2921. command = '';
  2922. commandleft = 0;
  2923. } else if (command != '') {
  2924. if (k == 10 || k == 13) {
  2925. // cr and execute command
  2926. cursorx = savex;
  2927. cursory = savey;
  2928. if (emacsen) {
  2929. mode = 1;
  2930. } else {
  2931. mode = 0;
  2932. }
  2933. var cy = command;
  2934. command = '';
  2935. commandleft = 0;
  2936. term_command(cy);
  2937. var cx = command.substr(0,1);
  2938. if (cx == '/' || cx == '?') lastsearch = cy;
  2939. else oldcommand = cy;
  2940. // incase its needed
  2941. term_scrollto();
  2942. } else if (k == 8) {
  2943. if (!synth) return;
  2944. command = command.substr(command, command.length-1);
  2945. cursorx--;
  2946. if (cursorx <= 0) {
  2947. var w = term_cols;
  2948. commandleft -= (w-16);
  2949. cursorx = w - 8;
  2950. if (commandleft < 0) {
  2951. cursorx = savex;
  2952. cursory = savey;
  2953. if (emacsen) {
  2954. mode = 1;
  2955. } else {
  2956. mode = 0;
  2957. }
  2958. }
  2959. }
  2960. } else {
  2961. command = command + kc;
  2962. cursorx++;
  2963. var w = term_cols;
  2964. if (cursorx >= (w-8)) {
  2965. cursorx = 8;
  2966. commandleft += w-16;
  2967. }
  2968. }
  2969. term_redraw();
  2970. term_calcx();
  2971. _update_backing();
  2972. return;
  2973. } else {
  2974. var t = (file[cursory+base]);
  2975. var lx = (t.substr(0, cursorx+left));
  2976. var ly = (t.substr(cursorx+left+(mode-1)));
  2977. var lz = (t.substr(cursorx+left));
  2978. var g = (tags[cursory+base]);
  2979. var gx = (g.substr(0, cursorx+left));
  2980. var gy = (g.substr(cursorx+left+(mode-1)));
  2981. var gz = (g.substr(cursorx+left));
  2982. if (!lx) lx = '';
  2983. if (k == 9) kc = ' ';
  2984. if (k == 10 || k == 13) {
  2985. // CR
  2986. if (!lz) lz = '';
  2987. file[cursory+base] = lx;
  2988. tags[cursory+base] = gx;
  2989. cursory++;
  2990. cursorx=0;
  2991. left=0;
  2992. term_insert(cursory+base);
  2993. file[cursory+base] = lz;
  2994. tags[cursory+base] = gz;
  2995. lastinsert += "\n";
  2996. } else if (k == 8) {
  2997. if (!synth) return;
  2998. // backspace
  2999. file[cursory+base] = lx.substr(0,lx.length-1)+lz;
  3000. tags[cursory+base] = gx.substr(0,lx.length-1)+gz;
  3001. lastinsert = lastinsert.substr(0,lastinsert.length-1);
  3002. cursorx--;
  3003. } else {
  3004. if (kc == '') return;
  3005. file[cursory+base] = lx+kc+ly;
  3006. tags[cursory+base] = gx+String.fromCharCode(tagstyle)+gy;
  3007. lastinsert += kc;
  3008. cursorx+=kc.length;
  3009. }
  3010. term_scrollto();
  3011. }
  3012. term_redraw();
  3013. _update_backing();
  3014. return;
  3015. }
  3016. function _redraw_cursor() {
  3017. term_draw_cursor(true);
  3018. _update_backing();
  3019. }
  3020. function term_draw_cursor(tf) {
  3021. // maybe use vertical bar if mode==1 hrm?
  3022. if (!tf || !cursor._opaque) {
  3023. cursor._opaque = true;
  3024. cursor.style.color = palette[1];
  3025. cursor.style.backgroundColor = palette[0];
  3026. } else {
  3027. cursor._opaque = false;
  3028. cursor.style.color = palette[0];
  3029. cursor.style.backgroundColor = palette[1];
  3030. }
  3031. }
  3032. function _redraw_term_force() {
  3033. while (term.firstChild) term.removeChild(term.firstChild);
  3034. }
  3035. function _redraw_term() {
  3036. var h = term_rows;
  3037. var w = term_cols;
  3038. var ka, kb;
  3039. var tospell = 0;
  3040. var osp = '';
  3041. var y;
  3042. var tago = new Array();
  3043. var isurl = new Array();
  3044. var ca, cb;
  3045. var sa, sb;
  3046. var qp;
  3047. if (vselm) {
  3048. sa = vsely-base;
  3049. sb = cursory;
  3050. if (sa > sb) {
  3051. zx = sa;
  3052. sa = sb;
  3053. sb = zx;
  3054. }
  3055. ca = vselx-left;
  3056. cb = cursorx;
  3057. if (ca > cb) {
  3058. zx = ca;
  3059. ca = cb;
  3060. cb = zx;
  3061. }
  3062. }
  3063. for (y = 0; y < h; y++) {
  3064. ka = ''; kb = '';
  3065. var x = file[y+base];
  3066. var g;
  3067. var zleft = 0;
  3068. var cx;
  3069. var j, vj;
  3070. if (y == (h-1)) {
  3071. if (cursory == y) {
  3072. zleft = commandleft;
  3073. x = command;
  3074. cx = 0;
  3075. statustext = '';
  3076. } else if (emacsen) {
  3077. x = '[' + (mode == 1 ? 'Ins' : 'Ovr') + '] ' + statustext;
  3078. while (x.length < w) {
  3079. x += ' ';
  3080. }
  3081. cx = 4;
  3082. } else if (vselm == 1) {
  3083. cx = 1; x = '-- VISUAL --';
  3084. statustext = '';
  3085. } else if (vselm == 2) {
  3086. cx = 1; x = '-- VISUAL LINE --';
  3087. statustext = '';
  3088. } else if (mode == 0) {
  3089. x = statustext;
  3090. cx = 16;
  3091. } else if (mode == 1) {
  3092. cx = 1; x = '-- INSERT --';
  3093. statustext = '';
  3094. } else if (mode == 2) {
  3095. cx = 1; x = '-- REPLACE --';
  3096. statustext = '';
  3097. }
  3098. g = _mxs(x.length, cx);
  3099. } else if (x == undefined) {
  3100. x = '~';
  3101. g = "\010";
  3102. } else {
  3103. zleft = left;
  3104. g = tags[y+base];
  3105. // do spellchecking
  3106. var p = 0;
  3107. vj = x.split(/[ ,;]+/);
  3108. for (j = 0; j < vj.length; j++) {
  3109. var vx = vj[j];
  3110. var vm = _word(vx);
  3111. if (j != 0) p++;
  3112. if (vx.match(/^(https?|ftp):\/\//)) {
  3113. g = g.substr(0, p)
  3114. + _mxo(g.substr(p, vx.length), ((1+tago.length)*256))
  3115. + g.substr(p+vx.length);
  3116. isurl[tago.length] = true;
  3117. tago[tago.length] = vx;
  3118. } else if (brokenwords[vm] && !safewords[vm]) {
  3119. g = g.substr(0, p)
  3120. + _mxo(g.substr(p, vx.length), ((1+tago.length)*256))
  3121. + g.substr(p+vx.length);
  3122. isurl[tago.length] = false;
  3123. tago[tago.length] = vx;
  3124. } else {
  3125. if (vm.length > 3 && !_safe(vm) && !safewords[vm] && !spelling) {
  3126. tospell++;
  3127. osp += escape("c"+tospell) + "="
  3128. + escape(vm) + "&";
  3129. spellcheck[tospell] = vm;
  3130. }
  3131. }
  3132. p += vx.length;
  3133. }
  3134. }
  3135. if (x == undefined) {
  3136. x = '';
  3137. g = '';
  3138. }
  3139. var zx;
  3140. vx = 0;
  3141. // truncate as necessary
  3142. x = x.substr(zleft, x.length-zleft);
  3143. g = g.substr(zleft, g.length-zleft);
  3144. if (x.length >= w) {
  3145. x = x.substr(0, w);
  3146. g = g.substr(0, w);
  3147. }
  3148. if (vselm) {
  3149. if (vselm == 1 && sa == sb && sa == y) {
  3150. // middle of line between ca->cb is selected
  3151. g = g.substr(0,ca) + _mxo(g.substr(ca,(cb-ca)+1), 4) + g.substr(cb,(g.length-cb)-1);
  3152. } else if ((sa < y && sb > y) || (vselm == 2 && (sa <= y && sb >= y))) {
  3153. // entire line selected
  3154. g = _mxo(g, 4);
  3155. } else if (sa < y && sb == y) {
  3156. // beginning of line selected (up to q)
  3157. // if (sb is cursory) then q = cursorx otherwise vselx
  3158. qp = (sb == cursory) ? cursorx : (vselx-left);
  3159. g = _mxo(g.substr(0, qp+1), 4) + g.substr(qp, (g.length-qp)-1);
  3160. } else if (sa == y && sb > y) {
  3161. // end of line selected (beginning at q)
  3162. // if (sa is cursory) then q = cursorx otherwise vselx
  3163. qp = (sa == cursory) ? cursorx : (vselx-left);
  3164. g = g.substr(0, qp) + _mxo(g.substr(qp, g.length-qp), 4);
  3165. }
  3166. }
  3167. vj = 0;
  3168. g += "\377"; // terminate
  3169. x += " ";
  3170. x = x.replace(/ /g, "\240");
  3171. if (term.childNodes.length > y) {
  3172. zx = term.childNodes[y];
  3173. if (zx._cachex == x && zx._cacheg == g) {
  3174. if (y == cursory) _calcy(zx, x, g);
  3175. continue;
  3176. }
  3177. // as a last ditch effort- to accelerate deletions...
  3178. // and inserts...
  3179. if (term.childNodes.length > (y+1)) {
  3180. var zy = term.childNodes[y+1];
  3181. if (zy._cachex == x && zy._cacheg == g) {
  3182. // okay then, so the NEXT line is the winner
  3183. // copy its nodes
  3184. term.removeChild(zy);
  3185. term.replaceChild(zy, zx);
  3186. if (zy.nextSibling) {
  3187. term.insertBefore(zx, zy.nextSibling);
  3188. } else {
  3189. term.appendChild(zx);
  3190. }
  3191. if (y == cursory) _calcy(zy, x, g);
  3192. continue;
  3193. }
  3194. }
  3195. // update
  3196. while (zx.firstChild) zx.removeChild(zx.firstChild);
  3197. } else {
  3198. zx = document.createElement('PRE');
  3199. zx.style.display='block';
  3200. zx.style.fontFamily = 'monospace';
  3201. zx.style.fontSize = '100%';
  3202. _zmp(zx);
  3203. zx.style.marginBottom = '1px';
  3204. }
  3205. cx = 255;
  3206. var ax = zx;
  3207. for (j = 0; j < x.length; j++) {
  3208. var gx = g.charCodeAt(j);
  3209. if (gx != cx) {
  3210. if (j != vj && ax) {
  3211. var t = x.substr(vj, (j-vj));
  3212. if (!t) t = '';
  3213. ax.appendChild(document.createTextNode(t));
  3214. if (zx != ax) zx.appendChild(ax);
  3215. vj = j;
  3216. }
  3217. if (gx > 255) {
  3218. var wx = parseInt(gx / 256)-1;
  3219. ax = document.createElement('A');
  3220. if (isurl[wx]) {
  3221. ax.style.borderBottom = '1px double blue';
  3222. ax.href = tago[wx];
  3223. ax.target = '_new';
  3224. ax.ondblclick = _openurl;
  3225. } else {
  3226. ax.style.borderBottom = '1px dashed red';
  3227. ax.href = 'javascript:void(0)';
  3228. ax.ondblclick = _suggest;
  3229. }
  3230. ax._term = _word(tago[wx]);
  3231. ax._len = tago[wx].length;
  3232. ax._row = y+base;
  3233. ax._col = j+zleft;
  3234. ax.onclick = _subclick;
  3235. } else {
  3236. ax = document.createElement('SPAN');
  3237. }
  3238. if (gx == 255) gx = 0;
  3239. if (gx & 1) {
  3240. ax.style.fontWeight = 'bold';
  3241. } else {
  3242. ax.style.fontWeight = 'normal';
  3243. }
  3244. if (gx & 2) {
  3245. ax.style.textDecoration = 'underline';
  3246. } else {
  3247. ax.style.textDecoration = 'none';
  3248. }
  3249. if (gx & 4) { // reverse video
  3250. ax.style.color = palette[1];
  3251. ax.style.backgroundColor = palette[0];
  3252. } else {
  3253. ax.style.color = palette[0];
  3254. ax.style.backgroundColor = palette[1];
  3255. }
  3256. if (gx & 8) { // unselectable
  3257. ax.unselectable = true;
  3258. if (ax.setAttribute) ax.setAttribute('unselectable', 'on');
  3259. ax.style.color = palette[0];
  3260. ax.style.backgroundColor = palette[1];
  3261. ax.style.userSelect = 'none';
  3262. ax.style['-moz-user-select'] = 'none';
  3263. }
  3264. if (gx & 16) {
  3265. ax.style.fontStyle = 'italic';
  3266. } else {
  3267. ax.style.fontStyle = 'normal';
  3268. }
  3269. cx = gx;
  3270. }
  3271. }
  3272. if (j != vj) {
  3273. var t = x.substr(vj, (j-vj)-1);
  3274. ax.appendChild(document.createTextNode(t));
  3275. if (zx != ax) zx.appendChild(ax);
  3276. vj = j;
  3277. }
  3278. ax.appendChild(document.createTextNode("\240"));
  3279. zx._cachex = x;
  3280. zx._cacheg = g;
  3281. if (term.childNodes.length <= y) {
  3282. term.appendChild(zx);
  3283. }
  3284. if (y == 1) {
  3285. var qx = zx;
  3286. var nh = 0;
  3287. while (qx && qx != document.body) {
  3288. nh += qx.offsetTop;
  3289. qx = qx.offsetParent;
  3290. }
  3291. if (nh != line_height) {
  3292. line_height = nh;
  3293. term_resize();
  3294. }
  3295. }
  3296. if (y == cursory) {
  3297. _calcy(zx, x, g);
  3298. }
  3299. ax = undefined; // break;
  3300. }
  3301. while (term.childNodes.length > h) {
  3302. term.removeChild(term.lastChild);
  3303. }
  3304. zx = undefined; // break
  3305. if (!spelling && tospell > 0) {
  3306. spelling = true;
  3307. var xh = _xhttp();
  3308. osp=osp.substr(0,osp.length-1);
  3309. xh.open("GET", "spell.cgi?"+osp, true);
  3310. xh.onreadystatechange = function() {
  3311. if (xh.readyState == 4) {
  3312. var j;
  3313. var a = xh.responseText.split("\n");
  3314. for (j = 0; j < a.length; j++) {
  3315. var kp = a[j].split("=", 2);
  3316. var k, v;
  3317. if (kp.length == 2) {
  3318. k = kp[0];
  3319. v = kp[1];
  3320. } else if (kp.length == 1) {
  3321. k = kp[0];
  3322. v = '';
  3323. } else {
  3324. k = a[j];
  3325. v = '';
  3326. }
  3327. if (k.substr(0,1) != 'c') continue;
  3328. k = k.substr(1, k.length-1);
  3329. var term = spellcheck[k];
  3330. if (v == undefined || v == '') {
  3331. brokenwords[term] = true;
  3332. suggestions[term] = new Array();
  3333. } else if (v == term) {
  3334. safewords[term] = true;
  3335. } else {
  3336. safewords[v] = true;
  3337. if (!suggestions[term]) {
  3338. suggestions[term] = new Array();
  3339. }
  3340. suggestions[term][ suggestions[term].length ] = v;
  3341. brokenwords[term] = true;
  3342. }
  3343. }
  3344. spelling=false;
  3345. window.setTimeout(term_redraw,10);
  3346. xh = undefined; // break (deferred)
  3347. }
  3348. };
  3349. xh.send(undefined);
  3350. }
  3351. if (cursory == (h-1)) {
  3352. tools.style.display = 'none';
  3353. } else {
  3354. tools.style.display = 'block';
  3355. }
  3356. _update_backing();
  3357. }
  3358. function _redraw_term_back() {
  3359. drawiv = undefined;
  3360. _redraw_term();
  3361. term_draw_cursor();
  3362. }
  3363. function term_redraw() {
  3364. if (drawiv) window.clearTimeout(drawiv);
  3365. drawiv = window.setTimeout(_redraw_term_back, 10);
  3366. }
  3367. function term_resize() {
  3368. var h = term.offsetHeight;
  3369. var r = line_height;
  3370. if (!line_height) r = cursor.offsetHeight-1; // 1 px overlap
  3371. var nh = (h/r);
  3372. term_rows = parseInt(nh);
  3373. term_win_height = h;
  3374. h = term.offsetWidth;
  3375. r = (term_cur_width+1); // 1 px padding
  3376. nh = (h/r);
  3377. term_cols = parseInt(nh);
  3378. term_win_width = h;
  3379. term_redraw();
  3380. }
  3381. function editor_disable(sav) {
  3382. if (cursoriv) {
  3383. window.clearInterval(cursoriv);
  3384. cursoriv = undefined;
  3385. }
  3386. _cbrestore();
  3387. if (term._formelement) {
  3388. if (sav) term._formelement.value = term_freeze();
  3389. // disconnect
  3390. term._formelement = undefined;
  3391. }
  3392. if (backing.removeEventListener) {
  3393. backing.removeEventListener('DOMAttrModified',_backing_paste,false);
  3394. backing.removeEventListener('Input',_backing_paste,false);
  3395. backing.removeEventListener('input',_backing_paste,false);
  3396. }
  3397. backing.oninput = undefined;
  3398. backing.onInput = undefined;
  3399. document.body.removeChild(suggest);
  3400. document.body.removeChild(term);
  3401. document.body.removeChild(printer);
  3402. document.body.removeChild(tools);
  3403. document.body.removeChild(cursor);
  3404. var z;
  3405. for (z = document.body.firstChild; z; z = z.nextSibling) {
  3406. if (z.tagName && z._flipe) z.style.display = z._orige;
  3407. }
  3408. // bug in firefox: can't remove this
  3409. //document.body.removeChild(backing);
  3410. if (backing.blur) backing.blur();
  3411. backing.style.display = 'none';
  3412. if (document.body.focus) document.body.focus();
  3413. if (document.focus) document.focus();
  3414. document.body.style.overflow = '';
  3415. }
  3416. function _cursor_fix() {
  3417. term_cur_width = cursor.offsetWidth;
  3418. }
  3419. function _zmp(o) {
  3420. o.style.marginTop='0px';
  3421. o.style.marginLeft='0px';
  3422. o.style.marginRight='0px';
  3423. o.style.marginBottom='0px';
  3424. o.style.paddingTop='0px';
  3425. o.style.paddingLeft='0px';
  3426. o.style.paddingRight='0px';
  3427. o.style.paddingBottom='0px';
  3428. }
  3429. function editor(t) {
  3430. if (term && term._formelement && term._formelement != t) {
  3431. editor_disable(false);
  3432. }
  3433. // okay, find EVERYTHING inside body and display none it
  3434. var z;
  3435. for (z = document.body.firstChild; z; z = z.nextSibling) {
  3436. if (z.tagName) {
  3437. z._orige = z.style.display;
  3438. z._flipe = true;
  3439. z.style.display = 'none';
  3440. }
  3441. }
  3442. if (!term) {
  3443. term = document.createElement('DIV');
  3444. printer = document.createElement('DIV');
  3445. suggest = document.createElement('DIV');
  3446. backing = document.createElement('TEXTAREA');
  3447. tools = document.createElement('DIV');
  3448. cursor = document.createElement('DIV');
  3449. }
  3450. // if (document.documentElement) {
  3451. // _zmp(document.documentElement);
  3452. // document.documentElement.height = '100%';
  3453. // _zmp(document.body);
  3454. // document.body.height = '100%';
  3455. // }
  3456. printer.className = 'print';
  3457. cursor.className = 'editorcursor';
  3458. term.className = 'editor';
  3459. suggest.style.position = 'absolute';
  3460. suggest.style.display = 'none';
  3461. backing.tabIndex = -1;
  3462. backing.style.position = 'absolute';
  3463. backing.style.bottom = '0px';
  3464. backing.style.right = '0px';
  3465. backing.style.width = '1px';
  3466. backing.style.height = '1px';
  3467. backing.style.visibility = 'hidden';
  3468. backing.oninput = _backing_paste;
  3469. backing.onInput = _backing_paste;
  3470. if (backing.addEventListener) {
  3471. backing.addEventListener('DOMAttrModified',_backing_paste,false);
  3472. backing.addEventListener('Input',_backing_paste,false);
  3473. backing.addEventListener('input',_backing_paste,false);
  3474. }
  3475. if (window.addEventListener) {
  3476. window.addEventListener('DOMMouseScroll',_mousescroll,false);
  3477. }
  3478. tools.className = 'editortools';
  3479. tools.style.position = 'absolute';
  3480. tools.style.right = '0px';
  3481. tools.style.bottom = '0px';
  3482. tools.innerHTML = ''
  3483. + '<input tabindex="-1" type="button" value="B" style="font-weight:bold;" onClick="term_command(\':F!b\');" />'
  3484. + '<input tabindex="-1" type="button" value="I" style="font-style:italic;" onClick="term_command(\':F!i\');" />'
  3485. + '<input tabindex="-1" type="button" value="U" style="text-decoration:underline;" onClick="term_command(\':F!u\');" />'
  3486. + '&nbsp;'
  3487. + '<input tabindex="-1" type="button" value="Print" onClick="term_command(\':ha\');" />'
  3488. + '&nbsp;'
  3489. + '<input tabindex="-1" type="button" value="Abort" onClick="term_command(\':q?\');" />'
  3490. + '<input tabindex="-1" type="button" value="Save and Close" onClick="term_command(\':wq\');" />'
  3491. cursor.onclick = _pass_click;
  3492. cursor.ondblclick = _pass_dblclick;
  3493. document.body.appendChild(suggest);
  3494. document.body.appendChild(term);
  3495. document.body.appendChild(printer);
  3496. document.body.appendChild(tools);
  3497. // firefox bug
  3498. if (once) document.body.appendChild(backing);
  3499. document.body.appendChild(cursor);
  3500. cursoriv = window.setInterval(_redraw_cursor, 300);
  3501. term.style.position = 'absolute';
  3502. term.style.top = '0px';
  3503. term.style.left = '0px';
  3504. term.style.display = 'block';
  3505. term.style.overflow = 'hidden';
  3506. term.style.width = '100%';
  3507. term.style.height = '100%';
  3508. term.style.cursor = 'default';
  3509. term.style.fontFamily = 'monospace';
  3510. term.style.fontSize = '100%';
  3511. _zmp(term);
  3512. term._formelement = t;
  3513. document.body.style.overflow = 'hidden';
  3514. tools.style.display = 'block';
  3515. _cbd('select', _cancel_ev);
  3516. _cbd('selectstart', _cancel_ev);
  3517. _cbd('keydown', term_keyfix);
  3518. _cbd('keypress', term_keypress);
  3519. _cbd('paste', _msie_paste);
  3520. _cbd('click', _mouseclick);
  3521. _cbd('mousedown', _mousedown);
  3522. _cbd('mousemove', _mousemove);
  3523. _cbd('mouseup', _mouseup);
  3524. _cbd('mousewheel', _mousescroll);
  3525. vselm = 0;
  3526. vseld = false;
  3527. vselx = undefined;
  3528. vsely = undefined;
  3529. t.blur();
  3530. cursorx = 0;
  3531. cursory = 0;
  3532. cursor.style.position = 'absolute';
  3533. cursor.style.top = 0;
  3534. cursor.style.left = 0;
  3535. cursor.style.fontFamily = 'monospace';
  3536. cursor.style.fontSize = '100%';
  3537. cursor.style.width = 'auto';
  3538. cursor.style.cursor = 'default';
  3539. _zmp(cursor);
  3540. cursor.style.overflow = 'hidden';
  3541. cursor.innerHTML = 'X';
  3542. cursor._opaque = false;
  3543. cursor._lasty = -1;
  3544. cursor._lastx = -1;
  3545. cursor._lastch = '-xyz-';
  3546. cursor._lastgh = 0;
  3547. palette = undefined;
  3548. if (document.defaultView && document.defaultView.getComputedStyle) {
  3549. palette = new Array();
  3550. var cs = document.defaultView.getComputedStyle(term, null);
  3551. palette[0] = cs.color;
  3552. palette[1] = cs.backgroundColor;
  3553. } else if (window.getComputedStyle) {
  3554. palette = new Array();
  3555. var cs = window.getComputedStyle(term, null);
  3556. palette[0] = cs.color;
  3557. palette[1] = cs.backgroundColor;
  3558. } else if (term.currentStyle) {
  3559. palette = new Array();
  3560. palette[0] = term.currentStyle.color;
  3561. palette[1] = term.currentStyle.backgroundColor;
  3562. }
  3563. if (emacsen) {
  3564. mode = 1;
  3565. } else {
  3566. mode = 0;
  3567. }
  3568. once = false;
  3569. backing._lastvalue = '';
  3570. backing.value = '';
  3571. backing.defaultValue = '';
  3572. suggest._visible = false;
  3573. suggest.display = 'none';
  3574. tools.style.backgroundColor = palette[0];
  3575. _dfx(tools);
  3576. // degrading...
  3577. file = new Array();
  3578. tags = new Array();
  3579. var st = t.value.split("\n");
  3580. var j;
  3581. for (j = 0; j < st.length; j++) {
  3582. if (st[j].substr(st[j].length-1, 1) == "\r") {
  3583. st[j] = st[j].substr(0, st[j].length-1);
  3584. }
  3585. var aa = _hra(st[j]);
  3586. file[j] = aa[0];
  3587. tags[j] = aa[1];
  3588. }
  3589. // fix
  3590. t.value = term_freeze();
  3591. _term_update_printer();
  3592. cursor.style.display = 'inline';
  3593. _cursor_fix();
  3594. window.setTimeout(term_redraw,1);
  3595. term_resize();
  3596. _cbw('resize', term_resize);
  3597. _cbw('beforeprint', _term_update_printer);
  3598. _update_backing();
  3599. }