Category : Files from Magazines
Archive   : DDJSRC.ZIP
Filename : EDITSHEL.C

 
Output of file : EDITSHEL.C contained in archive : DDJSRC.ZIP

/* --------- editshel.c ------------ */
#include
#include
#include
#include
#include
#include
#include
#include "window.h"
#include "menu.h"
#include "entry.h"
#include "editor.h"
#include "help.h"

int MAXLINES; /* maximum number of editor lines */
#define EDITWIDTH 78 /* length of an editor line */
#define BUFLEN (EDITWIDTH*MAXLINES)

/* --------- alt keys returned by getkey() --------- */
#define ALT_A 158
#define ALT_L 166
#define ALT_M 178
#define ALT_N 177

/* -------- configured advanced editor commands --------- */
#define FIND F7
#define FIND_AGAIN ALT_F7
#define LOAD_FILE ALT_L
#define SAVE_FILE ALT_S
#define MERGE_FILE ALT_M
#define NEW_FILE ALT_N
#define EDITOR_MENU F10
#define REFORM ALT_A

/* ---------- editor menu tables --------- */
static char *fselcs[] = {
"Load [Alt-L]",
"Save [Alt-S]",
"Merge [Alt-M]",
"New [Alt-N]",
"Quit [Alt-Q]",
NULL
};

static char *filehelp[] = {
"load",
"save",
"merge",
"new",
"quit"
};

static char *eselcs[] = {
"Move [F3]",
"Copy [F4]",
"Delete [F8]",
"Hide [F9]",
"Paragraph [F2]",
"Mark Beg [F5]",
"Mark End [F6]",
"Find [F7]",
"Find Again [Alt-F7]",
NULL
};

static char *edithelp[] = {
"move",
"copy",
"delete",
"hide",
"formpara",
"markbeg",
"markend",
"find",
"findagn",
};

static char *oselcs[] = {
"Auto Paragraph Reformat [Alt-A]",
"Insert [Ins]",
NULL
};

static char *opthelp[] = {
"auto",
"insert"
};

void fileedit(char *);
static int edit(int,int);
static void editmenu(int);
static int get_filename(char *, int);
static int write_file(void);
static int load_file(int,int);
static int save_file(int,int);
static int merge_file(int,int);
static int new_file(int,int);
static void editkeys(int);
static void statusline(void);
static int findstring(void);
static char *find(char *, unsigned);
static int read_file(char *, char *, int, int, int);
static int bufferok(char *);
static void notice(char *);
void (*edit_extend)(void);

static char fkeys[] = {LOAD_FILE,SAVE_FILE,
MERGE_FILE,NEW_FILE,QUIT};
static char forced[] = {MOVE_BLOCK,COPY_BLOCK,
DELETE_BLOCK,HIDE_BLOCK,
PARAGRAPH,BEGIN_BLOCK,
END_BLOCK,FIND,FIND_AGAIN};
static char options[] = {REFORM,INS};

static int (*ffuncs[])() =
{load_file,save_file,merge_file,new_file,edit};
static int (*efuncs[])() =
{edit,edit,edit,edit,edit,edit,edit,edit,edit};
static int (*ofuncs[])() =
{edit,edit,edit};

MENU emn [] = {
{"File", NULL, fselcs, filehelp, fkeys, ffuncs, 0},
{"Edit", NULL, eselcs, edithelp, forced, efuncs, 0},
{"Options", NULL, oselcs, opthelp, options, ofuncs, 0},
{NULL}
};

/* ------ filename data entry template and buffer ------- */
static char filename[65];
static char savefn [65];
static char filemask[65];

FIELD fn_template[] = {
{2,14,1,filename,filemask,"filename"},
{0}
};

/* ------- text find data entry template and buffer ------ */
static char findstr[71];
static char findmask[71];

FIELD find_template[] = {
{ 2,8,1,findstr,findmask,"findstr"},
{0}
};

extern int forcechar;
extern struct edit_env ev;

