_C PROGRAMMING_
by
Al Stevens

[LISTING ONE]


/* ------------ editor.h ------------- */
#define ALT_Q 144
#define ALT_R 147
/* -------- configured editor commands ---------- */
#define BACKTAB         SHIFT_HT
#define NEXTWORD        CTRL_FWD
#define PREVWORD        CTRL_BS
#define TOPSCREEN       CTRL_T
#define BOTSCREEN       CTRL_B
#define BEGIN_BUFFER    CTRL_HOME
#define END_BUFFER      CTRL_END
#define BEGIN_LINE      HOME
#define END_LINE        END
#define DELETE_LINE     ALT_D
#define DELETE_WORD     CTRL_D
#define INSERT          INS
#define QUIT            ALT_Q
#define PARAGRAPH       F2
#define BEGIN_BLOCK     F5
#define END_BLOCK       F6
#define MOVE_BLOCK      F3
#define COPY_BLOCK      F4
#define DELETE_BLOCK    F8
#define HIDE_BLOCK      F9
#define REPAINT         ALT_R
/* ------- configured default modes ----------- */
#define TAB 4
#define REFORMING TRUE    /* auto paragraph reformat mode */
#ifndef INSERTING
#define INSERTING TRUE    /* insert/overwrite mode        */
#endif
/* ---------- editor prototype ---------------- */
int text_editor(char *, int, int);
/* ------- macros ------------ */
#define curr(x,y) (ev.bfptr+(y)*ev.wwd+(x))
#define lineno(y) ((unsigned)(ev.bfptr-ev.topptr)/ev.wwd+(y))
/* ---------- editor environment ------------- */
struct edit_env    {
    int envinuse;       /* TRUE if the env is in use  */
    struct wn *wdo;     /* the editor window          */
    int wwd;            /* width of edit window       */
    int wsz;            /* size (chars) of window     */
    char *topptr;       /* -> first char in buffer    */
    char *bfptr;        /* -> first char in window    */
    char *nowptr;       /* -> current char in buffer  */
    char *lstptr;       /* -> last nonblank char      */
    char *endptr;       /* -> last char in buffer     */
    int text_changed;   /* TRUE if text has changed   */
    int nolines;        /* no. of lines in buffer     */
    int blkbeg;         /* marked block: 1st line     */
    int blkend;         /* marked block: last line    */
    int curr_x, curr_y; /* current buffer coordinates */
    int edinsert;       /* toggled insert mode        */
    int reforming;      /* toggled para reform mode   */
};


[LISTING TWO]

/* ----------------------- editor.c ---------------------- */

#include <stdio.h>
#include <ctype.h>
#include <conio.h>
#include <stdlib.h>
#include <string.h>
#include <mem.h>
#include <ctype.h>
#include "window.h"
#include "editor.h"

#define NEXTTAB (TAB-(ev.curr_x%TAB))
#define LASTTAB ((ev.wwd/TAB)*TAB)
#define PREVTAB (((ev.curr_x-1)%TAB)+1)

struct edit_env ev;         /* the editor environment      */
int do_display_text = TRUE; /* turns display on/off        */
extern struct wn wkw;       /* the current window          */
int forcechar;              /* externally force a kb char  */
void (*status_line)(void);  /* called once each keystroke  */
void (*editfunc)(int);      /* for unknown keystrokes      */

/* ---------- local function prototypes ----------- */
static int lastword(void);
static void last_char(void);
static void test_para(int);
static int trailing_spaces(int);
static int first_wordlen(int);
static int last_wordlen(void);
static void paraform(int);
static int blankline(int);
static void delete_word(void);
static void delete_line(void);
static void delete_block(void);
static void mvblock(int);
static void carrtn(int);
static void backspace(void);
static void fore_word(void);
static int spaceup(void);
static void back_word(void);
static int spacedn(void);
static void forward(void);
static int downward(void);
static void upward(void);
static void display_text(int);
static void disp_line(int y);
static void findlast(void);

