home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
World of A1200
/
World_Of_A1200.iso
/
programs
/
text
/
jed
/
src
/
jed.lha
/
movement.c
< prev
next >
Wrap
C/C++ Source or Header
|
1993-01-16
|
16KB
|
864 lines
/*
* MOVEMENT.C
* (c) 1992 J.Harper
*/
#include "jed.h"
#include "jed_protos.h"
Prototype VALUE * cmd_move (LONG, VALUE *);
Prototype VOID setautomark (VOID);
Local LONG moveautomark (VOID);
Local LONG movebookmark (WORD);
Local LONG setbookmark (WORD);
Prototype VOID killmarklist (TX *);
Local LONG moveblockstart (VOID);
Local LONG moveblockend (VOID);
Local LONG movecolumn (WORD);
Prototype LONG movedownpages (LONG);
Prototype LONG moveuppages (LONG);
Prototype LONG movedownlines (LONG);
Prototype LONG moveuplines (LONG);
Prototype LONG moveeof (VOID);
Prototype LONG moveeol (VOID);
Prototype LONG movesof (VOID);
Prototype LONG movesol (VOID);
Prototype LONG movelinenum (LONG);
Prototype LONG moveleft (WORD);
Prototype LONG moveright (WORD);
Local LONG movematchingbrac (VOID);
Local LONG movenextchar (LONG);
Local LONG moveprevchar (LONG);
Prototype LONG movenexttab (LONG);
Prototype LONG moveprevtab (LONG);
Prototype LONG movenextword (LONG);
Prototype LONG moveprevword (LONG);
Prototype BOOL moveoffset (LONG);
Prototype VOID positioncursorfine (WORD, WORD);
VALUE *
cmd_move(LONG argc, VALUE *argv)
{
STRPTR arg = ARG1.val_Value.String;
LONG rc;
BOOL argok = TRUE;
if(!TPLATE1(VTF_STRING))
return(&RES);
switch(*arg++)
{
case 'a':
if(*arg == 'm')
rc = moveautomark();
break;
case 'b':
switch(*arg++)
{
case 'm':
if(ARG2.val_Type == VTF_NUMBER)
rc = movebookmark((WORD)ARG2.val_Value.Number);
else
argok = FALSE;
break;
case 's':
rc = moveblockstart();
break;
case 'e':
rc = moveblockend();
break;
}
break;
case 'c':
if(*arg++ == 'n')
{
if(ARG2.val_Type == VTF_NUMBER)
rc = movecolumn((WORD)ARG2.val_Value.Number);
else
argok = FALSE;
}
break;
case 'd':
if(ARG2.val_Type == VTF_NUMBER)
{
if(*arg == 'p')
rc = movedownpages(ARG2.val_Value.Number);
else
rc = movedownlines(ARG2.val_Value.Number);
}
else
argok = FALSE;
break;
case 'e':
switch(*arg++)
{
case 'f':
rc = moveeof();
break;
case 'l':
rc = moveeol();
break;
}
break;
case 'l':
if(ARG2.val_Type == VTF_NUMBER)
{
switch(*arg++)
{
case 't':
rc = moveprevtab(ARG2.val_Value.Number);
break;
case 'n':
rc = movelinenum(ARG2.val_Value.Number);
default:
rc = moveleft((WORD)ARG2.val_Value.Number);
break;
}
}
else
argok = FALSE;
break;
case 'm':
if(*arg == 'b')
rc = movematchingbrac();
break;
case 'n':
if(ARG2.val_Type == VTF_NUMBER)
{
switch(*arg++)
{
case 'c':
rc = movenextchar(ARG2.val_Value.Number);
break;
case 'w':
rc = movenextword(ARG2.val_Value.Number);
break;
}
}
else
argok = FALSE;
break;
case 'o':
if(ARG2.val_Type == VTF_NUMBER)
rc = moveoffset(ARG2.val_Value.Number);
else
argok = FALSE;
break;
case 'p':
if(ARG2.val_Type == VTF_NUMBER)
{
switch(*arg++)
{
case 'c':
rc = moveprevchar(ARG2.val_Value.Number);
break;
case 'w':
rc = moveprevword(ARG2.val_Value.Number);
break;
}
}
else
argok = FALSE;
break;
case 'r':
if(ARG2.val_Type == VTF_NUMBER)
{
switch(*arg++)
{
case 't':
rc = movenexttab(ARG2.val_Value.Number);
break;
default:
rc = moveright((WORD)ARG2.val_Value.Number);
break;
}
}
else
argok = FALSE;
break;
case 's':
switch(*arg++)
{
case 'f':
rc = movesof();
break;
case 'l':
rc = movesol();
break;
case 'm':
if(ARG2.val_Type == VTF_NUMBER)
rc = setbookmark((WORD)ARG2.val_Value.Number);
else
argok = FALSE;
break;
}
break;
case 'u':
if(ARG2.val_Type == VTF_NUMBER)
{
if(*arg == 'p')
rc = moveuppages(ARG2.val_Value.Number);
else
rc = moveuplines(ARG2.val_Value.Number);
break;
}
else
argok = FALSE;
default:
settitle(BadArgMsg);
rc = FALSE;
}
if(!argok)
{
settitle("syntax error: argument 2 should be a number");
rc = FALSE;
}
setnumres(rc);
return(&RES);
}
VOID
setautomark(VOID)
{
VW *vw = CurrVW;
vw->vw_AutoMark = vw->vw_CursorPos;
}
Local LONG
moveautomark(VOID)
{
VW *vw = CurrVW;
POS temp = vw->vw_CursorPos;
vw->vw_CursorPos = vw->vw_AutoMark;
vw->vw_AutoMark = temp;
resyncxy();
return(TRUE);
}
Local LONG
movebookmark(WORD markNum)
{
VW *vw = CurrVW;
TX *tx = vw->vw_Tx;
MARK *mark;
for(mark = (MARK *)tx->tx_Marks.mlh_Head; mark->mk_Node.mln_Succ; mark = (MARK *)mark->mk_Node.mln_Succ)
{
if(mark->mk_Index == markNum)
break;
}
if(mark->mk_Node.mln_Succ)
{
setautomark();
vw->vw_CursorPos = mark->mk_Pos;
resyncxy();
return(TRUE);
}
settitle("error: no mark of that number");
return(FALSE);
}
Local LONG
setbookmark(WORD markNum)
{
VW *vw = CurrVW;
TX *tx = vw->vw_Tx;
MARK *mark;
for(mark = (MARK *)tx->tx_Marks.mlh_Head; mark->mk_Node.mln_Succ; mark = (MARK *)mark->mk_Node.mln_Succ)
{
if(mark->mk_Index == markNum)
break;
}
if(!mark->mk_Node.mln_Succ)
{
if(mark = AllocVec(sizeof(MARK), MEMF_CLEAR))
{
AddMTail(&tx->tx_Marks, &mark->mk_Node);
mark->mk_Index = markNum;
}
else
{
settitle(NoMemMsg);
return(FALSE);
}
}
mark->mk_Pos = vw->vw_CursorPos;
settitle("mark set");
return(TRUE);
}
VOID
killmarklist(TX *tx)
{
MARK *thismark, *nextmark;
thismark = (MARK *)tx->tx_Marks.mlh_Head;
while(nextmark = (MARK *)thismark->mk_Node.mln_Succ)
{
RemoveM(&thismark->mk_Node);
FreeVec(thismark);
thismark = nextmark;
}
}
Local LONG
moveblockstart(VOID)
{
VW *vw = CurrVW;
if((!vw->vw_BlockStatus) || (vw->vw_BlockStatus == 1))
{
setautomark();
vw->vw_CursorPos = vw->vw_Block[0];
resyncxy();
return(TRUE);
}
return(FALSE);
}
Local LONG
moveblockend(VOID)
{
VW *vw = CurrVW;
if((!vw->vw_BlockStatus) || (vw->vw_BlockStatus == 2))
{
setautomark();
vw->vw_CursorPos = vw->vw_Block[1];
resyncxy();
return(TRUE);
}
return(FALSE);
}
Local LONG
movecolumn(WORD col)
{
CurrVW->vw_CursorPos.pos_Col = col - 1;
resyncx();
return(TRUE);
}
LONG
movedownpages(LONG pages)
{
VW *vw = CurrVW;
LONG newline, rc;
newline = vw->vw_CursorPos.pos_Line + (pages * vw->vw_MaxY);
if(newline >= vw->vw_Tx->tx_NumLines)
{
newline = vw->vw_Tx->tx_NumLines - 1;
rc = FALSE;
}
else
{
vw->vw_StartLine += (pages * vw->vw_MaxY);
vw->vw_RefreshType |= RFF_ALL;
rc = TRUE;
}
vw->vw_CursorPos.pos_Line = newline;
resyncy();
return(rc);
}
LONG
moveuppages(LONG pages)
{
VW *vw = CurrVW;
LONG newline, rc;
newline = vw->vw_CursorPos.pos_Line - (pages * vw->vw_MaxY);
if(newline < 0)
{
newline = 0;
rc = FALSE;
}
else
{
vw->vw_StartLine -= (pages * vw->vw_MaxY);
if(vw->vw_StartLine < 0)
vw->vw_StartLine = 0;
vw->vw_RefreshType |= RFF_ALL;
rc = TRUE;
}
vw->vw_CursorPos.pos_Line = newline;
resyncy();
return(rc);
}
LONG
movedownlines(LONG lines)
{
VW *vw = CurrVW;
LONG newline, rc;
newline = vw->vw_CursorPos.pos_Line + lines;
if(newline >= vw->vw_Tx->tx_NumLines)
{
newline = vw->vw_Tx->tx_NumLines - 1;
rc = FALSE;
}
else
rc = TRUE;
vw->vw_CursorPos.pos_Line = newline;
resyncy();
return(rc);
}
LONG
moveuplines(LONG lines)
{
VW *vw = CurrVW;
LONG newline, rc;
newline = vw->vw_CursorPos.pos_Line - lines;
if(newline < 0)
{
newline = 0;
rc = FALSE;
}
else
rc = TRUE;
vw->vw_CursorPos.pos_Line = newline;
resyncy();
return(rc);
}
LONG
moveeof(VOID)
{
VW *vw = CurrVW;
setautomark();
vw->vw_CursorPos.pos_Line = vw->vw_Tx->tx_NumLines - 1;
resyncy();
return(TRUE);
}
LONG
moveeol(VOID)
{
VW *vw = CurrVW;
vw->vw_CursorPos.pos_Col = vw->vw_Tx->tx_Lines[vw->vw_CursorPos.pos_Line].ln_Strlen - 1;
resyncx();
return(TRUE);
}
LONG
movesof(VOID)
{
setautomark();
CurrVW->vw_CursorPos.pos_Line = 0;
resyncy();
return(TRUE);
}
LONG
movesol(VOID)
{
CurrVW->vw_CursorPos.pos_Col = 0;
resyncx();
return(TRUE);
}
LONG
movelinenum(LONG line)
{
VW *vw = CurrVW;
LONG rc;
if(--line < 0)
{
settitle("error: lines start at 1");
rc = FALSE;
}
else
{
if(line >= vw->vw_Tx->tx_NumLines)
{
settitlefmt("error: line %ld doesn't exist!", line + 1);
rc = FALSE;
}
else
{
setautomark();
vw->vw_CursorPos.pos_Line = line;
resyncy();
rc = TRUE;
}
}
return(rc);
}
LONG
moveleft(WORD distance)
{
VW *vw = CurrVW;
LONG rc;
vw->vw_CursorPos.pos_Col -= distance;
if(vw->vw_CursorPos.pos_Col < 0)
{
vw->vw_CursorPos.pos_Col = 0;
rc = FALSE;
}
else
rc = TRUE;
resyncx();
return(rc);
}
LONG
moveright(WORD distance)
{
VW *vw = CurrVW;
vw->vw_CursorPos.pos_Col += distance;
resyncx();
return(TRUE);
}
Local LONG
movematchingbrac(VOID)
{
#define NUM_BRAC_TYPES 10
static UBYTE bracs[] =
{
'{', '}',
'(', ')',
'[', ']',
'`', '\'',
'<', '>'
};
VW *vw = CurrVW;
TX *tx = vw->vw_Tx;
LINE *line = tx->tx_Lines + vw->vw_CursorPos.pos_Line;
if(vw->vw_CursorPos.pos_Col < line->ln_Strlen)
{
UBYTE startc = line->ln_Line[vw->vw_CursorPos.pos_Col];
WORD i;
for(i = 0; i < NUM_BRAC_TYPES; i++)
{
if(startc == bracs[i])
break;
}
if(i < NUM_BRAC_TYPES)
{
WORD x = vw->vw_CursorPos.pos_Col;
LONG y = vw->vw_CursorPos.pos_Line;
WORD braccount = 1;
BOOL found = FALSE;
if(i & 1)
{
/* search backwards
*/
UBYTE endc = bracs[i - 1];
while(!found)
{
UBYTE c;
if(--x < 0)
{
if(--y < 0)
{
settitle("error: can't find matching bracket");
return(FALSE);
}
line--;
x = line->ln_Strlen - 1;
}
c = line->ln_Line[x];
if(c == startc)
braccount++;
else if(c == endc)
{
if(!(--braccount))
found = TRUE;
}
}
}
else
{
/* search forwards
*/
UBYTE endc = bracs[i + 1];
while(!found)
{
UBYTE c;
if(++x >= line->ln_Strlen)
{
if(++y >= tx->tx_NumLines)
{
settitle("error: can't find matching bracket");
return(FALSE);
}
line++;
x = 0;
}
c = line->ln_Line[x];
if(c == startc)
braccount++;
else if(c == endc)
{
if(!(--braccount))
found = TRUE;
}
}
}
vw->vw_CursorPos.pos_Col = x;
vw->vw_CursorPos.pos_Line = y;
resyncxy();
return(TRUE);
}
}
settitle("error: cursor must be on a bracket");
return(FALSE);
}
Local LONG
movenextchar(LONG chars)
{
VW *vw = CurrVW;
TX *tx = vw->vw_Tx;
LONG rc = FALSE;
if((vw->vw_CursorPos.pos_Col += chars) >= tx->tx_Lines[vw->vw_CursorPos.pos_Line].ln_Strlen)
{
if(++vw->vw_CursorPos.pos_Line >= tx->tx_NumLines)
{
vw->vw_CursorPos.pos_Col -= chars;
vw->vw_CursorPos.pos_Line--;
}
else
{
vw->vw_CursorPos.pos_Col = 0;
resyncxy();
rc = TRUE;
}
}
else
{
resyncx();
rc = TRUE;
}
return(rc);
}
Local LONG
moveprevchar(LONG chars)
{
VW *vw = CurrVW;
LONG rc = FALSE;
if((vw->vw_CursorPos.pos_Col -= chars) < 0)
{
if(--vw->vw_CursorPos.pos_Line < 0)
{
vw->vw_CursorPos.pos_Line = 0;
vw->vw_CursorPos.pos_Col += chars;
}
else
{
vw->vw_CursorPos.pos_Col = vw->vw_Tx->tx_Lines[vw->vw_CursorPos.pos_Line].ln_Strlen - 1;
resyncxy();
rc = TRUE;
}
}
else
{
resyncx();
rc = TRUE;
}
return(rc);
}
LONG
movenexttab(LONG tabs)
{
VW *vw = CurrVW;
vw->vw_CursorPos.pos_Col = ((vw->vw_CursorPos.pos_Col / vw->vw_Prefs.prf_TabSize) + 1) * vw->vw_Prefs.prf_TabSize;
resyncx();
return(TRUE);
}
LONG
moveprevtab(LONG tabs)
{
VW *vw = CurrVW;
LONG rc;
if(vw->vw_CursorPos.pos_Col)
{
vw->vw_CursorPos.pos_Col = (((vw->vw_CursorPos.pos_Col - 1) / vw->vw_Prefs.prf_TabSize)) * vw->vw_Prefs.prf_TabSize;
if(vw->vw_CursorPos.pos_Col < 0)
{
vw->vw_CursorPos.pos_Col = 0;
rc = FALSE;
}
else
rc = TRUE;
resyncx();
return(rc);
}
return(TRUE);
}
LONG
movenextword(LONG words)
{
VW *vw = CurrVW;
TX *tx = vw->vw_Tx;
LONG rc = TRUE;
POS oldcurs = vw->vw_CursorPos;
while(words--)
{
LINE *line = tx->tx_Lines + vw->vw_CursorPos.pos_Line;
STRPTR word;
if(vw->vw_CursorPos.pos_Col >= line->ln_Strlen)
vw->vw_CursorPos.pos_Col = line->ln_Strlen - 1;
word = line->ln_Line + vw->vw_CursorPos.pos_Col;
while(isalnum(*word))
word++;
while(!isalnum(*word))
{
if(*word++ == 0)
{
if(++vw->vw_CursorPos.pos_Line >= tx->tx_NumLines)
{
vw->vw_CursorPos.pos_Line--;
word--;
rc = FALSE;
goto end;
}
line++;
word = line->ln_Line;
}
}
vw->vw_CursorPos.pos_Col = word - line->ln_Line;
}
end:
if(!rc)
vw->vw_CursorPos = oldcurs;
else
resyncxy();
return(rc);
}
LONG
moveprevword(LONG words)
{
VW *vw = CurrVW;
TX *tx = vw->vw_Tx;
LONG rc = TRUE;
POS oldcurs = vw->vw_CursorPos;
while(words--)
{
LINE *line = tx->tx_Lines + vw->vw_CursorPos.pos_Line;
STRPTR word;
if(vw->vw_CursorPos.pos_Col >= line->ln_Strlen)
vw->vw_CursorPos.pos_Col = line->ln_Strlen - 1;
word = line->ln_Line + vw->vw_CursorPos.pos_Col;
while(isalnum(*word))
{
if(word-- == line->ln_Line)
{
if(--vw->vw_CursorPos.pos_Line < 0)
{
vw->vw_CursorPos.pos_Line++;
word++;
rc = FALSE;
goto end;
}
line--;
word = line->ln_Line + line->ln_Strlen - 1;
}
}
while(!isalnum(*word))
{
if(word-- == line->ln_Line)
{
if(--vw->vw_CursorPos.pos_Line < 0)
{
vw->vw_CursorPos.pos_Line++;
word++;
rc = FALSE;
goto end;
}
line--;
word = line->ln_Line + line->ln_Strlen - 1;
}
}
while(isalnum(*word))
{
if(word-- == line->ln_Line)
break;
}
vw->vw_CursorPos.pos_Col = word - line->ln_Line + 1;
}
end:
if(!rc)
vw->vw_CursorPos = oldcurs;
else
resyncxy();
return(rc);
}
BOOL
moveoffset(LONG offset)
{
VW *vw = CurrVW;
TX *tx = vw->vw_Tx;
LINE *line = tx->tx_Lines;
LONG linenum = 0;
while(linenum < tx->tx_NumLines)
{
offset -= line->ln_Strlen;
if(offset < 0)
{
offset += line->ln_Strlen;
setautomark();
vw->vw_CursorPos.pos_Col = offset;
vw->vw_CursorPos.pos_Line = linenum;
resyncxy();
return(TRUE);
}
linenum++;
line++;
}
return(FALSE);
}
VOID
positioncursorfine(WORD x, WORD y)
{
VW *vw = CurrVW;
struct Window *wd = vw->vw_Window;
if(x >= wd->Width)
vw->vw_CursorPos.pos_Col = vw->vw_StartCol + vw->vw_MaxX + 1;
else if(x <= 0)
vw->vw_CursorPos.pos_Col = vw->vw_StartCol - 1;
else
vw->vw_CursorPos.pos_Col = vw->vw_StartCol + ((x - (WORD)vw->vw_XStartPix) / (WORD)vw->vw_FontX);
if(y >= vw->vw_Window->Height)
vw->vw_CursorPos.pos_Line = vw->vw_StartLine + vw->vw_MaxY;
else if(y <= 0)
vw->vw_CursorPos.pos_Line = vw->vw_StartLine - 1;
else
vw->vw_CursorPos.pos_Line = vw->vw_StartLine + ((y - (WORD)vw->vw_YStartPix) / (WORD)vw->vw_FontY);
if(vw->vw_CursorPos.pos_Col < 0)
vw->vw_CursorPos.pos_Col = 0;
if(vw->vw_CursorPos.pos_Line < 0)
vw->vw_CursorPos.pos_Line = 0;
if(vw->vw_CursorPos.pos_Line >= vw->vw_Tx->tx_NumLines)
vw->vw_CursorPos.pos_Line = vw->vw_Tx->tx_NumLines - 1;
}