static void editkeys(int c)
{
switch(c) {
case REFORM:
ev.reforming ^= TRUE;
break;
case NEW_FILE:
new_file(1,1);
break;
case LOAD_FILE:
load_file(1,1);
break;
case SAVE_FILE:
save_file(1,1);
break;
case MERGE_FILE:
merge_file(1,1);
break;
case FIND:
if (!findstring())
break;
case FIND_AGAIN:
ev.nowptr++;
ev.nowptr = find(ev.nowptr, ev.lstptr-ev.nowptr);
if (ev.nowptr != NULL) {
ev.curr_x = (ev.nowptr-ev.topptr) % ev.wwd;
if (ev.nowptr >= ev.bfptr+ev.wwd*ev.wdo->ht)
ev.bfptr = ev.nowptr - ev.curr_x;
ev.curr_y = (ev.nowptr - ev.bfptr) / ev.wwd;
}
else
error_message("Not found ...");
break;
case ALT_F:
editmenu(1);
break;
case ALT_E:
editmenu(2);
break;
case ALT_O:
editmenu(3);
break;
case EDITOR_MENU:
editmenu(0);
break;
default:
if (edit_extend)
(*edit_extend)();
else
putch(BELL);
break;
}
}

static void editmenu(n)
{
menu_select(emn, n);
}

static int edit(hs,vs)
{
forcechar = emn[hs-1].mskeys[vs-1] & 255;
return TRUE;
}

/* ---------- edit a file -------------- */
void fileedit(char *file)
{
char *bf, *mb;
extern void (*editfunc)();
extern void (*status_line)();

setmem(filename, 64, ' ');
setmem(filemask, 64, '_');
setmem(findmask, 70, '_');
setmem(findstr, 70, ' ');
establish_window(1,2,80,24,TEXTFG,TEXTBG,TRUE);
editfunc = editkeys;
status_line = statusline;
mb = display_menubar(emn);
statusline();
if ((bf = malloc(BUFLEN)) != NULL) {
setmem(bf, BUFLEN, ' ');
strcpy(filename, file);
filename[strlen(filename)] = ' ';
if (*file)
read_file(" Loading ... ",bf,0,FALSE,FALSE);
while (TRUE) {
text_editor(bf, MAXLINES, EDITWIDTH);
if (bufferok("quit"))
break;
}
free(bf);
}
restore_menubar(mb);
delete_window();
}


/* ---------- load a file --------------- */
static int load_file(hs,vs)
{
if (bufferok("reload"))
strcpy(savefn, filename);
if (get_filename(" Load what file? ", TRUE) != ESC) {
setmem(ev.topptr, BUFLEN, ' ');
read_file(" Loading ... ",ev.topptr,0,FALSE,TRUE);
forcechar = BEGIN_BUFFER;
ev.text_changed = FALSE;
}
else
strcpy(filename, savefn);
return TRUE;
}

/* ---------- merge a file into the edit buffer -------- */
static int merge_file(hs,vs)
{
strcpy(savefn, filename);
if (get_filename(" Merge what file? ", TRUE) != ESC) {
if (read_file(" Merging ... ",
curr(0, ev.curr_y),
lineno(ev.curr_y), TRUE, TRUE)) {
forcechar = REPAINT;
ev.text_changed = TRUE;
}
}
strcpy(filename, savefn);
return TRUE;
}

/* --------- save the file -------------- */
static int save_file(hs,vs)
{
if (get_filename(" Save as what file? ", FALSE) != ESC)
if (write_file())
ev.text_changed = FALSE;
return TRUE;
}

/* ---------- start a new file ------------- */
static int new_file(hs,vs)
{
if (bufferok("erase"))
if (get_filename(" Build as what file? ",TRUE)!=ESC){
setmem(ev.topptr, BUFLEN, ' ');
forcechar = BEGIN_BUFFER;
ev.text_changed = FALSE;
}
return TRUE;
}

/* -------- read a file name ------------- */
static int get_filename(char *ttl, int clear)
{
int rtn;

establish_window(1,23,80,25,ENTRYFG,ENTRYBG,TRUE);
window_title(ttl);
gotoxy(3,2);
cputs("File name:");
rtn = data_entry(fn_template, clear, 1);
delete_window();
return rtn;
}