/* ----- Process text entry for a window. ---- */
int text_editor(char *bf, int editlines, int editwidth)
{
    int depart, i, c;
    int svx, svlw, tx, tabctr, wraplen;

    current_window();
    depart = FALSE;
    tabctr = 0;
    if (ev.envinuse == FALSE)    {
        ev.wdo = &wkw;
        ev.wwd = editwidth;
        ev.wsz = ev.wwd * ev.wdo->ht;
        ev.topptr = ev.bfptr = bf;
        ev.nolines = editlines;
        ev.endptr = bf + ev.wwd * ev.nolines;
        ev.edinsert  = INSERTING;
        ev.reforming = REFORMING;
        ev.envinuse = TRUE;
    }
    set_cursor_type(ev.edinsert ? 0x0106 : 0x0607);
    display_text(0);
    findlast();
    /* ------- read text/command from the keyboard ------ */
    while (depart == FALSE)    {
        ev.nowptr = curr(ev.curr_x, ev.curr_y);
        if (status_line)
            (*status_line)(); /* external status line func */
        gotoxy(ev.curr_x + 2, ev.curr_y + 2);
        if (tabctr)    {          /* expand typed tabs */
            --tabctr;
            c = ' ';
        }
        else
            c = forcechar ? forcechar : getkey();
        forcechar = 0;
        switch (c)    {
/* ------------ fixed editor commands ----------------- */
            case '\r':
                carrtn(ev.edinsert);
                break;
            case UP:
                upward();
                break;
            case DN:
                downward();
                break;
            case FWD:
                forward();
                break;
            case '\b':
            case BS:
                if (!(ev.curr_x || ev.curr_y))
                    break;
                backspace();
                if (ev.curr_x == ev.wwd - 1)
                    last_char();
                if (c == BS)
                    break;
                ev.nowptr = curr(ev.curr_x, ev.curr_y);
            case DEL:
                movmem(ev.nowptr+1,ev.nowptr,
                    ev.wwd-1-ev.curr_x);
                *(ev.nowptr+ev.wwd-1-ev.curr_x) = ' ';
                disp_line(ev.curr_y);
                test_para(ev.curr_x+1);
                ev.text_changed = TRUE;
                break;
            case PGUP:
                ev.curr_y = 0;
                do_display_text = FALSE;
                for (i = 0; i < ev.wdo->ht; i++)
                    upward();
                do_display_text = TRUE;
                display_text(0);
                break;
            case PGDN:
                ev.curr_y = ev.wdo->ht-1;
                do_display_text = FALSE;
                for (i = 0; i < ev.wdo->ht; i++)
                    downward();
                do_display_text = TRUE;
                display_text(0);
                ev.curr_y = 0;
                break;
            case '\t':
                if (ev.curr_x + NEXTTAB < ev.wwd)    {
                    if (ev.edinsert)
                        tabctr = NEXTTAB;
                    else
                        ev.curr_x += NEXTTAB;
                }
                else
                    carrtn(ev.edinsert);
                break;
/* -------- configured editor commands --------------- */
            case REPAINT:
                display_text(ev.curr_y);
                break;
            case BACKTAB:
                if (ev.curr_x < TAB)    {
                    upward();
                    ev.curr_x = LASTTAB;
                }
                else
                    ev.curr_x -= PREVTAB;
                break;
            case NEXTWORD:
                fore_word();
                break;
            case PREVWORD:
                back_word();
                break;
            case BOTSCREEN:
                ev.curr_y = ev.wdo->ht - 1;
                break;
            case TOPSCREEN:
                ev.curr_y = 0;
                break;
            case BEGIN_BUFFER:
                ev.curr_x = ev.curr_y = 0;
                ev.bfptr = ev.topptr;
                display_text(0);
                break;
            case END_BUFFER:
                do_display_text = FALSE;
                ev.curr_x = 0;
                while (downward())
                    if (curr(0,ev.curr_y) >= ev.lstptr)
                        break;
                do_display_text = TRUE;
                display_text(0);
                break;
            case BEGIN_LINE:
                ev.curr_x = 0;
                break;
            case END_LINE:
                last_char();
                break;
            case DELETE_LINE:
                delete_line();
                ev.text_changed = TRUE;
                break;
            case DELETE_WORD:
                delete_word();
                ev.text_changed = TRUE;
                test_para(ev.curr_x);
                break;
            case INSERT:
                ev.edinsert ^= TRUE;
                set_cursor_type(ev.edinsert ? 0x106 : 0x607);
                break;
            case ESC:
            case QUIT:
                depart = TRUE;
                break;
            case PARAGRAPH:
                paraform(0);
                ev.text_changed = TRUE;
                break;
            case BEGIN_BLOCK:
                ev.blkbeg = lineno(ev.curr_y) + 1;
                if (ev.blkbeg > ev.blkend)
                    ev.blkend = ev.blkbeg;
                display_text(0);
                break;
            case END_BLOCK:
                ev.blkend = lineno(ev.curr_y) + 1;
                if (ev.blkend < ev.blkbeg)
                    ev.blkbeg = ev.blkend;
                display_text(0);
                break;
            case MOVE_BLOCK:
                mvblock(TRUE);
                ev.text_changed = TRUE;
                break;
            case COPY_BLOCK:
                mvblock(FALSE);
                ev.text_changed = TRUE;
                break;
            case DELETE_BLOCK:
                delete_block();
                ev.text_changed = TRUE;
                display_text(0);
                break;
            case HIDE_BLOCK:
                ev.blkbeg = ev.blkend = 0;
                display_text(0);
                break;
            default:
                if (!isprint(c))    {
                    /* ---- not recognized by editor --- */
                    if (editfunc)    {
                        /* --- extended commands --- */
                        (*editfunc)(c);
                        findlast();
                        display_text(0);
                    }
                    else
                        putch(BELL);
                    break;
                }
                /* --- displayable char: put in buffer --- */
                if (ev.nowptr == ev.endptr-1 ||
                   (lineno(ev.curr_y)+1 >=
                       ev.nolines && ev.edinsert &&
                       *curr(ev.wwd-2, ev.curr_y) != ' '))  {
                    error_message("End of buffer...");
                    break;
                }
                if (ev.edinsert) /* --- if insert mode --- */
                    movmem(ev.nowptr,ev.nowptr+1,
                        ev.wwd-1-ev.curr_x);
                if (ev.nowptr < ev.endptr)    {
                    if (ev.nowptr >= ev.lstptr)
                        ev.lstptr = ev.nowptr + 1;
                    *ev.nowptr = (char) c; /* put in buff */
                    disp_line(ev.curr_y);
                }
                if (ev.nowptr == curr(ev.wwd-1, ev.curr_y) &&
                    c == ' ' && ev.edinsert)    {
                    if (strncmp(curr(0,ev.curr_y+1),
                            "        ",TAB) == 0)    {
                        carrtn(TRUE);
                        break;
                    }
                }
                else if (ev.endptr &&
                        *curr(ev.wwd-1, ev.curr_y) != ' ')    {
                    /* ------- word wrap is needed ------- */
                    ev.nowptr = curr(ev.wwd-1, ev.curr_y);
                    svx = ev.curr_x;   /* save x vector */
                    svlw = lastword(); /* last word on line?*/
                    ev.curr_x = ev.wwd-1;
                    if (*(ev.nowptr-1) != ' ')
                        back_word();
                    tx = ev.curr_x;
                    wraplen = last_wordlen();
                    if (trailing_spaces(ev.curr_y+1) <
                            wraplen+2)
                        carrtn(TRUE);
                    else if (strncmp(curr(0,ev.curr_y+1),
                            "        ",TAB) == 0)
                        carrtn(TRUE);
                    else    {
                        ev.nowptr = curr(0, ev.curr_y+1);
                        movmem(ev.nowptr,ev.nowptr+wraplen+1,
                            ev.wwd-wraplen-1);
                        setmem(ev.nowptr, wraplen+1, ' ');
                        movmem(curr(ev.curr_x,ev.curr_y),
                            ev.nowptr,wraplen);
                        setmem(curr(ev.curr_x,ev.curr_y),
                            wraplen, ' ');
                        disp_line(ev.curr_y);
                        downward();
                        disp_line(ev.curr_y);
                    }
                    if (svlw)
                        ev.curr_x = svx-tx;
                    else
                        ev.curr_x = svx, --ev.curr_y;
                }
                forward();
                ev.text_changed = TRUE;
                break;
        }
    }
    return c;
}

