home *** CD-ROM | disk | FTP | other *** search
/ Source Code 1992 March / Source_Code_CD-ROM_Walnut_Creek_March_1992.iso / usenet / altsrcs / 2 / 2873 / extend.c < prev    next >
C/C++ Source or Header  |  1991-02-27  |  8KB  |  330 lines

  1. /*
  2. *   Extended (M-X) commands.
  3. */
  4. #include    "def.h"
  5.  
  6. extern    char    MSG_not_now[];
  7. extern    char    MSG_func[];
  8. extern    char    MSG_unk_func[];
  9. extern    char    MSG_cmd_t_ex[];
  10. extern    char    MSG_unk_ext[];
  11. extern    char    MSG_d_b[];
  12. extern    char    MSG_unbd[];
  13. extern    char    MSG_bnd_to[];
  14. extern    char    MSG_ins_self[];
  15. extern    char    MSG_bnd_file[];
  16. extern    char    MSG_bld_wall[];
  17. extern    char    MSG_null[];
  18.  
  19. #include    "lintfunc.dec"
  20. #ifdef CUSTOMIZE 
  21. static char *bindnm =
  22. {0
  23. };                              /* file name for customized key bindings */
  24. #endif 
  25.  
  26. /*
  27. * This function modifies the keyboard
  28. * binding table, by adjusting the entries in the
  29. * big "bindings" array. Most of the grief deals with the
  30. * prompting for additional arguments. This code does not
  31. * work right if there is a keyboard macro floating around.
  32. * Should be fixed.
  33. */
  34. bool bindtokey ()
  35. {
  36.  
  37.     register int    s;
  38.     register char  *cp;
  39.     register    SYMBOL * sp;
  40.     register int    c;
  41.     char    xname[NXNAME];
  42. #ifdef CUSTOMIZE
  43.     char    xname2[NXNAME];
  44.     FILE * bindf;
  45. #endif 
  46.  
  47.     if (kbdmip != NULL || kbdmop != NULL)
  48.         {
  49.         writ_echo (MSG_not_now);
  50.         return (FALSE);
  51.         }
  52.  
  53.     if ((s = eread (MSG_func, xname, NXNAME, EFAUTO, NULL)) != TRUE)
  54.         return (s);
  55.     if ((sp = symlookup (xname)) == NULL)
  56.         {
  57.         writ_echo (MSG_unk_func);
  58.         return (FALSE);
  59.         }
  60.  
  61. #ifdef CUSTOMIZE
  62.     strcpy (xname2, xname);
  63. #endif 
  64.     eputc (' ');
  65.     eputc ('K');
  66.     eputc ('e');
  67.     eputc ('y');
  68.     eputc (':');
  69.     eputc (' ');
  70.     ttflush ();
  71.     c = getkey ();              /* Read key.        */
  72.     keyname (xname, c);         /* Display keyname. */
  73.     eputs (xname);
  74.     ttflush ();
  75.     if (binding[c] != NULL)     /* Unbind old, and  */
  76.         --binding[c] -> s_nkey;
  77.     binding[c] = sp;            /* rebind new.      */
  78.     ++sp -> s_nkey;
  79.  
  80. #ifdef CUSTOMIZE
  81.  /* save the stuff in the beavfil * (hack !! internal file io !) */
  82.     if (bindf = fopen (bindnm, "a"))
  83.         {
  84.         fprintf (bindf, "%-16s %-16s %04x\n", xname, xname2, c);
  85.         fclose (bindf);
  86.         }
  87. #endif
  88.     return (TRUE);
  89. }
  90.  
  91.  
  92. /*
  93. * Extended command. Call the message line
  94. * routine to read in the command name and apply autocompletion
  95. * to it. When it comes back, look the name up in the symbol table
  96. * and run the command if it is found and has the right type.
  97. * Print an error if there is anything wrong.
  98. */
  99. char    extend (f, n, k)
  100. {
  101.  
  102.     register    SYMBOL * sp;
  103.     register char   s;
  104.     char    xname[NXNAME];
  105.  
  106.     if ((s = eread (MSG_cmd_t_ex, xname, NXNAME, EFNEW | EFAUTO, NULL)) != TRUE)
  107.         return (s);
  108.     if ((sp = symlookup (xname)) != NULL)
  109.         return ((*sp -> s_funcp) (f, n, KRANDOM));
  110.     writ_echo (MSG_unk_ext);
  111.     return (ABORT);
  112. }
  113.  
  114.  
  115. /*
  116. * Read a key from the keyboard, and look it
  117. * up in the binding table. Display the name of the function
  118. * currently bound to the key. Say that the key is not bound
  119. * if it is indeed not bound, or if the type is not a
  120. * "builtin". This is a bit of overkill, because this is the
  121. * only kind of function there is.
  122. */
  123. bool help ()
  124. {
  125.     register    SYMBOL * sp;
  126.     register int    c;
  127.     char    b[20];
  128.     char    buf[80];
  129.  
  130.     writ_echo (MSG_d_b);
  131.  
  132.     c = getkey ();
  133.     keyname (b, c);
  134.     if ((sp = binding[c]) == NULL)
  135.         {
  136.         sprintf (buf, MSG_unbd, b);
  137.         writ_echo (buf);
  138.         }
  139.     else
  140.         {
  141.         sprintf (buf, MSG_bnd_to, b, sp -> s_name);
  142.         writ_echo (buf);
  143.         }
  144.     return (TRUE);
  145. }
  146.  
  147. /*
  148. *   Sort the lines in the buffer.
  149. */
  150. void    sort_buf (b_ptr, cnt)
  151. BUFFER  *b_ptr;
  152. int     cnt;
  153.     {
  154.     LINE    *lp1, *lp2;
  155.     bool    no_swap;
  156.     int     loop1, loop2;
  157.  
  158.     for (loop1 = cnt; loop1 > 0; loop1--)
  159.         {
  160.         no_swap = TRUE;
  161.         lp1 = b_ptr -> b_linep -> l_fp; /* point to first line */
  162.         lp2 = lp1 -> l_fp;      /* point to next line */
  163.         for (loop2 = 0; loop2 <= loop1; loop2++)
  164.             {
  165.             /* compare strings and swap if necessary */
  166.             if (0 < strcmp (lp1 -> l_text, lp2 -> l_text))
  167.                 {
  168.                 lp1 -> l_bp -> l_fp = lp2;  /* get pointer to first string */
  169.                 lp2 -> l_fp -> l_bp = lp1;  /* make it point to second string */
  170.  
  171.                 lp1 -> l_fp = lp2 -> l_fp;  
  172.                 lp2 -> l_bp = lp1 -> l_bp;  
  173.  
  174.                 lp1 -> l_bp = lp2;  
  175.                 lp2 -> l_fp = lp1;
  176.  
  177.                 lp2 -> l_file_offset = lp1 -> l_file_offset;
  178.                 lp1 -> l_file_offset = lp2 -> l_file_offset + lp2 -> l_used;
  179.  
  180.                 no_swap = FALSE;
  181.                 }
  182.             else
  183.                 {
  184.                 /* if no swap then advance both pointers */
  185.                 lp1 = lp2;
  186.                 }
  187.             lp2 = lp1 -> l_fp;
  188.             }
  189.         /* quick exit if sort is finished sooner than expected */
  190.         if (no_swap)
  191.             {   
  192.             return; 
  193.             }
  194.         }
  195.     }
  196.  
  197. /*
  198. * This function creates a table, listing all
  199. * of the command keys and their current bindings, and stores
  200. * the table in the standard pop-op buffer (the one used by the
  201. * directory list command, the buffer list command, etc.). This
  202. * lets the editor produce it's own wall chart. The bindings to
  203. * "ins-self" are only displayed if there is an argument.
  204. */
  205. char    wallchart (f, n, k)
  206. {
  207.  
  208.     register char   s;
  209.     register int    key, i;
  210.     register    SYMBOL * sp;
  211.     register char  *cp1;
  212.     register char  *cp2;
  213.     char    buf[64];
  214.     WINDOW  *wp;
  215.  
  216.     if ((s = bclear (blistp)) != TRUE)/* Clear it out.    */
  217.         return (s);
  218.     i = 0;
  219.     (void) strcpy (blistp -> b_fname, MSG_null);
  220.     blistp -> b_flag = BFVIEW;
  221.     writ_echo (MSG_bld_wall);
  222.     for (key = 0; key < NKEYS; ++key)
  223.         {
  224.     /* For all keys.    */
  225.         sp = binding[key];
  226.         if (sp != NULL &&
  227.                 (f != FALSE || strcmp (sp -> s_name, MSG_ins_self) != 0))
  228.             {
  229.             cp1 = &buf[0];
  230.             cp2 = sp -> s_name; /* Add function name.   */
  231.             while (*cp1++ = *cp2++)
  232.                 ;
  233.             cp1--;
  234.             while (cp1 < &buf[32])/* Goto column 32.  */
  235.                 *cp1++ = ' ';
  236.             keyname (&buf[32], key);
  237.             if (addline (buf) == FALSE)
  238.                 break; /* lets go with what we have */
  239.             i++;
  240.             }
  241.         }
  242.     sort_buf (blistp, i);      /* sort buffer lines */
  243.     popblist ();
  244.     writ_echo (MSG_null);
  245.     /* make new window the current window */
  246.     wp = wheadp;
  247.     while (wp != NULL)
  248.         {
  249.         if (wp -> w_bufp == blistp)
  250.             {
  251.             curwp = wp;
  252.             curbp = wp -> w_bufp;
  253.             return (TRUE);
  254.             }
  255.         wp = wp -> w_wndp;
  256.         }
  257.     return (TRUE);
  258. }
  259.             
  260. /* check for BEAVFIL and read it in if found
  261. * - also, set local file variable for bindtokey for saving new defs
  262. * (this is some what of a hack as it only handles 'bindtokey' changes at 
  263. * this time - also local file io !!!)
  264. */
  265. void check_extend (nm)
  266. char   *nm;
  267. {
  268.  
  269. #ifdef CUSTOMIZE
  270.     register    SYMBOL * sp;
  271.     char    buff[NXNAME + 1];
  272.     char    keybuf[NXNAME + 1];
  273.     int     keyval;
  274.     FILE * bindf;
  275.  
  276.     if (!(bindnm = nm))
  277.         return;
  278.     if (!(bindf = fopen (bindnm, "r")))
  279.         return;
  280.     while (fscanf (bindf, "%s %s %x", keybuf, buff, &keyval) != EOF)
  281.         {
  282.         if (sp = symlookup (buff))
  283.             {
  284.             if (binding[keyval] != NULL)/* Unbind old, and  */
  285.                 --binding[keyval] -> s_nkey;
  286.             binding[keyval] = sp;/* rebind new.      */
  287.             ++sp -> s_nkey;
  288.             }
  289.         }
  290.  
  291.     fclose (bindf);
  292. #endif
  293. }
  294.  
  295.  
  296.  
  297. /* interactive method for loading binding file
  298. * (uses above routine, obviously)
  299. */
  300. char    load_extend ()
  301. {
  302.  
  303. #ifdef CUSTOMIZE
  304.     register char   s;
  305.     char    fname[NFILEN];
  306.  
  307.     if ((s = ereply (MSG_bnd_file, fname, NFILEN, NULL)) != TRUE)
  308.         return (s);
  309.     check_extend (fname);
  310.     writ_echo (okmsg);
  311. #endif
  312.     return (TRUE);
  313. }
  314.  
  315. int     find_keyval (name)
  316. char   *name;
  317. {
  318.     SYMBOL * sp;
  319.     int     key;
  320.  
  321.     for (key = 0; key < NKEYS; ++key)
  322.         {
  323.     /* For all keys.    */
  324.         sp = binding[key];
  325.         if (sp != NULL && (strcmp (sp -> s_name, name) == 0))
  326.             return (key);
  327.         }
  328.     return (0);
  329. }
  330.