minix/commands/elvis/move5.c

257 lines
4.2 KiB
C
Raw Normal View History

2005-04-21 16:53:53 +02:00
/* move5.c */
/* Author:
* Steve Kirkendall
* 14407 SW Teal Blvd. #C
* Beaverton, OR 97005
* kirkenda@cs.pdx.edu
*/
/* This file contains the word-oriented movement functions */
#include "config.h"
#include "ctype.h"
#include "vi.h"
MARK m_fword(m, cnt, cmd, prevkey)
MARK m; /* movement is relative to this mark */
long cnt; /* a numeric argument */
int cmd; /* either 'w' or 'W' */
int prevkey;/* previous command... if 'c' then exclude whitespace */
{
REG long l;
REG char *text;
REG int i;
DEFAULT(1);
l = markline(m);
pfetch(l);
text = ptext + markidx(m);
#ifndef CRUNCH
/* As a special case, "cw" or "cW" on whitespace without a count
* treats the single whitespace character under the cursor as a word.
*/
if (cnt == 1L && prevkey == 'c' && isspace(*text))
{
return m + 1L;
}
#endif
while (cnt-- > 0) /* yes, ASSIGNMENT! */
{
i = *text++;
if (cmd == 'W')
{
/* include any non-whitespace */
while (i && !isspace(i))
{
i = *text++;
}
}
else if (isalnum(i) || i == '_')
{
/* include an alphanumeric word */
while (i && isalnum(i))
{
i = *text++;
}
}
else
{
/* include contiguous punctuation */
while (i && !isalnum(i) && !isspace(i))
{
i = *text++;
}
}
/* if not part of "cw" or "cW" command... */
if (prevkey != 'c' || cnt > 0)
{
/* include trailing whitespace */
while (!i || isspace(i))
{
/* did we hit the end of this line? */
if (!i)
{
/* "dw" shouldn't delete newline after word */
if (prevkey && cnt == 0)
{
break;
}
/* move to next line, if there is one */
l++;
if (l > nlines)
{
return MARK_UNSET;
}
pfetch(l);
text = ptext;
}
i = *text++;
}
}
text--;
}
/* if argument to operator, then back off 1 char since "w" and "W"
* include the last char in the affected text.
*/
if (prevkey)
{
text--;
}
/* construct a MARK for this place */
m = buildmark(text);
return m;
}
MARK m_bword(m, cnt, cmd)
MARK m; /* movement is relative to this mark */
long cnt; /* a numeric argument */
int cmd; /* either 'b' or 'B' */
{
REG long l;
REG char *text;
DEFAULT(1);
l = markline(m);
pfetch(l);
text = ptext + markidx(m);
while (cnt-- > 0) /* yes, ASSIGNMENT! */
{
text--;
/* include preceding whitespace */
while (text < ptext || isspace(*text))
{
/* did we hit the end of this line? */
if (text < ptext)
{
/* move to preceding line, if there is one */
l--;
if (l <= 0)
{
return MARK_UNSET;
}
pfetch(l);
text = ptext + plen - 1;
}
else
{
text--;
}
}
if (cmd == 'B')
{
/* include any non-whitespace */
while (text >= ptext && !isspace(*text))
{
text--;
}
}
else if (isalnum(*text) || *text == '_')
{
/* include an alphanumeric word */
while (text >= ptext && isalnum(*text))
{
text--;
}
}
else
{
/* include contiguous punctuation */
while (text >= ptext && !isalnum(*text) && !isspace(*text))
{
text--;
}
}
text++;
}
/* construct a MARK for this place */
m = buildmark(text);
return m;
}
MARK m_eword(m, cnt, cmd)
MARK m; /* movement is relative to this mark */
long cnt; /* a numeric argument */
int cmd; /* either 'e' or 'E' */
{
REG long l;
REG char *text;
REG int i;
DEFAULT(1);
l = markline(m);
pfetch(l);
text = ptext + markidx(m);
while (cnt-- > 0) /* yes, ASSIGNMENT! */
{
if (*text)
text++;
i = *text++;
/* include preceding whitespace */
while (!i || isspace(i))
{
/* did we hit the end of this line? */
if (!i)
{
/* move to next line, if there is one */
l++;
if (l > nlines)
{
return MARK_UNSET;
}
pfetch(l);
text = ptext;
}
i = *text++;
}
if (cmd == 'E')
{
/* include any non-whitespace */
while (i && !isspace(i))
{
i = *text++;
}
}
else if (isalnum(i) || i == '_')
{
/* include an alphanumeric word */
while (i && isalnum(i))
{
i = *text++;
}
}
else
{
/* include contiguous punctuation */
while (i && !isalnum(i) && !isspace(i))
{
i = *text++;
}
}
text -= 2;
}
/* construct a MARK for this place */
m = buildmark(text);
return m;
}