home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Frozen Fish 1: Amiga
/
FrozenFish-Apr94.iso
/
bbs
/
alib
/
d3xx
/
d352
/
mg.lha
/
MG
/
src.LZH
/
mg
/
help.c
< prev
next >
Wrap
C/C++ Source or Header
|
1990-05-23
|
9KB
|
385 lines
/* Help functions for MicroGnuEmacs 3 */
#include "no_help.h"
#ifndef NO_HELP
#include "def.h"
#include "buffer.h"
#include "window.h"
#include "kbd.h"
#include "key.h"
#include "no_macro.h"
#ifndef NO_MACRO
#include "macro.h"
#endif
#ifdef ANSI
#include <string.h>
#endif
static int showall
PROTO((char *ind, struct keymap * map));
extern int rescan();
static VOID bindfound
PROTO((VOID));
static VOID findbind
PROTO((struct function *, char *, struct keymap *));
/*
* MAXKEYLEN is the offset into the line after key names in
* describe-bindings. Default is 32; if you have keynames longer than 32
* chars, set it to something longer than the longest of them (a multiple of
* 8 is suggested).
*/
#ifndef MAXKEYLEN
#define MAXKEYLEN 32
#endif
/*
* 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 */
desckey(f, n)
{
register struct keymap *curmap;
register struct function *funct;
register char *pep;
char prompt[80];
int c;
int m;
int i;
(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(DISSCR));
if ((funct = doscan(curmap, c))->f_type != F_PREFIX)
break;
*pep++ = '-';
*pep = '\0';
curmap = (struct keymap *) funct->f_pref;
}
if (funct->f_funcp != rescan
#ifndef NO_MACRO
|| funct->f_type == F_MACRO
#endif
)
break;
if (ISUPPER(key.k_chars[key.k_count - 1])) {
funct = doscan(curmap, TOLOWER(key.k_chars[key.k_count - 1]));
if (funct->f_type == F_PREFIX) {
*pep++ = '-';
*pep = '\0';
curmap = (struct keymap *) funct->f_pref;
continue;
}
if (funct->f_funcp != rescan
#ifndef NO_MACRO
|| funct->f_type == F_MACRO
#endif
)
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->f_type != F_PREFIX) {
if (i == key.k_count - 1
&& (funct->f_funcp != rescan
#ifndef NO_MACRO
|| funct->f_type == F_MACRO
#endif
))
goto found;
funct = NULL;
goto nextmode;
}
curmap = (struct keymap *) funct->f_pref;
}
*pep++ = '-';
*pep = '\0';
}
found:
#ifndef NO_MACRO
if (funct->f_type == F_MACRO)
ewprintf("%k runs the macro %s",
((struct macro *) funct->f_macro)->m_name);
else
#endif
if (funct->f_funcp == rescan || funct == NULL)
ewprintf("%k is not bound to any function");
else if ((pep = function_name(funct->f_funcp)) != NULL)
ewprintf("%k runs the command %s", pep);
else
ewprintf("%k is bound to an unnamed function");
epresf = TRUE;
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 MicroGnuEMACS produce it's own wall chart.
*/
static struct buffer *bp;
static char buf[80]; /* used by showall and findbind */
/* ARGSUSED */
wallchart(f, n)
{
int m;
static char locbind[80] = "Local keybindings for mode ";
if ((bp = bfind("*help*", TRUE)) == NULL)
return FALSE;
bp->b_flag &= ~BFCHG; /* don't ask, just */
if (bclear(bp) != TRUE)
return FALSE; /* clear it out. */
for (m = curbp->b_nmodes; m > 0; m--) {
(VOID) strcat(locbind, curbp->b_modes[m]->p_name);
(VOID) strcat(locbind, ":");
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;
struct keymap *map;
{
register struct map_element *ele;
register int i;
struct function *functp;
char *cp;
char *cp2;
int last;
if (addline(bp, "") == FALSE)
return FALSE;
last = -1;
for (ele = &map->map_element[0];
ele < &map->map_element[map->map_num];
ele++) {
/*
* Currently, map_default _must_ be a CFUNCT. May change
* later
*/
if (map->map_default->f_funcp != 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[MAXKEYLEN]);
(VOID) strcpy(cp, function_name(map->map_default->f_funcp));
if (addline(bp, buf) == FALSE)
return FALSE;
}
last = ele->k_num;
for (i = ele->k_base; i <= last; i++) {
functp = &(ele->k_entry[i - ele->k_base]);
cp2 = NULL;
if (functp->f_type == F_PREFIX)
cp2 = map_name((struct keymap *) functp->f_pref);
#ifndef NO_MACRO
else if (functp->f_type == F_MACRO)
cp2 = ((struct macro *) functp->f_macro)->m_name;
#endif
else if (functp->f_funcp != rescan)
cp2 = function_name(functp->f_funcp);
if (cp2 != NULL) {
cp = keyname(ind, i);
do {
*cp++ = ' ';
} while (cp < &buf[MAXKEYLEN]);
*cp = '\0';
(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++) {
for (i = ele->k_base; i <= ele->k_num; i++) {
if (ele->k_entry[i - ele->k_base].f_type == F_PREFIX) {
cp = keyname(ind, i);
*cp++ = ' ';
if (showall(cp, (struct keymap *) ele->k_entry[i - ele->k_base].f_pref) == FALSE)
return FALSE;
}
}
}
return TRUE;
}
help_help(f, n)
int f, n;
{
struct keymap *kp;
struct function *funct;
if ((kp = name_map("help")) == NULL)
return FALSE;
ewprintf("a b c: ");
epresf = ERASE;
do {
funct = doscan(kp, getkey(DISSCR));
} while (funct->f_type != F_CFUNCT || funct->f_funcp == help_help);
return (*funct->f_funcp) (f, n);
}
static char buf2[128];
static char *buf2p;
/* ARGSUSED */
apropos_command(f, n)
int f, n;
{
register char *cp1;
register int slen;
#ifndef NO_MACRO
extern struct macro kbdmacro;
register struct macro *mac;
#endif
char string[NMACN];
struct functnames *fnp;
struct function tmp;
struct buffer *bp;
if (eread("apropos: ", string, sizeof(string), EFNEW) == ABORT)
return ABORT;
/* FALSE means we got a 0 character string, which is fine */
if ((bp = bfind("*help*", TRUE)) == NULL)
return FALSE;
bp->b_flag &= ~BFCHG;
if (bclear(bp) == FALSE)
return FALSE;
tmp.f_type = F_CFUNCT;
slen = strlen(string);
for (fnp = &functnames[0]; fnp < &functnames[nfunct]; fnp++) {
for (cp1 = fnp->n_name; *cp1; cp1++)
if (strncmp(cp1, string, slen) == 0) {
(VOID) strcpy(buf2, fnp->n_name);
buf2p = &buf2[strlen(buf2)];
tmp.f_funcp = fnp->n_funct;
findbind(&tmp, buf, map_table[0].p_map);
if (addline(bp, buf2) == FALSE)
return FALSE;
break;
}
}
#ifndef NO_MACRO
tmp.f_type = F_MACRO;
for (mac = kbdmacro.m_macp; mac; mac = mac->m_macp) {
for (cp1 = mac->m_name; *cp1; cp1++) {
if (strncmp(cp1, string, slen) == 0) {
(VOID) strcpy(buf2, mac->m_name);
buf2p = &buf2[strlen(buf2)];
tmp.f_macro = (int (*) ()) mac;
findbind(&tmp, buf, map_table[0].p_map);
if (addline(bp, buf2) == FALSE)
return FALSE;
break;
}
}
}
#endif
return popbuftop(bp);
}
static VOID
findbind(funct, ind, map)
struct function *funct;
char *ind;
struct keymap *map;
{
register struct map_element *ele;
register int i;
char *cp;
int last;
last = -1;
for (ele = &map->map_element[0];
ele < &map->map_element[map->map_num];
ele++) {
/*
* Cheating - we test equality on the union by testing one of
* the elements. They are all pointers, but have different
* types. If someone with a processor that cares about this
* objects, we'll have to spell it out longhand. Bleah.
*/
if (map->map_default->f_type == funct->f_type
&& map->map_default->f_funcp == funct->f_funcp && ++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 (ele->k_entry[i - ele->k_base].f_type == funct->f_type
&& funct->f_funcp == ele->k_entry[i - ele->k_base].f_funcp) {
(VOID) keyname(ind, i);
bindfound();
}
}
}
for (ele = &map->map_element[0];
ele < &map->map_element[map->map_num];
ele++) {
for (i = ele->k_base; i <= ele->k_num; i++) {
if (ele->k_entry[i - ele->k_base].f_type == F_PREFIX) {
cp = keyname(ind, i);
*cp++ = ' ';
findbind(funct, cp, (struct keymap *) ele->k_entry[i - ele->k_base].f_pref);
}
}
}
}
static VOID
bindfound()
{
if (buf2p < &buf2[32]) {
do {
*buf2p++ = ' ';
} while (buf2p < &buf2[32]);
} else {
*buf2p++ = ',';
*buf2p++ = ' ';
}
(VOID) strcpy(buf2p, buf);
buf2p += strlen(buf);
}
#else
#include "nullfile.h"
#endif