home *** CD-ROM | disk | FTP | other *** search
/ OS/2 Shareware BBS: 5 Edit / 05-Edit.zip / ehp14cs.zip / aus_2.c < prev    next >
C/C++ Source or Header  |  1995-06-15  |  46KB  |  1,036 lines

  1. /****************************************************************/ 
  2. /*                                                              */
  3. /*      MODUL:  aus_2.c                                         */
  4. /*                                                              */
  5. /*      FUNKTIONEN:                                             */
  6. /*              - do_textbeginn (gehe zum Textbeginn)           */
  7. /*              - do_eot (gehe zum Textende)                    */
  8. /*              - do_deleol (loesche bis Zeilenende)            */
  9. /*              - do_del_word (loesche Wort, auf dem Cursor st.)*/
  10. /*              - do_wleft (gehe Wort nach links)               */
  11. /*              - do_wright (gehe Wort nach rechts)             */
  12. /*              - do_right (gehe ein Zeichen nach rechts)       */
  13. /*              - do_left (gehe ein Zeichen nach links)         */
  14. /*              - do_up (gehe eine Zeile nach oben)             */
  15. /*              - do_down (gehe eine Zeile nach unten)          */
  16. /*              - do_settab (Tablaenge setzen)                  */
  17. /*              - do_backtab (an vorherige Tabposition springen)*/
  18. /*              - do_tab (Tab einfuegen)                        */
  19. /*              - do_pgup (Page Up ausfuehren)                  */
  20. /*              - do_pgdn (Page Down ausfuehren)                */
  21. /*              - do_open (leere Zeile vor aktueller einfuegen) */
  22. /*              - do_hopen (leere Zeile hinter aktueller efg.)  */
  23. /*              - do_newline (newline ausfuehren)               */
  24. /*              - do_delline (loesche eine Zeile)               */
  25. /*              - do_join (Zeilenverknuepfung ausfuehren)       */
  26. /*              - do_goto (Springe bestimmte Zeile an)          */
  27. /*              - do_ende (beende Editor)                       */
  28. /*              - ex_load (Loadfile ausführen)                  */
  29. /*              - do_endemit (beende Editor mit Load-File)      */
  30. /*              - quit (verlasse Editor)                        */
  31. /*              - quitmit (verlasse Editor mit Load-File)       */
  32. /****************************************************************/
  33.  
  34. #ifdef OS2
  35. #define INCL_DOSPROCESS
  36. #include <os2.h>
  37. #else
  38. extern long old_int;
  39. #endif
  40.  
  41. #include "defs.h"
  42. #include <process.h>
  43.  
  44. extern char backupflag,highblockflag,clear_buff,bufflag;
  45. extern int schreib_file(),to_shell();
  46. extern short int letter,lastcode,aktcode,taste();
  47. extern int save_delline(),rest_delline();
  48. extern int tst_overlap();
  49. extern void do_find(),do_replace(),do_repfr();
  50. extern char bufflag,*loadfile,*mktemp();
  51. extern bzeil_typ *save_normal(),*save_rechteck();
  52. extern block_typ global_block,*dup_block();
  53. extern puff_typ macro[],puff_feld[];
  54. extern int ks_index;
  55. extern short int *keystack,*e_keystack,newwgetch();
  56. extern WINDOW *status;
  57. extern marker_typ marker[];
  58. #ifdef MOUSE
  59. #ifdef OS2
  60. extern int mouse_handle;
  61. extern char mouse_active;
  62. extern TID mouse_ThreadID;
  63. #endif
  64. #endif
  65.  
  66. /* *** interne Daten und Initialisierung *** */
  67. void do_join();
  68. void do_up();
  69. void do_eol();
  70. extern char *on_off[], /* Hilfstexte */
  71.                /* fuer Togglen der globalen Flags */
  72.         helpflag;  /* Flag: Hilfstexte anzeigen       */
  73.  
  74. /*****************************************************************************
  75. *
  76. *  Funktion       Gehe zum Textbeginn (do_textbeginn)
  77. *  --------
  78. *
  79. *  Beschreibung : Der Cursor wird in die erste Textzeile bewegt.
  80. *
  81. *****************************************************************************/
  82.  
  83. void do_textbeginn()
  84. {
  85.   akt_winp->lastline = akt_winp->textline;  /* Cursorposition als letzte */
  86.   akt_winp->lastcol  = akt_winp->screencol; /* Position merken */
  87.   textbeginn();          /* Cursor intern an Textanfang positionieren */
  88.   akt_winp->ws_line = 0; /* Erste Zeile wird erste sichtbare Zeile */
  89.   show_win(W_AKT);           /* Text im Fenster neu anzeigen     */
  90. }
  91.  
  92. /*****************************************************************************
  93. *
  94. *  Funktion       Cursor an Textende (do_eot)
  95. *  --------
  96. *
  97. *  Beschreibung : Der Cursor wird an das Textende bewegt.
  98. *
  99. *****************************************************************************/
  100.  
  101. void do_eot()
  102. {
  103.   akt_winp->lastline = akt_winp->textline;  /* Cursorposition als letzte */
  104.   akt_winp->lastcol  = akt_winp->screencol; /* Position merken */
  105.   textende();  /* Cursor intern ans Textende setzen */
  106.   /* Erste Zeile wird die Zeile, die eine halbe Bildschirmlaenge ueber */
  107.   /* dem Textende liegt. Ist das Ergebnis kleiner 0 (zu wenig Zeilen), */
  108.   /* wird die erste Textzeile erste sichtbare Zeile. */
  109.   if((akt_winp->ws_line = akt_winp->maxline - akt_winp->dy/2) < 0)
  110.     akt_winp->ws_line = 0;
  111.   show_win(W_AKT); /* Fensterinhalt neu darstellen */
  112. }
  113.  
  114. /*****************************************************************************
  115. *
  116. *  Funktion       loesche bis Zeilenende (do_deleol)
  117. *  --------
  118. *
  119. *  Beschreibung : Mit der aktuellen Cursorposition beginnend, wird der Rest
  120. *                 der Zeile geloescht.
  121. *
  122. *****************************************************************************/
  123.  
  124. void do_deleol()
  125. {
  126.   if (delete_eol())  /* Zeileninhalt bis zum Zeilenende loeschen */
  127.   { /* hat das geklappt, wird die Zeile neu angezeigt */
  128.     lineout(akt_winp->textline-akt_winp->ws_line);
  129.     setz_cursor(W_AKT);  /* und der Cursor auf seine richtige Position gesetzt */
  130.   }
  131. }
  132.  
  133. /*****************************************************************************
  134. *
  135. *  Funktion       loesche Wort, auf dem der Cursor steht (do_del_word)
  136. *  --------
  137. *
  138. *  Beschreibung : Das Wort, auf dem der Cursor steht, wird geloescht.
  139. *
  140. *****************************************************************************/
  141.  
  142. void do_del_word()
  143. {
  144.   if (is_last()) /* an oder hinter Zeilenende ? */
  145.     do_join();   /* Dann nächste Zeile ranziehen */
  146.   else
  147.     if (delete_word())  /* Wort in Textstruktur loeschen */ 
  148.     { /* hat das geklappt, Zeile neu anzeigen */
  149.       lineout(akt_winp->textline-akt_winp->ws_line);
  150.       setz_cursor(W_AKT); /* und Cursor auf seine richtige Position setzen */
  151.     }
  152. }
  153.  
  154. /*****************************************************************************
  155. *
  156. *  Funktion       Wort links (do_wleft)
  157. *  --------
  158. *
  159. *  Beschreibung : Der Cursor wird um ein Wort nach links bewegt..
  160. *
  161. *****************************************************************************/
  162.  
  163. void do_wleft()
  164. {
  165.   if (word_left())    /* Cursor ein Wort nach links */
  166.   {
  167.     if (akt_winp->screencol < akt_winp->ws_col) /* klappte das, und steht der */
  168.     /* Cursor nun links vom Bildschirm, muss das Fenster angepasst werden. */
  169.     {
  170.       akt_winp->ws_col = akt_winp->screencol; /* Aktuelle Spalte wird erste */
  171.       sw_ohne_refresh(W_AKT); /* Fensterinhalt wird neu angezeigt */
  172.     }
  173.   }
  174.   else
  175.   {
  176.      do_up();
  177.      do_eol();
  178.   }
  179.   setz_cursor(W_AKT);  /* Cursor auf seine richtige Position setzen */
  180. }
  181.  
  182. /*****************************************************************************
  183. *
  184. *  Funktion       Wort rechts (do_wright)
  185. *  --------
  186. *
  187. *  Beschreibung : Der Cursor wird um ein Wort nach rechts bewegt.
  188. *
  189. *****************************************************************************/
  190.  
  191. void do_wright()
  192. {
  193.   if (word_right() /* Cursor intern um ein Wort nach rechts bewegen */
  194.   && akt_winp->screencol >= akt_winp->ws_col + akt_winp->dx)
  195.   /* klappte das, und steht der Cursor dadurch rechts vom Bildschirm, */
  196.   /* so muss der Fensterinhalt angepasst werden */
  197.   {
  198.     /* Aktuelle Spalte wird zur letzten sichtbaren */
  199.     akt_winp->ws_col = akt_winp->screencol - akt_winp->dx + 1;
  200.     sw_ohne_refresh(W_AKT);  /* Fensterinhalt neu darstellen */
  201.   }
  202.   setz_cursor(W_AKT);  /* Cursor an seine richtige Position setzen */
  203. }
  204.  
  205. /*****************************************************************************
  206. *
  207. *  Funktion       fuehre Move nach rechts aus (do_right)
  208. *  --------
  209. *
  210. *  Beschreibung : Der Cursor wird intern um ein Zeichen nach rechts bewegt.
  211. *                 Bewegt sich dabei der Cursor aus dem Fenster, so wird
  212. *                 das Fenster gescrollt.
  213. *
  214. *****************************************************************************/
  215.  
  216. void do_right()
  217. {
  218.   /* *** interne Daten *** */
  219.   register int hilf,  /* Zum Einlesen einer Tastenkombination */
  220.            i=0;   /* Zaehler, um wieviele Spalten gescrollt werden muss */
  221.  
  222.   nodelay (akt_winp->winp,TRUE); /* taste soll -1 bei nichtgedrueckter */
  223.   do                             /* Taste liefern */
  224.     if (right()  /* Wenn Cursor nach rechts bewegt werden konnte und */
  225.     && akt_winp->screencol >= akt_winp->ws_col+akt_winp->dx)
  226.       i++; /* Rand ueberschritten wurde, dann Scrollzaehler erhoehen */
  227.   while ((hilf=taste(akt_winp->winp)) == aktcode); /* Naechste Tastenkom- */
  228.   /* bination lesen. Falls gleich der letzten, Aktion wiederholen */
  229.   lastcode = hilf; /* letzte Tastenkombination merken */
  230.   nodelay (akt_winp->winp,FALSE); /* taste soll wieder auf Tastendruck warten */
  231.   if(i>1)   /* Wenn um mehr als eine Spalte gescrollt werden soll, ist es */
  232.   { /* guenstiger, den gesamten Fensterinhalt neu zu zeigen. */
  233.     akt_winp->ws_col+=i; /* Fensterinhalt um i Spalten nach links */
  234.     sw_ohne_refresh(W_AKT);   /* Fensterinhalt neu anzeigen */
  235.   }
  236.   else if (i==1)
  237.     text_left(); /* Sonst Inhalt mit text_left um 1 nach links bewegen */
  238.   setz_cursor(W_AKT); /* Cursor an seine richtige Position setzen */
  239. }
  240.  
  241. /*****************************************************************************
  242. *
  243. *  Funktion       fuehre Move nach links aus (do_left)
  244. *  --------
  245. *
  246. *  Beschreibung : Der Cursor wird intern um ein Zeichen nach links bewegt.
  247. *                 Bewegt sich dabei der Cursor aus dem Fenster, so wird
  248. *                 das Fenster gescrollt.
  249. *                 Befand sich der Cursor in der ersten Spalte, so wird
  250. *                 er um eine Zeile nach oben und dann zum Ende dieser Zeile
  251. *                 bewegt.
  252. *
  253. *****************************************************************************/
  254.  
  255. void do_left()
  256. {
  257.   /* *** interne Daten *** */
  258.   register int hilf,  /* Zum Einlesen einer Tastenkombination */
  259.            i=0,   /* Zaehler, um wieviele Spalten gescrollt werden muss */
  260.            j=0;   /* Zaehler, um wieviele Zeilen gescrollt werden muss */ 
  261.   char redrawn=FALSE, /* Flag, ob Fenster schon neu gezeichnet wurde */
  262.        must_redraw=FALSE; /* Flag, ob auf jeden Fall neu gezeichnet werden muß */
  263.  
  264.   nodelay (akt_winp->winp,TRUE); /* Funktion taste soll /1 liefern, */
  265.   do                             /* Falls keine Taste gedrueckt ist */
  266.     /* konnte der Cursor nach links bewegt werden und geriet er */
  267.     /* dadurch ausserhalb des Bildschirms, wird der Scrollzaehler erhoeht. */
  268.     if (left())
  269.     {
  270.       if (akt_winp->screencol < akt_winp->ws_col-i)
  271.     i++;
  272.     }
  273.     else  /* Man stand am Zeilenanfang, also eine Zeile hoch und ans Ende */
  274.       if (up())
  275.       {
  276.     if (akt_winp->textline < akt_winp->ws_line)
  277.       j++;
  278.     eol();
  279.     /* Sprung ans Zeilenende könnte Scrolling nötig machen */
  280.     if (akt_winp->screencol >= akt_winp->ws_col-i+akt_winp->dx)
  281.     {
  282.       must_redraw = TRUE;
  283.       akt_winp->ws_col = akt_winp->screencol - akt_winp->dx + 1;
  284.       i = 0; /* Weite für horizontales Scrolling zurücksetzen */
  285.     }
  286.       }
  287.   while ((hilf=taste(akt_winp->winp)) == aktcode); /* Naechste Tasten- */
  288.   /* kombination einlesen. Ist die gleich der letzten, Aktion wiederholen */
  289.   lastcode = hilf; /* Letzte Tastenkombination merken */
  290.   nodelay (akt_winp->winp,FALSE); /* Funktion Taste soll wieder auf Tasten- */
  291.                   /* druck warten */
  292.   if(i>1 || must_redraw) /* Muss um mehr als eine Spalte gescrollt werden, */
  293.   {       /* ist es guenstiger, den Fensterinhalt neu anzuzeigen */
  294.     akt_winp->ws_col-=i; /* Fensterinhalt um i Spalten nach rechts */
  295.     akt_winp->ws_line-=j; /* Fensterinhalt um j Zeilen nach unten */
  296.     sw_ohne_refresh(W_AKT);   /* Fensterinhalt neu anzeigen */
  297.     redrawn = TRUE;
  298.   }
  299.   else if (i==1) /* Muss nur um eine Spalte gescrollt werden, so kann das */
  300.     text_right(); /* mit der Funktion text_right geschehen. */
  301.   if (!redrawn)
  302.   {
  303.     akt_winp->ws_line-=j; /* Fensterinhalt um j Zeilen nach unten */
  304.     if(j>1) /* Muss um mehr als eine Zeile gescrollt werden, ist es */
  305.     {       /* guenstiger, den Fensterinhalt neu anzuzeigen */
  306.       sw_ohne_refresh(W_AKT);   /* Fensterinhalt neu anzeigen */
  307.     }
  308.     else if (j==1) /* Muss nur um eine Zeile gescrollt werden, so kann das */
  309.       text_down(0); /* mit der Funktion text_down geschehen. */
  310.   }
  311.   setz_cursor(W_AKT);  /* Cursor an seine richtige Position setzen */
  312. }
  313.  
  314. /*****************************************************************************
  315. *
  316. *  Funktion       fuehre Move nach oben aus (do_up)
  317. *  --------
  318. *
  319. *  Beschreibung : Der Cursor wird intern um eine Zeile nach oben bewegt.
  320. *                 Bewegt sich dabei der Cursor aus dem Fenster, so wird
  321. *                 das Fenster gescrollt.
  322. *
  323. *****************************************************************************/
  324.  
  325. void do_up()
  326. {
  327.   /* *** interne Daten und Initialisierung *** */
  328.   register int hilf,  /* Zum Einlesen einer Tastenkombination */
  329.            i=0;   /* Zaehler, wie oft gescrollt werden muss */
  330.  
  331.   nodelay (akt_winp->winp,TRUE); /* Funktion taste soll -1 liefern, wenn */
  332.   do                             /* keine Taste gedrueckt ist. */
  333.   {
  334.     if(up()  /* Wenn Cursor 1 Zeile nach oben bewegt werden konnte und */
  335.     && akt_winp->textline < akt_winp->ws_line) /* dadurch Cursor ausserhalb */
  336.       i++; /* des Fensters steht, Scrollzaehler erhoehen. */
  337.   }while ((hilf=taste(akt_winp->winp)) == aktcode); /* Naechste Tasten- */
  338.   /* kombination einlesen. Falls diese gleich der letzten, Aktion wiederholen */
  339.   lastcode = hilf; /* letzte Tastenkombination merken */
  340.   nodelay (akt_winp->winp,FALSE); /* Funktion taste soll wieder auf */
  341.                   /* Tastendruck warten */
  342.   akt_winp->ws_line -= i; /* Fensterstart anpassen */
  343.   if(i>1) /* Falls um mehr als eine Zeile gescrollt werden muss, */
  344.     sw_ohne_refresh(W_AKT); /* komplettes Fenster neu anzeigen */
  345.   else if(i == 1) /* Sonst kann das Scrollen mit der Funktion text_down */
  346.     text_down(0); /* erledigt werden */
  347.   setz_cursor(W_AKT);  /* Cursor an richtige Position setzen */
  348. }
  349.  
  350. /*****************************************************************************
  351. *
  352. *  Funktion       fuehre Move nach unten aus (do_down)
  353. *  --------
  354. *
  355. *  Beschreibung : Der Cursor wird intern um ein Zeichen nach unten bewegt.
  356. *                 Bewegt sich dabei der Cursor aus dem Fenster, so wird
  357. *                 das Fenster gescrollt.
  358. *
  359. *****************************************************************************/
  360.  
  361. void do_down()
  362. {
  363.   /* *** interne Daten und Initialisierung *** */
  364.   register int hilf,  /* Zum Einlesen einer Tastenkombination */
  365.            i=0;   /* Zaehler, wie weit gescrollt werden muss */
  366.  
  367.   nodelay (akt_winp->winp,TRUE); /* Funktion taste soll -1 liefern, falls */
  368.   do                             /* keine Taste gedrueckt ist.            */
  369.   {
  370.     if(down() /* Falls Cursor um eine Zeile nach unten bewegt werden konnte */
  371.     && akt_winp->textline >= akt_winp->ws_line+akt_winp->dy) /* und Cursor */
  372.       i++; /* dadurch Fenster verlaesst, Scrollzaehler erhoehen */
  373.   }while ((hilf=taste(akt_winp->winp)) == aktcode); /* Tastenkombination */
  374.   /* einlesen. Falls diese gleich der letzten, Aktion wiederholen */
  375.   lastcode = hilf;  /* Letzte Tastenkombination merken */
  376.   nodelay (akt_winp->winp,FALSE); /* Funktion taste soll wieder auf Tasten- */
  377.                   /* druck warten */
  378.   akt_winp->ws_line += i; /* Fensterinhalt um i Zeilen nach oben */
  379.   if(i>1)  /* Falls mehr als eine Zeile gescrollt werden muss, */
  380.     sw_ohne_refresh(W_AKT); /* ganzes Fenster neu zeichnen */
  381.   else
  382.     if(i == 1)         /* Sonst Scrolling mit Funktion text_up erledigen */
  383.       text_up(0);
  384.   setz_cursor(W_AKT);       /* Cursor an richtige Position setzen */
  385. }
  386.  
  387. /*****************************************************************************
  388. *
  389. *  Funktion       Tablaenge setzen (do_settab)
  390. *  --------
  391. *
  392. *  Beschreibung : Die Tablaenge wird neu eingestellt. Ist die Eingabe leer,
  393. *                 so wird die Tablaenge nicht veraendert.
  394. *
  395. *****************************************************************************/
  396.  
  397. void do_settab()
  398. {
  399.   /* *** interne Daten *** */
  400.   char dummy[100],  /* String fuer Ausgabeaufbereitung */
  401.        num_str[6];  /* String fuer Eingabe */
  402.   int  num;         /* Ergebnis der Umwandlung von num_str in integer */
  403.  
  404.   sprintf(dummy,PROMPT_TABLEN,akt_winp->tablen);
  405.   print_stat(dummy);            /* Prompt ausgeben */
  406.   read_stat(num_str,6,GS_NUM);  /* Eingabe lesen (nur Ziffern (GS_NUM)) */
  407.   clear_stat();                 /* Statuszeile loeschen */
  408.   if((num = atoi(num_str)) > 0) /* Eingabe in Integer umwandeln */
  409.     akt_winp->tablen = num;     /* Falls Wert groesser 0, als neue Tab- */
  410.   setz_cursor(W_AKT);                /* laenge merken, Cursor positionieren */
  411. }
  412.  
  413. /*****************************************************************************
  414. *
  415. *  Funktion       eine Tabposition zurueckspringen (do_backtab)
  416. *  --------
  417. *
  418. *  Beschreibung : Abhaengig vom Autoindent- und Insertmodus wird auf den
  419. *                 Backtab-key reagiert:
  420. *                       AUTOINDENT: Tab richtet sich nach darueberliegender
  421. *                                   Zeile.
  422. *                       INSERT:     feste Tabweite zurueckspringen
  423. *
  424. *****************************************************************************/
  425.  
  426. void do_backtab()
  427. {
  428.   /* *** interne Daten *** */
  429.   register int diff,  /* Entfernung zur naechsten Tabgrenze (nur benutzt, */
  430.               /* falls Autoindent abgeschaltet) */
  431.            nsc;   /* Spaltennummer der Tabgrenze links des Cursors */
  432.  
  433.   if(akt_winp->autoindflag && up()) /* Falls Autoindent eingeschaltet, und */
  434.   { /* Cursor eine Zeile nach oben bewegt werden konnte, */
  435.     /* naechste Tabgrenze links vom Cursor nsc zuweisen. */
  436.     if ((nsc = akt_winp->tablen * ((akt_winp->screencol-1)/akt_winp->tablen))
  437.     >= fastll (akt_winp->alinep->text)) /* Ist nsc hinter Zeilenende, */
  438.       akt_winp->screencol = nsc; /* screencol auf nsc setzen. */
  439.     else                  /* Ist nsc in der Zeile, dann ein Wort nach links */
  440.       word_left();
  441.     down();   /* Anschliessed in die urspruengliche Zeile zurueckkehren */
  442.   }
  443.   else  /* Falls Autoindent ausgeschaltet ist, Entfernung zur naechsten */
  444.     /* links vom Cursor gelegenen Tab-Grenze berechnen */
  445.     for(diff = (akt_winp->screencol-1)%akt_winp->tablen + 1;diff>0;diff--)
  446.       left(); /* So oft dann den Cursor nach links bewegen */
  447.  
  448.   if(akt_winp->ws_col > akt_winp->screencol) /* Falls Cursor dadurch */
  449.   {                                          /* links vom Fenster, */
  450.     akt_winp->ws_col = akt_winp->screencol;  /* Aktuelle Spalte zur ersten */
  451.     sw_ohne_refresh(W_AKT); /* sichtbaren Spalte machen, Fensterinhalt neu zeigen */
  452.   }
  453.   setz_cursor(W_AKT); /* Cursor an richtige Position setzen */
  454. }
  455.  
  456. /*****************************************************************************
  457. *
  458. *  Funktion       Tab einfuegen (do_tab)
  459. *  --------
  460. *
  461. *  Beschreibung : Abhaengig vom Autoindent- und Insertmodus wird auf den
  462. *                 Tab-key reagiert:
  463. *                       AUTOINDENT: Tab richtet sich nach darueberliegender
  464. *                                   Zeile.
  465. *                       INSERT:     Spaces werden eingefuegt.
  466. *                 Achtung: Es wird vorausgesetzt, daß word_right() nur
  467. *                          vorwaerts geht, die Distanz zur aktuellen Spalte
  468. *                          also immer positiv ist!
  469. *
  470. *****************************************************************************/
  471.  
  472. void do_tab()
  473. {
  474.   /* *** interne Daten und Initialisierung *** */
  475.   register int old_sc,  /* Zwischenspeicher fuer Cursorspalte */
  476.            dsc = 0, /* Entfernung, die durch Tab geskipt wird */
  477.            anz_ins; /* Anzahl der eingefuegten Blanks */
  478.   char         scrolled = FALSE; /* Flag, ob enter_char scrollte */
  479.  
  480.   if(akt_winp->autoindflag && up()) /* Bei Autoindent eine Zeile hoch */
  481.   {
  482.     old_sc = akt_winp->screencol; /* falls das klappt, Spalte merken */
  483.     word_right();                 /* ein Wort nach rechts */
  484.     down();                       /* und wieder in alte Zeile */
  485.     dsc = akt_winp->screencol - old_sc; /* "Streckenlaenge" merken */
  486.     akt_winp->screencol = old_sc; /* Screencol wieder auf alten Wert */
  487.   }
  488.   /* falls normaler Tab oder bei autoindent nicht weitergegangen werden */
  489.   if(!dsc) /* konnte, Entfernung zur naechsten festen Tabgrenze berechnen */
  490.     dsc = akt_winp->tablen - akt_winp->screencol%akt_winp->tablen;
  491.   if(akt_winp->insflag) /* Falls Insert-Mode aktiv, dsc Blanks einfuegen */
  492.   {
  493.     if((anz_ins = insert(dsc)) < dsc) /* Falls weniger als dsc chars ein- */
  494.     { /* gefuegt werden konnten, eingefuegte Zeichen loeschen */
  495.       mdelete(anz_ins);
  496.       print_err("Zeile zu lang! ");  /* und Fehlermeldung ausgeben */
  497.       return;
  498.     }
  499.     else
  500.       while(anz_ins--)   /* Eingefuegte Zeichen mit Blanks belegen */
  501.     enter_char(' ', &scrolled, scrolled?PUT:INSERT, FALSE);
  502.   }
  503.   else  /* Falls im Overwrite-Modus, dsc Zeichen nach rechts bewegen */
  504.     while(dsc--)
  505.       right();
  506.   if(akt_winp->ws_col + akt_winp->dx <= akt_winp->screencol)
  507.   { /* Falls Cursor ausserhalb des Fensters, Fensterinhalt anpassen */
  508.     /* Aktuelle Spalte soll in der Mitte des Fensters stehen */
  509.     akt_winp->ws_col = akt_winp->screencol - akt_winp->dx/2;
  510.     sw_ohne_refresh(W_AKT); /* Anschliessend Fensterinhalt neu anzeigen */
  511.   }
  512.   setz_cursor(W_AKT);  /* Cursor an seine Position plazieren */
  513. }
  514.  
  515. /*****************************************************************************
  516. *
  517. *  Funktion       Page Up ausfuehren (do_pgup)
  518. *  --------
  519. *
  520. *  Beschreibung : Der interne Cursor wird um eine Seite hochbewegt. Dann
  521. *                 wird die Fensterposition angepasst und der Fensterinhalt
  522. *                 erneut dargestellt.
  523. *
  524. *****************************************************************************/
  525.  
  526. void do_pgup()
  527. {
  528.   /* *** interne Daten *** */
  529.   register int hilf;  /* Zum Einlesen einer Tastenkombination */
  530.  
  531.   nodelay (akt_winp->winp,TRUE);  /* Funktion taste soll -1 liefern, */
  532.   do                              /* falls keine Taste gedrueckt ist */
  533.     if((akt_winp->ws_line -= screen_up()) < 0) /* Neuen Fensterstart */
  534.       akt_winp->ws_line = 0;                   /* berechnen          */
  535.   while ((hilf=taste(akt_winp->winp)) == aktcode); /* Naechste Tasten- */
  536.   /* kombination lesen. Ist sie gleich der letzten, Aktion wiederholen */
  537.   lastcode = hilf; /* zuletzt gelesene Tastenkombination merken */
  538.   nodelay (akt_winp->winp,FALSE); /* Fkt. Taste soll auf Taste warten */
  539.   show_win(W_AKT);                 /* Text im Fenster neu anzeigen     */
  540. }
  541.  
  542. /*****************************************************************************
  543. *
  544. *  Funktion       Page Down ausfuehren (do_pgdn)
  545. *  --------
  546. *
  547. *  Beschreibung : Der interne Cursor wird um eine Seite nach unten bewegt.
  548. *                 Dann wird die Fensterposition angepasst und der
  549. *                 Fensterinhalt erneut dargestellt. Steht der Cursor in der
  550. *                 letzten Textzeile, so wird diese in die Bildschirmmitte
  551. *                 plaziert.
  552. *
  553. *****************************************************************************/
  554.  
  555. void do_pgdn()
  556. {
  557.   /* *** interne Daten *** */
  558.   register int hilf;  /* Zum Einlesen einer Tastenkombination */
  559.  
  560.   nodelay (akt_winp->winp,TRUE);  /* Funktion taste soll -1 liefern, */
  561.   do                              /* falls keine Taste gedrueckt ist */
  562.     akt_winp->ws_line += screen_down(); /* Cursor um eine Seite nach unten */
  563.                       /* bewegen und Fensterstart anpassen */
  564.   while ((hilf=taste(akt_winp->winp)) == aktcode); /* Naechste Tasten- */
  565.   /* kombinationo einlesen. Falls gleich der letzten, Aktion wiederholen */
  566.   lastcode = hilf;                    /* letzte Tastenkombination merken */
  567.   nodelay (akt_winp->winp,FALSE); /* Fkt. taste soll auf Taste warten */
  568.   show_win(W_AKT);                  /* Text im Fenster neu anzeigen     */
  569. }
  570.  
  571. /*****************************************************************************
  572. *
  573. *  Funktion       leere Zeile vor aktueller einfuegen (do_open)
  574. *  --------
  575. *
  576. *  Beschreibung : vor der aktuellen Zeile wird eine Zeile eingefuegt, die dann
  577. *                 zur aktuellen wird.
  578. *
  579. *****************************************************************************/
  580.  
  581. void do_open()
  582. {
  583.   /* *** interne Daten *** */
  584.   int old_sc;  /* Zwischenspeicher fuer alte Cursorspalte          */
  585.  
  586.   if(akt_winp->maxline < MAX_ANZ_LINES-1) /* Nur neue Zeile einfuegen, */
  587.   {      /* wenn dadurch maximale Zeilenzahl nicht ueberschritten wird */
  588.     check_buff();  /* evtl. noch im Puffer befindliche Daten in Text kopieren */
  589.     if(akt_winp->maxline >= 0)   /* Enthaelt Text mindestens eine Zeile ? */
  590.     {                     /* Ja, dann muss auf Autoindent geachtet werden */
  591.       akt_winp->alinep = akt_winp->alinep->prev; /* da up nicht vor die erste */
  592.       akt_winp->textline--; /* Zeile geht, muss man "zu Fuss" eine Zeile hoch.    */
  593.       old_sc = akt_winp->screencol;    /* Zeile wird dahinter eingefuegt, */
  594.       akt_winp->screencol = MAXLENGTH; /* also screencol aufs Ende        */
  595.       koppel_line(ADAPT_COORS);  /* Zeile in Textstruktur einfuegen      */
  596.       if (akt_winp->autoindflag) /* Bei Autoindent stellt man sich ueber */
  597.     indent_line(FALSE);           /* den Anfang der Zeile darunter   */
  598.       else
  599.     akt_winp->screencol = old_sc;
  600.  
  601.       if(akt_winp->screencol < akt_winp->ws_col /* Wenn Cursor links oder */
  602.       || akt_winp->ws_col+akt_winp->dx < akt_winp->screencol) /* rechts   */
  603.       { /* ausserhalb des Fensters steht, wird die aktuelle Spalte zur    */
  604.     akt_winp->ws_col = akt_winp->screencol; /* ersten sichtbaren      */
  605.     sw_ohne_refresh(W_AKT);  /* Fensterinhalt neu anzeigen                 */
  606.       }
  607.       else /* Steht Cursor innerhalb des Fensters, wird mit text_down eine */
  608.     text_down(akt_winp->textline - akt_winp->ws_line); /* Zeile auf    */
  609.     }   /* dem Bildschirm eingefuegt */
  610.     else  /* War der Text leer, wird lediglich eine neue Zeile erzeugt */
  611.       koppel_line(IGNORE_COORS); /* Marker und lastpos sind im leeren Text egal */
  612.     setz_cursor(W_AKT);      /* Cursor an richtige Position setzen */
  613.   }
  614.   else                /* Wuerde der Text durch eine weitere Zeile zu lang, */
  615.     print_err(T_SIZE_ERRTEXT);     /* Fehlermeldung ausgeben */
  616. }
  617.  
  618. /*****************************************************************************
  619. *
  620. *  Funktion       leere Zeile hinter aktueller einfuegen (do_hopen)
  621. *  --------
  622. *
  623. *  Beschreibung : hinter der aktuellen Zeile wird eine Zeile eingefuegt, die dann
  624. *                 zur aktuellen wird.
  625. *
  626. *****************************************************************************/
  627.  
  628. void do_hopen()
  629. {
  630.   /* *** interne Daten und Initialisierung *** */
  631.   int hilfs  = akt_winp->shellflag, /* Zwischenspeicher fuer shellflag */
  632.       hilfi  = akt_winp->insflag,   /* Zwischenspeicher fuer insflag   */
  633.       old_sc = akt_winp->screencol; /* Zwischenspeicher fuer screencol */
  634.  
  635.   check_buff(); /* evtl. noch im Puffer stehende Daten in Text uebertragen */
  636.   akt_winp->screencol = fastll(akt_winp->alinep->text); /* Ans Zeilenende */
  637.   akt_winp->insflag = TRUE; /* so wird auf jeden Fall neue Zeile eingefuegt */
  638.   akt_winp->shellflag = FALSE;    /* keine Zeile an Shell schicken */
  639.   if(!do_newline())    /* Zeile einfuegen und testen, ob das geklappt hat */
  640.     akt_winp->screencol = old_sc; /* Falls nein, Cursor wieder in alte Spalte */
  641.   akt_winp->insflag = hilfi;      /* Insflag und shellflag restaurieren */
  642.   akt_winp->shellflag = hilfs;
  643.   setz_cursor(W_AKT);         /* Damit Flags in Kopf richtig angezeigt werden */
  644. }
  645.  
  646. /*****************************************************************************
  647. *
  648. *  Funktion       newline ausfuehren (do_newline)
  649. *  --------
  650. *
  651. *  Ergebnis     :
  652. *                   Typ          : int
  653. *                   Wertebereich : TRUE,FALSE
  654. *                   Bedeutung    : TRUE: Es konnte noch eine Zeile eingefuegt
  655. *                                  werden.
  656. *
  657. *  Beschreibung : Die aktuelle Zeile wird evtl. gesplittet und in der
  658. *                 Textstruktur eine neue Zeile angelegt. Falls dabei der
  659. *                 Cursor aus dem Fenster laeuft, wird der Bildschirm ge-
  660. *                 scrollt.
  661. *
  662. *****************************************************************************/
  663.  
  664. int do_newline()
  665. {
  666.   /* *** interne Daten und Initialisierung *** */
  667.   char *cmd,           /* An SHELL zu uebergebende Kommandozeile */
  668.        swflag = FALSE; /* Zeigt an, ob Fensterinhalt neu gezeigt werden muss */
  669.   int  old_sc;         /* Zwischenspeicher fuer Cursorspalte */
  670.  
  671.   if (akt_winp->insflag) /* Falls im Insert-Mode, dann */
  672.     if (new_line())      /* Zeile einfuegen und testen, ob das geklappt hat */
  673.     { /* Testen, ob Fenster gescrollt werden muss */
  674.       if (akt_winp->textline-akt_winp->ws_line >= akt_winp->dy)
  675.       {
  676.     akt_winp->ws_line++; /* wenn ja, Nummer der ersten Zeile + 1 */
  677.     text_up(0);          /* und Fensterinhalt scrollen */
  678.       }
  679.       else /* Wenn nicht gescrollt werden muss, eine Zeile einfuegen */
  680.     text_down(akt_winp->textline-akt_winp->ws_line);
  681.       if(akt_winp->autoindflag)    /* Wenn Autoindent aktiv ist,       */
  682.     indent_line(TRUE);         /* neue Zeile korrekt einruecken    */
  683.                    /* nur die Zeile neu gezeigt werden */
  684.       /* Dann wird getestet, ob der Cursor */
  685.       if(akt_winp->ws_col + akt_winp->dx <= akt_winp->screencol /* rechts */
  686.       || akt_winp->screencol < akt_winp->ws_col) /* oder links vom */
  687.       {                                          /* Fenster steht  */
  688.     akt_winp->ws_col = akt_winp->screencol;  /* Wenn ja, dann wird */
  689.     swflag = TRUE; /* aktuelle Spalte zur ersten sichtbaren, und   */
  690.       }            /* das Fenster wird als neu zu zeichnend markiert   */
  691.       else         /* Wenn der Cursor innerhalb des Fensters blieb,    */
  692.     lineout(akt_winp->textline - akt_winp->ws_line); /* dann muss  */
  693.     }                          /* die neue Textzeile angezeigt werden  */
  694.     else       /* Wenn keine neue Zeile eingefuegt werden konnte, dann */
  695.     {
  696.       print_err (T_SIZE_ERRTEXT); /* Fehlermeldung ausgeben */
  697.       return (FALSE);             /* und Funktion abbrechen */
  698.     }
  699.   else                  /* OVERWRITE-modus */
  700.   {
  701.     if (!down())        /* Cursor eine Zeile nach unten bewegen */
  702.       return(FALSE);    /* Klappte das nicht, Funktion abbrechen */
  703.     else                /* Klappte es, Cursor an Zeilenanfang stellen */
  704.       bol();
  705.     if (akt_winp->textline-akt_winp->ws_line >= akt_winp->dy) /* Testen, */
  706.     { /* ob Cursor nach unten aus dem Fenster gegangen ist */
  707.       akt_winp->ws_line++; /* Wenn ja, Fensterstart anpassen */
  708.       text_up(0);          /* und Fensterinhalt scrollen */
  709.     }
  710.     /* Wenn Cursor links vom Rand steht, dann muss die */
  711.     /* erste Spalte sichtbar sein                      */
  712.     if(akt_winp->ws_col)
  713.     { /* Ist das nicht so, wird der Fensterinhalt als neu zu zeichnend   */
  714.       swflag = TRUE;        /* markiert und Spalte 0 als erste sichtbare */
  715.       akt_winp->ws_col = 0; /* markiert. */
  716.     }
  717.   }
  718.  
  719.      /*** Testen, ob Zeile an SHELL uebergeben werden muss *** */
  720.  
  721.   if(akt_winp->shellflag && (cmd = akt_winp->alinep->prev->text))
  722.   { /* Das ist der Fall, wenn shellflag gesetzt ist und die aufgespaltene */
  723.     old_sc = akt_winp->screencol; /* Zeile nicht leer ist. Dann wird die  */
  724.     up();  /* Cursorspalte gemerkt und der Cursor eine Zeile hochbewegt.  */
  725.     if(akt_winp->maxline < MAX_ANZ_LINES-1) /* Platz fuer weitere Zeile ? */
  726.     {
  727.       koppel_line(ADAPT_COORS);  /* Zeile einfuegen, so dass Shellausgabe */
  728.                  /* nicht mit evtl. Zeilenrest vermischt wird */
  729.       if(to_shell(cmd))   /* nur wenn auch etwas eingefuegt werden konnte */
  730.       {                    /* eine Zeile nach Ende der Ausgabe anspringen */
  731.     gotox(akt_winp->block.e_line+1); /* Steht Cursor anschliessend    */
  732.     /* unter dem Fenster, Fensterposition anpassen */
  733.     if(akt_winp->textline >= akt_winp->ws_line + akt_winp->dy)
  734.       akt_winp->ws_line = akt_winp->textline - akt_winp->dy/2;
  735.     swflag = TRUE;        /* veraenderter Bildschirminhalt */
  736.       }
  737.       else                     /* Wenn keine Shellausgabe vorhanden ist, */
  738.     del_line(ADAPT_COORS); /* eingefuegte Leerzeile wieder loeschen  */
  739.     }
  740.     else                       /* konnte keine Zeile mehr einfuegen */
  741.       pe_or(T_SIZE_ERRTEXT);   /* also Fehlermeldung ausgeben */
  742.     akt_winp->screencol = old_sc; /* Cursorspalte restaurieren */
  743.   }
  744.   if(swflag)            /* Wenn Fensterinhalt als zu restaurierend gekenn- */
  745.     sw_ohne_refresh(W_AKT);  /* zeichnet, Fensterinhalt neu anzeigen */
  746.   setz_cursor(W_AKT);        /* Cursor an richtige Position setzen */
  747.   return (TRUE);
  748. }
  749.  
  750. /*****************************************************************************
  751. *
  752. *  Funktion       loesche eine Zeile (do_delline)
  753. *  --------
  754. *
  755. *  Beschreibung : Die aktuelle Zeile wird aus der Textstruktur geloescht
  756. *                 und der Bildschirm aktualisiert.
  757. *
  758. *****************************************************************************/
  759.  
  760. void do_delline()
  761. {
  762.   /* *** interne Daten und Initialisierung *** */
  763.   register int i=0,  /* Zaehler fuer geloeschte Zeilen */
  764.            hilf, /* Zum Einlesen einer Tastenkombination */
  765.            ret;  /* Zwischenspeicher fuer Rueckgabewert von del_line */
  766.  
  767.   nodelay (akt_winp->winp,TRUE); /* Funktion taste soll -1 liefern, falls */
  768.   do                             /* keine Taste gedrueckt ist. */
  769.   {
  770.     save_delline();              /* zu loeschende Zeile abspeichern */
  771.     if((ret = del_line(ADAPT_COORS)) != NO_LINE_DEL) /* Zeile loeschen, */
  772.       i++;    /* Rueckgabewert von del_line merken und Zaehler anpassen */
  773.   }while ((hilf=taste(akt_winp->winp)) == aktcode); /* Naechste Tasten- */
  774.   /* kombination einlesen. Falls gleich der letzten, Aktion wiederholen */
  775.   lastcode = hilf; /* Zuletzt gelesene Tastenkombination merken */
  776.   nodelay (akt_winp->winp,FALSE); /* Fkt. taste soll auf Taste warten */
  777.  
  778.   if(i == 1 && ret == LAST_LINE_DEL) /* Wenn nur die letzte Zeile geloescht */
  779.   {  /* wurde, dann diese Zeile auf Bildschirm loeschen, Rahmen reparieren */
  780.     wmove(akt_winp->winp,akt_winp->maxline+2-akt_winp->ws_line,1);
  781.     wclrtoeol(akt_winp->winp);
  782.     mvwaddch(akt_winp->winp,akt_winp->maxline+2-akt_winp->ws_line,akt_winp->dx + 1,REST_CHAR);
  783.     setz_cursor(W_AKT);
  784.   }
  785.   if(i) /* Wenn mindestens eine Zeile geloescht wurde, testen ob Cursor */
  786.   {     /* nach oben aus dem Fenster gewandert ist.                     */
  787.     if(akt_winp->textline < akt_winp->ws_line) /* Wenn ja, dann warum ? */
  788.       if(akt_winp->textline == -1) /* Wenn wegen "Text leer", dann      */
  789.     akt_winp->ws_line = 0;     /* ws_line auf 0 setzen              */
  790.       else                         /* Sonst aktuelle Zeile zur ersten   */
  791.     akt_winp->ws_line = akt_winp->textline; /* sichtbaren machen    */
  792.     show_win(W_AKT); /* Anschliessend Fensterinhalt anzeigen                 */
  793.   }
  794.  
  795. /*****************************************************************************
  796. *
  797. *  Funktion       Zeilenverknuepfung ausfuehren (do_join)
  798. *  --------
  799. *
  800. *  Beschreibung : Mittels der Funktion join werden die aktuelle und die
  801. *                 nachfolgende Zeile verknuepft. Bei der Verknüpfung wird
  802. *                 zwischen dem ersten non-Whitespace der nachfolgenden Zeile
  803. *                 und dem letzten Zeichen der aktuellen Zeile genau ein
  804. *                 Space eingefügt. Falls bei diesen Aktionen ein Fehler
  805. *                 auftritt, wird gegebenfalls eine Fehlermeldung ausgegeben.
  806. *
  807. *****************************************************************************/ 
  808.  
  809. void do_join()
  810. {
  811.   /* *** interne Daten *** */
  812.   char first_of_2nd_is_blank,  /* Flag, ob nachfolgende Zeile mit WS beginnt */
  813.        second_is_empty,        /* Flag, ob nachfolgende Zeile leer ist       */
  814.        dw,                     /* Flag, ob Leerraum zu löschen ist           */
  815.        first_is_blank;         /* Flag, ob aktuelle Zeile leer ist           */
  816.  
  817.   if (akt_winp->maxline > 0      /* Geht nur, wenn mehr als eine Zeile */
  818.   && akt_winp->alinep->next != akt_winp->dummyp) /* und aktuelle Z. */
  819.   {                              /* nicht letzte Zeile ist */
  820.     second_is_empty = !akt_winp->alinep->next->text;
  821.     first_of_2nd_is_blank = (second_is_empty ||
  822.                  *(akt_winp->alinep->next->text) == ' ');
  823.     dw = (!second_is_empty && strlen(akt_winp->alinep->next->text) >= 2
  824.       && *(akt_winp->alinep->next->text+1) == ' ');
  825.     first_is_blank = !akt_winp->alinep->text;
  826.     do_eol();            /* Zunächst ein Zeichen rechts vom Zeilenende */
  827.     switch (join(ADAPT_COORS))   /* Verknuepfung ausfuehren, Ergebnis testen */
  828.     {
  829.       case J_TOOLONG : print_err(L_SIZE_ERRTEXT); /* Zeile wurde zu lang,    */
  830.                break;                     /* Meldung ausgeben        */
  831.       case J_OK      : if(first_of_2nd_is_blank   /* Falls nächste Zeile     */
  832.                && !second_is_empty)       /* nicht leer ist und      */
  833.                           /* mit einem Blank beginnt */
  834.                {
  835.              do_right();      /* ein Blank dazwischen lassen */
  836.              if (dw)
  837.                 do_del_word();   /* Text ranziehen */
  838.                }
  839.                else               /* Sonst Blank einfügen */
  840.                { /* geht gut, da bei join mindestens ein Zeichen
  841.                 Reserve. Aber nur einfügen, wenn erste Zeile 
  842.                 nicht leer war ! */
  843.              if (!first_is_blank)
  844.              {
  845.                insert(1);  /* Platz am Zeilenende läßt */
  846.                enter_char(' ', (char*) 0, akt_winp->insflag, FALSE);
  847.              }
  848.                }
  849.                show_win(W_AKT); /* Alles OK, Fensterinhalt neu anzeigen */
  850.     }
  851.   }
  852. }
  853.  
  854. /*****************************************************************************
  855. *
  856. *  Funktion       Springe bestimmte Zeile an (do_goto)
  857. *  --------
  858. *
  859. *  Beschreibung : Nach Einlesen einer Zeilennummer wird, falls moeglich,
  860. *                 die aktuelle Zeile entsprechend gesezt.
  861. *
  862. *****************************************************************************/
  863.  
  864. void do_goto()
  865. {
  866.   /* *** interne Daten *** */
  867.   char number[10]; /* String fuer einzulesende Zeilennummer */
  868.   int numi;        /* Eingelesene Zeilennummer als Integer  */
  869.  
  870.   print_stat(PROMPT_LINENUMB);
  871.   read_stat(number,9,GS_NUM);     /* Zeilennummer einlesen (nur Ziffern) */
  872.   clear_stat();                   /* Statuszeile wieder loeschen */
  873.  
  874.   /* String in int wandeln und Bereichspruefung durchfuehren */
  875.   if((numi = atoi(number)) > 0 && numi <= akt_winp->maxline+1)
  876.   { /* Wenn Zeilennummer im korrekten Bereich, dann */
  877.     akt_winp->lastline = akt_winp->textline; /* aktuelle Position als  */
  878.     akt_winp->lastcol = akt_winp->screencol; /* letzte Position merken */
  879.     gotox(numi-1);                     /* gewuenschte Zeile anspringen */
  880.     if((akt_winp->ws_line = numi-akt_winp->dy/2) < 0) /* Zeile in der Mitte */
  881.       akt_winp->ws_line = 0; /* plazieren. Falls das nicht geht, weil       */
  882.       /* Zeilennummer zu klein, ws_line entsprechend anpassen               */
  883.     sw_ohne_refresh(W_AKT);  /* Fensterinhalt neu anzeigen */
  884.   }
  885.   setz_cursor(W_AKT);        /* Cursor an richtige Position setzen */
  886. }
  887.  
  888. /*****************************************************************************
  889. *
  890. *  Funktion       beende editor (do_ende)
  891. *  --------
  892. *
  893. *  Beschreibung : Nach einer Rueckfrage wird der Editor evtl. beendet.
  894. *                 Nach dem letzten Speichern geaenderte Files werden ab-
  895. *                 gespeichert. Danach wird das Config-File geupdatet.
  896. *
  897. *****************************************************************************/
  898.  
  899. void do_ende()
  900. {
  901.   /* Meldung ausgeben und J/N-Abfrage vornehmen */
  902.   if(!did_anything_change() || ja_nein(PROMPT_WARNSAVE))
  903.     /* Will User wirklich beenden, alle geaenderten Dateien sichern */
  904.     if(save_all() || ja_nein(PROMPT_EXITANYWY)) /* Bei Fehler Abfrage */
  905.     { /* Wenn Speichern klappte, oder Abfrage mit J beantwortet wurde, */
  906.       write_config();  /* wird die Konfigurationsdatei gespeichert, */
  907.       alles_frei();    /* aller reservierter Speicher freigegeben   */
  908.       ende(0, TRUE);   /* und der Editor beendet.                   */
  909.     }
  910.   setz_cursor(W_AKT); /* Will der User doch nicht abbrechen, wird der Cursor */
  911. }                /* an seine korrekte Position gesetzt. */
  912.  
  913. /******************************************************************************
  914. *
  915. * Funktion     : Loadfile ausführen (ex_load)
  916. * --------------
  917. *
  918. * Beschreibung : Das in der globalen Variablen spezifizierte loadfile wird
  919. *                ausgeführt. Dazu wird der Inhalt der Datei in eine tempo-
  920. *                räre Datei kopiert (mit system("copy...")). An die temporäre
  921. *                Datei wird eine Zeile angehängt, die "exit" enthält.
  922. *                Dann wird command.com über spawnlp aufgerufen, als Parameter
  923. *                wird "<"+<Name der temporären Datei> übergeben. Die Shell
  924. *                liest also die Kommandos aus der temporären Datei und wird
  925. *                anschließend durch exit beendet. Anschließend wird die
  926. *                tempräre Datei gelöscht und der Return-Wert von spawnlp
  927. *                behandelt.
  928. *
  929. ******************************************************************************/
  930.  
  931. void ex_load()
  932. {
  933.   int sys_ret;      /* Rückgabewert der system-Funktion */
  934.   int ex_st;
  935.  
  936.   if(access(loadfile,4) == 0)  /* Lese-Zugriff auf Loadfile ? */
  937.   {
  938.     sys_ret = system(loadfile);
  939.     if(sys_ret == -1)
  940.       fprintf(stderr,NO_LOAD_ERRTEXT);  /* Falls system nicht klappte, */
  941.     ex_st=sys_ret;       /* Fehlermeldung ausgeben und ende */
  942.   }
  943.   else
  944.   {
  945.     fprintf(stderr,"Loadfile %s nicht gefunden !\n",loadfile);
  946.     ex_st=1;
  947.   }
  948. #ifdef MOUSE
  949. #ifdef OS2
  950.   mouse_active = FALSE;
  951.   DosWaitThread (&mouse_ThreadID, DCWW_WAIT);
  952. #else
  953.   set_mouse_int(0); /* Mausroutine maskieren */
  954. #endif
  955. #endif
  956. #ifndef OS2
  957.   *(long*)(27*4) = old_int; /* Vektor des Break-Interruptes restaurieren */
  958. #endif
  959.   exit (ex_st);
  960. }
  961.  
  962. /*****************************************************************************
  963. *
  964. *  Funktion       beende editor mit loadfile (do_endemit)
  965. *  --------
  966. *
  967. *  Beschreibung : Nach einer Rueckfrage wird der Editor evtl. beendet.
  968. *                 Nach dem letzten Speichern geaenderte Files werden ab-
  969. *                 gespeichert. Danach wird das Config-File geupdatet
  970. *                 und das Load-File ausgefuehrt.
  971. *
  972. *****************************************************************************/
  973.  
  974. void do_endemit()
  975. {
  976.   /* Funktion der Abfragen s.o. */
  977.   if(!did_anything_change() || ja_nein(PROMPT_WARNSAVE))
  978.     if(save_all() || ja_nein(PROMPT_EXITANYWY))
  979.     {
  980.       write_config();  /* Konfigurationsdatei abspeichern */
  981.       alles_frei();    /* Saemtlichen reservierten Speicherplatz freigeben */
  982.       clear();         /* Bildschirm loeschen */
  983.       refresh();
  984.       endwin();        /* Curses "abschalten" */
  985.       ex_load();       /* Loadfile ausführen, Programm wird beendet */
  986.     }
  987.   setz_cursor(W_AKT); /* Will User doch nicht beenden, Cursor wieder plazieren */
  988. }
  989.  
  990.  
  991. /*****************************************************************************
  992. *
  993. *  Funktion       verlasse editor (quit)
  994. *  --------
  995. *
  996. *  Beschreibung : Das Programm wird (nach Rueckfrage) beendet.
  997. *
  998. *****************************************************************************/
  999.  
  1000. void quit()
  1001. {
  1002.   if (!did_anything_change() || ja_nein (PROMPT_WARNQUIT))
  1003.   { /* Sicherheitsabfrage */
  1004.     write_config();  /* Wenn User wirklich beenden will, Config-Datei */
  1005.     alles_frei();    /* speicher, Speicherplatz freigeben, */
  1006.     ende(0, TRUE);   /* Editor beenden */
  1007.   }
  1008.   setz_cursor(W_AKT);     /* Falls doch nicht beendet werden soll, Cursor */
  1009. }                    /* wieder an richtige Position stellen */
  1010.  
  1011. /*****************************************************************************
  1012. *
  1013. *  Funktion       quit mit Ausfuehren des load-Files (quitmit)
  1014. *  --------
  1015. *
  1016. *  Beschreibung : Nach einer positiv beantworteten Rueckfrage wird die
  1017. *                 Config-Datei gespeichert und der Editor mit dem
  1018. *                 Load-File ueberlagert.
  1019. *
  1020. *****************************************************************************/
  1021.  
  1022. void quitmit()
  1023. {
  1024.   if (!did_anything_change() || ja_nein (PROMPT_WARNQUIT))
  1025.   { /* Sicherheitsabfrage */
  1026.     write_config(); /* Falls mit J geantwortet wurde, Config-Datei */
  1027.     alles_frei();   /* speichern, Speicherplatz freigeben, */
  1028.     clear();        /* Bildschirm loeschen */
  1029.     refresh();
  1030.     endwin();       /* Curses "abschalten" */
  1031.     ex_load();
  1032.   }
  1033.   setz_cursor(W_AKT); /* Wollte User doch nicht beenden, Cursor plazieren */
  1034. }
  1035.