/* BEGIN DOCUMENTATION Name: TCMWRD.C Created: 02/07/84 DTS Last Update: 05/03/84 Title: Text collection management word editing functions. Index: Abstract: Implements word orientated keypad functions of TCM system. All functions have same basic format. Usage: coutptr = func(cinptr); Parameters: cinptr - pointer to current character in fixed line buffer. coutptr - pointer to new current character after function applied. Note: Many routines use and change global editing parameters defined in TCMPUBLIC.H. Environment: DECUS C, RSX11M V4.0 See Also: TCM.DOC, TCMTABLES.C, TCMEDIT.C, TCMEDFUNC.C Description: wordlf - Move cursor left word wordrt - Move cursor right word dewdlf - Delete word to the left of the cursor dewdrt - Delete word right deline - Delete line cursor is on inline - Insert blank line at cursor line undelt - Undelete last word or line deleted. Example(s): Uses: Internal: Note: delbuf[] stores deleted line or word, '\r' indicates a line delete was done & '\n' marks a line break as part of a word or character delete. Update History: 03/07/84 - DTS Added call to padchr to instring. END DOCUMENTATION */ #include #include #include #include "tcmerr.h" #include "tcmdefs.h" #include "tcmpublic.h" /* external data references */ extern char wrddel[]; /* String of word terminating characters */ extern int linevir; /* Displayable chars on current line (TCMSCRN) */ /* external function references */ extern char *index(); extern rfline(); extern charpointer csleft(); extern charpointer csdown(); extern charpointer dechrt(); extern charpointer inewln(); /* forward references */ extern boolean inword(); /* Returns true if character is not a word terminator */ extern delchrs(); /* Delete characters from current line */ extern instring(); /* Insert string in current line */ /*** WORDLF: Move cursor left word, if at start backup line ***/ charpointer wordlf(chr) register charpointer chr; { iff chr-line > lin[0].len then /* Beyond end of line */ { chr = &line[lin[0].len - 1]; *chr = eos; bufcol = virlen(line) + 1; } else iff bufcol == 1 then chr = csleft(chr); else { bufcol--; chr--; /* Backup char, assumes no enhancements */ while(! inword(*chr) and bufcol > 0) { bufcol--; chr--; } /* Backup until inword */ while( inword(*chr) and bufcol > 0) { bufcol--; chr--; } /* Backup until not inword */ bufcol++; chr++; /* Advance to next character */ } return(chr); } /* end wordlf */ /*** WORDRT: Move cursor right word, if at end advance line ***/ charpointer wordrt(chr) register charpointer chr; { register charpointer linend; linend = &line[lin[0].len - 1]; while(inword(*chr) and chr < linend) { chr++; bufcol++; } /* Advance until not in word */ iff chr >= linend then /* At or beyond end */ { iff bufline < curwin->botline then { bufcol = 1; chr = csdown(chr); } /* Advance to next line */ } else { /* Advance character, assumes no enhancements */ while(! inword(*chr) and chr < linend) { chr++; bufcol++; } /* Advance until in word */ } return(chr); } /* end wordrt */ /*** DEWDRT: Delete word right ***/ charpointer dewdrt(chr) register charpointer chr; { register charpointer nxt; register int oldcol; iff rdonly then { tcmerr(TS_IKY); return(chr); } iff (chr-line) >= (lin[0].len-1) then /* At or beyond end of line */ { cpystr(delbuf,"\n"); chr = dechrt(chr); } else { oldcol = bufcol; nxt = wordrt(chr); /* Point to start of next word */ iff bufcol == 1 then /* Must have gone to next line */ nxt = csleft(nxt); bufcol = oldcol; delchrs(chr,nxt-chr,delbuf); /* Remove from line, place in delbuf */ } return(chr); } /* end dewdrt */ /*** DEWDLF: Delete word to the left of the cursor ***/ charpointer dewdlf(chr) register charpointer chr; { register charpointer nxt; iff rdonly then { tcmerr(TS_IKY); return(chr); } iff bufcol == 1 then /* At start of line */ nxt = deleft(chr); /* Delete character left */ else { nxt = wordlf(chr); /* Move word left first */ delchrs(nxt,chr-nxt,delbuf); /* Remove from line */ } return(nxt); } /* end dewdlf */ /*** DELINE: Delete line cursor is on ***/ charpointer deline(chr) register charpointer chr; { register int oldcol; iff rdonly then { tcmerr(TS_IKY); return(chr); } chr = &line[lin[0].len-1]; /* Point to end */ *chr++ = '\r'; /* Mark as a line */ *chr = eos; cpystr(delbuf,line); /* Save entire line to delete buffer */ line[0] = eos; oldcol = bufcol; bufcol = lin[0].len = 1; /* Kill entire line */ linevir = 0; lin[0].fircol = newlin; iff curwin->botline > bufline then /* Stay here if last line */ { chr = csdown(line); chr = deleft(line); chr = deleft(chr); /* Delete line in buffer */ bufcol = oldcol; } return(virchr(line,oldcol)); } /* end deline */ /*** inline: Insert blank line at cursor line ***/ charpointer inline(chr) register charpointer chr; { register charpointer nchr; register int oldcol; iff rdonly then { tcmerr(TS_IKY); return(chr); } oldcol = bufcol; bufcol = 1; /* Cursor at start of new line */ nchr = inewln(line); iff ret.cd == TS_SUC then return(nchr); else { bufcol = oldcol; return(chr); } } /* end inline */ /*** UNDELT: Undelete last deleted word or line. ***/ charpointer undelt(chr) register charpointer chr; { register charpointer linend; register int oldcol; iff rdonly then { tcmerr(TS_IKY); return(chr); } iff (linend = index(delbuf,'\r')) != NULL then /* Undelete line */ { oldcol = bufcol; *linend = eos; iff (bufline < curwin->botline) or (lin[0].len > 1) then chr = inline(chr); /* Insert blank line */ else { linevir = virlen(delbuf); lin[0].fircol = newlin; } iff ret.cd == TS_SUC then { instring(line,delbuf); /* Insert entire line */ *linend = '\r'; /* Restore end marker */ chr = virchr(line,oldcol); } bufcol = oldcol; } else iff delbuf[0] == '\n' then /* Insert line break */ chr = inewln(chr); else { instring(chr,delbuf); /* Insert word at chr */ rfline(bufcol,chr-line,lin[0].len+1); /* Update screen pointers */ } return(chr); } /* end undelt */ /*** INWORD: Return false if character is a word terminator ***/ inword(ch) register char ch; { register charpointer ptr; for(ptr = wrddel; *ptr != eos; ptr++) iff *ptr == ch then break; iff *ptr == eos then return(true); else return(false); } /* end inword */ /*** INSTRING: Insert string into current line buffer ***/ /* wrap if line is too long for margins */ instring(ptr,strg) register charpointer ptr,strg; { register struct twindcb *win; register int slen; register charpointer linend; char tempch; win = curwin; slen = strlen(strg); iff ptr >= &line[lin[0].len] then /* pad with spaces */ padlin(ptr); iff ret.cd == TS_SUC then { linend = &line[lin[0].len+1]; lin[0].len += slen; linevir = virlen(strg) + virlen(line); iff (linevir > win->width) and (win->botline+1 >= win->virt_lines) then tcmerr(TS_MCP); else iff win->curmax + lin[0].len > win->max_chars then tcmerr(TS_BFP); iff ret.cd != TS_SUC then /* Undo everything */ { lin[0].len -= slen; linevir = virlen(line); } else { moveup(ptr,ptr+slen,linend-ptr); /* Make room for string in line */ tempch = *(ptr+slen); cpystr(ptr,strg); /* Insert string */ *(ptr+slen) = tempch; iff virlen(line) > curwin->width then wrapln(ptr); } } } /* end instring */ /*** DELCHRS: Remove characters from current line buffer ***/ delchrs(ptr,cnt,cutptr) register charpointer ptr; /* Pointer into line[] */ charpointer cutptr; /* Pointer to save buffer */ register int cnt; /* Number of actual chars to delete */ { register charpointer linend,chrend; char tempch; linend = &line[lin[0].len-1]; /* End of line */ iff linend - ptr < cnt then /* Cnt is actual chars, not displayable only */ cnt = linend - ptr; iff cnt > 0 then { chrend = ptr + cnt; tempch = *chrend; *chrend = eos; cpystr(cutptr,ptr); /* Save chars to delbuf */ *chrend = tempch; movedn(chrend,ptr,linend-chrend); /* Close line cnt characters */ rfline(bufcol,ptr-line,lin[0].len); /* Update screen pointers */ lin[0].len -= cnt; linevir -= virlen(cutptr); } } /* end delchrs */ /*** WRAPLN: Wrap current line in line[] buffer, too long ***/ wrapln(chr) register charpointer chr; { register int oldcol; oldcol = bufcol; chr = inewln(chr); /* Temporary call other functions */ iff ret.cd == TS_SUC then { bufcol = 1; chr = csdown(line); } iff ret.cd == TS_SUC then chr = deleft(chr); bufcol = oldcol; } /* end wrapln */