00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014 #include "config.h"
00015 #include "ctype.h"
00016 #include "vi.h"
00017 #if MSDOS
00018 # include <process.h>
00019 # include <string.h>
00020 #endif
00021 #if TOS
00022 # include <osbind.h>
00023 # include <string.h>
00024 #endif
00025 #if OSK
00026 # include <stdio.h>
00027 #endif
00028
00029
00030
00031 MARK v_quit()
00032 {
00033 move(LINES - 1, 0);
00034 mode = MODE_EX;
00035 return cursor;
00036 }
00037
00038
00039 MARK v_redraw()
00040 {
00041 redraw(MARK_UNSET, FALSE);
00042 return cursor;
00043 }
00044
00045
00046
00047
00048
00049
00050 MARK v_1ex(m, text)
00051 MARK m;
00052 char *text;
00053 {
00054
00055 exwrote = (mode == MODE_COLON);
00056 doexcmd(text);
00057 exrefresh();
00058
00059
00060 if (mode != MODE_VI && mode != MODE_COLON)
00061 return cursor;
00062
00063
00064 if (exwrote)
00065 {
00066 mode = MODE_VI;
00067 msg("[Hit <RETURN> to continue]");
00068 if (getkey(0) == ':')
00069 { mode = MODE_COLON;
00070 addch('\n');
00071 }
00072 else
00073 redraw(MARK_UNSET, FALSE);
00074 }
00075
00076 return cursor;
00077 }
00078
00079
00080
00081 MARK v_undo(m)
00082 MARK m;
00083 {
00084 if (undo())
00085 {
00086 redraw(MARK_UNSET, FALSE);
00087 }
00088 return cursor;
00089 }
00090
00091
00092 MARK v_xchar(m, cnt, cmd)
00093 MARK m;
00094 long cnt;
00095 int cmd;
00096 {
00097 DEFAULT(1);
00098
00099
00100 if (cmd == 'X')
00101 {
00102 if (markidx(m) < cnt)
00103 return MARK_UNSET;
00104 m -= cnt;
00105 }
00106
00107
00108 pfetch(markline(m));
00109 if (markidx(m + cnt) > plen)
00110 {
00111 cnt = plen - markidx(m);
00112 }
00113 if (cnt == 0L)
00114 {
00115 return MARK_UNSET;
00116 }
00117
00118
00119 ChangeText
00120 {
00121 cut(m, m + cnt);
00122 delete(m, m + cnt);
00123 }
00124 return m;
00125 }
00126
00127
00128
00129 MARK v_mark(m, count, key)
00130 MARK m;
00131 long count;
00132 int key;
00133 {
00134 if (key < 'a' || key > 'z')
00135 {
00136 msg("Marks must be from a to z");
00137 }
00138 else
00139 {
00140 mark[key - 'a'] = m;
00141 }
00142 return m;
00143 }
00144
00145
00146 MARK v_ulcase(m, cnt)
00147 MARK m;
00148 long cnt;
00149 {
00150 REG char *pos;
00151 REG int j;
00152
00153 DEFAULT(1);
00154
00155
00156 pfetch(markline(m));
00157
00158
00159 for (j = 0, pos = &ptext[markidx(m)]; j < cnt && *pos; j++, pos++)
00160 {
00161 if (isupper(*pos))
00162 {
00163 tmpblk.c[j] = tolower(*pos);
00164 }
00165 else
00166 {
00167 tmpblk.c[j] = toupper(*pos);
00168 }
00169 }
00170
00171
00172 if (strncmp(tmpblk.c, &ptext[markidx(m)], j))
00173 {
00174 ChangeText
00175 {
00176 tmpblk.c[j] = '\0';
00177 change(m, m + j, tmpblk.c);
00178 }
00179 }
00180
00181 return m + j;
00182 }
00183
00184
00185 MARK v_replace(m, cnt, key)
00186 MARK m;
00187 long cnt;
00188 int key;
00189 {
00190 REG char *text;
00191 REG int i;
00192
00193 DEFAULT(1);
00194
00195
00196 if (key == '\r')
00197 {
00198 key = '\n';
00199 }
00200
00201
00202 if (cnt > BLKSIZE - 2 - markidx(m))
00203 {
00204 cnt = BLKSIZE - 2 - markidx(m);
00205 }
00206
00207
00208 for (text = tmpblk.c, i = cnt; i > 0; i--)
00209 {
00210 *text++ = key;
00211 }
00212 *text = '\0';
00213
00214
00215 pfetch(markline(m));
00216 key = markidx(m);
00217 if (key + cnt > plen)
00218 {
00219 cnt = plen - key;
00220 }
00221
00222
00223 ChangeText
00224 {
00225 change(m, m + cnt, tmpblk.c);
00226 }
00227
00228 if (*tmpblk.c == '\n')
00229 {
00230 return (m & ~(BLKSIZE - 1)) + cnt * BLKSIZE;
00231 }
00232 else
00233 {
00234 return m + cnt - 1;
00235 }
00236 }
00237
00238 MARK v_overtype(m)
00239 MARK m;
00240 {
00241 MARK end;
00242 static long width;
00243
00244
00245 if (doingdot)
00246 {
00247
00248 if (width < 0)
00249 {
00250 msg("Can't repeat a multi-line overtype command");
00251 return MARK_UNSET;
00252 }
00253
00254
00255 if (width == 0)
00256 {
00257 return m;
00258 }
00259
00260
00261 return v_subst(m, width);
00262 }
00263
00264
00265 ChangeText
00266 {
00267 end = input(m, m, WHEN_VIREP, FALSE);
00268 }
00269
00270
00271
00272
00273 if (markline(end) == markline(m) && end >= m - 1L)
00274 {
00275 width = end - m + 1L;
00276 }
00277 else
00278 {
00279 width = -1L;
00280 }
00281
00282 return end;
00283 }
00284
00285
00286
00287
00288 MARK v_selcut(m, cnt, key)
00289 MARK m;
00290 long cnt;
00291 int key;
00292 {
00293 cutname(key);
00294 return m;
00295 }
00296
00297
00298
00299 MARK v_paste(m, cnt, cmd)
00300 MARK m;
00301 long cnt;
00302 int cmd;
00303 {
00304 MARK dest;
00305
00306 ChangeText
00307 {
00308
00309 dest = paste(m, cmd == 'p', TRUE);
00310
00311
00312 if (dest && markline(dest) != markline(m))
00313 {
00314
00315
00316
00317 dest = m;
00318 if (cmd == 'p')
00319 {
00320 dest += BLKSIZE;
00321 }
00322 force_flags |= FRNT;
00323 }
00324 }
00325 return dest;
00326 }
00327
00328
00329 MARK v_yank(m, n)
00330 MARK m, n;
00331 {
00332 cut(m, n);
00333 return m;
00334 }
00335
00336
00337 MARK v_delete(m, n)
00338 MARK m, n;
00339 {
00340
00341 if (n <= m)
00342 {
00343 return MARK_UNSET;
00344 }
00345
00346
00347 ChangeText
00348 {
00349 cut(m, n);
00350 delete(m, n);
00351 }
00352 return m;
00353 }
00354
00355
00356
00357 MARK v_insert(m, cnt, key)
00358 MARK m;
00359 long cnt;
00360 int key;
00361 {
00362 int wasdot;
00363 long reps;
00364 int above;
00365
00366 DEFAULT(1);
00367
00368 ChangeText
00369 {
00370
00371 above = FALSE;
00372 switch (key)
00373 {
00374 case 'i':
00375 break;
00376
00377 case 'a':
00378 pfetch(markline(m));
00379 if (plen > 0)
00380 {
00381 m++;
00382 }
00383 break;
00384
00385 case 'I':
00386 m = m_front(m, 1L);
00387 break;
00388
00389 case 'A':
00390 pfetch(markline(m));
00391 m = (m & ~(BLKSIZE - 1)) + plen;
00392 break;
00393
00394 case 'O':
00395 m &= ~(BLKSIZE - 1);
00396 add(m, "\n");
00397 above = TRUE;
00398 break;
00399
00400 case 'o':
00401 m = (m & ~(BLKSIZE - 1)) + BLKSIZE;
00402 add(m, "\n");
00403 break;
00404 }
00405
00406
00407 for (reps = cnt, wasdot = doingdot; reps > 0; reps--, doingdot = TRUE)
00408 {
00409 m = input(m, m, WHEN_VIINP, above) + 1;
00410 }
00411 if (markidx(m) > 0)
00412 {
00413 m--;
00414 }
00415
00416 doingdot = wasdot;
00417 }
00418
00419 #ifndef CRUNCH
00420 # ifndef NO_EXTENSIONS
00421 if (key == 'i' && *o_inputmode && mode == MODE_VI)
00422 {
00423 msg("Now in command mode! To return to input mode, hit <i>");
00424 }
00425 # endif
00426 #endif
00427
00428 return m;
00429 }
00430
00431
00432 MARK v_change(m, n)
00433 MARK m, n;
00434 {
00435 int lnmode;
00436
00437
00438 if (m > n)
00439 {
00440 MARK tmp;
00441 tmp = m;
00442 m = n;
00443 n = tmp;
00444 }
00445
00446
00447 lnmode = (markidx(m) == 0 && markidx(n) == 0 && m != n);
00448 if (lnmode)
00449 {
00450 n -= BLKSIZE;
00451 pfetch(markline(n));
00452 n = (n & ~(BLKSIZE - 1)) + plen;
00453 }
00454
00455 ChangeText
00456 {
00457 cut(m, n);
00458 m = input(m, n, WHEN_VIINP, FALSE);
00459 }
00460
00461 return m;
00462 }
00463
00464
00465 MARK v_subst(m, cnt)
00466 MARK m;
00467 long cnt;
00468 {
00469 DEFAULT(1);
00470
00471
00472 pfetch(markline(m));
00473 if (markidx(m) + cnt > plen)
00474 {
00475 cnt = plen - markidx(m);
00476 }
00477
00478
00479 ChangeText
00480 {
00481 cut(m, m + cnt);
00482 m = input(m, m + cnt, WHEN_VIINP, FALSE);
00483 }
00484 return m;
00485 }
00486
00487
00488 MARK v_join(m, cnt)
00489 MARK m;
00490 long cnt;
00491 {
00492 MARK joint;
00493
00494 DEFAULT(1);
00495
00496
00497 pfetch(markline(m));
00498 joint = (m & ~(BLKSIZE - 1)) + plen;
00499
00500
00501 cmd_join(m, m + MARK_AT_LINE(cnt), CMD_JOIN, 0, "");
00502
00503
00504 return joint;
00505 }
00506
00507
00508
00509 MARK v_lshift(m, n)
00510 MARK m, n;
00511 {
00512
00513 n -= BLKSIZE;
00514
00515 cmd_shift(m, n, CMD_SHIFTL, FALSE, (char *)0);
00516
00517 return m;
00518 }
00519
00520
00521 MARK v_rshift(m, n)
00522 MARK m, n;
00523 {
00524
00525 n -= BLKSIZE;
00526
00527 cmd_shift(m, n, CMD_SHIFTR, FALSE, (char *)0);
00528
00529 return m;
00530 }
00531
00532
00533 MARK v_reformat(m, n)
00534 MARK m, n;
00535 {
00536
00537 n -= BLKSIZE;
00538
00539
00540 filter(m, n, o_equalprg, TRUE);
00541
00542 redraw(MARK_UNSET, FALSE);
00543 return m;
00544 }
00545
00546
00547
00548 MARK v_filter(m, n)
00549 MARK m, n;
00550 {
00551 char cmdln[150];
00552
00553
00554 n -= BLKSIZE;
00555
00556 if (vgets('!', cmdln, sizeof(cmdln)) > 0)
00557 {
00558 filter(m, n, cmdln, TRUE);
00559 }
00560
00561 redraw(MARK_UNSET, FALSE);
00562 return m;
00563 }
00564
00565
00566
00567 MARK v_status()
00568 {
00569 cmd_file(cursor, cursor, CMD_FILE, 0, "");
00570 return cursor;
00571 }
00572
00573
00574
00575 MARK v_again(m, n)
00576 MARK m, n;
00577 {
00578 cmd_substitute(m, n - BLKSIZE, CMD_SUBAGAIN, TRUE, "");
00579 return cursor;
00580 }
00581
00582
00583
00584
00585 MARK v_switch()
00586 {
00587 if (!*prevorig)
00588 msg("No previous file");
00589 else
00590 { strcpy(tmpblk.c, prevorig);
00591 cmd_edit(cursor, cursor, CMD_EDIT, 0, tmpblk.c);
00592 }
00593 return cursor;
00594 }
00595
00596
00597
00598 MARK v_tag(keyword, m, cnt)
00599 char *keyword;
00600 MARK m;
00601 long cnt;
00602 {
00603
00604 cursor = m;
00605
00606
00607 cmd_tag(cursor, cursor, CMD_TAG, 0, keyword);
00608
00609 return cursor;
00610 }
00611
00612 #ifndef NO_EXTENSIONS
00613
00614
00615 MARK v_keyword(keyword, m, cnt)
00616 char *keyword;
00617 MARK m;
00618 long cnt;
00619 {
00620 int waswarn;
00621 char cmdline[130];
00622
00623 move(LINES - 1, 0);
00624 addstr("---------------------------------------------------------\n");
00625 clrtoeol();
00626 refresh();
00627 sprintf(cmdline, "%s %s", o_keywordprg, keyword);
00628 waswarn = *o_warn;
00629 *o_warn = FALSE;
00630 suspend_curses();
00631 if (system(cmdline))
00632 {
00633 addstr("<<< failed >>>\n");
00634 }
00635 resume_curses(FALSE);
00636 mode = MODE_VI;
00637 redraw(MARK_UNSET, FALSE);
00638 *o_warn = waswarn;
00639
00640 return m;
00641 }
00642
00643
00644
00645 MARK v_increment(keyword, m, cnt)
00646 char *keyword;
00647 MARK m;
00648 long cnt;
00649 {
00650 static sign;
00651 char newval[12];
00652 long atol();
00653
00654 DEFAULT(1);
00655
00656
00657 if (!doingdot)
00658 {
00659 sign = getkey(0);
00660 }
00661
00662
00663 switch (sign)
00664 {
00665 case '+':
00666 case '#':
00667 cnt = atol(keyword) + cnt;
00668 break;
00669
00670 case '-':
00671 cnt = atol(keyword) - cnt;
00672 break;
00673
00674 case '=':
00675 break;
00676
00677 default:
00678 return MARK_UNSET;
00679 }
00680 sprintf(newval, "%ld", cnt);
00681
00682 ChangeText
00683 {
00684 change(m, m + strlen(keyword), newval);
00685 }
00686
00687 return m;
00688 }
00689 #endif
00690
00691
00692
00693
00694 MARK v_xit(m, cnt, key)
00695 MARK m;
00696 long cnt;
00697 int key;
00698 {
00699
00700 if (key != 'Z')
00701 {
00702 return MARK_UNSET;
00703 }
00704
00705
00706 move(LINES - 1, 0);
00707 clrtoeol();
00708
00709
00710 cmd_xit(m, m, CMD_XIT, FALSE, "");
00711
00712
00713 return m;
00714 }
00715
00716
00717
00718 MARK v_undoline(m)
00719 MARK m;
00720 {
00721
00722 if (markline(m) != U_line)
00723 {
00724 return MARK_UNSET;
00725 }
00726
00727
00728 ChangeText
00729 {
00730 strcat(U_text, "\n");
00731 change(MARK_AT_LINE(U_line), MARK_AT_LINE(U_line + 1), U_text);
00732 }
00733
00734
00735 U_line = -1L;
00736
00737
00738 return m & ~(BLKSIZE - 1);
00739 }
00740
00741
00742 #ifndef NO_ERRLIST
00743 MARK v_errlist(m)
00744 MARK m;
00745 {
00746 cmd_errlist(m, m, CMD_ERRLIST, FALSE, "");
00747 return cursor;
00748 }
00749 #endif
00750
00751
00752 #ifndef NO_AT
00753
00754 MARK v_at(m, cnt, key)
00755 MARK m;
00756 long cnt;
00757 int key;
00758 {
00759 int size;
00760
00761 size = cb2str(key, tmpblk.c, BLKSIZE);
00762 if (size <= 0 || size == BLKSIZE)
00763 {
00764 return MARK_UNSET;
00765 }
00766
00767 execmap(0, tmpblk.c, FALSE);
00768 return cursor;
00769 }
00770 #endif
00771
00772
00773 #ifdef SIGTSTP
00774 MARK v_suspend()
00775 {
00776 cmd_suspend(MARK_UNSET, MARK_UNSET, CMD_SUSPEND, FALSE, "");
00777 return MARK_UNSET;
00778 }
00779 #endif
00780
00781
00782 #ifndef NO_VISIBLE
00783
00784 MARK v_start(m, cnt, cmd)
00785 MARK m;
00786 long cnt;
00787 int cmd;
00788 {
00789 if (V_from)
00790 {
00791 V_from = MARK_UNSET;
00792 }
00793 else
00794 {
00795 V_from = m;
00796 V_linemd = isupper(cmd);
00797 }
00798 return m;
00799 }
00800 #endif
00801
00802 #ifndef NO_POPUP
00803 # define MENU_HEIGHT 11
00804 # define MENU_WIDTH 23
00805 MARK v_popup(m, n)
00806 MARK m, n;
00807 {
00808 int i;
00809 int y, x;
00810 int key;
00811 int sel;
00812 static int dfltsel;
00813 static char *labels[11] =
00814 {
00815 "ESC cancel! ",
00816 " d delete (cut) ",
00817 " y yank (copy) ",
00818 " p paste after ",
00819 " P paste before ",
00820 " > more indented ",
00821 " < less indented ",
00822 " = reformat ",
00823 " ! external filter ",
00824 " ZZ save & exit ",
00825 " u undo previous "
00826 };
00827
00828
00829 x = physcol - (MENU_WIDTH / 2);
00830 if (x < 0)
00831 x = 0;
00832 else if (x + MENU_WIDTH + 2 > COLS)
00833 x = COLS - MENU_WIDTH - 2;
00834 if (markline(cursor) < topline || markline(cursor) > botline)
00835 y = 0;
00836 else if (markline(cursor) + 1L + MENU_HEIGHT > botline)
00837 y = (int)(markline(cursor) - topline) - MENU_HEIGHT;
00838 else
00839 y = (int)(markline(cursor) - topline) + 1L;
00840
00841
00842 for (sel = 0; sel < MENU_HEIGHT; sel++)
00843 {
00844 move(y + sel, x);
00845 do_POPUP();
00846 if (sel == dfltsel)
00847 qaddstr("-->");
00848 else
00849 qaddstr(" ");
00850 qaddstr(labels[sel]);
00851 do_SE();
00852 }
00853
00854
00855 move(y + dfltsel, x + 4);
00856 for (sel = dfltsel; (key = getkey(WHEN_POPUP)) != '\\' && key != '\r'; )
00857 {
00858
00859 move(y + sel, x);
00860 do_POPUP();
00861 qaddstr(" ");
00862 qaddstr(labels[sel]);
00863 do_SE();
00864
00865
00866 if (key == 'j' && sel < MENU_HEIGHT - 1)
00867 {
00868 sel++;
00869 }
00870 else if (key == 'k' && sel > 0)
00871 {
00872 sel--;
00873 }
00874 else if (key == '\033')
00875 {
00876 sel = 0;
00877 break;
00878 }
00879 else
00880 {
00881 for (i = 1; i < MENU_HEIGHT && labels[i][1] != key; i++)
00882 {
00883 }
00884 if (i < MENU_HEIGHT)
00885 {
00886 sel = i;
00887 break;
00888 }
00889 }
00890
00891
00892 move(y + sel, x);
00893 do_POPUP();
00894 qaddstr("-->");
00895 qaddstr(labels[sel]);
00896 do_SE();
00897 move(y + sel, x + 4);
00898 }
00899
00900
00901 dfltsel = 3;
00902
00903
00904 switch (sel)
00905 {
00906 case 0:
00907 m = cursor;
00908 dfltsel = 0;
00909 break;
00910
00911 case 1:
00912 m = v_delete(m, n);
00913 break;
00914
00915 case 2:
00916 m = v_yank(m, n);
00917 break;
00918
00919 case 3:
00920 m = v_paste(n, 1L, 'P');
00921 break;
00922
00923 case 4:
00924 m = v_paste(m, 1L, 'P');
00925 dfltsel = 4;
00926 break;
00927
00928 case 5:
00929 m = v_rshift(m, n);
00930 dfltsel = 5;
00931 break;
00932
00933 case 6:
00934 m = v_lshift(m, n);
00935 dfltsel = 6;
00936 break;
00937
00938 case 7:
00939 m = v_reformat(m, n);
00940 dfltsel = 7;
00941 break;
00942
00943 case 8:
00944 m = v_filter(m, n);
00945 dfltsel = 0;
00946 break;
00947
00948 case 9:
00949
00950 do
00951 {
00952 key = getkey(0);
00953 } while (key != '\\' && key != 'Z' && key != '\r'
00954 && key != '\033');
00955 if (key != '\033')
00956 {
00957 m = v_xit(m, 0L, 'Z');
00958 }
00959 break;
00960
00961 case 10:
00962 m = v_undo(m);
00963 dfltsel = 9;
00964 break;
00965 }
00966
00967
00968
00969
00970 if (sel != 5 && sel != 9)
00971 redraw(MARK_UNSET, FALSE);
00972
00973 return m;
00974 }
00975 #endif