home *** CD-ROM | disk | FTP | other *** search
/ The World of Computer Software / World_Of_Computer_Software-02-385-Vol-1of3.iso / z / zsh220.zip / zsh2.2 / src / zle_hist.c < prev    next >
C/C++ Source or Header  |  1992-05-07  |  10KB  |  621 lines

  1. /*
  2.  *
  3.  * zle_hist.c - history editing
  4.  *
  5.  * This file is part of zsh, the Z shell.
  6.  *
  7.  * This software is Copyright 1992 by Paul Falstad
  8.  *
  9.  * Permission is hereby granted to copy, reproduce, redistribute or otherwise
  10.  * use this software as long as: there is no monetary profit gained
  11.  * specifically from the use or reproduction of this software, it is not
  12.  * sold, rented, traded or otherwise marketed, and this copyright notice is
  13.  * included prominently in any copy made. 
  14.  *
  15.  * The author make no claims as to the fitness or correctness of this software
  16.  * for any use whatsoever, and it is provided as is. Any use of this software
  17.  * is at the user's own risk. 
  18.  *
  19.  */
  20.  
  21. #define ZLE
  22. #include "zsh.h"
  23.  
  24. void toggleliteralhistory() /**/
  25. {
  26. char *s;
  27.  
  28.     if (histline == curhist)
  29.         {
  30.         if (curhistline)
  31.             free(curhistline);
  32.         curhistline = ztrdup(line);
  33.         }
  34.     lithist ^= 1;
  35.     if (!(s = qgetevent(histline)))
  36.         feep();
  37.     else
  38.         sethistline(s);
  39. }
  40.  
  41. void uphistory() /**/
  42. {
  43. char *s;
  44.  
  45.     if (mult < 0) { mult = -mult; downhistory(); return; }
  46.     if (histline == curhist)
  47.         {
  48.         if (curhistline)
  49.             free(curhistline);
  50.         curhistline = ztrdup(line);
  51.         }
  52.     histline -= mult;
  53.     if (!(s = qgetevent(histline)))
  54.         {
  55.         if (unset(NOHISTBEEP)) feep();
  56.         histline += mult;
  57.         }
  58.     else
  59.         sethistline(s);
  60. }
  61.  
  62. void uplineorhistory() /**/
  63. {
  64. int ocs = cs;
  65.  
  66.     if (mult < 0) { mult = -mult; downlineorhistory(); return; }
  67.     if ((lastcmd & ZLE_LINEMOVE) != ZLE_LINEMOVE)
  68.         lastcol = cs-findbol();
  69.     cs = findbol();
  70.     while (mult) {
  71.         if (!cs)
  72.             break;
  73.         cs--;
  74.         cs = findbol();
  75.         mult--;
  76.     }
  77.     if (mult) {
  78.         cs = ocs;
  79.         if (virangeflag) {
  80.             feep();
  81.             return;
  82.         }
  83.         uphistory();
  84.     } else {
  85.         int x = findeol();
  86.         if ((cs += lastcol) > x)
  87.             cs = x;
  88.     }
  89. }
  90.  
  91. void downlineorhistory() /**/
  92. {
  93. int ocs = cs;
  94.  
  95.     if (mult < 0) { mult = -mult; uplineorhistory(); return; }
  96.     if ((lastcmd & ZLE_LINEMOVE) != ZLE_LINEMOVE)
  97.         lastcol = cs-findbol();
  98.     while (mult) {
  99.         int x = findeol();
  100.         if (x == ll)
  101.             break;
  102.         cs = x+1;
  103.         mult--;
  104.     }
  105.     if (mult) {
  106.         cs = ocs;
  107.         if (virangeflag) {
  108.             feep();
  109.             return;
  110.         }
  111.         downhistory();
  112.     } else {
  113.         int x = findeol();
  114.         if ((cs += lastcol) > x)
  115.             cs = x;
  116.     }
  117. }
  118.  
  119. void acceptlineanddownhistory() /**/
  120. {
  121. char *s,*t;
  122.  
  123.     if (!(s = qgetevent(histline+1)))
  124.         {
  125.         feep();
  126.         return;
  127.         }
  128.     pushnode(bufstack,t = ztrdup(s));
  129.     for (; *t; t++)
  130.         if (*t == HISTSPACE)
  131.             *t = ' ';
  132.     done = 1;
  133.     stackhist = histline+1;
  134. }
  135.  
  136. void downhistory() /**/
  137. {
  138. char *s;
  139.  
  140.     if (mult < 0) { mult = -mult; uphistory(); return; }
  141.     histline += mult;
  142.     if (!(s = qgetevent(histline)))
  143.         {
  144.         if (unset(NOHISTBEEP)) feep();
  145.         histline -= mult;
  146.         return;
  147.         }
  148.     sethistline(s);
  149. }
  150.  
  151. static int histpos;
  152.  
  153. void historysearchbackward() /**/
  154. {
  155. int t0,ohistline = histline;
  156. char *s;
  157.  
  158.     if (histline == curhist)
  159.         {
  160.         if (curhistline)
  161.             free(curhistline);
  162.         curhistline = ztrdup(line);
  163.         }
  164.     if (lastcmd & ZLE_HISTSEARCH) t0 = histpos;
  165.     else for (t0 = 0; line[t0] && iword(line[t0]); t0++);
  166.     histpos = t0;
  167.     for (;;)
  168.         {
  169.         histline--;
  170.         if (!(s = qgetevent(histline)))
  171.             {
  172.             feep();
  173.             histline = ohistline;
  174.             return;
  175.             }
  176.         if (!hstrncmp(s,line,t0) && hstrcmp(s,line))
  177.             break;
  178.         }
  179.     sethistline(s);
  180. }
  181.  
  182. void historysearchforward() /**/
  183. {
  184. int t0,ohistline = histline;
  185. char *s;
  186.  
  187.     if (histline == curhist)
  188.         {
  189.         if (curhistline)
  190.             free(curhistline);
  191.         curhistline = ztrdup(line);
  192.         }
  193.     if (lastcmd & ZLE_HISTSEARCH) t0 = histpos;
  194.     else for (t0 = 0; line[t0] && iword(line[t0]); t0++);
  195.     histpos = t0;
  196.     for (;;)
  197.         {
  198.         histline++;
  199.         if (!(s = qgetevent(histline)))
  200.             {
  201.             feep();
  202.             histline = ohistline;
  203.             return;
  204.             }
  205.         if (!hstrncmp(s,line,t0) && hstrcmp(s,line))
  206.             break;
  207.         }
  208.     sethistline(s);
  209. }
  210.  
  211. void beginningofbufferorhistory() /**/
  212. {
  213.     if (findbol())
  214.         cs = 0;
  215.     else
  216.         beginningofhistory();
  217. }
  218.  
  219. void beginningofhistory() /**/
  220. {
  221. char *s;
  222.  
  223.     if (histline == curhist)
  224.         {
  225.         if (curhistline)
  226.             free(curhistline);
  227.         curhistline = ztrdup(line);
  228.         }
  229.     if (!(s = qgetevent(firsthist())))
  230.         {
  231.         if (unset(NOHISTBEEP)) feep();
  232.         return;
  233.         }
  234.     histline = firsthist();
  235.     sethistline(s);
  236. }
  237.  
  238. void endofbufferorhistory() /**/
  239. {
  240.     if (findeol() != ll)
  241.         cs = ll;
  242.     else
  243.         endofhistory();
  244. }
  245.  
  246. void endofhistory() /**/
  247. {
  248.     if (histline == curhist) {
  249.         if (unset(NOHISTBEEP)) feep();
  250.     } else
  251.         {
  252.         histline = curhist;
  253.         sethistline(curhistline);
  254.         }
  255. }
  256.  
  257. void insertlastword() /**/
  258. {
  259. char *s,*t;
  260. int len,z = lithist;
  261.  
  262.     /* multiple calls will now search back through the history, pem */
  263.     static char    *lastinsert;
  264.     static int    lasthist, lastpos;
  265.     int        evhist = curhist - 1;
  266.  
  267.     if (lastinsert) {
  268.         int len = strlen(lastinsert);
  269.         int pos = cs;
  270.         if (    lastpos <= pos &&
  271.             len == pos - lastpos &&
  272.             strncmp(lastinsert, (char *) &line[lastpos], len) == 0) {
  273.         evhist = --lasthist;
  274.         cs = lastpos;
  275.         foredel(pos-cs);
  276.         }
  277.         free(lastinsert);
  278.         lastinsert = NULL;
  279.     }
  280.     lithist = 0;
  281.     if (!(s = qgetevent(evhist), lithist = z, s))
  282.         {
  283.         feep();
  284.         return;
  285.         }
  286.     for (t = s+strlen(s); t > s; t--)
  287.         if (*t == HISTSPACE)
  288.             break;
  289.     if (t != s)
  290.         t++;
  291.     lasthist = evhist;
  292.     lastpos = cs;
  293.     lastinsert = ztrdup(t);
  294.     spaceinline(len = strlen(t));
  295.     strncpy((char *) line+cs,t,len);
  296.     cs += len;
  297. }
  298.  
  299. char *qgetevent(ev) /**/
  300. int ev;
  301. {
  302.     if (ev > curhist)
  303.         return NULL;
  304.     return ((ev == curhist) ? curhistline : quietgetevent(ev));
  305. }
  306.  
  307. void pushline() /**/
  308. {
  309.     if (mult < 0) return;
  310.     pushnode(bufstack,ztrdup(line));
  311.     while (--mult)
  312.         pushnode(bufstack,ztrdup(""));
  313.     stackcs = cs;
  314.     *line = '\0';
  315.     ll = cs = 0;
  316. }
  317.  
  318. void getline() /**/
  319. {
  320. char *s = getnode(bufstack);
  321.  
  322.     if (!s)
  323.         feep();
  324.     else
  325.         {
  326.         int cc;
  327.  
  328.         cc = strlen(s);
  329.         spaceinline(cc);
  330.         strncpy((char *) line+cs,s,cc);
  331.         cs += cc;
  332.         free(s);
  333.         }
  334. }
  335.  
  336. void historyincrementalsearchbackward() /**/
  337. {
  338.     doisearch(-1);
  339. }
  340.  
  341. void historyincrementalsearchforward() /**/
  342. {
  343.     doisearch(1);
  344. }
  345.  
  346. void doisearch(dir) /**/
  347. int dir;
  348. {
  349. char *s,*oldl;
  350. char ibuf[256],*sbuf = ibuf+10;
  351. int sbptr = 0,ch,ohl = histline,ocs = cs;
  352. int nomatch = 0,chequiv = 0;
  353.  
  354.     strcpy(ibuf,"i-search: ");
  355.     statusline = ibuf;
  356.     oldl = ztrdup(line);
  357.     if (histline == curhist)
  358.         {
  359.         if (curhistline)
  360.             free(curhistline);
  361.         curhistline = ztrdup(line);
  362.         }
  363.     for (;;)
  364.         {
  365.         nomatch = 0;
  366.         if (sbptr > 1 || (sbptr == 1 && sbuf[0] != '^'))
  367.             {
  368.             int ohistline = histline;
  369.  
  370.             for (;;)
  371.                 {
  372.                 char *t;
  373.  
  374.                 if (!(s = qgetevent(histline)))
  375.                     {
  376.                     feep();
  377.                     nomatch = 1;
  378.                     histline = ohistline;
  379.                     break;
  380.                     }
  381.                 if ((sbuf[0] == '^') ?
  382.                         (t = (hstrncmp(s,sbuf+1,sbptr-1)) ? NULL : s) :
  383.                         (t = hstrnstr(s,sbuf,sbptr)))
  384.                     if (!(chequiv && !hstrcmp(line,s)))
  385.                         {
  386.                         sethistline(s);
  387.                         cs = t-s+sbptr-(sbuf[0] == '^');
  388.                         break;
  389.                         }
  390.                 histline += dir;
  391.                 }
  392.             chequiv = 0;
  393.             }
  394.         refresh();
  395.         if ((ch = getkey(1)) == -1)
  396.             break;
  397.         if (ch == 22 || ch == 17) {
  398.             if ((ch = getkey(1)) == -1)
  399.                 break;
  400.         } else if (ch == 24) { /* ^XS and ^XR */
  401.             if ((ch = getkey(1)) == -1)
  402.                 break;
  403.             if (ch != 's' && ch != 'r') {
  404.                 ungetkey(24);
  405.                 ungetkey(ch);
  406.                 break;
  407.             }
  408.             ungetkey(ch & 0x1f);
  409.             continue;
  410.         } else if (ch == 8 || ch == 127) {
  411.             if (sbptr)
  412.                 sbuf[--sbptr] = '\0';
  413.             else
  414.                 feep();
  415.             histline = ohl;
  416.             continue;
  417.         } else if (ch == 7 || ch == 3) {
  418.             setline(oldl);
  419.             cs = ocs;
  420.             histline = ohl;
  421.             statusline = NULL;
  422.             break;
  423.         } else if (ch == 27)
  424.             break;
  425.         else if (ch == 10 || ch == 13) {
  426.             ungetkey(ch);
  427.             break;
  428.         } else if (ch == 18) {
  429.             ohl = (histline += (dir = -1));
  430.             chequiv = 1;
  431.             continue;
  432.         } else if (ch == 19) {
  433.             ohl = (histline += (dir = 1));
  434.             chequiv = 1;
  435.             continue;
  436.         } else if (!(ch & 0x60)) {
  437.             ungetkey(ch);
  438.             break;
  439.         }
  440.         if (!nomatch && sbptr != 39 && !icntrl(ch)) {
  441.             sbuf[sbptr++] = ch;
  442.             sbuf[sbptr] = '\0';
  443.         }
  444.     }
  445.     free(oldl);
  446.     statusline = NULL;
  447. }
  448.  
  449. void acceptandinfernexthistory() /**/
  450. {
  451. int t0;
  452. char *s,*t;
  453.  
  454.     done = 1;
  455.     for (t0 = histline-2;;t0--)
  456.         {
  457.         if (!(s = qgetevent(t0)))
  458.             return;
  459.         if (!hstrncmp(s,line,ll))
  460.             break;
  461.         }
  462.     if (!(s = qgetevent(t0+1)))
  463.         return;
  464.     pushnode(bufstack,t = ztrdup(s));
  465.     for (; *t; t++)
  466.         if (*t == HISTSPACE)
  467.             *t = ' ';
  468.     stackhist = t0+1;
  469. }
  470.  
  471. void infernexthistory() /**/
  472. {
  473. int t0;
  474. char *s,*t;
  475.  
  476.     if (!(t = qgetevent(histline-1)))
  477.         {
  478.         feep();
  479.         return;
  480.         }
  481.     for (t0 = histline-2;;t0--)
  482.         {
  483.         if (!(s = qgetevent(t0)))
  484.             {
  485.             feep();
  486.             return;
  487.             }
  488.         if (!strcmp(s,t))
  489.             break;
  490.         }
  491.     if (!(s = qgetevent(t0+1)))
  492.         {
  493.         feep();
  494.         return;
  495.         }
  496.     histline = t0+1;
  497.     sethistline(s);
  498. }
  499.  
  500. void vifetchhistory() /**/
  501. {
  502. char *s;
  503.  
  504.     if (mult < 0) return;
  505.     if (histline == curhist) {
  506.         if (!(lastcmd & ZLE_ARG)) {
  507.             cs = ll;
  508.             cs = findbol();
  509.             return;
  510.         }
  511.         if (curhistline)
  512.             free(curhistline);
  513.         curhistline = ztrdup(line);
  514.     }
  515.     if (!(lastcmd & ZLE_ARG)) mult = curhist;
  516.     if (!(s = qgetevent(mult)))
  517.         feep();
  518.     else {
  519.         histline = mult;
  520.         sethistline(s);
  521.     }
  522. }
  523.  
  524. int getvisrchstr() /**/
  525. {
  526. char sbuf[80];
  527. int sptr = 1;
  528.  
  529.     if (visrchstr)
  530.         {
  531.         free(visrchstr);
  532.         visrchstr = NULL;
  533.         }
  534.     statusline = sbuf;
  535.     sbuf[0] = c;
  536.     sbuf[1] = '\0';
  537.     while (sptr)
  538.         {
  539.         refresh();
  540.         c = getkey(0);
  541.         if (c == '\r' || c == '\n' || c == '\033')
  542.             {
  543.             visrchstr = ztrdup(sbuf+1);
  544.             return 1;
  545.             }
  546.         if (c == '\b' || c == 127)
  547.             {
  548.             sbuf[--sptr] = '\0';
  549.             continue;
  550.             }
  551.         if (sptr != 79)
  552.             {
  553.             sbuf[sptr++] = c;
  554.             sbuf[sptr] = '\0';
  555.             }
  556.         }
  557.     return 0;
  558. }
  559.  
  560. void vihistorysearchforward() /**/
  561. {
  562.     visrchsense = 1;
  563.     if (getvisrchstr())
  564.         virepeatsearch();
  565. }
  566.  
  567. void vihistorysearchbackward() /**/
  568. {
  569.     visrchsense = -1;
  570.     if (getvisrchstr())
  571.         virepeatsearch();
  572. }
  573.  
  574. void virepeatsearch() /**/
  575. {
  576. int ohistline = histline,t0;
  577. char *s;
  578.  
  579.     if (!visrchstr)
  580.         {
  581.         feep();
  582.         return;
  583.         }
  584.     t0 = strlen(visrchstr);
  585.     if (histline == curhist)
  586.         {
  587.         if (curhistline)
  588.             free(curhistline);
  589.         curhistline = ztrdup(line);
  590.         }
  591.     for (;;)
  592.         {
  593.         histline += visrchsense;
  594.         if (!(s = qgetevent(histline)))
  595.             {
  596.             feep();
  597.             histline = ohistline;
  598.             return;
  599.             }
  600.         if (!hstrcmp(line,s))
  601.             continue;
  602.         if (*visrchstr == '^')
  603.             {
  604.             if (!hstrncmp(s,visrchstr+1,t0-1))
  605.                 break;
  606.             }
  607.         else
  608.             if (hstrnstr(s,visrchstr,t0))
  609.                 break;
  610.         }
  611.     sethistline(s);
  612. }
  613.  
  614. void virevrepeatsearch() /**/
  615. {
  616.     visrchsense = -visrchsense;
  617.     virepeatsearch();
  618.     visrchsense = -visrchsense;
  619. }
  620.  
  621.