home *** CD-ROM | disk | FTP | other *** search
/ Usenet 1994 January / usenetsourcesnewsgroupsinfomagicjanuary1994.iso / sources / misc / volume2 / vi-tag-stack < prev    next >
Encoding:
Internet Message Format  |  1991-08-07  |  6.9 KB

  1. From: michael@garfield.UUCP (Mike Rendell)
  2. Newsgroups: comp.sources.misc
  3. Subject: v02i055: Diffs for a tag stack in vi (v3.7)
  4. Message-ID: <7223@ncoast.UUCP>
  5. Date: 11 Feb 88 01:00:52 GMT
  6. Approved: allbery@ncoast.UUCP
  7.  
  8. Comp.sources.misc: Volume 2, Issue 55
  9. Submitted-By: "Mike Rendell" <michael@garfield.UUCP>
  10. Archive-Name: vi-tag-stack
  11.  
  12. [I held on to this while trying to post to comp.bugs.4bsd on r$'s suggestion.
  13. Alas, ncoast never heard of it and our news admin isn't interested.  ++bsa]
  14.  
  15. After using vi on the sun, which has a tag stack, I decided to hack it into
  16. our vaxen's vi (4.3bsd).  The following are the resulting patches for
  17. ex_tagio.c, ex_vmain.c, ex_cmds.c and ex_cmdsub.c.
  18.  
  19. For those of you who don't have suns and don't know what I'm talking about
  20. [and probably most of you with suns, as this feature seems to be
  21. undocumented] this is what the tag stack does:  When you tag something, your
  22. current file (and your current position) are saved on a stack.  When you
  23. want to get back to the previous file(s) you hit ^T.  This is similar to
  24. ^^ except that you can go back multiple levels.  Also I have added a ":push"
  25. command that acts like ":next" except that it pushes the current file on the
  26. tag stack. ":pop" is the same as ^T (really visa versa, for those who know
  27. how vi does these things...). By the way, ^T can take a count to indicate
  28. how many levels to pop.
  29.  
  30. This feature is invaluable when poking around large programs with many
  31. source files.
  32.  
  33.                 Mike Rendell
  34.                 cdnnet: michael@garfield.mun.cdn
  35.                 uucp: michael@garfield
  36.                     {uunet,utai}!garfield!michael
  37.  
  38. Index: ex_tagio.c
  39.  
  40. *** /tmp/,RCSt1014586    Thu Nov  5 17:45:30 1987
  41. --- /tmp/,RCSt2014586    Thu Nov  5 17:45:34 1987
  42. ***************
  43. *** 14,19 ****
  44. --- 14,23 ----
  45.   
  46.   #include <sys/file.h>
  47.   #include "ex.h"
  48. + #ifdef    TAGSTACK
  49. + #include "ex_temp.h"
  50. + #include "ex_vis.h"
  51. + #endif    /* TAGSTACK */
  52.   
  53.   static long offset = -1;
  54.   static long block = -1;
  55. ***************
  56. *** 102,105 ****
  57. --- 106,242 ----
  58.       block = -1;
  59.       bcnt = 0;
  60.   }
  61. + # ifdef    TAGSTACK
  62. + #define    TSTACKMEMSIZE    (10*1024)        /* 10k should suffice */
  63. + typedef struct tstack_str Tstack;
  64. + struct tstack_str {
  65. +     char    *t_file;
  66. +     line    t_dot;
  67. +     int    t_cursor;
  68. +     Tstack    *t_prev;
  69. + };
  70. + int        tstack_cnt = 1;
  71. + static char    tstack_mem[TSTACKMEMSIZE];
  72. + static char    *tstack_ptr = tstack_mem;
  73. + static Tstack    *tstack = (Tstack *) 0;
  74. + /*
  75. +  * save current file/lineno/cursor
  76. +  */
  77. + tag_push(fname)
  78. +     char    *fname;
  79. + {
  80. +     int        len;
  81. +     Tstack        *tp;
  82. +     /* Don't bother if there is no current file */
  83. +     if (fname[0] == '\0')
  84. +         return;
  85. +     /* See how much space we will need */
  86. +     len = sizeof(Tstack) + strlen(fname) + 1;
  87. +     /* keep things word aligned */
  88. +     len += len & 3;
  89. +     if (tstack_ptr + len >= &tstack_mem[TSTACKMEMSIZE]) {
  90. +         lprintf("[Tag stack full] ");
  91. +         return;
  92. +     }
  93. +     tp = (Tstack *) tstack_ptr;
  94. +     tp->t_prev = tstack;
  95. +     tp->t_file = tstack_ptr + sizeof(Tstack);
  96. +     (void) strcpy(tp->t_file, fname);
  97. +     tp->t_dot = lineDOT();
  98. +     tp->t_cursor = inopen ? cursor - linebuf : 0;
  99. +     tstack_ptr += len;
  100. +     tstack = tp;
  101. + }
  102. + tag_pop(bang)
  103. +     int    bang;
  104. + {
  105. +     Tstack        *tp;
  106. +     line        *addr;
  107. +     bool        samef = 1;
  108. +     int        i;
  109. +     /* Do this first so tstack_cnt will be reset regardless */
  110. +     i = tstack_cnt;
  111. +     tstack_cnt = 1;
  112. +     if (!tstack)
  113. +         error("Tag stack empty");
  114. +     for (tp = tstack ; --i > 0 && tp ; tp = tp->t_prev)
  115. +         ;
  116. +     if (!tp)
  117. +         error("Tag stack not that deep");
  118. +     if (strcmp(tp->t_file, savedfile) || !edited) {
  119. +         char cmdbuf2[sizeof(savedfile) + 10];
  120. +         char *oglobp;
  121. +         int omagic;
  122. +         char opeek;
  123. +         if (!bang) {
  124. +             ckaw();
  125. +             if (chng && dol > zero)
  126. +                 error("No write@since last change (:pop! overrides)");
  127. +         }
  128. +         omagic = value(MAGIC);
  129. +         oglobp = globp;
  130. +         strcpy(cmdbuf2, "e! ");
  131. +         strcat(cmdbuf2, tp->t_file);
  132. +         globp = cmdbuf2;
  133. +         opeek = peekc; ungetchar(0);
  134. +         commands(1, 1);
  135. +         peekc = opeek;
  136. +         globp = oglobp;
  137. +         value(MAGIC) = omagic;
  138. +         samef = 0;
  139. +     }
  140. +     /*
  141. +      * Update these now that we know everything is ok
  142. +      */
  143. +     tstack = tp->t_prev;
  144. +     tstack_ptr = (char *) tp;
  145. +     /*
  146. +      *    Try to find the line that we were on
  147. +      */
  148. +     addr = zero + tp->t_dot;
  149. +     /*
  150. +      *    Line is gone?
  151. +      */
  152. +     if (addr <= zero || addr > dol)
  153. +         addr = one;
  154. +     /*
  155. +      * Try to find position on the line
  156. +      */
  157. +     if (inopen) {
  158. +         char    *s;
  159. +         if (samef && addr != dot)
  160. +             markDOT();
  161. +         getline(*addr);
  162. +         s = linebuf + (inopen ? tp->t_cursor : 0);
  163. +         if (s >= linebuf && s < strend(linebuf)) {
  164. +             char    tbuf[8]; /* 001024 (max line) + ' ' + \0 */
  165. +             if (s != linebuf)
  166. +                 (void) sprintf(tbuf, "00%d ", s - linebuf);
  167. +             else
  168. +                 tbuf[0] = '0', tbuf[1] = '0', tbuf[2] = '\0';
  169. +             macpush(tbuf, 0);
  170. +         }
  171. +     }
  172. +     dot = addr;
  173. +     if (ospeed > B300)
  174. +         hold |= HOLDWIG;
  175. +     return;
  176. + }
  177. + # endif    TAGSTACK
  178.   #endif
  179.  
  180. Index: ex_cmds.c
  181.  
  182. *** /tmp/,RCSt1014564    Thu Nov  5 17:45:06 1987
  183. --- /tmp/,RCSt2014564    Thu Nov  5 17:45:19 1987
  184. ***************
  185. *** 410,418 ****
  186.           case 'P':
  187.               switch (peekchar()) {
  188.   
  189. - /* put */
  190.               case 'u':
  191.                   tail("put");
  192.                   setdot();
  193.                   c = cmdreg();
  194.                   eol();
  195. --- 410,439 ----
  196.           case 'P':
  197.               switch (peekchar()) {
  198.   
  199.               case 'u':
  200. + #ifdef    TAGSTACK
  201. + /* push */
  202. +                 ignchar();
  203. +                 if (peekchar() == 's') {
  204. +                     tail2of("push");
  205. +                     setnoaddr();
  206. +                     ckaw();
  207. +                     ignore(quickly());
  208. +                     if (getargs())
  209. +                         makargs();
  210. +                     next();
  211. +                     tag_push(altfile);
  212. +                     c = 'e';
  213. +                     filename(c);
  214. +                     goto doecmd;
  215. +                 }
  216. + /* put */
  217. +                 tail2of("put");
  218. + #else    /* TAGSTACK */
  219. + /* put */
  220.                   tail("put");
  221. + #endif    /* TAGSTACK */
  222.                   setdot();
  223.                   c = cmdreg();
  224.                   eol();
  225. ***************
  226. *** 437,442 ****
  227. --- 458,482 ----
  228.                   tail2of("print");
  229.                   break;
  230.   
  231. + #ifdef    TAGSTACK    
  232. +             case 'o':
  233. + /* pop */
  234. +                 {
  235. +                     int    bang;
  236. +                     tail("pop");
  237. +                     setnoaddr();
  238. +                     bang = exclam();
  239. +                     eol();
  240. +                     tag_pop(bang);
  241. +                     if (!inopen)
  242. +                         lchng = chng - 1;
  243. +                     else
  244. +                         nochng();
  245. +                     continue;
  246. +                 }
  247. + #endif    TAGSTACK
  248. +     
  249.               default:
  250.                   tail("print");
  251.                   break;
  252.  
  253. Index: ex_cmdsub.c
  254.  
  255. *** /tmp/,RCSt1014573    Thu Nov  5 17:45:40 1987
  256. --- /tmp/,RCSt2014573    Thu Nov  5 17:45:54 1987
  257. ***************
  258. *** 623,628 ****
  259. --- 623,631 ----
  260.                   }
  261.               }
  262.               strcpy(cmdbuf, cp);
  263. + #ifdef    TAGSTACK
  264. +             tag_push(savedfile);
  265. + #endif    /* TAGSTACK */
  266.               if (strcmp(filebuf, savedfile) || !edited) {
  267.                   char cmdbuf2[sizeof filebuf + 10];
  268.   
  269.  
  270. Index: ex_vmain.c
  271.  
  272. *** /tmp/,RCSt1014581    Thu Nov  5 17:45:46 1987
  273. --- /tmp/,RCSt2014581    Thu Nov  5 17:46:02 1987
  274. ***************
  275. *** 844,850 ****
  276. --- 844,866 ----
  277.                   globp = "e #";
  278.               goto gogo;
  279.   
  280. + #ifdef    TAGSTACK
  281.           /*
  282. +          *    Pop a tag off the stack
  283. +          */
  284. +         case CTRL(t):
  285. +             if (hadcnt) {
  286. +                 extern int tstack_cnt;
  287. +                 tstack_cnt = cnt;
  288. +             }
  289. +             vsave();
  290. +             oglobp = globp;
  291. +             globp = "pop";
  292. +             goto gogo;
  293. + #endif    /* TAGSTACK */
  294. +         /*
  295.            * ^]        Takes word after cursor as tag, and then does
  296.            *        tag command.  Read ``go right to''.
  297.            */
  298.