AUSAM/source/ded/change.c
#include "ded.h"
#include "match.h"
#include "char.h"
int c_row, c_col;
/* this procedure, to avoid inefficiency, uses auxscreen
* and rowmap to manipulate the screen. This is tricky.
*/
change(pat,str,direction,fin_ch,fline,fcol)
struct RE pat[];
char *str;
int direction;
char fin_ch;
int fline, fcol;
{ char line[ENOUGH];
int newsize, oldsize;
int border, linesafter;
int i, srow;
char reply;
struct CURSOR tmp;
int fin_line, fin_col;
int nx_line, nx_col;
if ( find(pat,direction,fline,fcol) )
{ store_c(&virt_c,&tmp);
/* auxscreen has been set up by find */
c_row=0; c_col=ms_col;
getline(ms_line, auxscreen[0]);
copyover(str, true, fin_ch);
fin_line = ms_line+c_row; fin_col = c_col-1;
getline(mf_line,line);
copyover(line+mf_col, false, fin_ch);
newsize=c_row+1;
oldsize=mf_line-ms_line+1;
border=(NINROWS-newsize)/2;
if (border<2) border=0;
else
if (border>2) border=2;
if (ms_line-border < 0) border = ms_line;
savescreen(); /* includes saveedit */
if (newsize>NINROWS)
fdiag("!! replacement is too big !!");
else
if ( topl<=ms_line-border &&
ms_line+c_row+border-LASTINROW<=topl+LASTINROW )
{ /* rewrite the screen by rolling up -
* first get the top border on the screen
*/
if (ms_line>topl+LASTINROW+1) set_topl(ms_line-NINROWS);
if (ms_line+c_row+border<=topl+LASTINROW)
linesafter = (topl+LASTINROW)-(ms_line+c_row);
else
if (ms_line+c_row+border>maxl)
linesafter = maxl-(ms_line+c_row);
else
linesafter = border;
for (i=0; i<newsize+linesafter; i++)
{ srow = ms_line-topl+i;
getfline(ms_line+i, line); /* old copy */
if (i>=newsize)
getfline(ms_line+oldsize+(i-newsize), auxscreen[i]);
if (srow<=LASTINROW)
redraw(srow, 0, auxscreen[i]);
else
if (srow==LASTINROW+1)
{ rollup(1);
redraw(LASTINROW, 0, auxscreen[i]);
}
else editerror("change can't rollup");
/* put old copy in auxscreen now */
cat2(line,"",auxscreen[i]);
}
}
else
{ /* rewrite screen */
clearscreen();
topl=ms_line-((NINROWS-newsize)/2);
if (topl<0) topl=0;
else
if (topl+LASTINROW>maxl) topl=maxl-LASTINROW;
for (i=topl; i<=topl+LASTINROW; i++)
{ if (i<ms_line)
{ getfline(i,line); redraw(i-topl,0,line); }
else
{ getfline(i, line);
if (i>=ms_line+newsize)
getfline(i-newsize+oldsize, auxscreen[i-ms_line]);
redraw(i-topl, 0, auxscreen[i-ms_line]);
cat2(line,"",auxscreen[i-ms_line]);
}
}
}
/* now see if the change is acceptable to the user */
redraw(EDITROW,0,">ok?");
position(ms_line-topl,ms_col);
fixpos();
complain();
do
{ reply = ttyin();
if (reply==c_ESCAPE || lcase(reply)=='y')
{ showedit();
if (newsize != oldsize)
shuffile(mf_line+1,newsize-oldsize);
nx_line = (direction==FORWARD ? fin_line : ms_line);
nx_col = (direction==FORWARD ? fin_col : ms_col);
}
else
if (lcase(reply)=='n' || reply==c_RUBOUT)
{ showedit();
for (i=ms_line; i<=topl+LASTINROW; i++)
redraw(i-topl, 0, auxscreen[i-ms_line]);
nx_line = ms_line; nx_col = ms_col;
}
else
{ redraw(EDITROW,0,">OK - Y OR N?");
fixpos();
complain();
continue;
}
if (reply==c_ESCAPE || reply==c_RUBOUT)
/* round again! */
{ store_c(&tmp, &virt_c);
set_c(ms_line-topl, ms_col, (mode==EDMODE ? &in_c : &virt_c));
blobit(); ttyflush();
recall(change, pat, str, direction, fin_ch, nx_line, nx_col);
}
else
/* win or lose, you end up at the same position */
{ store_c(&tmp,&virt_c);
i_mode(ms_line-topl,ms_col);
}
} while (true);
}
else
tdiag("?? can't find it ??");
}
/* at present, 'special' just says whether to terminate on a '/' */
copyover(str, special, fin_ch)
char *str;
int special;
char fin_ch;
{ register char c;
while (true)
{ switch (c = *str++)
{ case '\'':
if (special)
{ c = *str++;
switch (c)
{ case '\0':
fdiag("!! replacement string ends with ' !!");
/* no need to break */
case '$':
auxscreen[c_row][c_col]=0;
goto nxline;
default:
break;
}
}
/* fall through on most characters */
goto normalchar;
default:
if (c==fin_ch && special)
{ if (*str!=0)
fdiag("?? string doesn't end after '%c' !!", fin_ch);
else
{ auxscreen[c_row][c_col] = 0;
return;
}
}
/* fall through on most characters */
normalchar:
if (c_col>=ncols) break;
else
{ auxscreen[c_row][c_col++] = c;
continue;
}
case '\0':
auxscreen[c_row][c_col] = 0;
return;
}
/* move to a new row */
str--; /* rescan character */
nxline:
if (++c_row >= NINROWS)
fdiag("?? replacement is too large ??");
else
c_col=0;
}
}