/* --------- write a file ------------ */
static int write_file()
{
FILE *fp;
int ln, i, ln1;
char *cp, buf[EDITWIDTH+1];

if ((fp = fopen(filename, "w")) == NULL) {
error_message(" Can't write that file! ");
return FALSE;
}
notice(" Writing file ... ");
/* ----- find the last significant line ----- */
for (ln = MAXLINES-1; ln > -1; --ln) {
cp = ev.topptr + ln * EDITWIDTH;
for (i = 0; i < EDITWIDTH; i++)
if (*(cp + i) != ' ')
break;
if (i < EDITWIDTH)
break;
}
for (ln1 = 0; ln1 <= ln; ln1++) {
movmem(ev.topptr + ln1 * EDITWIDTH, buf, EDITWIDTH);
i = EDITWIDTH-1;
cp = buf;
while (i >= 0 && *(cp + i) == ' ')
--i;
if (i == -1 || *(cp + i) != ' ')
i++;
*(cp + i) = '\n';
*(cp + i + 1) = '\0';
fputs(cp, fp);
}
fclose(fp);
delete_window();
return TRUE;
}

/* -------------- read (load or merge) a file ----------- */
static int
read_file(char *nt,char *ln,int lines,int merging,int needed)
{
FILE *fp;
char ibf[120];
char *cp;
int x;

if ((fp = fopen(filename, "r")) != NULL) {
notice(nt);
while (fgets(ibf, 120, fp) && lines < MAXLINES) {
lines++;
if (merging) {
movmem(ln,ln+EDITWIDTH,
BUFLEN-lines*EDITWIDTH);
setmem(ln,EDITWIDTH,' ');
}
cp = ibf, x = 0;
while (*cp && *cp != '\n') {
if (*cp == '\t')
x += TAB-(x%TAB);
else
*(ln+x++) = *cp;
cp++;
}
ln += EDITWIDTH;
}
fclose(fp);
delete_window();
return TRUE;
}
else if (needed)
error_message("No such file can be found");
return FALSE;
}

/* ----------- display a status line ----------- */
static void statusline()
{
char stat[81], *st;
int cl[81], *cp;
static char msk[] =
"Line:%3d Column:%2d %-9.9s %-21.21s F1:Help \
F10:Menu ";
unsigned y = 1;
unsigned x = 1;
unsigned attr = ((MENUFG | (MENUBG << 4)) << 8);

if (ev.wwd) {
y = (unsigned) (ev.nowptr-ev.topptr) / ev.wwd + 1;
x = (unsigned) (ev.nowptr-ev.topptr) % ev.wwd + 1;
}
sprintf(stat,msk,y,x,
(ev.edinsert ? "Insert" : "Overwrite"),
(ev.reforming ? "Auto Paragraph Reform" : " "));
for (st = stat, cp = cl; *st; st++)
*cp++ = (*st & 255) | attr;
__vram(__vptr(1,25),cl,80);
set_help("editor");
}

/* -------- get a string to find --------- */
static int findstring()
{
char *cp = findstr+60;
int ans;

establish_window(1,23,80,25,ENTRYFG,ENTRYBG,TRUE);
gotoxy(2,2);
cputs("Find?");
ans = data_entry(find_template, TRUE, 1);
delete_window();
if (ans == ESC)
return FALSE;
while (*--cp == ' ')
;
if (*cp)
*(cp+1) = '\0';
return TRUE;
}

/* -------- find a string in the buffer -------------- */
static char *find(char *bf, unsigned len)
{
char *cp;

for (cp = bf; cp < bf+len-strlen(findstr); cp++)
if (strncmp(cp, findstr, strlen(findstr)) == 0)
return cp;
return NULL;
}

/* ---------- test for buffer changed ----------- */
static int bufferok(char *s)
{
int c = 'Y';
if (ev.text_changed) {
establish_window(23,11,56,13,ERRORFG,ERRORBG,TRUE);
gotoxy(2,2);
cprintf("Text has changed, %s? (y/n)", s);
hidecursor();
do
putch(BELL), c = getkey();
while (toupper(c) != 'Y' && toupper(c) != 'N');
delete_window();
}
return toupper(c) == 'Y';
}

/* -------- small message ------------ */
static void notice(char *s)
{
int lf = (80-strlen(s))/2-1;
int rt = lf+strlen(s)+2;
establish_window(lf,11,rt,13,HELPFG,HELPBG,TRUE);
gotoxy(2,2);
cputs(s);
}