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