home *** CD-ROM | disk | FTP | other *** search
/ Usenet 1994 January / usenetsourcesnewsgroupsinfomagicjanuary1994.iso / sources / unix / volume7 / rvi / part2 / rv_cmd.c next >
Encoding:
C/C++ Source or Header  |  1986-11-30  |  13.3 KB  |  739 lines

  1. #include "rv.h"
  2. #include <ctype.h>
  3. /*
  4.  * rv_cmd.c  -  Main command loop
  5.  */
  6.  
  7. boolean    change_flag;        /* Used by word_scan() */
  8.  
  9. rv_cmd()
  10. /*
  11.  * Loop and execute commands
  12.  * The screen is always refreshed afterwards.
  13.  */
  14. {
  15.     register struct sc_screen *sc;
  16.     INT    i,j,k;    /* temp vars */
  17.     INT     c;        /* Command character */
  18.     boolean specified_count;/* TRUE if count was explicitly specified */
  19.     INT     cmd_count;    /* Count, default 1 */
  20.     void    read_where_mod(), where_mod(), rv_undo(), rv_dot(), rv_debug();
  21.     void    rv_mark();
  22.     boolean    search();
  23.  
  24.     sc = &screen;
  25.  
  26. for (;;) {   /* Loop forever */
  27.     errflag = 0;
  28.     yank_cmd = ' ';
  29.     specified_count = read_cmd(&c, &cmd_count);
  30.  
  31.     /*
  32.      * Main command switch
  33.      */
  34.     switch (c) {
  35.  
  36. case CTRL(L):
  37. #ifdef USG
  38. case KEY_CLEAR:
  39. #endif
  40.     /*
  41.      * Clear and redisplay screen
  42.      */
  43.      clearok(curscr, TRUE);
  44.      break;
  45.  
  46. case CTRL(R):
  47.     /*
  48.      * Redraw screen
  49.      */
  50.      clearok(curscr, TRUE);
  51.      redraw_screen((struct li_line *)0);
  52.      break;
  53.  
  54. case CTRL(E):
  55. #ifdef USG
  56. case KEY_SF:
  57. #endif
  58.     /*
  59.      * Scroll up one line.  Leave cursor
  60.      * on same line, if possible.
  61.      */
  62.     i = sc->sc_lineno + (CURLINE == 0 ? 1 : 0);
  63.     j = sc->sc_column;
  64.     /* Force scroll 1 line */
  65.     move_abs_cursor((sc->sc_botline - sc->sc_curline) + sc->sc_lineno+1, 0);
  66.     move_abs_cursor(i, j); /* Restore cursor */
  67.     break;
  68.  
  69. case CTRL(Y):
  70. #ifdef USG
  71. case KEY_SR:
  72. #endif
  73.     /*
  74.      * Scroll down one line.  Leave cursor
  75.      * on same line, if possible.
  76.      */
  77.     i = sc->sc_lineno - (CURLINE == LINES-2 ? 1 : 0);
  78.     j = sc->sc_column;
  79.     /* Scroll reverse scroll 1 line */
  80.     move_abs_cursor(sc->sc_lineno-1 - (sc->sc_curline - sc->sc_topline), 0);
  81.     move_abs_cursor(i, j);
  82.     break;
  83.  
  84. case 'h':
  85. case '\b':
  86. #ifdef USG
  87. case KEY_LEFT:
  88. case KEY_BACKSPACE:
  89. #endif
  90.     /*
  91.      * Move cursor left 1 character
  92.      */
  93.     move_cursor(sc->sc_lineno, sc->sc_column-cmd_count);
  94.     break;
  95.  
  96. case 'l':
  97. case ' ':
  98. #ifdef USG
  99. case KEY_RIGHT:
  100. #endif
  101.     /*
  102.      * Move cursor right 1 character
  103.      */
  104.     move_cursor(sc->sc_lineno, sc->sc_column+cmd_count);
  105.     break;
  106.  
  107. case 'k':
  108. case CTRL(P):
  109. #ifdef USG
  110. case KEY_UP:
  111. #endif
  112.     /*
  113.      * Move cursor up 1 character
  114.      */
  115.     move_abs_cursor(sc->sc_lineno-cmd_count, COL_SAME);
  116.     break;
  117.  
  118. case '-':
  119.     /*
  120.      * Move to first nonwhite character on previous line
  121.      */
  122.      move_abs_cursor(sc->sc_lineno-cmd_count, COL_FIRST_NONWHITE);
  123.      break;
  124.  
  125. case 'j':
  126. case '\n':
  127. case CTRL(N):
  128. #ifdef USG
  129. case KEY_DOWN:
  130. #endif
  131.     /*
  132.      * Move cursor down 1 character
  133.      */
  134.     move_abs_cursor(sc->sc_lineno+cmd_count, COL_SAME);
  135.     break;
  136.  
  137. case '\r':
  138. case '+':
  139.     /*
  140.      * Move to first nonwhite character on next line
  141.      */
  142.     move_abs_cursor(sc->sc_lineno+cmd_count, COL_FIRST_NONWHITE);
  143.     break;
  144.  
  145. case 'x':
  146. #ifdef USG
  147. case KEY_DC:
  148. #endif
  149.     /*
  150.      * Delete character under cursor
  151.      */
  152.     toss_undo();
  153.     if (sc->sc_curline->li_width <= 0) {
  154.         errflag = 1;
  155.         flash();
  156.         break;
  157.     }
  158.     sc->sc_validcol = TRUE;
  159.     sc->sc_firstline = sc->sc_lineno;
  160.     sc->sc_firstcol  = sc->sc_column;
  161.     sc->sc_lastline = sc->sc_lineno;
  162.     sc->sc_lastcol = sc->sc_column+cmd_count-1;
  163.     if (sc->sc_lastcol >= sc->sc_curline->li_width)
  164.         sc->sc_lastcol = sc->sc_curline->li_width-1;
  165.     delete();
  166.     break;
  167.  
  168. case 'X':
  169.     /*
  170.      * Delete character before cursor
  171.      */
  172.     toss_undo();
  173.     if (sc->sc_column <= 0) {
  174.         errflag = 1;
  175.         flash();
  176.         break;
  177.     }
  178.     sc->sc_validcol = TRUE;
  179.     sc->sc_lastline = sc->sc_lineno;
  180.     sc->sc_lastcol = sc->sc_column-1;
  181.     sc->sc_firstline = sc->sc_lineno;
  182.     sc->sc_firstcol = sc->sc_column-cmd_count;
  183.     if (sc->sc_firstcol < 0)
  184.         sc->sc_firstcol = 0;
  185.     delete();
  186.     break;
  187.  
  188. case CTRL(G):
  189.     /*
  190.      * Print file size
  191.      */
  192.     sizemsg();
  193.     break;
  194.  
  195. case CTRL(U):
  196. #ifdef USG
  197. case KEY_PPAGE:
  198. #endif
  199.     /*
  200.      * Scroll screen up 1 page
  201.      */
  202.     if (specified_count)
  203.         set_scroll = cmd_count;
  204.     else
  205.         cmd_count = set_scroll;
  206.     if (sc->sc_lineno <= 1) { /* If at top of file */
  207.         errflag = 1;
  208.         flash();
  209.         break;
  210.     }
  211.     k = sc->sc_curline - sc->sc_topline;
  212.     move_cursor(sc->sc_lineno - k, 0); /* Goto top of screen */
  213.     for (i=0; i < cmd_count; ++i) {  /* Scrolling loop */
  214.         if (sc->sc_lineno <= 1)  /* If past top of file */
  215.             break;
  216.         move_abs_cursor(sc->sc_lineno-1, 0); /* Scroll up */
  217.         if (errflag)
  218.             break;
  219.     }
  220.     if (i >= cmd_count) 
  221.         move_abs_cursor(sc->sc_lineno + k, 0);  /* Move cursor back */
  222.     move_cursor(sc->sc_lineno, COL_FIRST_NONWHITE); /* Set column */
  223.     break;
  224.  
  225. case CTRL(D):
  226. #ifdef USG
  227. case KEY_NPAGE:
  228. #endif
  229.     /*
  230.      * Scroll screen down a page
  231.      */
  232.     if (specified_count)
  233.         set_scroll = cmd_count;
  234.     else
  235.         cmd_count = set_scroll;
  236.     if (sc->sc_lineno >= file.fi_numlines) { /* If past bottom of file */
  237.         errflag = 1;
  238.         flash();
  239.         break;
  240.     }
  241.     k = sc->sc_botline - sc->sc_curline;
  242.     move_cursor(sc->sc_lineno + k, 0); /* Goto bottom of screen */
  243.     for (i=0; i < cmd_count; ++i) { /* Scrolling loop */
  244.         if (sc->sc_lineno >= file.fi_numlines) /* If past end of file */
  245.             break;
  246.         move_abs_cursor(sc->sc_lineno+1, 0); /* Scroll */
  247.         if (errflag)
  248.             break;
  249.     }
  250.     if (i >= cmd_count) 
  251.         move_abs_cursor(sc->sc_lineno - k, 0);  /* Move cursor back */
  252.     move_cursor(sc->sc_lineno, COL_FIRST_NONWHITE); /* Set column */
  253.     break;
  254.  
  255. case CTRL(B):
  256.     /*
  257.      * Go back a page, with two
  258.      * lines of continuity
  259.      */
  260.     if (sc->sc_lineno <= 1) { /* If past top of file */
  261.         flash();
  262.         errflag = 1;
  263.         break;
  264.     }
  265.     clearok(curscr, TRUE);
  266.     /* Go to top of screen */
  267.     move_cursor(sc->sc_lineno - (sc->sc_curline - sc->sc_topline), 0);
  268.     /* Go back LINES-2 */
  269.     i = sc->sc_lineno - cmd_count*(LINES-2) + LINES/2;
  270.     if (i <= 0)
  271.         i = 1;
  272.     move_abs_cursor(i, COL_FIRST_NONWHITE);
  273.     break;
  274.  
  275. case CTRL(F):
  276.     /*
  277.      * Go forward a page, with two
  278.      * lines of continuity
  279.      */
  280.     if (sc->sc_lineno >= file.fi_numlines) { /* if past end of file */
  281.         flash();
  282.         errflag = 1;
  283.         break;
  284.     }
  285.     clearok(curscr, TRUE);
  286.     /* Go to bottom of screen */
  287.     move_cursor(sc->sc_lineno + (sc->sc_botline - sc->sc_curline), 0);
  288.     /* Go forward LINES-2 */
  289.     i = sc->sc_lineno + cmd_count*(LINES-2) - LINES/2;
  290.     if (i > file.fi_numlines)
  291.         i = file.fi_numlines;
  292.     move_abs_cursor(i, COL_FIRST_NONWHITE);
  293.     break;
  294.  
  295. case 'M':
  296.     /*
  297.      * Position cursor to middle line
  298.      */
  299.     move_abs_cursor(sc->sc_lineno-(sc->sc_curline-sc->sc_topline)+LINES/2,
  300.         COL_FIRST_NONWHITE);
  301.     break;
  302.  
  303. case 'Q':
  304.     /*
  305.      * Drop into ed
  306.      */
  307.     quit();
  308.     break;
  309.  
  310. case 'y':
  311.     /*
  312.      * Yank
  313.      */
  314.     toss_undo();
  315.     read_where_mod(c, specified_count, cmd_count);
  316.     if (errflag)
  317.         break;
  318.     yank();
  319.     break;
  320.  
  321. case 'Y':
  322.     /*
  323.      * Yank lines
  324.      */
  325.     toss_undo();
  326.     sc->sc_validcol = FALSE;
  327.     sc->sc_firstline = sc->sc_lineno;
  328.     sc->sc_lastline = sc->sc_lineno + cmd_count-1;
  329.     if (sc->sc_lastline > file.fi_numlines)
  330.         sc->sc_lastline = file.fi_numlines;
  331.     yank();
  332.     break;
  333.  
  334. case 'p':
  335.     /*
  336.      * Put buffer
  337.      */
  338.     undo.un_deleted = FALSE;
  339.     j = sc->sc_lineno+1;
  340.     put(1);
  341.     if (cmd_count > 1)
  342.         if (sc->sc_validcol)
  343.             dup_insert(cmd_count);
  344.         else {
  345.             for (i=1; i < cmd_count; ++i)
  346.                 put(1);
  347.             undo.un_firstline = j;
  348.         }
  349.     break;
  350.  
  351. case 'P':
  352.     /*
  353.      * Put buffer above cursor
  354.      */
  355.     undo.un_deleted = FALSE;
  356.     j = sc->sc_lineno-1;
  357.     put(-1);
  358.     if (cmd_count > 1)
  359.         if (sc->sc_validcol)
  360.             dup_insert(cmd_count);
  361.         else {
  362.             for (i=1; i < cmd_count; ++i)
  363.                 put(-1);
  364.             undo.un_lastline = j;
  365.         }
  366.     break;
  367.  
  368. case 'd':
  369.     /*
  370.      * Delete
  371.      */
  372.     toss_undo();
  373.     read_where_mod(c, specified_count, cmd_count);
  374.     if (errflag)
  375.         break;
  376.     delete();
  377.     break;
  378.  
  379. case 'D':
  380. #ifdef USG
  381. case KEY_EOL:
  382. #endif
  383.     /*
  384.      * Delete rest of line
  385.      */
  386.     toss_undo();
  387.     sc->sc_validcol = TRUE;
  388.     sc->sc_firstline = sc->sc_lineno;
  389.     sc->sc_lastline = sc->sc_lineno;
  390.     sc->sc_firstcol = sc->sc_column;
  391.     sc->sc_lastcol = sc->sc_curline->li_width-1;
  392.     delete();
  393.     break;
  394.  
  395. #ifdef USG
  396. case KEY_DL:
  397. #else
  398. case -2:
  399. #endif
  400.     /*
  401.      * Delete line
  402.      */
  403.     toss_undo();
  404.     sc->sc_validcol = FALSE;
  405.     sc->sc_firstline = sc->sc_lineno;
  406.     sc->sc_lastline = sc->sc_lineno;
  407.     delete();
  408.     break;
  409.  
  410. case 'c':
  411.     /*
  412.      * Change
  413.      */
  414.     toss_undo();
  415.     change_flag = TRUE;
  416.     read_where_mod(c, specified_count, cmd_count);
  417.     if (errflag)
  418.         break;
  419.     change();
  420.     change_flag = FALSE;
  421.     break;
  422.  
  423. case 'C':
  424.     /*
  425.      * Change rest of line
  426.      */
  427.     toss_undo();
  428.     sc->sc_firstline = sc->sc_lineno;
  429.     sc->sc_lastline = sc->sc_lineno + cmd_count-1;
  430.     if (sc->sc_lastline == sc->sc_firstline) {
  431.         sc->sc_validcol = TRUE;
  432.         sc->sc_firstline = sc->sc_lineno;
  433.         sc->sc_firstcol = sc->sc_column;
  434.         sc->sc_lastcol = sc->sc_curline->li_width-1;
  435.     } else {
  436.         sc->sc_validcol = FALSE;
  437.         if (sc->sc_lastline > file.fi_numlines)
  438.             sc->sc_lastline = file.fi_numlines;
  439.     }
  440.     change();
  441.     break;
  442.     
  443. case 'i':
  444. #ifdef USG
  445. case KEY_IC:
  446. #endif
  447.     /*
  448.      * Insert before cursor
  449.      */
  450.     toss_undo();
  451.     sc->sc_validcol = TRUE;
  452.     sc->sc_firstcol = sc->sc_column;
  453.     sc->sc_lastcol = sc->sc_column-1;
  454.     sc->sc_firstline = sc->sc_lastline = sc->sc_lineno;
  455.     insert();
  456.     if (cmd_count > 1)
  457.         dup_insert(cmd_count);
  458.     break;
  459.  
  460. case 'I':
  461.     /*
  462.      * Insert before first nonwhite char
  463.      */
  464.     toss_undo();
  465.     move_cursor(sc->sc_lineno, COL_FIRST_NONWHITE);
  466.     sc->sc_validcol = TRUE;
  467.     sc->sc_firstcol = sc->sc_column;
  468.     sc->sc_lastcol = sc->sc_column-1;
  469.     sc->sc_firstline = sc->sc_lastline = sc->sc_lineno;
  470.     insert();
  471.     if (cmd_count > 1)
  472.         dup_insert(cmd_count);
  473.     break;
  474.  
  475. case 'a':
  476.     /*
  477.      * Append after cursor
  478.      */
  479.     toss_undo();
  480.     if (sc->sc_curline->li_width > 0)
  481.         sc->sc_column++;
  482.     input_mode = TRUE; /* So move_cursor() will let us go past eol */
  483.     move_cursor(sc->sc_lineno, sc->sc_column);
  484.     sc->sc_validcol = TRUE;
  485.     sc->sc_firstcol = sc->sc_column;
  486.     sc->sc_lastcol = sc->sc_column-1;
  487.     sc->sc_firstline = sc->sc_lastline = sc->sc_lineno;
  488.     insert();
  489.     if (cmd_count > 1)
  490.         dup_insert(cmd_count);
  491.     break;
  492.  
  493. case 'A':
  494.     /*
  495.      * Append at end of line
  496.      */
  497.     toss_undo();
  498.     sc->sc_column = sc->sc_curline->li_width;
  499.     input_mode = TRUE; /* So move_cursor() will let us go past eol */
  500.     move_cursor(sc->sc_lineno, sc->sc_column);
  501.     sc->sc_validcol = TRUE;
  502.     sc->sc_firstcol = sc->sc_column;
  503.     sc->sc_lastcol = sc->sc_column-1;
  504.     sc->sc_firstline = sc->sc_lastline = sc->sc_lineno;
  505.     insert();
  506.     if (cmd_count > 1)
  507.         dup_insert(cmd_count);
  508.     break;
  509.  
  510. case 'R':
  511.     /*
  512.      * Replace text
  513.      */
  514.     toss_undo();
  515.     sc->sc_validcol = TRUE;
  516.     sc->sc_firstcol = sc->sc_column;
  517.     sc->sc_lastcol = sc->sc_column-1;
  518.     sc->sc_firstline = sc->sc_lastline = sc->sc_lineno;
  519.     replace_flag = TRUE;
  520.     insert();
  521.     replace_flag = FALSE;
  522.     if (cmd_count > 1)
  523.         dup_insert(cmd_count);
  524.     break;
  525.  
  526. case '~':
  527.     /*
  528.      * Switch case of char
  529.      */
  530. case 'r':
  531.     /*
  532.      * Replace character under cursor
  533.      */
  534.     toss_undo();
  535.     if (sc->sc_curline->li_width <= 0) { /* If empty line */
  536.         errflag = 1;
  537.         flash();
  538.         break;
  539.     }
  540.     if (c != '~')
  541.         while ((i = getch()) == '\0')
  542.             ;
  543.     else {
  544.         i = sc->sc_curline->li_text[sc->sc_column];
  545.         if (isupper(i))
  546.             i = tolower(i);
  547.         else if (islower(i))
  548.             i = toupper(i);
  549.     }
  550.     save_Undo();
  551.     sc->sc_validcol = TRUE;
  552.     sc->sc_firstline = sc->sc_lastline = sc->sc_lineno;
  553.     sc->sc_firstcol = sc->sc_lastcol = sc->sc_column;
  554.     undo.un_deleted = TRUE;
  555.     undo.un_inserted = TRUE;
  556.     undo.un_validcol = sc->sc_validcol = TRUE;
  557.     undo.un_firstline = undo.un_lastline = sc->sc_lineno;
  558.     undo.un_firstcol = undo.un_lastcol = sc->sc_column;
  559.     yank();
  560.     sc->sc_curline->li_text[sc->sc_column] = i;
  561.     redraw_curline(sc->sc_curline->li_text);
  562.     move_cursor(sc->sc_lineno, sc->sc_column);
  563.     if (cmd_count > 1)
  564.         dup_insert(cmd_count);
  565.     if (c == '~' && sc->sc_column < sc->sc_curline->li_width-1)
  566.         move_cursor(sc->sc_lineno, sc->sc_column+1);
  567.     break;
  568.  
  569. case 's':
  570.     /*
  571.      * Substitute 1 character
  572.      */
  573.     toss_undo();
  574.     sc->sc_validcol = TRUE;
  575.     sc->sc_firstcol = sc->sc_column;
  576.     sc->sc_lastcol = sc->sc_column+cmd_count-1;
  577.     sc->sc_firstline = sc->sc_lastline = sc->sc_lineno;
  578.     if (sc->sc_lastcol >= sc->sc_curline->li_width)
  579.         sc->sc_lastcol = sc->sc_curline->li_width - 1;
  580.     insert();
  581.     break;
  582.  
  583. case 'U':
  584.     /*
  585.      * Undo changes to current line
  586.      */
  587.     toss_undo();
  588.     if (sc->sc_origline.li_text == NULL) { /* If no changes */
  589.         errflag = 1;
  590.         flash();
  591.         break;
  592.     }
  593.     redraw_curline(sc->sc_origline.li_text);
  594.     move_cursor(sc->sc_lineno, COL_FIRST_NONWHITE);
  595.     sc->sc_origline.li_text = NULL;
  596.     break;
  597.  
  598. case 'u':
  599.     /*
  600.      * General undo
  601.      */
  602.     rv_undo();
  603.     break;
  604.  
  605. case '.':
  606.     /*
  607.      * Repeat last change
  608.      */
  609.     for (i=0; i < cmd_count; ++i)
  610.         rv_dot();
  611.     break;
  612.  
  613. case 'J':
  614.     /*
  615.      * Join lines
  616.      */
  617.     toss_undo();
  618.     join();
  619.     break;
  620.  
  621.  
  622. case 'o':
  623.     /*
  624.      * Open line after cursor
  625.      */
  626.     toss_undo();
  627.     openline(1);
  628.     insert();
  629.     break;
  630.  
  631. case 'O':
  632. #ifdef USG
  633. case KEY_IL:
  634. #endif
  635.     /*
  636.      * Open line before cursor
  637.      */
  638.     toss_undo();
  639.     openline(-1);
  640.     insert();
  641.     break;
  642.  
  643. case 'S':
  644.     /*
  645.      * Substitute lines
  646.      */
  647.     toss_undo();
  648.     sc->sc_validcol = FALSE;
  649.     sc->sc_firstline = sc->sc_lineno;
  650.     sc->sc_lastline = sc->sc_lineno+cmd_count-1;
  651.     if (sc->sc_lastline > file.fi_numlines) {
  652.         errflag = 1;
  653.         flash();
  654.         break;
  655.     }
  656.     change();
  657.     break;
  658.  
  659. case 'm':
  660.     /*
  661.      * Mark text
  662.      */
  663.     rv_mark();
  664.     break;
  665.  
  666. case ':':
  667.     /*
  668.      * Line command
  669.      */
  670.     mvaddch(LINES-1, 0, ':');
  671.     rv_linecmd(rv_getline());
  672.     break;
  673.  
  674. case '&':
  675.     /* 
  676.      * Repeat last s/../../
  677.      */
  678.     rv_linecmd("s//%/");
  679.     break;
  680.     
  681. case CTRL(V):
  682.     /*
  683.      * Display debug info
  684.      */
  685.     rv_debug();
  686.     break;
  687.  
  688. case 'Z':
  689.     /*
  690.      * Write and quit
  691.      */
  692.     if (getch() != 'Z') {
  693.         errflag = 1;
  694.         flash();
  695.         break;
  696.     }
  697.     rv_linecmd("wq");
  698.     break;
  699.         
  700. default:
  701.     /*
  702.      * A cursor movement command
  703.      */
  704.     where_mod(c, specified_count, cmd_count, TRUE);
  705.     if (errflag)
  706.         break;
  707.     /*
  708.      * Determine which row,col pair is the new location (first or last?)
  709.      */
  710.     j = COL_FIRST_NONWHITE;
  711.     if (sc->sc_firstline == sc->sc_lineno &&
  712.        (!sc->sc_validcol || sc->sc_firstcol == sc->sc_column)) {
  713.         i = sc->sc_lastline;
  714.         if (sc->sc_validcol)
  715.             j = sc->sc_lastcol;
  716.     } else {
  717.         i = sc->sc_firstline;
  718.         if (sc->sc_validcol)
  719.             j = sc->sc_firstcol;
  720.     }
  721.     if (i == sc->sc_lineno) /* If already on line */
  722.         move_cursor(i,j);
  723.     else
  724.         move_abs_cursor(i,j);
  725.     break;
  726.         
  727.  
  728.     } /* End of switch */
  729.  
  730.     opened_line = FALSE;
  731.  
  732.     fflush(file.fi_fpout);
  733.     hitcr_continue();
  734.     refresh();
  735.  
  736. }   /* End of loop */
  737.  
  738. }
  739.