File: [local] / src / usr.bin / mg / help.c (download)
Revision 1.4, Mon Jan 29 01:58:07 2001 UTC (23 years, 3 months ago) by niklas
Branch: MAIN
CVS Tags: OPENBSD_2_9_BASE, OPENBSD_2_9 Changes since 1.3: +2 -0 lines
$OpenBSD$
|
/* $OpenBSD: help.c,v 1.4 2001/01/29 01:58:07 niklas Exp $ */
/*
* Help functions for Mg 2
*/
#include "def.h"
#ifndef NO_HELP
#include "kbd.h"
#include "key.h"
#ifndef NO_MACRO
#include "macro.h"
#endif /* !NO_MACRO */
static int showall __P((char *ind, KEYMAP *map));
static VOID findbind __P((PF, char *, KEYMAP *));
static VOID bindfound __P((void));
static BUFFER *bp;
static char buf[80]; /* used by showall and findbind */
static char buf2[128];
static char *buf2p;
/*
* Read a key from the keyboard, and look it up in the keymap.
* Display the name of the function currently bound to the key.
*/
/* ARGSUSED */
int
desckey(f, n)
int f, n;
{
KEYMAP *curmap;
PF funct;
int c, m, i;
char *pep;
char prompt[80];
#ifndef NO_MACRO
if (inmacro)
return TRUE; /* ignore inside keyboard macro */
#endif /* !NO_MACRO */
(VOID)strcpy(prompt, "Describe key briefly: ");
pep = prompt + strlen(prompt);
key.k_count = 0;
m = curbp->b_nmodes;
curmap = curbp->b_modes[m]->p_map;
for (;;) {
for (;;) {
ewprintf("%s", prompt);
pep[-1] = ' ';
pep = keyname(pep, key.k_chars[key.k_count++] =
c = getkey(FALSE));
if ((funct = doscan(curmap, c)) != prefix)
break;
*pep++ = '-';
*pep = '\0';
curmap = ele->k_prefmap;
}
if (funct != rescan)
break;
if (ISUPPER(key.k_chars[key.k_count - 1])) {
funct = doscan(curmap,
TOLOWER(key.k_chars[key.k_count - 1]));
if (funct == prefix) {
*pep++ = '-';
*pep = '\0';
curmap = ele->k_prefmap;
continue;
}
if (funct != rescan)
break;
}
nextmode:
if (--m < 0)
break;
curmap = curbp->b_modes[m]->p_map;
for (i = 0; i < key.k_count; i++) {
funct = doscan(curmap, key.k_chars[i]);
if (funct != prefix) {
if (i == key.k_count - 1 && funct != rescan)
goto found;
funct = rescan;
goto nextmode;
}
curmap = ele->k_prefmap;
}
*pep++ = '-';
*pep = '\0';
}
found:
if (funct == rescan)
ewprintf("%k is not bound to any function");
else if ((pep = function_name(funct)) != NULL)
ewprintf("%k runs the command %s", pep);
else
ewprintf("%k is bound to an unnamed function");
return TRUE;
}
/*
* This function creates a table, listing all of the command
* keys and their current bindings, and stores the table in the
* *help* pop-up buffer. This lets Mg produce it's own wall chart.
*/
/* ARGSUSED */
int
wallchart(f, n)
int f, n;
{
int m;
static char locbind[80] = "Local keybindings for mode ";
bp = bfind("*help*", TRUE);
if (bclear(bp) != TRUE)
/* clear it out */
return FALSE;
for (m = curbp->b_nmodes; m > 0; m--) {
(VOID)strcpy(&locbind[27], curbp->b_modes[m]->p_name);
(VOID)strcat(&locbind[27], ":");
if ((addline(bp, locbind) == FALSE) ||
(showall(buf, curbp->b_modes[m]->p_map) == FALSE) ||
(addline(bp, "") == FALSE))
return FALSE;
}
if ((addline(bp, "Global bindings:") == FALSE) ||
(showall(buf, map_table[0].p_map) == FALSE))
return FALSE;
return popbuftop(bp);
}
static int
showall(ind, map)
char *ind;
KEYMAP *map;
{
MAP_ELEMENT *ele;
PF functp;
int i, last;
char *cp, *cp2;
if (addline(bp, "") == FALSE)
return FALSE;
last = -1;
for (ele = &map->map_element[0];
ele < &map->map_element[map->map_num]; ele++) {
if (map->map_default != rescan && ++last < ele->k_base) {
cp = keyname(ind, last);
if (last < ele->k_base - 1) {
(VOID)strcpy(cp, " .. ");
cp = keyname(cp + 4, ele->k_base - 1);
}
do {
*cp++ = ' ';
} while (cp < &buf[16]);
(VOID)strcpy(cp, function_name(map->map_default));
if (addline(bp, buf) == FALSE)
return FALSE;
}
last = ele->k_num;
for (i = ele->k_base; i <= last; i++) {
functp = ele->k_funcp[i - ele->k_base];
if (functp != rescan) {
if (functp != prefix)
cp2 = function_name(functp);
else
cp2 = map_name(ele->k_prefmap);
if (cp2 != NULL) {
cp = keyname(ind, i);
do {
*cp++ = ' ';
} while (cp < &buf[16]);
(VOID)strcpy(cp, cp2);
if (addline(bp, buf) == FALSE)
return FALSE;
}
}
}
}
for (ele = &map->map_element[0];
ele < &map->map_element[map->map_num]; ele++) {
if (ele->k_prefmap != NULL) {
for (i = ele->k_base;
ele->k_funcp[i - ele->k_base] != prefix; i++) {
if (i >= ele->k_num)
/* damaged map */
return FALSE;
}
cp = keyname(ind, i);
*cp++ = ' ';
if (showall(cp, ele->k_prefmap) == FALSE)
return FALSE;
}
}
return TRUE;
}
int
help_help(f, n)
int f, n;
{
KEYMAP *kp;
PF funct;
if ((kp = name_map("help")) == NULL)
return FALSE;
ewprintf("a b c: ");
do {
funct = doscan(kp, getkey(FALSE));
} while (funct == NULL || funct == help_help);
#ifndef NO_MACRO
if (macrodef && macrocount < MAXMACRO)
macro[macrocount - 1].m_funct = funct;
#endif /* !NO_MACRO */
return (*funct)(f, n);
}
/* ARGSUSED */
int
apropos_command(f, n)
int f, n;
{
BUFFER *bp;
FUNCTNAMES *fnp;
char *cp1, *cp2;
char string[32];
if (eread("apropos: ", string, sizeof(string), EFNEW) == ABORT)
return ABORT;
/* FALSE means we got a 0 character string, which is fine */
bp = bfind("*help*", TRUE);
if (bclear(bp) == FALSE)
return FALSE;
for (fnp = &functnames[0]; fnp < &functnames[nfunct]; fnp++) {
for (cp1 = fnp->n_name; *cp1; cp1++) {
cp2 = string;
while (*cp2 && *cp1 == *cp2)
cp1++, cp2++;
if (!*cp2) {
(VOID)strcpy(buf2, fnp->n_name);
buf2p = &buf2[strlen(buf2)];
findbind(fnp->n_funct, buf, map_table[0].p_map);
if (addline(bp, buf2) == FALSE)
return FALSE;
break;
} else
cp1 -= cp2 - string;
}
}
return popbuftop(bp);
}
static VOID
findbind(funct, ind, map)
KEYMAP *map;
PF funct;
char *ind;
{
MAP_ELEMENT *ele;
int i, last;
char *cp;
last = -1;
for (ele = &map->map_element[0];
ele < &map->map_element[map->map_num]; ele++) {
if (map->map_default == funct && ++last < ele->k_base) {
cp = keyname(ind, last);
if (last < ele->k_base - 1) {
(VOID)strcpy(cp, " .. ");
(VOID)keyname(cp + 4, ele->k_base - 1);
}
bindfound();
}
last = ele->k_num;
for (i = ele->k_base; i <= last; i++) {
if (funct == ele->k_funcp[i - ele->k_base]) {
if (funct == prefix) {
cp = map_name(ele->k_prefmap);
if (!cp ||
strncmp(cp, buf2, strlen(cp)) != 0)
continue;
}
(VOID)keyname(ind, i);
bindfound();
}
}
}
for (ele = &map->map_element[0];
ele < &map->map_element[map->map_num]; ele++) {
if (ele->k_prefmap != NULL) {
for (i = ele->k_base;
ele->k_funcp[i - ele->k_base] != prefix; i++) {
if (i >= ele->k_num)
/* damaged */
return;
}
cp = keyname(ind, i);
*cp++ = ' ';
findbind(funct, cp, ele->k_prefmap);
}
}
}
static VOID
bindfound()
{
if (buf2p < &buf2[32]) {
do {
*buf2p++ = ' ';
} while (buf2p < &buf2[32]);
} else {
*buf2p++ = ',';
*buf2p++ = ' ';
}
(VOID)strcpy(buf2p, buf);
buf2p += strlen(buf);
}
#endif /* !NO_HELP */