home *** CD-ROM | disk | FTP | other *** search
-
- /*
- * EDIT.C
- * (c) 1992 J.Harper
- */
-
- #include "jed.h"
- #include "jed_protos.h"
-
- Prototype BOOL clearlinelist (TX *);
- Prototype VOID killlinelist (TX *);
- Prototype VOID killsomelines (TX *, LONG, LONG);
- Prototype LINE * resizelinelist (TX *, LONG, LONG);
- Prototype BOOL stuffline (STRPTR, LONG);
- Prototype BOOL insertstr (STRPTR);
- Prototype BOOL insertstrn (STRPTR, WORD);
- Prototype BOOL insertstring (STRPTR, LONG);
- Prototype BOOL insertsection (STRPTR);
- Prototype BOOL deletechars (WORD);
- Prototype BOOL deletelines (LONG);
- Prototype BOOL deletesection (POS *);
- Prototype BOOL splitline (VOID);
- Prototype BOOL joinlines (VOID);
- Prototype BOOL wrapline (VOID);
- Prototype BOOL padcursor (VOID);
- Prototype VOID orderpos (POS *, POS *);
- Prototype BOOL getsection (STRPTR, POS *);
- Prototype LONG sectionlength (POS *, POS *);
- Prototype VOID copysection (POS *, POS *, STRPTR);
- Prototype BOOL posinblock (WORD, LONG);
- Prototype BOOL cursinblock (VOID);
- Prototype BOOL pageinblock (VOID);
- Prototype WORD lineinblock (LONG);
- Prototype VOID orderblock (VOID);
- Prototype VOID setblockrefresh (VOID);
- Prototype LONG offset (VOID);
- Prototype LONG size (VOID);
-
- #define allocll(n) AllocVec(sizeof(LINE) * (n), 0L)
- #define freell(l) FreeVec(l)
-
- /*
- * This macro copies a line list (or part of one).
- * d = destination
- * s = source
- * n = number of LINE's to copy.
- */
- #define movll(d,s,n) CopyMemQuick((ULONG *)(s), (ULONG *)(d), (n) << 3)
-
- /*
- * Makes file empty (null string in first line)
- */
- BOOL
- clearlinelist(TX *tx)
- {
- if(tx->tx_Lines)
- killlinelist(tx);
- if(tx->tx_Lines = allocll(1));
- {
- if(tx->tx_Lines[0].ln_Line = savestring(""))
- tx->tx_Lines[0].ln_Strlen = 1;
- else
- tx->tx_Lines[0].ln_Strlen = 0;
- tx->tx_NumLines = 1;
- return(TRUE);
- }
- return(FALSE);
- }
-
- /*
- * deallocates all lines and their list
- */
- VOID
- killlinelist(TX *tx)
- {
- if(tx->tx_Lines)
- {
- LINE *line;
- LONG i;
- for(i = 0, line = tx->tx_Lines; i < tx->tx_NumLines; i++, line++)
- {
- if(line->ln_Strlen)
- FreeVec(line->ln_Line);
- }
- freell(tx->tx_Lines);
- tx->tx_Lines = NULL;
- tx->tx_NumLines = 0;
- }
- killmarklist(tx);
- }
-
- /*
- * deallocates some lines (but not the list)
- */
- VOID
- killsomelines(TX *tx, LONG start, LONG number)
- {
- LINE *line = tx->tx_Lines + start;
- LONG i;
-
- for(i = 0; i < number; i++, line++)
- {
- if(line->ln_Strlen)
- {
- FreeVec(line->ln_Line);
- line->ln_Strlen = 0;
- line->ln_Line = NULL;
- }
- }
- }
-
- /*
- * Creates blank entries or removes existing lines starting from line 'where'
- * 'change' is the number of lines to insert, negative numbers mean delete
- * that number of lines starting at the cursor line.
- * If lines are deleted the actual text is also deleted.
- */
- LINE *
- resizelinelist(TX *tx, LONG change, LONG where)
- {
- LINE *newlines;
- LONG newsize = tx->tx_NumLines + change;
-
- if((newsize >= 0) && (newlines = allocll(newsize)))
- {
- if(tx->tx_Lines)
- {
- if(change > 0)
- {
- movll(newlines, tx->tx_Lines, where);
- movll(newlines + where + change, tx->tx_Lines + where, tx->tx_NumLines - where);
- }
- else
- {
- movll(newlines, tx->tx_Lines, where);
- movll(newlines + where, tx->tx_Lines + where - change, tx->tx_NumLines - where + change);
- killsomelines(tx, where, -change);
- }
- freell(tx->tx_Lines);
- }
- if(change > 0)
- bzero(newlines + where, change * sizeof(LINE));
- tx->tx_Lines = newlines;
- tx->tx_NumLines = newsize;
- return(newlines);
- }
- return(FALSE);
- }
-
- /*
- * Pastes a line into the current view at line num.
- * a LINE should have been made if it is wanted.
- * text is not copied, it should have been AllocVec()'ed (or savestring()'ed)
- */
- BOOL
- stuffline(STRPTR text, LONG lineNum)
- {
- LINE *line = CurrVW->vw_Tx->tx_Lines + lineNum;
-
- if(line->ln_Strlen)
- FreeVec(line->ln_Line);
-
- line->ln_Strlen = strlen(text) + 1;
- line->ln_Line = text;
- return(TRUE);
- }
-
- /*
- * Inserts a string into the current line at the cursor pos
- */
- BOOL
- insertstr(STRPTR text)
- {
- return(insertstrn(text, strlen(text)));
- }
-
- BOOL
- insertstrn(STRPTR text, WORD textLen)
- {
- VW *vw = CurrVW;
- TX *tx = vw->vw_Tx;
- LINE *line = tx->tx_Lines + vw->vw_CursorPos.pos_Line;
- STRPTR newline;
-
- if(newline = AllocVec(textLen + line->ln_Strlen, 0L))
- {
- if(line->ln_Strlen)
- {
- memcpy(newline, line->ln_Line, vw->vw_CursorPos.pos_Col);
- memcpy(newline + vw->vw_CursorPos.pos_Col, text, textLen);
- strcpy(newline + vw->vw_CursorPos.pos_Col + textLen, line->ln_Line + vw->vw_CursorPos.pos_Col);
- }
- else
- {
- memcpy(newline, text, textLen);
- newline[textLen] = 0;
- }
- stuffline(newline, vw->vw_CursorPos.pos_Line);
- keepposaddx(textLen);
- return(TRUE);
- }
- return(FALSE);
- }
-
- /*
- * Inserts a null teminated string, this routine acts on any '\n' or '\t'
- * characters that it finds.
- * I expect that this routine will be incredibly slow.
- */
- BOOL
- insertstring(STRPTR text, LONG tabSize)
- {
- STRPTR buff = AllocVec(1024, 0L);
- if(buff)
- {
- VW *vw = CurrVW;
- STRPTR str = text;
- setrefresh(RFF_LINEFROM, vw->vw_CursorPos.pos_Col, vw->vw_CursorPos.pos_Line);
- while(*str)
- {
- UBYTE c;
- LONG i = 0;
- WORD startx = vw->vw_CursorPos.pos_Col;
-
- while((c = *str++) && (c != '\n') && (i < 1024))
- {
- if(c == '\t')
- {
- WORD numspc = tabSize - ((i + startx) % tabSize);
- memcpy(buff + i, Spaces, numspc);
- i += numspc;
- }
- else
- buff[i++] = c;
- }
- buff[i] = 0;
- if(c == '\n')
- {
- vw->vw_RefreshType |= RFF_ALLFROM;
- if(vw->vw_CursorPos.pos_Col)
- {
- if(!insertstrn(buff, i))
- goto abort;
- if(!splitline())
- goto abort;
- }
- else
- {
- STRPTR copy;
- if(!resizelinelist(vw->vw_Tx, +1, vw->vw_CursorPos.pos_Line))
- goto abort;
- if(!(copy = savestring(buff)))
- goto abort;
- stuffline(copy, vw->vw_CursorPos.pos_Line);
- keepposaddy(+1);
- }
- startx = 0;
- }
- else
- {
- str--;
- if(!insertstrn(buff, i))
- {
- abort:
- settitle(NoMemMsg);
- FreeVec(buff);
- return(FALSE);
- }
- }
- }
- FreeVec(buff);
- return(TRUE);
- }
- settitle(NoMemMsg);
- return(FALSE);
- }
-
- /*
- * Inserts a section from the text file into the current cursor position.
- * You can't insert into the text that is to be inserted.
- * Works out if the copied text is to be inserted before the cursor (if so
- * all line numbers have to recalculated after each line is inserted).
- */
- BOOL
- insertsection(STRPTR sectType)
- {
- VW *vw = CurrVW;
- TX *tx = vw->vw_Tx;
- POS endpos, temp;
- POS startpos = vw->vw_CursorPos;
-
- if(getsection(sectType, &endpos))
- {
- BOOL copyback = FALSE;
-
- /* If some of the next code seems totally weird it's because the
- * startpos and vw_CursorPos are actually swapped with each other
- * for this part :-)
- */
- if(!(
- ((startpos.pos_Line < vw->vw_CursorPos.pos_Line) || (startpos.pos_Line > endpos.pos_Line)) ||
- ((startpos.pos_Line == vw->vw_CursorPos.pos_Line) && (startpos.pos_Col < vw->vw_CursorPos.pos_Col)) ||
- ((startpos.pos_Line == endpos.pos_Line) && (startpos.pos_Col >= endpos.pos_Col))
- )){
- settitle("error: can't insert into self");
- vw->vw_CursorPos = startpos;
- return(FALSE);
- }
-
- /* They're switched back here.
- */
- temp = vw->vw_CursorPos;
- vw->vw_CursorPos = startpos;
- startpos = temp;
-
- /* Test if we're copying to a line behind where we're copying from,
- * this would really screw up the copy if not accounted for!
- */
- if(vw->vw_CursorPos.pos_Line < startpos.pos_Line)
- copyback = TRUE;
-
- if(startpos.pos_Line == endpos.pos_Line)
- {
- setrefresh(RFF_LINEFROM, vw->vw_CursorPos.pos_Col, vw->vw_CursorPos.pos_Line);
- return(insertstrn(tx->tx_Lines[startpos.pos_Line].ln_Line + startpos.pos_Col, endpos.pos_Col - startpos.pos_Col));
- }
- else
- {
- LONG middle;
- setrefresh(RFF_ALLFROM, vw->vw_CursorPos.pos_Col, vw->vw_CursorPos.pos_Line);
- if(startpos.pos_Col || vw->vw_CursorPos.pos_Col)
- {
- LINE *sline = tx->tx_Lines + startpos.pos_Line;
- if(!insertstrn(sline->ln_Line + startpos.pos_Col, sline->ln_Strlen - startpos.pos_Col - 1))
- goto abort;
- if(!splitline())
- goto abort;
- if(copyback)
- {
- endpos.pos_Line++;
- startpos.pos_Line += 2;
- }
- else
- startpos.pos_Line++;
- }
- middle = endpos.pos_Line - startpos.pos_Line;
- if(!resizelinelist(vw->vw_Tx, middle, vw->vw_CursorPos.pos_Line))
- goto abort;
- if(copyback)
- {
- endpos.pos_Line += middle;
- startpos.pos_Line += middle;
- }
- while(startpos.pos_Line < endpos.pos_Line)
- {
- LINE *sline = tx->tx_Lines + startpos.pos_Line;
- LINE *dline = tx->tx_Lines + vw->vw_CursorPos.pos_Line;
- STRPTR copy = savestring(sline->ln_Line);
- if(!copy)
- goto abort;
- dline->ln_Line = copy;
- dline->ln_Strlen = sline->ln_Strlen;
- keepposaddy(+1);
- startpos.pos_Line++;
- }
- if(endpos.pos_Col)
- {
- if(!insertstrn(tx->tx_Lines[endpos.pos_Line].ln_Line, endpos.pos_Col))
- {
- abort:
- settitle(NoMemMsg);
- return(FALSE);
- }
- }
- }
- return(TRUE);
- }
- return(FALSE);
- }
-
- /*
- * Deletes some text from the cursor pos (this line only)
- */
- BOOL
- deletechars(WORD size)
- {
- VW *vw = CurrVW;
- TX *tx = vw->vw_Tx;
- LINE *line = tx->tx_Lines + vw->vw_CursorPos.pos_Line;
-
- if(line->ln_Strlen)
- {
- STRPTR newline;
-
- if(size >= line->ln_Strlen)
- size = line->ln_Strlen - 1;
-
- if(newline = AllocVec(line->ln_Strlen - size, 0L))
- {
- strncpy(newline, line->ln_Line, vw->vw_CursorPos.pos_Col);
- strcpy(newline + vw->vw_CursorPos.pos_Col, line->ln_Line + vw->vw_CursorPos.pos_Col + size);
- FreeVec(line->ln_Line);
- line->ln_Strlen -= size;
- line->ln_Line = newline;
-
- keeppossubx(size);
- return(TRUE);
- }
- return(FALSE);
- }
- return(TRUE);
- }
-
- /*
- * deletes some lines from the cursor pos
- */
- BOOL
- deletelines(LONG size)
- {
- VW *vw = CurrVW;
- BOOL rc;
- rc = (BOOL)resizelinelist(vw->vw_Tx, -size, vw->vw_CursorPos.pos_Line);
- keeppossuby(size);
- return(rc);
- }
-
- /*
- * Deletes from the cursor to endPos
- * sets refresh flags and resync*()'s text but doesn't call refresh().
- */
- BOOL
- deletesection(POS *endPos)
- {
- VW *vw = CurrVW;
- TX *tx = vw->vw_Tx;
- POS oldcurs = vw->vw_CursorPos;
- if(endPos->pos_Line == vw->vw_CursorPos.pos_Line)
- {
- deletechars(endPos->pos_Col - vw->vw_CursorPos.pos_Col);
- setrefresh(RFF_LINEFROM, oldcurs.pos_Col, oldcurs.pos_Line);
- resyncx();
- }
- else
- {
- LONG middle;
- BOOL joinflag = FALSE;
-
- if(vw->vw_CursorPos.pos_Col)
- {
- WORD start = tx->tx_Lines[vw->vw_CursorPos.pos_Line].ln_Strlen - vw->vw_CursorPos.pos_Col - 1;
- if(start)
- deletechars(start);
- vw->vw_CursorPos.pos_Col = 0;
- vw->vw_CursorPos.pos_Line++;
- joinflag = TRUE;
- }
- if(middle = endPos->pos_Line - vw->vw_CursorPos.pos_Line)
- {
- deletelines(middle);
- endPos->pos_Line -= middle;
- }
- if(endPos->pos_Col)
- deletechars(endPos->pos_Col);
- if(joinflag && vw->vw_CursorPos.pos_Line)
- {
- vw->vw_CursorPos.pos_Line--;
- vw->vw_CursorPos.pos_Col = tx->tx_Lines[vw->vw_CursorPos.pos_Line].ln_Strlen - 1;
- joinlines();
- }
- setrefresh(RFF_ALLFROM, oldcurs.pos_Col, oldcurs.pos_Line);
- resyncxy();
- }
- return(TRUE);
- }
-
- /*
- * splits the line into two at the cursor pos
- */
- BOOL
- splitline(VOID)
- {
- VW *vw = CurrVW;
- TX *tx = vw->vw_Tx;
-
- if(resizelinelist(tx, +1, vw->vw_CursorPos.pos_Line + 1))
- {
- LINE *line = tx->tx_Lines + vw->vw_CursorPos.pos_Line;
- STRPTR newline1;
- if(newline1 = savestringn(line->ln_Line, vw->vw_CursorPos.pos_Col))
- {
- STRPTR newline2;
- if(newline2 = savestring(line->ln_Line + vw->vw_CursorPos.pos_Col))
- {
- stuffline(newline1, vw->vw_CursorPos.pos_Line);
- stuffline(newline2, vw->vw_CursorPos.pos_Line + 1);
- keeppossplity();
- return(TRUE);
- }
- freestring(newline1);
- }
- }
- settitle(NoMemMsg);
- return(FALSE);
- }
-
- /*
- * joins the current line to the line below it.
- */
- BOOL
- joinlines(VOID)
- {
- VW *vw = CurrVW;
- TX *tx = vw->vw_Tx;
-
- if((vw->vw_CursorPos.pos_Line + 1) < tx->tx_NumLines)
- {
- LINE *line1 = tx->tx_Lines + vw->vw_CursorPos.pos_Line;
- LINE *line2 = line1 + 1;
- STRPTR newstr;
-
- if(newstr = AllocVec(line1->ln_Strlen + line2->ln_Strlen - 1, 0L))
- {
- stpcpy(stpcpy(newstr, line1->ln_Line), line2->ln_Line);
- resizelinelist(tx, -1, vw->vw_CursorPos.pos_Line);
- stuffline(newstr, vw->vw_CursorPos.pos_Line);
- keepposjoiny();
- return(TRUE);
- }
- settitle(NoMemMsg);
- }
- return(FALSE);
- }
-
- /*
- * Does a 'wordwrap'
- */
- BOOL
- wrapline(VOID)
- {
- VW *vw = CurrVW;
- TX *tx = vw->vw_Tx;
- LINE *line = tx->tx_Lines + vw->vw_CursorPos.pos_Line;
- STRPTR txt = line->ln_Line + vw->vw_CursorPos.pos_Col;
-
- while(!isspace(*txt--))
- {
- if(txt == line->ln_Line - 1)
- return(FALSE);
- }
- txt++;
- vw->vw_CursorPos.pos_Col = txt - line->ln_Line;
- setrefresh(RFF_ALLFROM, vw->vw_CursorPos.pos_Col, vw->vw_CursorPos.pos_Line);
-
- if(resizelinelist(tx, +1, vw->vw_CursorPos.pos_Line + 1))
- {
- LINE *line = tx->tx_Lines + vw->vw_CursorPos.pos_Line;
- STRPTR newline1;
- if(newline1 = savestringn(line->ln_Line, vw->vw_CursorPos.pos_Col))
- {
- STRPTR newline2;
- LONG newlen = line->ln_Strlen - vw->vw_CursorPos.pos_Col - 1;
- LONG indlen = 0;
- LONG movlen = vw->vw_Prefs.prf_RightMargin - vw->vw_CursorPos.pos_Col - 1;
- if(vw->vw_Prefs.prf_AutoIndent)
- {
- STRPTR spc = line->ln_Line;
- while(isspace(*spc++))
- indlen++;
- }
- else
- indlen = vw->vw_Prefs.prf_LeftMargin;
- movlen += indlen;
- if(newline2 = AllocVec(newlen + indlen + 1, 0L))
- {
- STRPTR spc = newline2;
- while(indlen--)
- *spc++ = ' ';
- memcpy(spc, line->ln_Line + vw->vw_CursorPos.pos_Col + 1, newlen);
-
- stuffline(newline1, vw->vw_CursorPos.pos_Line);
- stuffline(newline2, vw->vw_CursorPos.pos_Line + 1);
-
- /* This next bit isn't too satisfactory.
- */
- keeppossubx(line->ln_Strlen - vw->vw_CursorPos.pos_Col - 1);
- keeppossplity();
- if(movlen > 0)
- keepposaddx(movlen);
- else
- keeppossubx(-movlen);
-
- return(TRUE);
- }
- freestring(newline1);
- }
- }
- settitle(NoMemMsg);
- return(FALSE);
- }
-
- /*
- * Inserts spaces from end of line to cursor position (for free-form editing)
- */
- BOOL
- padcursor(VOID)
- {
- VW *vw = CurrVW;
- TX *tx = vw->vw_Tx;
- LINE *line = tx->tx_Lines + vw->vw_CursorPos.pos_Line;
-
- if(vw->vw_LineUndo.line != vw->vw_CursorPos.pos_Line)
- {
- freestring(vw->vw_LineUndo.text);
- vw->vw_LineUndo.text = savestring(line->ln_Line);
- vw->vw_LineUndo.line = vw->vw_CursorPos.pos_Line;
- vw->vw_LineUndo.changes = tx->tx_Changes;
- }
- if(line->ln_Strlen < (vw->vw_CursorPos.pos_Col + 1))
- {
- STRPTR newline;
- if(newline = AllocVec(vw->vw_CursorPos.pos_Col + 1, 0L))
- {
- WORD i;
- strcpy(newline, line->ln_Line);
- for(i = line->ln_Strlen - 1; i < vw->vw_CursorPos.pos_Col; i++)
- newline[i] = ' ';
- newline[i] = 0;
- stuffline(newline, vw->vw_CursorPos.pos_Line);
- return(TRUE);
- }
- settitle(NoMemMsg);
- vw->vw_CursorPos.pos_Col = line->ln_Strlen - 1;
- return(FALSE);
- }
- return(TRUE);
- }
-
- /*
- * if end is before start then swap the two
- */
- VOID
- orderpos(POS *start, POS *end)
- {
- if
- (
- ((start->pos_Line == end->pos_Line) && (start->pos_Col > end->pos_Col)) ||
- (start->pos_Line > end->pos_Line)
- )
- {
- POS temp;
- temp = *start;
- *start = *end;
- *end = temp;
- }
- }
-
- /*
- * cursor is set to start of section, end to end (end is exclusive)
- * types,
- * b - marked Block
- * c - char under Cursor
- * f - whole File
- * l - Line
- * p - Previous character
- * n - Next character
- * w - word
- * el - to EoL
- * sl - to SoL
- * ef - to EoF
- * sf - to SoF
- * mX - to mark X
- */
- BOOL
- getsection(STRPTR type, POS *end)
- {
- VW *vw = CurrVW;
- TX *tx = vw->vw_Tx;
- BOOL rc = TRUE;
-
- switch(tolower(*type++))
- {
- case 'b':
- if(!vw->vw_BlockStatus)
- {
- vw->vw_CursorPos = vw->vw_Block[0];
- *end = vw->vw_Block[1];
- vw->vw_BlockStatus = -1;
- setblockrefresh();
- }
- else
- rc = FALSE;
- break;
- case 'c':
- end->pos_Col = vw->vw_CursorPos.pos_Col + 1;
- end->pos_Line = vw->vw_CursorPos.pos_Line;
- if(end->pos_Col >= tx->tx_Lines[end->pos_Line].ln_Strlen)
- {
- end->pos_Col = 0;
- if(++end->pos_Line >= tx->tx_NumLines)
- rc = FALSE;
- }
- break;
- case 'f':
- vw->vw_CursorPos.pos_Col = vw->vw_CursorPos.pos_Line = 0;
- end->pos_Col = tx->tx_Lines[tx->tx_NumLines - 1].ln_Strlen - 1;
- end->pos_Line = tx->tx_NumLines - 1;
- break;
- case 'l':
- vw->vw_CursorPos.pos_Col = 0;
- end->pos_Col = 0;
- end->pos_Line = vw->vw_CursorPos.pos_Line + 1;
- if(end->pos_Line >= tx->tx_NumLines)
- {
- end->pos_Line--;
- end->pos_Col = tx->tx_Lines[end->pos_Line].ln_Strlen - 1;
- }
- break;
- case 'p':
- end->pos_Col = vw->vw_CursorPos.pos_Col--;
- end->pos_Line = vw->vw_CursorPos.pos_Line;
- if(vw->vw_CursorPos.pos_Col < 0)
- {
- if(--vw->vw_CursorPos.pos_Line < 0)
- {
- vw->vw_CursorPos.pos_Col++;
- vw->vw_CursorPos.pos_Line++;
- return(FALSE);
- }
- vw->vw_CursorPos.pos_Col = tx->tx_Lines[vw->vw_CursorPos.pos_Line].ln_Strlen - 1;
- }
- break;
- case 'n':
- if(++vw->vw_CursorPos.pos_Col > tx->tx_Lines[vw->vw_CursorPos.pos_Line].ln_Strlen - 1)
- {
- if(++vw->vw_CursorPos.pos_Line >= tx->tx_NumLines)
- {
- vw->vw_CursorPos.pos_Col--;
- vw->vw_CursorPos.pos_Line--;
- return(FALSE);
- }
- vw->vw_CursorPos.pos_Col = 0;
- }
- end->pos_Col = vw->vw_CursorPos.pos_Col + 1;
- end->pos_Line = vw->vw_CursorPos.pos_Line;
- if(end->pos_Col > tx->tx_Lines[end->pos_Line].ln_Strlen - 1)
- {
- if(++end->pos_Line >= tx->tx_NumLines)
- return(FALSE);
- end->pos_Col = 0;
- }
- break;
- case 'w':
- if(vw->vw_CursorPos.pos_Col < tx->tx_Lines[vw->vw_CursorPos.pos_Line].ln_Strlen)
- {
- STRPTR line = tx->tx_Lines[vw->vw_CursorPos.pos_Line].ln_Line;
- STRPTR word = line + vw->vw_CursorPos.pos_Col;
- while(isalnum(*word--))
- ;
- word += 2;
- vw->vw_CursorPos.pos_Col = word - line;
- end->pos_Col = stpalnum(word) - line;
- end->pos_Line = vw->vw_CursorPos.pos_Line;
- rc = TRUE;
- }
- else
- rc = FALSE;
- break;
- case 'e':
- switch(tolower(*type++))
- {
- case 'f':
- end->pos_Col = tx->tx_Lines[tx->tx_NumLines - 1].ln_Strlen - 1;
- end->pos_Line = tx->tx_NumLines - 1;
- break;
- case 'l':
- end->pos_Col = tx->tx_Lines[vw->vw_CursorPos.pos_Line].ln_Strlen - 1;
- end->pos_Line = vw->vw_CursorPos.pos_Line;
- break;
- default:
- rc = FALSE;
- }
- break;
- case 's':
- switch(tolower(*type++))
- {
- case 'f':
- *end = vw->vw_CursorPos;
- vw->vw_CursorPos.pos_Col = vw->vw_CursorPos.pos_Line = 0;
- break;
- case 'l':
- *end = vw->vw_CursorPos;
- vw->vw_CursorPos.pos_Col = 0;
- break;
- default:
- rc = FALSE;
- }
- break;
- case 'm':
- APTR dummy;
- MARK *mk;
- WORD mknum = strtol(type, &dummy, 0);
- for(mk = (MARK *)tx->tx_Marks.mlh_Head; mk->mk_Node.mln_Succ; mk = (MARK *)mk->mk_Node.mln_Succ)
- {
- if(mk->mk_Index == mknum)
- break;
- }
- if(mk->mk_Node.mln_Succ)
- {
- *end = mk->mk_Pos;
- if(end->pos_Line >= tx->tx_NumLines)
- end->pos_Line = tx->tx_NumLines - 1;
- if(end->pos_Col >= tx->tx_Lines[end->pos_Line].ln_Strlen)
- end->pos_Col = tx->tx_Lines[end->pos_Line].ln_Strlen - 1;
- orderpos(&vw->vw_CursorPos, end);
- }
- else
- {
- settitlefmt("error: mark %ld is not set", mknum);
- rc = FALSE;
- }
- break;
- default:
- settitle("error: invalid section specification");
- rc = FALSE;
- break;
- }
- return(rc);
- }
-
- /*
- * Returns the number of bytes needed to store a section, doesn't include
- * a zero terminator but does include all newline chars.
- */
- LONG
- sectionlength(POS *startPos, POS *endPos)
- {
- LONG linenum = startPos->pos_Line;
- LINE *line = CurrVW->vw_Tx->tx_Lines + linenum;
- LONG length;
-
- if(startPos->pos_Line == endPos->pos_Line)
- length = endPos->pos_Col - startPos->pos_Col;
- else
- {
- length = line->ln_Strlen - startPos->pos_Col;
- linenum++;
- line++;
- while(linenum < endPos->pos_Line)
- {
- length += line->ln_Strlen;
- linenum++;
- line++;
- }
- length += endPos->pos_Col;
- }
- return(length);
- }
-
- /*
- * Copies a section to a buffer.
- * end of copy does NOT have a zero appended to it.
- */
- VOID
- copysection(POS *startPos, POS *endPos, STRPTR buff)
- {
- LONG linenum = startPos->pos_Line;
- LINE *line = CurrVW->vw_Tx->tx_Lines + linenum;
- LONG copylen;
-
- if(startPos->pos_Line == endPos->pos_Line)
- {
- copylen = endPos->pos_Col - startPos->pos_Col;
- memcpy(buff, line->ln_Line + startPos->pos_Col, copylen);
- buff[copylen] = 0;
- }
- else
- {
- copylen = line->ln_Strlen - startPos->pos_Col - 1;
- memcpy(buff, line->ln_Line + startPos->pos_Col, copylen);
- buff[copylen] = '\n';
- buff += copylen + 1;
- linenum++;
- line++;
- while(linenum < endPos->pos_Line)
- {
- copylen = line->ln_Strlen - 1;
- memcpy(buff, line->ln_Line, copylen);
- buff[copylen] = '\n';
- buff += copylen + 1;
- linenum++;
- line++;
- }
- memcpy(buff, line->ln_Line, endPos->pos_Col);
- }
- }
-
- /*
- * returns TRUE if the specified position is inside a block
- */
- BOOL
- posinblock(WORD col, LONG line)
- {
- VW *vw = CurrVW;
- if
- (
- (vw->vw_BlockStatus) ||
- (line < vw->vw_Block[0].pos_Line) ||
- ((line == vw->vw_Block[0].pos_Line) && (col < vw->vw_Block[0].pos_Col))
- )
- return(FALSE);
- if
- (
- (line < vw->vw_Block[1].pos_Line) ||
- ((line == vw->vw_Block[1].pos_Line) && (col < vw->vw_Block[1].pos_Col))
- )
- return(TRUE);
- return(FALSE);
- }
-
- BOOL
- cursinblock(VOID)
- {
- VW *vw = CurrVW;
- return(posinblock(vw->vw_CursorPos.pos_Col, vw->vw_CursorPos.pos_Line));
- }
-
-
- BOOL
- pageinblock(VOID)
- {
- VW *vw = CurrVW;
- if
- (
- (vw->vw_BlockStatus) ||
- (vw->vw_Block[1].pos_Line < vw->vw_StartLine) ||
- (vw->vw_Block[0].pos_Line >= vw->vw_StartLine + vw->vw_MaxY)
- )
- return(FALSE);
- return(TRUE);
- }
-
- /*
- * these returns,
- *
- * 0 line not in block
- * 1 whole line in block
- * 2 start of line in block
- * 3 end of line in block
- * 4 middle of line in block
- *
- * note:
- * this isn't very intelligent (but it works :-).
- */
- WORD
- lineinblock(LONG line)
- {
- VW *vw = CurrVW;
- BOOL startin = FALSE;
- BOOL endin = FALSE;
-
- if
- (
- (vw->vw_BlockStatus) ||
- (line < vw->vw_Block[0].pos_Line) ||
- (line > vw->vw_Block[1].pos_Line)
- )
- return(0);
-
- if(line == vw->vw_Block[1].pos_Line)
- startin = TRUE;
- if(line == vw->vw_Block[0].pos_Line)
- endin = TRUE;
-
- if(startin)
- {
- if(endin)
- return(4);
- return(2);
- }
- if(endin)
- return(3);
- return(1);
- }
-
- /*
- * makes sure that the marked block is valid
- */
- VOID
- orderblock(VOID)
- {
- VW *vw = CurrVW;
- LINE *fline = vw->vw_Tx->tx_Lines;
- if(!vw->vw_BlockStatus)
- {
- if(vw->vw_Block[0].pos_Col >= fline[vw->vw_Block[0].pos_Line].ln_Strlen)
- vw->vw_Block[0].pos_Col = fline[vw->vw_Block[0].pos_Line].ln_Strlen - 1;
- if(vw->vw_Block[1].pos_Col >= fline[vw->vw_Block[1].pos_Line].ln_Strlen)
- vw->vw_Block[1].pos_Col = fline[vw->vw_Block[1].pos_Line].ln_Strlen - 1;
-
- if(vw->vw_Block[0].pos_Line > vw->vw_Block[1].pos_Line)
- {
- POS temp = vw->vw_Block[1];
- vw->vw_Block[1] = vw->vw_Block[0];
- vw->vw_Block[0] = temp;
- }
- else if(vw->vw_Block[0].pos_Line == vw->vw_Block[1].pos_Line)
- {
- if(vw->vw_Block[0].pos_Col > vw->vw_Block[1].pos_Col)
- {
- POS temp = vw->vw_Block[1];
- vw->vw_Block[1] = vw->vw_Block[0];
- vw->vw_Block[0] = temp;
- }
- }
- }
- }
-
- /*
- * Set up the refresh flags to refresh the block in the most efficient manner.
- * To make it better I'll have to add a refresh type which allows you to say
- * where to stop drawing.
- */
- VOID
- setblockrefresh(VOID)
- {
- VW *vw = CurrVW;
- LONG endline = vw->vw_StartLine + vw->vw_MaxY;
- WORD refx;
- LONG refy;
-
- if((vw->vw_Block[0].pos_Line > endline) || (vw->vw_Block[1].pos_Line < vw->vw_StartLine))
- return;
-
- if(vw->vw_Block[0].pos_Line < vw->vw_StartLine)
- {
- refy= vw->vw_StartLine;
- refx = 0;
- }
- else
- {
- refy = vw->vw_Block[0].pos_Line;
- refx = vw->vw_Block[0].pos_Col;
- }
- if(vw->vw_Block[0].pos_Line == vw->vw_Block[1].pos_Line)
- setrefresh(RFF_LINEFROM, refx, refy);
- else
- setrefresh(RFF_ALLFROM, refx, refy);
- }
-
- /*
- * Returns the number of bytes from the start of the file that the cursor
- * is.
- */
- LONG
- offset(VOID)
- {
- VW *vw = CurrVW;
- LINE *line = vw->vw_Tx->tx_Lines;
- LONG linenum = 0;
- LONG off = 0;
-
- while(linenum < vw->vw_CursorPos.pos_Line)
- {
- off += line->ln_Strlen;
- line++;
- linenum++;
- }
- off += vw->vw_CursorPos.pos_Col;
- return(off);
- }
-
- /*
- * Returns the number of bytes in the file
- */
- LONG
- size(VOID)
- {
- TX *tx = CurrVW->vw_Tx;
- LINE *line = tx->tx_Lines;
- LONG linenum = 0;
- LONG size = 0;
-
- while(linenum < tx->tx_NumLines)
- {
- size += line->ln_Strlen;
- line++;
- linenum++;
- }
- return(size);
- }
-
-