add a CVS snapshot, to thoroughly test on the Debian side
[alioth/jupp.git] / poshist.c
1 /* $MirOS: contrib/code/jupp/poshist.c,v 1.2 2008/05/13 13:08:24 tg Exp $ */
2 /*
3  *      Position history
4  *      Copyright
5  *              (C) 1992 Joseph H. Allen
6  *
7  *      This file is part of JOE (Joe's Own Editor)
8  */
9 #include "config.h"
10 #include "types.h"
11
12 #ifdef HAVE_STDLIB_H
13 #include <stdlib.h>
14 #endif
15
16 #include "b.h"
17 #include "queue.h"
18 #include "w.h"
19
20 typedef struct pos POS;
21
22 struct pos {
23         LINK(POS) link;
24         P *p;
25         W *w;
26 };
27
28 POS pos = { {&pos, &pos} };
29 POS frpos = { {&frpos, &frpos} };
30 POS *curpos = &pos;
31 int npos = 0;
32
33 static void markpos(W *w, P *p)
34 {
35         POS *new = alitem(&frpos, sizeof(POS));
36
37         new->p = NULL;
38         pdupown(p, &new->p);
39         poffline(new->p);
40         new->w = w;
41         enqueb(POS, link, &pos, new);
42         if (npos == 20) {
43                 new = pos.link.next;
44                 prm(new->p);
45                 demote(POS, link, &frpos, new);
46         } else {
47                 ++npos;
48         }
49 }
50
51 void afterpos(void)
52 {
53         if (curpos != &pos) {
54                 demote(POS, link, &pos, curpos);
55                 curpos = &pos;
56         }
57 }
58
59 void aftermove(W *w, P *p)
60 {
61         if (pos.link.prev != &pos && pos.link.prev->w == w && pos.link.prev->p && labs(pos.link.prev->p->line - p->line) < 3) {
62                 poffline(pset(pos.link.prev->p, p));
63         } else {
64                 markpos(w, p);
65         }
66 }
67
68 void windie(W *w)
69 {
70         POS *n;
71
72         for (n = pos.link.prev; n != &pos; n = n->link.prev) {
73                 if (n->w == w) {
74                         n->w = NULL;
75                 }
76         }
77 }
78
79 int unextpos(BW *bw)
80 {
81         W *w = bw->parent;
82
83       lp:
84         if (curpos->link.next != &pos && curpos != &pos) {
85                 curpos = curpos->link.next;
86                 if (!curpos->p || !curpos->w) {
87                         goto lp;
88                 }
89                 if (w->t->curwin == curpos->w && curpos->p->byte == ((BW *) w->t->curwin->object)->cursor->byte) {
90                         goto lp;
91                 }
92                 if (w->t->curwin != curpos->w) {
93                         w->t->curwin = curpos->w;
94                         if (w->t->curwin->y == -1) {
95                                 wfit(w->t);
96                         }
97                 }
98                 w = w->t->curwin;
99                 bw = (BW *) w->object;
100                 if (bw->cursor->byte != curpos->p->byte) {
101                         pset(bw->cursor, curpos->p);
102                 }
103                 return 0;
104         } else {
105                 return -1;
106         }
107 }
108
109 int uprevpos(BW *bw)
110 {
111         W *w = bw->parent;
112
113       lp:
114         if (curpos->link.prev != &pos) {
115                 curpos = curpos->link.prev;
116                 if (!curpos->p || !curpos->w) {
117                         goto lp;
118                 }
119                 if (w->t->curwin == curpos->w && curpos->p->byte == ((BW *) w->t->curwin->object)->cursor->byte) {
120                         goto lp;
121                 }
122                 if (w->t->curwin != curpos->w) {
123                         w->t->curwin = curpos->w;
124                         if (w->t->curwin->y == -1) {
125                                 wfit(w->t);
126                         }
127                 }
128                 w = w->t->curwin;
129                 bw = (BW *) w->object;
130                 if (bw->cursor->byte != curpos->p->byte) {
131                         pset(bw->cursor, curpos->p);
132                 }
133                 return 0;
134         } else {
135                 return -1;
136         }
137 }