-/* $OpenBSD: help.c,v 1.34 2012/04/12 04:47:59 lum Exp $ */
-
-/* This file is in the public domain. */
-
-/*
- * Help functions for Mg 2
- */
-
-#include "def.h"
-#include "funmap.h"
-
-#include "kbd.h"
-#include "key.h"
-#include "macro.h"
-
-static int showall(struct buffer *, KEYMAP *, char *);
-static int findbind(KEYMAP *, PF, char *, size_t);
-
-/*
- * 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(int f, int n)
-{
- KEYMAP *curmap;
- PF funct;
- int c, m, i, num;
- char *pep;
- char dprompt[80];
-
- if (inmacro)
- return (TRUE); /* ignore inside keyboard macro */
-
- num = strlcpy(dprompt, "Describe key briefly: ", sizeof(dprompt));
- if (num >= sizeof(dprompt))
- num = sizeof(dprompt) - 1;
- pep = dprompt + num;
- key.k_count = 0;
- m = curbp->b_nmodes;
- curmap = curbp->b_modes[m]->p_map;
- for (;;) {
- for (;;) {
- ewprintf("%s", dprompt);
- pep[-1] = ' ';
- pep = getkeyname(pep, sizeof(dprompt) - (pep - dprompt),
- key.k_chars[key.k_count++] = c = getkey(FALSE));
- if ((funct = doscan(curmap, c, &curmap)) != NULL)
- break;
- *pep++ = '-';
- *pep = '\0';
- }
- if (funct != rescan)
- break;
- if (ISUPPER(key.k_chars[key.k_count - 1])) {
- funct = doscan(curmap,
- TOLOWER(key.k_chars[key.k_count - 1]), &curmap);
- if (funct == NULL) {
- *pep++ = '-';
- *pep = '\0';
- 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], &curmap);
- if (funct != NULL) {
- if (i == key.k_count - 1 && funct != rescan)
- goto found;
- funct = rescan;
- goto nextmode;
- }
- }
- *pep++ = '-';
- *pep = '\0';
- }
-found:
- if (funct == rescan || funct == selfinsert)
- ewprintf("%k is not bound to any function");
- else if ((pep = (char *)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(int f, int n)
-{
- int m;
- struct buffer *bp;
-
- bp = bfind("*help*", TRUE);
- if (bclear(bp) != TRUE)
- /* clear it out */
- return (FALSE);
- bp->b_flag |= BFREADONLY;
- for (m = curbp->b_nmodes; m > 0; m--) {
- if ((addlinef(bp, "Local keybindings for mode %s:",
- curbp->b_modes[m]->p_name) == FALSE) ||
- (showall(bp, curbp->b_modes[m]->p_map, "") == FALSE) ||
- (addline(bp, "") == FALSE))
- return (FALSE);
- }
- if ((addline(bp, "Global bindings:") == FALSE) ||
- (showall(bp, fundamental_map, "") == FALSE))
- return (FALSE);
- return (popbuftop(bp, WNONE));
-}
-
-static int
-showall(struct buffer *bp, KEYMAP *map, char *prefix)
-{
- KEYMAP *newmap;
- char buf[80], keybuf[16];
- PF fun;
- int c;
-
- if (addline(bp, "") == FALSE)
- return (FALSE);
-
- /* XXX - 256 ? */
- for (c = 0; c < 256; c++) {
- fun = doscan(map, c, &newmap);
- if (fun == rescan || fun == selfinsert)
- continue;
- getkeyname(buf, sizeof(buf), c);
- (void)snprintf(keybuf, sizeof(keybuf), "%s%s ", prefix, buf);
- if (fun == NULL) {
- if (showall(bp, newmap, keybuf) == FALSE)
- return (FALSE);
- } else {
- if (addlinef(bp, "%-16s%s", keybuf,
- function_name(fun)) == FALSE)
- return (FALSE);
- }
- }
- return (TRUE);
-}
-
-int
-help_help(int f, int n)
-{
- KEYMAP *kp;
- PF funct;
-
- if ((kp = name_map("help")) == NULL)
- return (FALSE);
- ewprintf("a b c: ");
- do {
- funct = doscan(kp, getkey(FALSE), NULL);
- } while (funct == NULL || funct == help_help);
-
- if (macrodef && macrocount < MAXMACRO)
- macro[macrocount - 1].m_funct = funct;
-
- return ((*funct)(f, n));
-}
-
-/* ARGSUSED */
-int
-apropos_command(int f, int n)
-{
- struct buffer *bp;
- struct list *fnames, *el;
- char string[32];
-
- if (eread("apropos: ", string, sizeof(string), EFNUL | EFNEW) == NULL)
- return (ABORT);
- /* FALSE means we got a 0 character string, which is fine */
- bp = bfind("*help*", TRUE);
- if (bclear(bp) == FALSE)
- return (FALSE);
-
- fnames = complete_function_list("");
- for (el = fnames; el != NULL; el = el->l_next) {
- char buf[32];
-
- if (strstr(el->l_name, string) == NULL)
- continue;
-
- buf[0] = '\0';
- findbind(fundamental_map, name_function(el->l_name),
- buf, sizeof(buf));
-
- if (addlinef(bp, "%-32s%s", el->l_name, buf) == FALSE) {
- free_file_list(fnames);
- return (FALSE);
- }
- }
- free_file_list(fnames);
- return (popbuftop(bp, WNONE));
-}
-
-static int
-findbind(KEYMAP *map, PF fun, char *buf, size_t len)
-{
- KEYMAP *newmap;
- PF nfun;
- char buf2[16], keybuf[16];
- int c;
-
- /* XXX - 256 ? */
- for (c = 0; c < 256; c++) {
- nfun = doscan(map, c, &newmap);
- if (nfun == fun) {
- getkeyname(buf, len, c);
- return (TRUE);
- }
- if (nfun == NULL) {
- if (findbind(newmap, fun, buf2, sizeof(buf2)) == TRUE) {
- getkeyname(keybuf, sizeof(keybuf), c);
- (void)snprintf(buf, len, "%s %s", keybuf, buf2);
- return (TRUE);
- }
- }
- }
- return (FALSE);
-}