#include "ded.h" #include "char.h" #include "ter.h" #include "str.h" /* for strlength() */ /************************************************************************ * * * copyright Richard Bornat 1981 * * * ************************************************************************/ #define TMARGIN 2 #define BMARGIN 2 char conc_mess[] = "!! lines too long to join !!", eof_mess[] = "!! end of file !!"; /* join virt_c.row to previous line */ join_prev() { register int vrow = virt_c.row; register int fline = topl+vrow; char linebuf[ENOUGH]; register int lc; if (vrow==EDITROW) complain(); else if (fline==0) upwards(); /* i.e. refuse, giving reasons */ else { lc = conc_2_lines(fline-1, linebuf); /* will moan if no room */ if (vrow==0) /* to avoid too much scrolling, adjust then scroll */ { if (lc>0) { redraw(vrow,0,linebuf); shuffile(fline,-1,0); virt_c.col = lc; } retag(vrow); scrdown(SCROLL,true); /* will adjust virt_c.row */ } else if (lc>0) join_rows(vrow-1, lc, MARGIN); } } /* join row r,c to next row - note that virt_c will be set * by this procedure */ join_next(r,c) register int r,c; { register int fline = topl+r; if (r==EDITROW) complain(); else { char tail[ENOUGH]; getline(fline+1,tail); if (c+strlength(tail+MARGIN)>ncols) cdiag(conc_mess); else if (r==LASTINROW) /* as above, adjust then scroll to avoid difficulties */ { redraw(r,c,tail+MARGIN); shuffile(fline+1,-1,0); retag(r); if (fline==maxl) cdiag(eof_mess); else scrup(SCROLL,true); } else join_rows(r,c,MARGIN); } } /************************************************************************ * * * join two rows on the screen, taking care to move the cursor * * up or down as appropriate * * * ************************************************************************/ /* after this procedure, virt_c is set to join position */ join_rows(r,c,t) register int r,c; int t; /* r,c is the join position, t is the position on the next row of * the new tail-of-line. Obviously, this procedure should NEVER * be called with r==LASTINROW */ { int up; char linebuf[ENOUGH]; if (r==LASTINROW) editerror("on last line! [join_rows]"); /* strategy is - join up at top of file - join down at end of file - if cursor is followed by blanks, make it move up - if cursor is preceded by blanks, make it move down - with hardware support, pull up except in top margin - with no support, pull up in bottom margin, down in top margin, elsewhere take the cheapest alternative. */ if (topl==0) { up = true; if (EOF && virt_c.row==r && charsin(r+1,LASTINROW)==0) cdiag(eof_mess); } else if (EOF) up=false; else if (r==virt_c.row && /* cursor on first of lines - make it move */ lastcol(r)=TMARGIN; else up = (r>LASTINROW-BMARGIN || (r>=TMARGIN && scrollup(0,r,(char *)0)=lastcol(r+1) ? join0 : ter.join_rows)) (r,c,t,up,linebuf); /* now set the virtual cursor to record the fact */ if (!up) { r++; dec_topl(); } virt_c.row = r; virt_c.col = c; retag(r); } /************************************************************************ * * * delete an onscreen row. * * * ************************************************************************/ del_row(r) register int r; { struct CURSOR tmp; tmp = virt_c; join_next(r,MARGIN); /* adjust virt_c to reflect deletion */ if (tmp.row<=r) tmp.row += (virt_c.row-r); else tmp.row -= (1-(virt_c.row-r)); virt_c = tmp; } /************************************************************************ * * * make lines stick together * * * ************************************************************************/ /* join fline and fline+1 */ conc_2_lines(fline,buf) register int fline; register char *buf; { char buf2[ENOUGH]; int bp; getline(fline,buf); bp = strlength(buf); /* find the join point */ if (buf[bp-1]==c_CONTROL) bp--; /* eat the mark */ else if (bp>MARGIN) buf[bp++] = c_SPACE; /* insert a space */ getline(fline+1,buf2); if (bp+strlength(buf2+MARGIN)>ncols) { cdiag(conc_mess); return(-1); } else { cat(buf2+MARGIN,buf+bp); return(bp); } }