/* ----- see if a word is the last word on the line ------ */
static int lastword()
{
    int x = ev.curr_x;
    char *bf = curr(ev.curr_x, ev.curr_y);
    while (x++ < ev.wwd-1)
        if (*bf++ == ' ')
            return 0;
    return 1;
}

/* --- go to last displayable character on the line --- */
static void last_char()
{
    char *bf = curr(0, ev.curr_y);
    ev.curr_x = ev.wwd-1;
    while (ev.curr_x && *(bf + ev.curr_x) == ' ')
        --ev.curr_x;
    if (ev.curr_x && ev.curr_x < ev.wwd - 1)
        ev.curr_x++;
}

/* ----- test to see if paragraph should be reformed ----- */
static void test_para(int x)
{
    int ts, fw;
    int svb, sve;

    if (ev.reforming && ev.curr_y < ev.nolines)    {
        ts = trailing_spaces(ev.curr_y);
        fw = first_wordlen(ev.curr_y+1);
        if (fw && ts > fw)    {
            svb = ev.blkbeg, sve = ev.blkend;
            ev.blkbeg = ev.blkend = 0;
            paraform(x);
            ev.blkbeg = svb, ev.blkend = sve;
            if (svb)
                display_text(0);
        }
    }
}

/* ---- count the trailing spaces on a line ----- */
static int trailing_spaces(int y)
{
    int x = ev.wwd-1, ct = 0;
    char *bf = curr(0, y);
    while (x >= 0)    {
        if (*(bf + x) != ' ')
            break;
        --x;
        ct++;
    }
    return ct;
}

