int
p4_lined (struct lined *l, char *dflt)
{
char *b, buf[0x100];
int c, i, display = 0;
b = P, P = buf;
C = L = 0;
if (dflt)
replace_string (l, dflt);
while (L < LMAX)
{
c = p4_getekey ();
if (l->caps)
c = p4_change_case (c);
switch (c)
{
case 0:
break;
case CTRL('P' ):
c = p4_getkey ();
if (l->caps)
c = p4_change_case (c);
default:
if (c >= 0x100)
{
if (!l->executes || c < P4_KEY_k1 || P4_KEY_k0 < c)
{
p4_dot_bell ();
break;
}
right (L - C);
l->executes[c - P4_KEY_k1] (c - P4_KEY_k1);
for (i = 0; i < L; i++)
p4_putc_printable (P[i]);
left (L - C);
break;
}
if (dflt)
replace_string (l, "" );
insertc (l, c);
break;
case '\t' :
#ifndef WITH_NO_COMPLETION
if (l->complete)
{
char cpl[0x100];
p4_store_c_string (P, C, cpl, sizeof cpl);
if (display)
{
extern FCode(p4_cr);
FX (p4_cr);
c = l->complete (cpl, cpl, 1);
FX (p4_cr);
redisplay (l);
}else{
c = l->complete (cpl, cpl, 0);
display = 1;
}
if (c == 0)
{
p4_dot_bell ();
continue;
}
for (i = C; i < (int)strlen (cpl); i++)
{ insertc (l, cpl[i]); }
if (c == 1) { insertc (l, ' ' ); }
else { p4_dot_bell (); }
continue;
}
#endif
do
if (C < L && l->overtype)
++C, p4_goright ();
else
insertc (l, ' ' );
while (C % 8 != 0);
break;
case CTRL('D' ):
case P4_KEY_kr:
if (C == L)
{
p4_dot_bell ();
break;
}
p4_goright ();
C++;
break;
case CTRL('S' ):
case P4_KEY_kl:
if (C == 0)
{
p4_dot_bell ();
break;
}
p4_goleft ();
C--;
break;
case CTRL('A' ):
while (C && P[C - 1] == ' ' )
p4_goleft (), C--;
while (C && P[C - 1] != ' ' )
p4_goleft (), C--;
break;
case CTRL('F' ):
while (C < L && P[C] != ' ' )
p4_goright (), C++;
while (C < L && P[C] == ' ' )
p4_goright (), C++;
break;
case P4_KEY_kb:
case '\x7F' :
case CTRL('H' ):
if (C == 0)
{
p4_dot_bell ();
break;
}
C--;
p4_goleft ();
if (l->overtype)
{
p4_putc_printable (P[C] = ' ' );
p4_goleft ();
break;
}
case P4_KEY_kD:
case CTRL('G' ):
if (C == L)
{
p4_dot_bell ();
break;
}
for (i = C; ++i < L;)
p4_putc_printable (P[i - 1] = P[i]);
p4_putc_printable (' ' );
left (i - C);
L--;
break;
case P4_KEY_kI:
case CTRL('V' ):
l->overtype = !l->overtype;
continue;
case CTRL('C' ):
l->caps = !l->caps;
continue;
case P4_KEY_ku:
case CTRL('E' ):
if (!H || !back_history (l))
p4_dot_bell ();
break;
case P4_KEY_kd:
case CTRL('X' ):
if (!H || !fwd_history (l))
p4_dot_bell ();
break;
case P4_KEY_kh:
left (C);
C = 0;
break;
case P4_KEY_kH:
right (L - C);
C = L;
break;
case CTRL('Q' ):
switch (toupper (p4_getkey ()) | '@' )
{
case 'S' :
left (C);
C = 0;
break;
case 'D' :
right (L - C);
C = L;
break;
default:
p4_dot_bell ();
}
break;
case CTRL('U' ):
replace_string (l, "" );
return 0;
case CTRL('J' ):
case CTRL('M' ):
goto end;
}
display = 0;
dflt = NULL;
}
end:
right (L - C);
P[L] = '\0' ;
if (H && L > 0)
put_history_string (l, P);
if (l->intercept)
{ L = l->intercept(P,L); P[L+1] = '\0' ; }
memcpy (b, P, L + 1);
P = b;
return 1;
} |