home *** CD-ROM | disk | FTP | other *** search
/ The Datafile PD-CD 5 / DATAFILE_PDCD5.iso / utilities / p / psh / c / readlines < prev    next >
Text File  |  1995-05-08  |  4KB  |  198 lines

  1. /* vi:tabstop=4:shiftwidth=4:smartindent
  2.  *
  3.  * readlines.c - Initialise readline and history stuff
  4.  *
  5.  */
  6.  
  7. #include <ctype.h>
  8. #include <stdio.h>
  9. #include <string.h>
  10. #include <readline.h>
  11. #include <history.h>
  12. #include <unistd.h>
  13. #include <pwd.h>
  14. #include <sys/os.h>
  15. #include "psh.h"
  16.  
  17. extern char    *rl_line_buffer;
  18. extern int    rl_point;
  19. extern void    rl_delete_text(int start, int end);
  20. extern void    rl_insert_text(char *);
  21. extern void rl_begin_undo_group(void);
  22. extern void rl_end_undo_group(void);
  23.  
  24. /* Grabs the word under the cursor. Returns this in an
  25.  * array. The word is deleted from the text, and an
  26.  * undo-group started before the deletion. The variable
  27.  * rl_point is adjusted to point to the word's start.
  28.  * Returns NULL if no word was under the cursor.
  29.  */
  30. static char *extract_word(void)
  31. {
  32.     char        *s, *e, *t;
  33.     static char    tmp[MAXLEN];
  34.  
  35.     s = rl_line_buffer+rl_point;
  36.  
  37.     /* If we're on a space or end of line, take one step back.
  38.      */
  39.     if ((*s == '\0') || (isspace(*s)))
  40.     {
  41.         s--;
  42.  
  43.         /* If, after stepping back, we're still on a space, or are
  44.          * before the string start, then there's nothing to convert.
  45.          */
  46.         if ((s<rl_line_buffer) || (isspace(*s)))
  47.         {
  48.             return NULL;
  49.         }
  50.     }
  51.  
  52.     /* Search backwards for the space or string start.
  53.      * After this, s points to the first character of the word.
  54.      */
  55.     while (!isspace(*s) && (s >= rl_line_buffer)) s--;
  56.     s++;
  57.  
  58.     /* Now search forward from the word start, to the
  59.      * first space or string end.
  60.      * After this, e points to the last character of the word.
  61.      */
  62.     e = s;
  63.     t = tmp;
  64.     while (!isspace(*e) && (*e != '\0')) *t++ = *e++;
  65.     e--;
  66.     *t = '\0';
  67.  
  68.     /* Start the undo-group
  69.      */
  70.     rl_begin_undo_group();
  71.  
  72.     /* Remove the word from the line
  73.      */
  74.     rl_delete_text(s-rl_line_buffer, e-rl_line_buffer+1);
  75.  
  76.     /* Adjust the cursor pointer.
  77.      */
  78.     rl_point = s-rl_line_buffer;
  79.  
  80.     return tmp;
  81. }
  82.  
  83. /* Allow old RISC OS cursor key editing
  84.  */
  85. int cursor_on(int count, int key)
  86. {
  87.     int retvals[3];
  88.     os_byte(4, 0, 0, retvals);
  89.     return 0;
  90. }
  91. /* Disallow old RISC OS cursor key editing
  92.  */
  93. int cursor_off(int count, int key)
  94. {
  95.     int retvals[3];
  96.     os_byte(4, 2, 0, retvals);
  97.     os_vdu(13);
  98.     rl_forced_update_display();
  99.     return 0;
  100. }
  101.  
  102. /* An additional readline function. This takes the word under
  103.  * the cursor and does Unix->RISC OS conversion on it. By default
  104.  * it is mapped to Meta-k, though can be remapped in the .inputrc 
  105.  * by binding the function riscos-name. The function also escapes
  106.  * any ! or ^ in the converted name.
  107.  */
  108.  
  109. int    riscos_name(int count, int key)
  110. {
  111.     char    *w, *k, *p;
  112.     char    tmp[MAXLEN], tmp2[MAXLEN], tmp3[MAXLEN];
  113.  
  114.     if ((w = extract_word()) != NULL)
  115.     {
  116.         p = w = strcpy(tmp3, __uname(w, 0));
  117.         k = tmp;
  118.         while (*w)
  119.         {
  120.             if ((*w == '^') || (*w == '!'))
  121.             {
  122.                 *k++ = '\\';
  123.             }
  124.             if ((*w == '~') && !((w > p) && isspace(*(w-1))))
  125.             {
  126.                 strcpy(tmp2, w);
  127.                 p = strtok(tmp2, " .\t\n\r");
  128.                 DEBUG(printf("\nGot dirname %s\n", p);rl_refresh_line();)
  129.                 if (p[1])
  130.                 {
  131.                     struct passwd    *user;
  132.  
  133.                     p++;
  134.                     user = getpwnam(p);
  135.                     if (user)
  136.                     {
  137.                         w += strlen(p)+1;
  138.                         strcpy(k, __uname(user->pw_dir, 0));
  139.                         k += strlen(k);
  140.                     }
  141.                     else
  142.                     {
  143.                         *k++ = *w++;
  144.                     }
  145.                 }
  146.                 else
  147.                 {
  148.                     *k++ = '&';
  149.                     w++;
  150.                 }
  151.             }
  152.             else
  153.             {
  154.                 *k++ = *w++;
  155.             }
  156.         }
  157.         *k = '\0';
  158.  
  159.         rl_insert_text(tmp);
  160.  
  161.         /* End of action
  162.          */
  163.         rl_end_undo_group();
  164.     }
  165.     return 0;
  166. }
  167.  
  168. /* Initialises the readline stuff and reads in the history
  169.  */
  170. void    init_readline(char *me)
  171. {
  172.     /* What's my name ?
  173.      */
  174.     rl_readline_name = me;
  175.  
  176.     /* Add a function to do Unix->RISC OS name conversions.
  177.      * This is mapped to Meta-k, so doing
  178.      * cd /usr/local/bin[ESC][k] will change the line
  179.      * to 
  180.      * cd $.usr.local.bin or whatever.
  181.      */
  182.     rl_add_defun("riscos-name", riscos_name, META('k'));
  183.  
  184.     /* Copy generates Meta-K, so map this to something which
  185.      * does *fx4,0 and so turns cursor editing on.
  186.      */
  187.     rl_add_defun("cursor-edit-on", cursor_on, META('K'));
  188.  
  189.     /* Bind Meta-Control-[ (Escape-Escape) to turn RISC OS cursor
  190.      * editing off.
  191.      */
  192.     rl_add_defun("cursor-edit-off", cursor_off, META(CTRL('[')));
  193.  
  194.     /* Bring in ~/.history
  195.      */
  196.     read_history(NULL);
  197. }
  198.