/* ----- count the length of the first word on a line --- */
static int first_wordlen(int y)
{
    int ct = 0, x = 0;
    char *bf = curr(0, y);
    while (x < ev.wwd-1 && *bf == ' ')
        x++, bf++;
    while (x < ev.wwd-1 && *bf != ' ')
        ct++, x++, bf++;
    return ct;
}

/* ----- count the length of the last word on a line --- */
static int last_wordlen()
{
    int ct = 0, x = ev.wwd-1;
    char *bf = curr(x, ev.curr_y);
    while (x && *bf == ' ')
        --x, --bf;
    while (x && *bf != ' ')
        --x, --bf, ct++;
    return ct;
}

/* ------------ form a paragraph -------------- */
static void paraform(int x)
{
    char *cp1, *cp2, *cpend, *svcp;
    int x1, y1, firstline = TRUE;
    int y = ev.curr_y;

    if (!ev.blkbeg)    {    /* ---- if block not marked ---- */
        if (blankline(lineno(y)+1))
            return;        /* next line is blank, no reform */
        ev.blkbeg=ev.blkend=lineno(y)+1; /* pseudoblock */
        ev.blkend++;
        y1 = y+1;
        while (ev.blkend < ev.nolines)    { /* look for para */
            if (strncmp(curr(0, y1++), "        ", TAB) == 0)
                break;
            ev.blkend++;
        }
        --ev.blkend;
    }
    if (lineno(y) != ev.blkbeg-1)
        x = 0;
    x1 = x;
    cp1 = cp2 = ev.topptr + (ev.blkbeg - 1) * ev.wwd + x;
    cpend = ev.topptr + ev.blkend * ev.wwd;
    while (cp2 < cpend)    {
        while (*cp2 == ' ' && cp2 < cpend)    {
            if (firstline)
                *cp1++ = *cp2, x1++;
            cp2++;
        }
        firstline = FALSE;
        if (cp2 == cpend)
            break;
        /* ---- at a word ---- */
        while (*cp2 != ' ' && cp2 < cpend)    {
            if (x1 >= ev.wwd-1)    {
                /* wrap the word */
                svcp = cp1 + (ev.wwd - x1);
                while (*--cp1 != ' ')
                    *cp1 = ' ',    --cp2;
                x1 = 0;
                ev.blkbeg++;
                cp1 = svcp;
                if (y < ev.wdo->ht)
                    disp_line(y++);
            }
            *cp1++ = *cp2++;
            x1++;
        }
        if (cp2 < cpend)
            *cp1++ = ' ', x1++;
    }
    while (cp1 < cpend)
        *cp1++ = ' ';
     ev.blkbeg++;
    if (y < ev.wdo->ht)
        disp_line(y++);
    firstline = ev.blkbeg;
     if (ev.blkbeg <= ev.blkend)    {
        delete_block();
        display_text(y);
    }
    ev.blkbeg = ev.blkend = 0;
    if (firstline)
        display_text(0);
}

/* ------- test for a blank line ---------- */
static int blankline(int line)
{
    char *cp = ev.topptr + (line-1) * ev.wwd;
    int x = ev.wwd;
    while (x--)
        if (*cp++ != ' ')
            break;
    return !(x > -1);
}

