home *** CD-ROM | disk | FTP | other *** search
/ minnie.tuhs.org / unixen.tar / unixen / PDP-11 / Distributions / ucb / spencer_2bsd.tar.gz / 2bsd.tar / src / ex / ex_v.c < prev    next >
C/C++ Source or Header  |  1980-02-17  |  8KB  |  375 lines

  1. /* Copyright (c) 1979 Regents of the University of California */
  2. #include "ex.h"
  3. #include "ex_re.h"
  4. #include "ex_tty.h"
  5. #include "ex_vis.h"
  6.  
  7. /*
  8.  * Entry points to open and visual from command mode processor.
  9.  * The open/visual code breaks down roughly as follows:
  10.  *
  11.  * ex_v.c    entry points, checking of terminal characteristics
  12.  *
  13.  * ex_vadj.c    logical screen control, use of intelligent operations
  14.  *        insert/delete line and coordination with screen image;
  15.  *        updating of screen after changes.
  16.  *
  17.  * ex_vget.c    input of single keys and reading of input lines
  18.  *        from the echo area, handling of \ escapes on input for
  19.  *        uppercase only terminals, handling of memory for repeated
  20.  *        commands and small saved texts from inserts and partline
  21.  *        deletes, notification of multi line changes in the echo
  22.  *        area.
  23.  *
  24.  * ex_vmain.c    main command decoding, some command processing.
  25.  *
  26.  * ex_voperate.c decoding of operator/operand sequences and
  27.  *        contextual scans, implementation of word motions.
  28.  *
  29.  * ex_vops.c    major operator interfaces, undos, motions, deletes,
  30.  *        changes, opening new lines, shifts, replacements and yanks
  31.  *        coordinating logical and physical changes.
  32.  *
  33.  * ex_vops2.c    subroutines for operator interfaces in ex_vops.c,
  34.  *        insert mode, read input line processing at lowest level.
  35.  *
  36.  * ex_vops3.c    structured motion definitions of ( ) { } and [ ] operators,
  37.  *        indent for lisp routines, () and {} balancing. 
  38.  *
  39.  * ex_vput.c    output routines, clearing, physical mapping of logical cursor
  40.  *        positioning, cursor motions, handling of insert character
  41.  *        and delete character functions of intelligent and unintelligent
  42.  *        terminals, visual mode tracing routines (for debugging),
  43.  *        control of screen image and its updating.
  44.  *
  45.  * ex_vwind.c    window level control of display, forward and backward rolls,
  46.  *        absolute motions, contextual displays, line depth determination
  47.  */
  48.  
  49. /*
  50.  * Enter open mode
  51.  */
  52. oop()
  53. {
  54.     register char *ic;
  55.     char atube[TUBESIZE + LBSIZE];
  56.     register int f;
  57.  
  58.     ovbeg();
  59.     if (peekchar() == '/') {
  60.         ignore(compile(getchar(), 1));
  61.         savere(scanre);
  62.         if (execute(0, dot) == 0)
  63.             error("Fail|Pattern not found on addressed line");
  64.         ic = loc1;
  65.         if (ic > linebuf && *ic == 0)
  66.             ic--;
  67.     } else {
  68.         getDOT();
  69.         ic = vskipwh(linebuf);
  70.     }
  71.     newline();
  72.  
  73.     /*
  74.      * If overstrike then have to HARDOPEN
  75.      * else if can move cursor up off current line can use CRTOPEN (~~vi1)
  76.      * otherwise (ugh) have to use ONEOPEN (like adm3)
  77.      */
  78.     if (OS && !EO)
  79.         bastate = HARDOPEN;
  80.     else if (CA || UP)
  81.         bastate = CRTOPEN;
  82.     else
  83.         bastate = ONEOPEN;
  84.     setwind();
  85.  
  86.     /*
  87.      * To avoid bombing on glass-crt's when the line is too long
  88.      * pretend that such terminals are 160 columns wide.
  89.      * If a line is too wide for display, we will dynamically
  90.      * switch to hardcopy open mode.
  91.      */
  92.     if (state != CRTOPEN)
  93.         WCOLS = TUBECOLS;
  94.     if (!inglobal)
  95.         savevis();
  96.     vok(atube);
  97.     if (state != CRTOPEN)
  98.         COLUMNS = WCOLS;
  99.     Outchar = vputchar;
  100.     f = ostart();
  101.     if (state == CRTOPEN) {
  102.         if (outcol == UKCOL)
  103.             outcol = 0;
  104.         vmoveitup(1);
  105.     } else
  106.         outline = destline = WBOT;
  107.     vshow(dot, NOLINE);
  108.     vnline(ic);
  109.     vmain();
  110.     if (state != CRTOPEN)
  111.         vclean();
  112.     Command = "open";
  113.     ovend(f);
  114. }
  115.  
  116. ovbeg()
  117. {
  118.  
  119.     if (!value(OPEN))
  120.         error("Can't use open/visual unless open option is set");
  121.     if (inopen)
  122.         error("Recursive open/visual not allowed");
  123.     Vlines = lineDOL();
  124.     fixzero();
  125.     setdot();
  126.     pastwh();
  127.     dot = addr2;
  128. }
  129.  
  130. ovend(f)
  131.     int f;
  132. {
  133.  
  134.     splitw++;
  135.     vgoto(WECHO, 0);
  136.     vclreol();
  137.     vgoto(WECHO, 0);
  138.     holdcm = 0;
  139.     splitw = 0;
  140.     ostop(f);
  141.     setoutt();
  142.     undvis();
  143.     COLUMNS = OCOLUMNS;
  144.     inopen = 0;
  145.     flusho();
  146.     netchHAD(Vlines);
  147. }
  148.  
  149. /*
  150.  * Enter visual mode
  151.  */
  152. vop()
  153. {
  154.     register int c;
  155.     char atube[TUBESIZE + LBSIZE];
  156.     register int f;
  157.  
  158.     if (!CA && UP == NOSTR) {
  159.         if (initev) {
  160. toopen:
  161.             merror("[Using open mode]");
  162.             putNFL();
  163.             oop();
  164.             return;
  165.         }
  166.         error("Visual needs addressible cursor or upline capability");
  167.     }
  168.     if (OS && !EO) {
  169.         if (initev)
  170.             goto toopen;
  171.         error("Can't use visual on a terminal which overstrikes");
  172.     }
  173.     if (!CL) {
  174.         if (initev)
  175.             goto toopen;
  176.         error("Visual requires clear screen capability");
  177.     }
  178.     ovbeg();
  179.     bastate = VISUAL;
  180.     c = 0;
  181.     if (any(peekchar(), "+-^."))
  182.         c = getchar();
  183.     pastwh();
  184.     vsetsiz(isdigit(peekchar()) ? getnum() : value(WINDOW));
  185.     setwind();
  186.     newline();
  187.     vok(atube);
  188.     if (!inglobal)
  189.         savevis();
  190.     Outchar = vputchar;
  191.     vmoving = 0;
  192.     f = ostart();
  193.     if (initev == 0) {
  194.         vcontext(dot, c);
  195.         vnline(NOSTR);
  196.     }
  197.     vmain();
  198.     Command = "visual";
  199.     ovend(f);
  200. }
  201.  
  202. /*
  203.  * Hack to allow entry to visual with
  204.  * empty buffer since routines internally
  205.  * demand at least one line.
  206.  */
  207. fixzero()
  208. {
  209.  
  210.     if (dol == zero) {
  211.         register bool ochng = chng;
  212.  
  213.         vdoappend("");
  214.         if (!ochng)
  215.             sync();
  216.         addr1 = addr2 = one;
  217.     } else if (addr2 == zero)
  218.         addr2 = one;
  219. }
  220.  
  221. /*
  222.  * Save lines before visual between unddol and truedol.
  223.  * Accomplish this by throwing away current [unddol,truedol]
  224.  * and then saving all the lines in the buffer and moving
  225.  * unddol back to dol.  Don't do this if in a global.
  226.  *
  227.  * If you do
  228.  *    g/xxx/vi.
  229.  * and then do a
  230.  *    :e xxxx
  231.  * at some point, and then quit from the visual and undo
  232.  * you get the old file back.  Somewhat weird.
  233.  */
  234. savevis()
  235. {
  236.  
  237.     if (inglobal)
  238.         return;
  239.     truedol = unddol;
  240.     saveall();
  241.     unddol = dol;
  242.     undkind = UNDNONE;
  243. }
  244.  
  245. /*
  246.  * Restore a sensible state after a visual/open, moving the saved
  247.  * stuff back to [unddol,dol], and killing the partial line kill indicators.
  248.  */
  249. undvis()
  250. {
  251.  
  252.     if (ruptible)
  253.         signal(SIGINT, onintr);
  254.     squish();
  255.     pkill[0] = pkill[1] = 0;
  256.     unddol = truedol;
  257.     unddel = zero;
  258.     undap1 = one;
  259.     undap2 = dol + 1;
  260.     undkind = UNDALL;
  261. }
  262.  
  263. /*
  264.  * Set the window parameters based on the base state bastate
  265.  * and the available buffer space.
  266.  */
  267. setwind()
  268. {
  269.  
  270.     WCOLS = COLUMNS;
  271.     switch (bastate) {
  272.  
  273.     case ONEOPEN:
  274.         if (AM)
  275.             WCOLS--;
  276.         /* fall into ... */
  277.  
  278.     case HARDOPEN:
  279.         basWTOP = WTOP = WBOT = WECHO = 0;
  280.         ZERO = 0;
  281.         holdcm++;
  282.         break;
  283.  
  284.     case CRTOPEN:
  285.         basWTOP = LINES - 2;
  286.         /* fall into */
  287.  
  288.     case VISUAL:
  289.         ZERO = LINES - TUBESIZE / WCOLS;
  290.         if (ZERO < 0)
  291.             ZERO = 0;
  292.         if (ZERO > basWTOP)
  293.             error("Screen too large for internal buffer");
  294.         WTOP = basWTOP; WBOT = LINES - 2; WECHO = LINES - 1;
  295.         break;
  296.     }
  297.     state = bastate;
  298.     basWLINES = WLINES = WBOT - WTOP + 1;
  299. }
  300.  
  301. /*
  302.  * Can we hack an open/visual on this terminal?
  303.  * If so, then divide the screen buffer up into lines,
  304.  * and initialize a bunch of state variables before we start.
  305.  */
  306. vok(atube)
  307.     register char *atube;
  308. {
  309.     register int i;
  310.  
  311.     if (WCOLS == 1000)
  312.         serror("Don't know enough about your terminal to use %s", Command);
  313.     if (WCOLS > TUBECOLS)
  314.         error("Terminal too wide");
  315.     if (WLINES >= TUBELINES || WCOLS * (WECHO - ZERO + 1) > TUBESIZE)
  316.         error("Screen too large");
  317.  
  318.     vtube0 = atube;
  319.     vclrbyte(atube, WCOLS * (WECHO - ZERO + 1));
  320.     for (i = 0; i < ZERO; i++)
  321.         vtube[i] = (char *) -20000;
  322.     for (; i <= WECHO; i++)
  323.         vtube[i] = atube, atube += WCOLS;
  324.     for (; i < TUBELINES; i++)
  325.         vtube[i] = (char *) -20000;
  326.     vutmp = atube;
  327.     vundkind = VNONE;
  328.     vUNDdot = 0;
  329.     OCOLUMNS = COLUMNS;
  330.     inopen = 1;
  331. #ifndef V6
  332.     signal(SIGINT, vintr);
  333. #endif
  334.     vmoving = 0;
  335.     splitw = 0;
  336.     doomed = 0;
  337.     holdupd = 0;
  338.     Peekkey = 0;
  339.     vcnt = vcline = 0;
  340.     if (vSCROLL == 0)
  341.         vSCROLL = value(SCROLL);
  342. }
  343.  
  344. #ifndef V6
  345. vintr()
  346. {
  347.  
  348.     signal(SIGINT, vintr);
  349.     if (vcatch)
  350.         onintr();
  351.     ungetkey(ATTN);
  352.     draino();
  353. }
  354. #endif
  355.  
  356. /*
  357.  * Set the size of the screen to size lines, to take effect the
  358.  * next time the screen is redrawn.
  359.  */
  360. vsetsiz(size)
  361.     int size;
  362. {
  363.     register int b;
  364.  
  365.     if (bastate != VISUAL)
  366.         return;
  367.     b = LINES - 1 - size;
  368.     if (b >= LINES - 1)
  369.         b = LINES - 2;
  370.     if (b < 0)
  371.         b = 0;
  372.     basWTOP = b;
  373.     basWLINES = WBOT - b + 1;
  374. }
  375.