home *** CD-ROM | disk | FTP | other *** search
/ The C Users' Group Library 1994 August / wc-cdrom-cusersgrouplibrary-1994-08.iso / vol_100 / 199_01 / ged2.c < prev    next >
Text File  |  1987-12-17  |  10KB  |  485 lines

  1. /*
  2. Header:          CUG199;
  3. Title:           Module 2 of ged editor;
  4. Last Updated:    09/19/87;
  5.  
  6. Description:    "PURPOSE: perform text changing commands";
  7.  
  8. Keywords:        e, editor, qed, ged, DeSmet, MSDOS;
  9. Filename:        ged2.c;
  10. Warnings:       "O file must be present during link of ged";
  11.  
  12. Authors:         G. Nigel Gilbert, James W. Haefner, and Mel Tearle;
  13. Compilers:       DeSmet 3.0;
  14.  
  15. References:
  16. Endref;
  17. */
  18.  
  19. /*
  20. e/qed/ged screen editor
  21.  
  22. (C) G. Nigel Gilbert, MICROLOGY, 1981 -  August-December 1981
  23.  
  24. Modified:  Aug-Dec   1984:  BDS-C 'e'(vers 4.6a) to 'qe' (J.W. Haefner)
  25.            March     1985:  BDS-C 'qe' to DeSmet-C 'qed' (J.W. Haefner)
  26.  
  27.            May       1986:  qed converted to ged         (Mel Tearle)
  28.            August    1987:  ged converted to MSC 4.0     (Mel Tearle)
  29.  
  30. File:      ged2.c
  31.  
  32. Functions: movechar, moveline, scroll, calcjmp, jumpline,
  33.            movepage, moveword, insertchar, deletechar, crdelete,
  34.            deleteword, crinsert, undo, adjustc, sync
  35. */
  36.  
  37.  
  38. #ifndef  TC
  39. #include "ged.h"
  40. #else
  41. #include "ged.t"
  42. #endif
  43.  
  44.  
  45. /* move cursor by 'move' columns to the right
  46.  * return YES unless going off text
  47.  */
  48. int movechar(move)
  49. int  move;
  50. {
  51. int  cp, len, result;
  52.  
  53. cp = charn + move;
  54. result = YES;
  55.  
  56. if ( cp < 0 )  {
  57.      result = moveline(-1);
  58.      if ( result )  {
  59.           adjustc( LLIM );
  60.           movechar( cp + 1 );
  61.      }
  62.      else sync(0);
  63. }
  64. else if ( cp > ( len = strlen(text) ) )  {
  65.           result = moveline(1);
  66.           if ( result )  {
  67.                sync(0);
  68.                movechar( cp-len-1 );
  69.           }
  70.           else adjustc( LLIM );
  71. }
  72. else sync(cp);
  73. return  result;
  74. }
  75.  
  76.  
  77. /* move cursor by 'move' lines down
  78.  * return YES if Ok, NO if going off text
  79.  */
  80. int moveline(move)
  81. int move;
  82. {
  83. int line;
  84.  
  85. puttext();
  86. if ( ( move < 0 ? -move : move ) > SHEIGHT )  scr_xy( WAITPOS, 0 );
  87. line = cline;
  88.  
  89. if ( ( cline = loc( cline, move ) ) != line )  {
  90.        gettext( cline );
  91.        if ( cline < pfirst || cline > plast )  {
  92.             if ( move == 1 || move == -1 )  scroll( move );
  93.                  else putpage();
  94.        }
  95.        else  {
  96.          if ( ( !blocking )  &&  ( !offset ) )  {
  97.                 cursory += cline - line;
  98.                 adjustc( cursorx );
  99.          }
  100.          else  {
  101.             putline( line, cursory );
  102.             cursory += cline - line;
  103.             adjustc( cursorx );
  104.             putline( cline, cursory );
  105.          }
  106.        }
  107.   return  YES;
  108.   }
  109. else return  NO;
  110. }
  111.  
  112.  
  113. /* scroll up ( move EQ 1 ) or down 1 line
  114.  */
  115. void scroll(move)
  116. int  move;
  117. {
  118.  
  119. if ( move == 1 )
  120.      scr_scrup( 1, topline, 0, SHEIGHT, SWIDTH );
  121.   else
  122.      scr_scrdn( 1, topline, 0, SHEIGHT, SWIDTH );
  123.  
  124. adjustc( cursorx );
  125. putline( cline, cursory );
  126.  
  127. if ( plast - pfirst == ( SHEIGHT - topline) )  plast += move;
  128. pfirst += move;
  129. }
  130.  
  131.  
  132. /* calc number of lines to jump
  133.  */
  134. void calcjmp()
  135. {
  136. int to;
  137.  
  138. /* reset jmpto for repeat incrmtl jumps
  139.  */
  140. jmpto = 1;
  141.  
  142. if ( ans[0] == '+' )
  143.      if ( ( to = atoi( ans+1 ) ) )  jumpline( to );
  144. if ( ans[0] == '-' )
  145.      if ( (to = atoi( ans ) ) )     jumpline( to );
  146. if ( ans[0] >= '0' )  {
  147.      if ( (to = atoi( ans ) ) )     jumpline( to-cline );
  148.            jmpto = to;
  149.    }
  150. }
  151.  
  152.  
  153. /* move current line by move lines down,
  154.  * checking for interrupt from user
  155.  * (if interrupted, do nothing, and return NO)
  156.  */
  157. int jumpline(move)
  158. int move;
  159. {
  160. int  line, dest;
  161. char testkey();
  162.  
  163. puttext();
  164. dest = cline + move;
  165. dest -= dest % 100;
  166.  
  167. if ( dest > lastread )  {
  168.      scr_xy( WAITPOS, 0 );
  169.      line = cline;
  170.      while ( line < dest && loc( line, 100 ) != line )  {
  171.              line += 100;
  172.              if ( testkey() == ESCKEY )  {
  173.                   error( " Interrupted" );
  174.                   return  NO;
  175.              }
  176.      }
  177. }
  178. moveline( move );
  179. return  YES;
  180. }
  181.  
  182.  
  183. /* move current line by a page down ( dir == 0 ) or up (-1)
  184.  */
  185. void movepage(dir)
  186. int dir;
  187. {
  188. int move, line;
  189.  
  190. scr_cursoff();
  191. puttext();
  192. move = ( SHEIGHT-topline )/2 - PAGEOVERLAP;
  193.  
  194. if (dir)  move = pfirst - cline - move;
  195. else move = plast - cline + move;
  196.  
  197. if ( ( cline = loc( ( line = cline ), move ) ) != line )  {
  198.        gettext( cline );
  199.        putpage();
  200. }
  201. scr_curson();
  202. }
  203.  
  204.  
  205. /* move 1 word to the right (move -ve: left)
  206.  */
  207. void moveword(move)
  208. int move;
  209. {
  210. if ( charn + move < 0 &&  cline > 1 )  {
  211.      moveline(-1);
  212.      charn = strlen( text );
  213. }
  214. else if ( charn + move >= strlen( text ) )  {
  215.           moveline(1);
  216.           sync(0);
  217.           if ( inword( text[0] ) )  return;
  218. }
  219.  
  220. while ( ( move < 0 || text[charn] ) && inword( text[charn] )
  221.                                     && ( charn += move ) );
  222. while ( ( move < 0 || text[charn] ) && !inword( text[charn] )
  223.                                     && ( charn += move ) );
  224. if ( move < 0  &&  charn )  {
  225.      while ( inword(text[charn] )   &&  --charn );
  226.      if ( charn || !inword( text[charn] ) )
  227.           charn++;
  228. }
  229. sync( charn );
  230. }
  231.  
  232.  
  233. /* if not overtype then insert 'c' at charn, move cursor up one
  234.  * else overwrite character under cursor
  235.  */
  236. void insertchar(c)
  237. char c;
  238. {
  239. int  cp;
  240.  
  241. if ( ( cp = strlen( text ) + 1 ) >= ( LLIM - 1 ) )
  242.        error( " Line too long " );
  243. else  {
  244.   if ( !overtype  ||  ( overtype  &&  ( charn == ( cp - 1 ) ) ) )
  245.        for ( ; cp >= charn; cp-- )
  246.              text[cp+1] = text[cp];
  247.  
  248.   text[charn] = c;
  249.   altered = YES;
  250.   rewrite( charn, cursorx );
  251.   sync( charn+1 );
  252.   }
  253. }
  254.  
  255.  
  256. /* deletes char before (dir=-1) or at (dir=0) cursor
  257.  */
  258. void deletechar(dir)
  259. int dir;
  260. {
  261. char c;
  262. int  cp;
  263.  
  264. cp = charn + dir;
  265. if ( cp < 0 )  {
  266.      if ( cline > 1 )  crdelete(-1);
  267. }
  268. else if ( text[cp] == '\0' )  {
  269.      if ( cline < lastl )  crdelete(0);
  270. }
  271. else  {
  272.   do  {
  273.      c = text[cp] = text[cp+1];
  274.      cp++;
  275.   }
  276.   while(c);
  277.  
  278.   altered = YES;
  279.   sync( charn + dir );
  280.   if ( calcoffset() != lastoff )
  281.        rewrite( 0, 0 );
  282.   else
  283.        rewrite( charn, cursorx );
  284.   }
  285. }
  286.  
  287.  
  288. /* delete a [CR] before (dir==-1) or at (dir==0) cursor
  289.  */
  290. void crdelete(dir)
  291. int dir;
  292. {
  293. int  delline, len, *t;
  294. char textb[LLIM];
  295.  
  296. altered = YES;
  297. if ( dir == 0 )  {
  298.      delline = cline + 1;
  299.      strcpy( textb, getline( delline ) );
  300.      cursory++;
  301. }
  302. else  {
  303.   delline = cline;
  304.   strcpy( textb, text );
  305.   if ( cline > 1 )  gettext( cline-1 );
  306.   else  puttext();
  307. }
  308. sync( ( len = strlen(text) ) );
  309.  
  310. if ( len + strlen(textb) >= LLIM )  {
  311.      textb[LLIM-len] = '\0';
  312.      error( " Line too long - cut short " );
  313. }
  314.  
  315. strcat( text, textb );
  316. puttext();
  317. deltp( delline );
  318.  
  319. if ( delline > plast || delline <= pfirst )  putpage();
  320. else  {
  321.     scr_scrup( 1, cursory--, 0, SHEIGHT, SWIDTH );
  322.     rewrite( 0, 0 );
  323.  
  324.     if ( plast <= lastl && lastl-pfirst > SHEIGHT - topline )
  325.          putline( plast, SHEIGHT );
  326.     else  plast = lastl;
  327.   }
  328. }
  329.  
  330.  
  331. /* deletes up to first occurrence of white space
  332.  * if no white space then delete to end of line
  333.  * see inword() in ged7.c
  334.  */
  335. void deleteword()
  336. {
  337. int  pend, cp, in;
  338. char c;
  339.  
  340. for ( in = inword( text[pend = charn] );
  341.       ( c = text[pend] )  &&  ( in ? inword(c): !inword(c) );
  342.         pend++ )
  343.         ;
  344. for  ( cp = charn; ( text[cp] = text[pend] ); pend++, cp++ )
  345.         ;
  346. rewrite( charn, cursorx );
  347. altered = YES;
  348. }
  349.  
  350.  
  351. /* insert a [CR] behind ( dir=0 ) or in front of (dir=-1) cursor
  352.  * dir is 0
  353.  */
  354. void crinsert(dir)
  355. {
  356. char textb[LLIM], c;
  357. int  charnb;
  358.  
  359. charnb = 0;
  360. if ( autoin  &&  !isspace( text[charn] ) )
  361.      while( isspace( ( c = text[charnb] ) ) )  textb[charnb++] = c;
  362.  
  363. strcpy( &textb[charnb], &text[charn] );
  364. text[charn] = '\0';
  365. altered = YES;
  366.  
  367. if ( dir == 0 )  {
  368.      puttext();
  369.      strcpy( text, textb );
  370.      altered = YES;
  371.      sync( charnb );
  372.      if ( ( cline = writ_txb( cline, textb ) ) == FAIL )  return;
  373. }
  374. else if ( writ_txb( cline, textb ) == FAIL )  return;
  375.  
  376. if ( cursory >= SHEIGHT )  {
  377.      puttext();
  378.      putpage();
  379. }
  380. else  {
  381.   scr_scrdn( 1, cursory+1, 0, SHEIGHT, SWIDTH );
  382.  
  383.   if ( dir == 0 )
  384.        putline( cline-1, cursory++ );
  385.   else
  386.        putline( cline+1, cursory+1 );
  387.  
  388.   if ( plast - pfirst < SHEIGHT - topline )  plast++;
  389.  
  390.   rewrite( 0, 0 );
  391.   }
  392. }
  393.  
  394.  
  395. /* undo edit on current line and then from history
  396.  */
  397. void undo()
  398. {
  399. int  onpage;     /* flag for changes to current screen */
  400. int  l, slot;
  401.  
  402. char textb[LLIM];
  403.  
  404. if ( altered )  {
  405.      if ( cline <= lastl )  gettext( cline );  else text[0] = '\0';
  406.      altered = NO;
  407.      adjustc( cursorx );
  408.      rewrite( 0, 0 );
  409. }
  410. else  {
  411.   if ( histcnt == 0 )  {
  412.        error( " Nothing to undo " );
  413.        return;
  414.   }
  415.   onpage = NO;
  416.   do  {
  417.     if ( --histptr < 0 )  histptr = ( HISTLEN - 1 );
  418.     histcnt--;
  419.  
  420.     l = history[histptr].histline;
  421.  
  422.     onpage = onpage || ( l >= pfirst && l <= plast );
  423.     storehist = NO;
  424.     switch ( history[histptr].histtype )  {
  425.       case HISTINSERT:
  426.         deltp( l+1 );
  427.         break;
  428.       case HISTDELETE:
  429.         if ( ( slot = pageloc[history[histptr].histp.page] ) <= 0 )
  430.                slot = swappin( history[histptr].histp.page );
  431.         strcpy( textb, slotaddr[slot] + history[histptr].histp.moffset );
  432.         writ_txb( l-1, textb );
  433.         break;
  434.       case HISTREPLACE:
  435.         tp[l].page    = history[histptr].histp.page;
  436.         tp[l].moffset = history[histptr].histp.moffset;
  437.         break;
  438.     }
  439.   }
  440.  
  441.   /* until command changes
  442.    */
  443.   while ( histcnt  &&  history[histptr].histcomm ==
  444.           history[( histptr-1 < 0 ? HISTLEN-1 : histptr-1) ].histcomm );
  445.  
  446.   if ( l < pfirst || l > plast )
  447.            cline = l;
  448.   putpage();
  449.   }
  450. if ( cline <= lastl )  gettext( cline );
  451. }
  452.  
  453.  
  454. /* set cursorx to col. cursor nearest to col. 'x' so that
  455.  * cursor isn't in the middle of a tab or off the end of the
  456.  * current line
  457.  */
  458. void adjustc(x)
  459. int x;
  460. {
  461. char c;
  462.  
  463. for( charn = 0, cursorx = 0;
  464.      cursorx < x  && ( ( c = text[charn] ) != '\0');
  465.      charn++, cursorx++ )
  466.      if ( c == '\t' )
  467.           cursorx += tabwidth -1 -( cursorx % tabwidth );
  468. }
  469.  
  470.  
  471. /* put cursorx and charn onto character 'cp' of current line
  472.  */
  473. void sync(cp)
  474. int cp;
  475. {
  476. for( charn = 0, cursorx = 0;
  477.      charn < cp;
  478.      cursorx++, charn++ )
  479.      if ( text[charn] == '\t' )
  480.           cursorx = cursorx + tabwidth-1-( cursorx % tabwidth );
  481. }
  482.  
  483.  
  484. /* that's all */
  485.