PageRenderTime 446ms CodeModel.GetById 17ms RepoModel.GetById 1ms app.codeStats 0ms

/vi.js

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