add directory study
This commit is contained in:
298
study/linux-travel/MINIX-1.5/1.5/Source/commands/elvis/input.c
Normal file
298
study/linux-travel/MINIX-1.5/1.5/Source/commands/elvis/input.c
Normal file
@@ -0,0 +1,298 @@
|
||||
/* input.c */
|
||||
|
||||
/* Author:
|
||||
* Steve Kirkendall
|
||||
* 16820 SW Tallac Way
|
||||
* Beaverton, OR 97006
|
||||
* kirkenda@jove.cs.pdx.edu, or ...uunet!tektronix!psueea!jove!kirkenda
|
||||
*/
|
||||
|
||||
|
||||
/* This file contains the input() function, which implements vi's INPUT mode */
|
||||
|
||||
#include "vi.h"
|
||||
|
||||
|
||||
/* This function allows the user to replace an existing (possibly zero-length)
|
||||
* chunk of text with typed-in text. It returns the MARK of the last character
|
||||
* that the user typed in.
|
||||
*/
|
||||
MARK input(from, to, when)
|
||||
MARK from; /* where to start inserting text */
|
||||
MARK to; /* extent of text to delete */
|
||||
int when; /* either WHEN_VIINP or WHEN_VIREP */
|
||||
{
|
||||
char key[2]; /* key char followed by '\0' char */
|
||||
char *build; /* used in building a newline+indent string */
|
||||
char *scan; /* used while looking at the indent chars of a line */
|
||||
MARK m;
|
||||
|
||||
#ifdef DEBUG
|
||||
/* if "from" and "to" are reversed, complain */
|
||||
if (from > to)
|
||||
{
|
||||
msg("ERROR: input(%ld:%d, %ld:%d)",
|
||||
markline(from), markidx(from),
|
||||
markline(to), markidx(to));
|
||||
return MARK_UNSET;
|
||||
}
|
||||
#endif
|
||||
|
||||
key[1] = 0;
|
||||
|
||||
/* if we're replacing text with new text, save the old stuff */
|
||||
/* (Alas, there is no easy way to save text for replace mode) */
|
||||
if (from != to)
|
||||
{
|
||||
cut(from, to);
|
||||
}
|
||||
|
||||
ChangeText
|
||||
{
|
||||
/* if doing a dot command, then reuse the previous text */
|
||||
if (doingdot)
|
||||
{
|
||||
/* delete the text thats there now */
|
||||
if (from != to)
|
||||
{
|
||||
delete(from, to);
|
||||
}
|
||||
|
||||
cutname('.');
|
||||
cursor = paste(from, FALSE, TRUE) + 1L;
|
||||
}
|
||||
else
|
||||
{
|
||||
/* if doing a change within the line... */
|
||||
if (from != to && markline(from) == markline(to))
|
||||
{
|
||||
/* mark the end of the text with a "$" */
|
||||
change(to - 1, to, "$");
|
||||
}
|
||||
else
|
||||
{
|
||||
/* delete the old text right off */
|
||||
if (from != to)
|
||||
{
|
||||
delete(from, to);
|
||||
}
|
||||
to = from;
|
||||
}
|
||||
|
||||
/* handle autoindent of the first line, maybe */
|
||||
cursor = from;
|
||||
if (*o_autoindent && markline(cursor) > 1L && markidx(cursor) == 0)
|
||||
{
|
||||
/* Only autoindent blank lines. */
|
||||
pfetch(markline(cursor));
|
||||
if (plen == 0)
|
||||
{
|
||||
/* Okay, we really want to autoindent */
|
||||
pfetch(markline(cursor) - 1L);
|
||||
for (scan = ptext, build = tmpblk.c;
|
||||
*scan == ' ' || *scan == '\t';
|
||||
)
|
||||
{
|
||||
*build++ = *scan++;
|
||||
}
|
||||
if (build > tmpblk.c)
|
||||
{
|
||||
*build = '\0';
|
||||
add(cursor, tmpblk.c);
|
||||
cursor += (build - tmpblk.c);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/* repeatedly add characters from the user */
|
||||
for (;;)
|
||||
{
|
||||
/* Get a character */
|
||||
redraw(cursor, TRUE);
|
||||
key[0] = getkey(when);
|
||||
|
||||
/* if whitespace & wrapmargin is set & we're
|
||||
/* past the warpmargin, then change the
|
||||
/* whitespace character into a newline
|
||||
*/
|
||||
if ((*key == ' ' || *key == '\t')
|
||||
&& *o_wrapmargin != 0)
|
||||
{
|
||||
pfetch(markline(cursor));
|
||||
if (idx2col(cursor, ptext, TRUE) > COLS - (*o_wrapmargin & 0xff))
|
||||
{
|
||||
*key = '\n';
|
||||
}
|
||||
}
|
||||
|
||||
/* process it */
|
||||
switch (*key)
|
||||
{
|
||||
case ctrl('['):
|
||||
goto BreakBreak;
|
||||
|
||||
case ctrl('U'):
|
||||
if (markline(cursor) == markline(from))
|
||||
{
|
||||
cursor == from;
|
||||
}
|
||||
else
|
||||
{
|
||||
cursor &= ~(BLKSIZE - 1);
|
||||
}
|
||||
break;
|
||||
|
||||
case '\b':
|
||||
case ctrl('D'):
|
||||
if (cursor <= from)
|
||||
{
|
||||
beep();
|
||||
}
|
||||
else if (markidx(cursor) == 0)
|
||||
{
|
||||
cursor -= BLKSIZE;
|
||||
pfetch(markline(cursor));
|
||||
cursor += plen;
|
||||
}
|
||||
else
|
||||
{
|
||||
cursor--;
|
||||
}
|
||||
break;
|
||||
|
||||
case ctrl('W'):
|
||||
m = movebword(cursor, 1L);
|
||||
if (markline(m) == markline(cursor) && m >= from)
|
||||
{
|
||||
cursor = m;
|
||||
if (from > cursor)
|
||||
{
|
||||
from = cursor;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
beep();
|
||||
}
|
||||
break;
|
||||
|
||||
case '\n':
|
||||
case '\r':
|
||||
build = tmpblk.c;
|
||||
*build++ = '\n';
|
||||
if (*o_autoindent)
|
||||
{
|
||||
pfetch(markline(cursor));
|
||||
for (scan = ptext; *scan == ' ' || *scan == '\t'; )
|
||||
{
|
||||
*build++ = *scan++;
|
||||
}
|
||||
}
|
||||
*build = 0;
|
||||
if (cursor >= to && when != WHEN_VIREP)
|
||||
{
|
||||
add(cursor, tmpblk.c);
|
||||
}
|
||||
else
|
||||
{
|
||||
change(cursor, to, tmpblk.c);
|
||||
}
|
||||
redraw(cursor, TRUE);
|
||||
to = cursor = (cursor & ~(BLKSIZE - 1))
|
||||
+ BLKSIZE
|
||||
+ (int)(build - tmpblk.c) - 1;
|
||||
break;
|
||||
|
||||
case ctrl('A'):
|
||||
if (cursor < to)
|
||||
{
|
||||
delete(cursor, to);
|
||||
}
|
||||
cutname('.');
|
||||
to = cursor = paste(cursor, FALSE, TRUE) + 1L;
|
||||
break;
|
||||
|
||||
case ctrl('V'):
|
||||
if (cursor >= to && when != WHEN_VIREP)
|
||||
{
|
||||
add(cursor, "^");
|
||||
}
|
||||
else
|
||||
{
|
||||
change(cursor, to, "^");
|
||||
}
|
||||
redraw(cursor, TRUE);
|
||||
*key = getkey(0);
|
||||
if (*key == '\n')
|
||||
{
|
||||
/* '\n' too hard to handle */
|
||||
*key = '\r';
|
||||
}
|
||||
change(cursor, cursor + 1, key);
|
||||
cursor++;
|
||||
if (cursor > to)
|
||||
{
|
||||
to = cursor;
|
||||
}
|
||||
break;
|
||||
|
||||
case ctrl('L'):
|
||||
case ctrl('R'):
|
||||
redraw(MARK_UNSET, FALSE);
|
||||
break;
|
||||
|
||||
case ctrl('T'):
|
||||
*key = '\t';
|
||||
/* fall through to default case... */
|
||||
|
||||
default:
|
||||
if (cursor >= to && when != WHEN_VIREP)
|
||||
{
|
||||
add(cursor, key);
|
||||
cursor++;
|
||||
to = cursor;
|
||||
}
|
||||
else
|
||||
{
|
||||
pfetch(markline(cursor));
|
||||
if (markidx(cursor) == plen)
|
||||
{
|
||||
add(cursor, key);
|
||||
}
|
||||
else
|
||||
{
|
||||
change(cursor, cursor + 1, key);
|
||||
}
|
||||
cursor++;
|
||||
}
|
||||
} /* end switch(*key) */
|
||||
} /* end for(;;) */
|
||||
BreakBreak:;
|
||||
|
||||
/* delete any excess characters */
|
||||
if (cursor < to)
|
||||
{
|
||||
delete(cursor, to);
|
||||
}
|
||||
|
||||
} /* end if doingdot else */
|
||||
|
||||
} /* end ChangeText */
|
||||
|
||||
/* put the new text into a cut buffer for possible reuse */
|
||||
if (!doingdot)
|
||||
{
|
||||
blksync();
|
||||
cutname('.');
|
||||
cut(from, cursor);
|
||||
}
|
||||
|
||||
/* move to last char that we inputted, unless it was newline */
|
||||
if (markidx(cursor) != 0)
|
||||
{
|
||||
cursor--;
|
||||
}
|
||||
|
||||
rptlines = 0L;
|
||||
return cursor;
|
||||
}
|
||||
Reference in New Issue
Block a user