/*
* input.c: parse and process user input
*
* Copyright(c) 1997-2000 - All Rights Reserved
*
* See the COPYRIGHT file.
*/
#ifndef lint
static char rcsid[] = "@(#)$Id: input.c,v 1.40 2001/02/20 02:06:55 kalt Exp $";
#endif
#include "os.h"
#include "struct.h"
#include "server.h"
#include "window.h"
#include "term.h"
#include "config.h"
extern void parse_command(char *, int);
extern int cmd_msgnotice(char *, char *);
extern char *tab_get();
extern char *space_get();
extern struct window_ *current;
extern struct server_ *server;
static char inbuf[512] = "";
static char history[100][512];
static int curh = -1, nexh = -1;
static unsigned int inlen = 0, inpos = 0;
static void
parse_input()
{
vsic_slog(LOG_INPUT, ">>> %s", inbuf);
if (nexh == -1)
for (nexh = 99; nexh > 0; nexh--)
history[nexh][0] = '\0';
strcpy(history[nexh], inbuf);
if (nexh++ == 99)
nexh = 0;
history[curh = nexh][0] = '\0';
switch (*inbuf)
{
case '/' :
if (inbuf[1] == '/')
if (inbuf[2] == '/')
vsic_write(inbuf+3);
else
parse_command(inbuf+2, 0);
else
parse_command(inbuf+1, 1);
break;
default :
cmd_msgnotice(NULL, inbuf);
break;
}
inbuf[0] = '\0';
inlen = inpos = 0;
}
int
cmd_run(p)
char *p;
{
FILE *s;
char fname[255];
if (!*p)
return -1;
strcpy(fname, cfgdir);
strcat(fname, p);
if (s = fopen(fname, "r"))
{
while (!feof(s))
{
if (fgets(inbuf+1, 400, s) == NULL)
break;
if (inbuf[1] == '#')
continue;
inbuf[0] = '/';
inbuf[strlen(inbuf) - 1] = '\0';
select_active(NULL, 2);
server = current->via;
parse_input(inbuf);
}
fclose(s);
}
else if (strcmp(p, "startup"))
vsic_slog(LOG_CLIENT, "--- %s: %s.", p, strerror(errno));
return 0;
}
void
space_trick()
{
char obuf[512] = "";
char *ch;
if (ch = index(inbuf, ':'))
strcpy(obuf, (ch[1] == ' ') ? ch+2 : ch+1);
else
strcpy(obuf, inbuf);
ch = space_get();
if (*ch)
{
sprintf(inbuf, "%s: ", ch);
inpos = strlen(inbuf);
strcat(inbuf, obuf);
inlen = strlen(inbuf);
}
}
void
tab_trick()
{
char obuf[512] = "";
char *ch;
if (ch = index(inbuf, ' '))
if (ch = index(ch+1, ' '))
strcpy(obuf, ch+1);
ch = tab_get();
if (*ch)
{
char *cmd;
if (*ch == '@')
{
ch++;
cmd = "squery";
}
else
cmd = "msg";
sprintf(inbuf, "/%s %s ", cmd, ch);
}
else
strcpy(inbuf, "/msg ");
inpos = strlen(inbuf);
strcat(inbuf, obuf);
inlen = strlen(inbuf);
}
char
in_delprev()
{
if (inpos)
{
char *wp;
wp = inbuf+inpos-1;
while (*wp++)
*(wp-1) = *wp;
inlen--; inpos--;
return 1;
}
else
{
term_beep();
return 0;
}
}
char
in_delnext()
{
if (inpos < inlen)
{
char *wp;
wp = inbuf+inpos;
while (*wp++)
*(wp-1) = *wp;
inlen--;
return 1;
}
else
{
term_beep();
return 0;
}
}
void
in_insert(ch, trunc)
char ch, *trunc;
{
int i;
if (*trunc)
{
inbuf[inlen = inpos] = '\0';
*trunc = 0;
}
if (inlen < 400)
{
inlen++;
for (i = inlen; i > inpos; i--)
inbuf[i] = inbuf[i-1];
inbuf[inpos++] = ch;
}
else
term_beep();
}
void
display_input()
{
term_input(inbuf + ((CO-10)*(inpos/(CO-10))) - ((inpos>=CO-10) ? 10 :0),
inpos - ((CO-10)*(inpos/(CO-10))) + ((inpos>=CO-10) ? 10:0));
}
void
sic_getch()
{
static char escape = 0, screen = 0, search = 0, quote = 0, replace = 0;
static char cursor = 0;
char ch, chg = 0;
assert(inlen == strlen(inbuf));
assert(inpos <= inlen);
if (read(0, &ch, 1) != 1)
return;
server = current->via;
if (quote)
{
quote = 0;
in_insert(ch, &replace);
chg = 1;
}
else
{
select_active(NULL, 2);
if (search)
{
if (ch == '/')
sic_scroll2(search = +2, inbuf);
else if (ch == '?')
sic_scroll2(search = -2, inbuf);
else
{
search = 0;
inbuf[0] = '\0';
inlen = inpos = 0;
chg = 1;
}
}
if (search == 0)
{
if (screen)
{
screen = 0;
switch (ch)
{
case 'a':
case ctrl('A'):
case ctrl('X'):
sic_chgwin(-3); chg = 1;
break;
case 'c':
case ctrl('C'):
sic_newwin();
sic_chgwin(-3); chg = 1;
break;
case 'd':
case ctrl('D'):
sic_wdcc();
break;
case 'k':
case ctrl('K'):
sic_wkill();
break;
case 'l':
case ctrl('L'):
sic_wlist();
break;
case '\0': /* ^-space */
case ' ':
case 'n':
case ctrl('N'):
sic_chgwin(-1); chg = 1;
break;
case 'p':
case ctrl('P'):
sic_chgwin(-2); chg = 1;
break;
case 's':
sic_swin(2);
break;
default:
if (ch >= 48 && ch <= 57)
sic_chgwin((int) ch - 48); chg = 1;
}
}
else if (escape)
{
switch (ch)
{
case '[':
cursor = 1;
break;
case '0': case '1': case '2': case '3': case '4':
case '5': case '6': case '7': case '8': case '9':
current->fnb = ch - 48;
sic_redowin(0);
break;
case '/':
sic_scroll2(search = +2, inbuf);
break;
case '?':
sic_scroll2(search = -2, inbuf);
break;
case '<':
sic_scroll2(-1, NULL);
break;
case '>':
sic_scroll2(+1, NULL);
break;
case '-':
sic_scroll(-1);
break;
case '+':
sic_scroll(+1);
break;
case '.':
sic_clog(0);
sic_redowin(0);
break;
case 'b':
if (inpos)
{
if (!isspace((int) inbuf[inpos]))
inpos -= 1;
while (inpos && isspace((int) inbuf[inpos--]));
while (inpos && !isspace((int) inbuf[inpos-1]))
inpos -= 1;
chg = 1;
}
replace = 0;
break;
case 'f':
if (inpos < inlen)
{
while (isspace((int) inbuf[inpos++]));
while (inbuf[inpos] && !isspace((int) inbuf[inpos]))
inpos += 1;
chg = 1;
}
replace = 0;
break;
case 'd':
if (inpos < inlen)
{
while (isspace((int) inbuf[inpos]))
in_delnext();
while (inbuf[inpos] && !isspace((int) inbuf[inpos]))
in_delnext();
chg = 1;
}
replace = 0;
break;
case 'H':
if (option(current->custw.zopt_on, Z_NOCOLOR))
unset_option(current->custw.zopt_on, Z_NOCOLOR);
else
set_option(current->custw.zopt_on, Z_NOCOLOR);
sic_redowin(0);
break;
case 'h':
if (option(current->custw.zopt_on, Z_IRCII))
unset_option(current->custw.zopt_on, Z_IRCII);
else
set_option(current->custw.zopt_on, Z_IRCII);
sic_redowin(0);
break;
case ctrl('H'):
case 127:
if (inpos)
{
while (inpos && isspace((int) inbuf[inpos-1]))
in_delprev();
while (inpos && !isspace((int) inbuf[inpos-1]))
in_delprev();
chg = 1;
}
replace = 0;
break;
case 'n':
sic_scroll((LI-2)/2);
break;
case 'N':
sic_scroll2(+2, NULL);
break;
case 'p':
sic_scroll(-(LI-2)/2);
break;
case 'P':
sic_scroll2(-2, NULL);
break;
case 's':
if (inbuf[0])
{
sic_scroll2(0, inbuf);
inbuf[0] = '\0';
inpos = inlen = replace = 0; chg = 1;
}
else
sic_scroll2(0, NULL);
sic_redowin(0);
break;
case 'S':
if (option(current->custw.zopt_on, Z_SHOWALL))
unset_option(current->custw.zopt_on, Z_SHOWALL);
else
set_option(current->custw.zopt_on, Z_SHOWALL);
sic_redowin(0);
break;
case 't':
sic_wptoggle();
sic_redowin(0);
break;
case 'u':
if (option(current->custw.zopt_on, Z_UNDEL))
unset_option(current->custw.zopt_on, Z_UNDEL);
else
set_option(current->custw.zopt_on, Z_UNDEL);
sic_redowin(0);
break;
}
escape = 0;
}
else if (cursor)
{
switch (ch)
{
case 'C': /* cursor right */
if (inpos < inlen)
{
inpos++;
chg = 1;
}
replace = 0;
break;
case 'D': /* cursor left */
if (inpos)
{
inpos--;
chg = 1;
}
replace = 0;
break;
case 'B': /* cursor down */
if (curh != -1)
{
do
if (curh++ == 99)
curh = 0;
while (*history[curh] == '\0');
strcpy(inbuf, history[curh]);
inlen = strlen(inbuf);
inpos = 0;
replace = 1;
chg = 1;
}
else
term_beep();
break;
case 'A': /* cursor up */
if (curh != -1)
{
do
if (curh-- == 0)
curh = 99;
while (*history[curh] == '\0');
strcpy(inbuf, history[curh]);
inlen = strlen(inbuf);
inpos = 0;
replace = 1;
chg = 1;
}
else
term_beep();
break;
}
cursor = 0;
}
else
switch (ch)
{
case 0:
space_trick();
replace = 1;
chg = 1;
break;
case 27: /* escape */
escape = 1;
break;
case ctrl('A'):
inpos = 0;
replace = 0;
chg = 1;
break;
case ctrl('B'):
if (inpos)
{
inpos--;
chg = 1;
}
replace = 0;
break;
case ctrl('D'):
replace = 0;
chg = in_delnext();
break;
case ctrl('E'):
inpos = inlen;
replace = 0;
chg = 1;
break;
case ctrl('F'):
if (inpos < inlen)
{
inpos++;
chg = 1;
}
replace = 0;
break;
case ctrl('I'):
tab_trick();
replace = 1;
chg = 1;
break;
case ctrl('H'):
case 127:
chg = in_delprev();
replace = 0;
break;
case ctrl('K'):
inbuf[inpos] = '\0';
inlen = inpos;
chg = 1;
replace = 0;
break;
case ctrl('L'):
sic_redowin(1);
chg = 1;
break;
case ctrl('N'):
if (curh != -1)
{
do
if (curh++ == 99)
curh = 0;
while (*history[curh] == '\0');
strcpy(inbuf, history[curh]);
inlen = strlen(inbuf);
inpos = 0;
replace = 1;
chg = 1;
}
else
term_beep();
break;
case ctrl('P'):
if (curh != -1)
{
do
if (curh-- == 0)
curh = 99;
while (*history[curh] == '\0');
strcpy(inbuf, history[curh]);
inlen = strlen(inbuf);
inpos = 0;
replace = 1;
chg = 1;
}
else
term_beep();
break;
case ctrl('T'):
if (inpos && inpos < inlen)
{
char sw = inbuf[inpos];
inbuf[inpos] = inbuf[inpos-1];
inbuf[inpos-1] = sw;
chg = 1;
}
else
term_beep();
replace = 0;
break;
case ctrl('U'):
inbuf[0] = '\0';
inlen = inpos = 0;
replace = 0;
chg = 1;
break;
case ctrl('V'):
quote = 1;
break;
case ctrl('W'):
if (inpos)
{
while (inpos && isspace((int) inbuf[inpos-1]))
in_delprev();
while (inpos && !isspace((int) inbuf[inpos-1]))
in_delprev();
chg = 1;
}
replace = 0;
break;
case ctrl('X'):
screen = 1;
break;
case ctrl('J'):
case ctrl('M'):
if (*inbuf)
{
parse_input();
chg = 1;
}
else
sic_scroll(LI-4);
replace = 0;
break;
default:
in_insert(ch, &replace);
chg = 1;
}
}
}
if (chg)
display_input();
return;
}
syntax highlighted by Code2HTML, v. 0.9.1