/* ------------- delete a word -------------- */
static void delete_word()
{
    int wct = 0;
    char *cp1, *cp2;

    cp1 = cp2 = curr(ev.curr_x, ev.curr_y);
    if (*cp2 == ' ')
        while (*cp2 == ' ' && ev.curr_x + wct < ev.wwd)
            wct++, cp2++;
    else    {
        while (*cp2 != ' ' && ev.curr_x + wct < ev.wwd)
            wct++, cp2++;
        while (*cp2 == ' ' && ev.curr_x + wct < ev.wwd)
            wct++, cp2++;
    }
    movmem(cp2, cp1, ev.wwd - ev.curr_x - wct);
    setmem(cp1 + ev.wwd - ev.curr_x - wct, wct, ' ');
    disp_line(ev.curr_y);
}

/* ----------- delete a line --------------- */
static void delete_line()
{
    char *cp1, *cp2;
    int len;

    cp1 = ev.bfptr + ev.curr_y * ev.wwd;
    cp2 = cp1 + ev.wwd;
    if (cp1 < ev.lstptr)    {
        len = ev.endptr - cp2;
        movmem(cp2, cp1, len);
        ev.lstptr -= ev.wwd;
        setmem(ev.endptr - ev.wwd, ev.wwd, ' ');
        display_text(ev.curr_y);
    }
}

/* ----------- delete a block ------------- */
static void delete_block()
{
    char *cp1, *cp2;
    int len;

    if (!ev.blkbeg || !ev.blkend)    {
        error_message("No block marked ...");
        return;
    }
    cp1 = ev.topptr + ev.blkend * ev.wwd;
    cp2 = ev.topptr + (ev.blkbeg - 1) * ev.wwd;
    len = ev.endptr - cp1;
    movmem(cp1, cp2, len);
    setmem(cp2 + len, ev.endptr - (cp2 + len), ' ');
    ev.blkbeg = ev.blkend = 0;
    ev.lstptr -= cp1 - cp2;
}

/* ------- move and copy text blocks -------- */
static void mvblock(int moving)
{
    char *cp1, *cp2, *hd;
    unsigned len;

    if (!ev.blkbeg || !ev.blkend)    {
        error_message("No block marked ...");
        return;
    }
    if (lineno(ev.curr_y) >= ev.blkbeg-1
            && lineno(ev.curr_y) <= ev.blkend-1)    {
        error_message("Don't move/copy a block into itself");
        return;
    }
    len = (ev.blkend - ev.blkbeg + 1) * ev.wwd;
    if ((hd = malloc(len)) == NULL)
        return;
    cp1 = ev.topptr + (ev.blkbeg-1) * ev.wwd;
    movmem(cp1, hd, len);
    cp2 = ev.topptr + lineno(ev.curr_y) * ev.wwd;
    if (moving)    {
        if (lineno(ev.curr_y) > ev.blkbeg-1)
            cp2 -= len;
        delete_block();
    }
    if (cp2+len <= ev.endptr)    {
        movmem(cp2, cp2 + len, ev.endptr - cp2 - len);
        movmem(hd, cp2, len);
        ev.lstptr += cp1 - cp2;
    }
    else
        error_message("Not enough room...");
    free(hd);
    ev.blkbeg = ev.blkend = 0;
    display_text(0);
}

/* ------- find the last character in the buffer -------- */
static void findlast()
{
    char *lp = ev.endptr - 1, *tp = ev.topptr;
    while (lp > tp && *lp == ' ')
        --lp;
    if (*lp != ' ')
        lp++;
    ev.lstptr = lp;
}

/* -------- carriage return -------- */
static void carrtn(int insert)
{
    int insct;
    char *cp = curr(ev.curr_x, ev.curr_y);
    char *nl = cp+((cp-ev.topptr)%ev.wwd);
    int ctl = 2;
    if (lineno(ev.curr_y) + 2 < ev.nolines)
        if (insert && nl < ev.endptr)    {
            insct = ev.wwd - ev.curr_x;
            while (ctl--)    {
                if (ev.endptr > cp + insct)    {
                    movmem(cp, cp+insct, ev.endptr-insct-cp);
                    setmem(cp, insct, ' ');
                }
                else if (ctl == 1)
                    setmem(cp, ev.endptr - cp, ' ');
                cp += insct * 2;
                insct = ev.curr_x;
            }
        }
    ev.curr_x = 0;
    downward();
    if (insert)    {
        ev.text_changed = TRUE;
        test_para(0);
        display_text(ev.curr_y-1);
        if (lineno(ev.curr_y) + 2 < ev.nolines)
            if ((ev.lstptr + ev.wwd) <= ev.endptr)
                if (ev.lstptr > curr(ev.curr_x, ev.curr_y))
                    ev.lstptr += ev.wwd;
    }
}

/* ------- move the buffer offset back one position ------ */
static void backspace()
{
    if (ev.curr_x == 0)    {
        if (ev.curr_y)
            ev.curr_x = ev.wwd - 1;
        upward();
    }
    else
        --ev.curr_x;
}

/* -------- move the buffer offset forward one word ------ */
static void fore_word()
{
    while (*ev.nowptr != ' ')    {
        if (spaceup() == 0)
            return;
        if (ev.curr_x == 0)
            break;
    }
    while (*ev.nowptr == ' ')
        if (spaceup() == 0)
            return;
}

static int spaceup()
{
    if (ev.nowptr >= ev.lstptr)
        return 0;
    ev.nowptr++;
    forward();
    return 1;
}

/* ------- move the buffer offset backward one word ------ */
static void back_word()
{
    spacedn();
    while (*ev.nowptr == ' ')
        if (spacedn() == 0)
            return;
    while (*ev.nowptr != ' ')    {
        if (ev.curr_x == 0)
            return;
        if (spacedn() == 0)
            return;
    }
    spaceup();
}

static int spacedn()
{
    if (ev.nowptr == ev.topptr)
        return 0;
    --ev.nowptr;
    backspace();
    return 1;
}

/* ----- move the buffer offset forward one position ----- */
static void forward()
{
    int ww = ev.wwd;
    if (++ev.curr_x == ww)    {
        downward();
        ev.curr_x = 0;
    }
}

/* ------- move the buffer offset down one position ------ */
static int downward()
{
    if (ev.curr_y < ev.wdo->ht - 1)    {
        ev.curr_y++;
        return 1;
    }
    else if ((ev.bfptr + ev.wsz) < ev.endptr)    {
        ev.bfptr += ev.wwd;
        if (do_display_text)    {
            scroll_window(1);
            disp_line(ev.wdo->ht-1);
        }
        return 1;
    }
    return 0;
}

/* -------- move the buffer offset up one position ------ */
static void upward()
{
    if (ev.curr_y)
        --ev.curr_y;
    else if ((ev.topptr + ev.wwd) <= ev.bfptr)    {
        ev.bfptr -= ev.wwd;
        if (do_display_text)    {
            scroll_window(0);
            disp_line(0);
        }
    }
}

/* ---- display lines in a window ------ */
static void display_text(y)
{
    while (y < ev.wdo->ht)
        disp_line(y++);
}

/* ---------- Display a line -------- */
static void disp_line(int y)
{
    char ln[81];

    if (lineno(y) >= ev.blkbeg-1)
        if (lineno(y) <= ev.blkend-1)    {
            textcolor(BLOCKFG);
            textbackground(BLOCKBG);
        }
    movmem(ev.bfptr+y*ev.wwd, ln, ev.wwd);
    ln[ev.wwd] = '\0';
    writeline(2, y+2, ln);
    textcolor(TEXTFG);
    textbackground(TEXTBG);
}



[LISTING THREE]

/* --------- testedit.c ------------ */
#include <stdio.h>
#include <mem.h>
#include <conio.h>
#include "window.h"
#include "editor.h"

#define LNS 40               /* number of editor lines   */
#define WD  60               /* length of an editor line */
#define LF (1+(80-WD)/2)     /* leftmost column          */
#define TP (1+(25-LNS/2)/2)  /* top row                  */
#define RT LF+WD+1           /* rightmost column         */
#define BT TP+LNS/2+1        /* bottom row               */

char notes[LNS*WD];
void main(int, char **);

void main(int argc, char **argv)
{
    FILE *fd;
    if (argc > 1)    {
        setmem(notes, sizeof notes, ' ');
        if ((fd = fopen(argv[1], "r")) != NULL) {
            fread(notes, WD, LNS, fd);
            fclose(fd);
        }
        clear_screen();
        establish_window(LF,TP,RT,BT,TEXTFG,TEXTBG,FALSE);
        if (text_editor(notes, LNS, WD) != ESC)  {
            fd = fopen(argv[1], "w");
            fwrite(notes, WD, LNS, fd);
            fclose(fd);
        }
        delete_window();
        clear_screen();
        set_cursor_type(0x0607);
    }
}


