joe-3.1jupp31.tgz (die zweite Klappeā€¦)
[alioth/jupp.git] / pw.c
1 /* $MirOS: contrib/code/jupp/pw.c,v 1.8 2017/01/11 22:56:48 tg Exp $ */
2 /*
3  *      Prompt windows
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 #include <stdlib.h>
13 #include <string.h>
14
15 #include "b.h"
16 #include "bw.h"
17 #include "help.h"
18 #include "kbd.h"
19 #include "path.h"
20 #include "pw.h"
21 #include "scrn.h"
22 #include "tab.h"
23 #include "termcap.h"
24 #include "tw.h"
25 #include "uedit.h"
26 #include "undo.h"
27 #include "utils.h"
28 #include "vfile.h"
29 #include "menu.h"
30 #include "va.h"
31 #include "w.h"
32
33 extern int smode;
34 extern int dobeep;
35
36 static void disppw(BW *bw, int flg)
37 {
38         W *w = bw->parent;
39         PW *pw = (PW *) bw->object;
40
41         if (!flg) {
42                 return;
43         }
44
45         /* Scroll buffer and position prompt */
46         if (pw->promptlen > w->w / 2 + w->w / 4) {
47                 pw->promptofst = pw->promptlen - w->w / 2;
48                 if (piscol(bw->cursor) < w->w - (pw->promptlen - pw->promptofst)) {
49                         bw->offset = 0;
50                 } else {
51                         bw->offset = piscol(bw->cursor) - (w->w - (pw->promptlen - pw->promptofst) - 1);
52                 }
53         } else {
54                 if (piscol(bw->cursor) < w->w - pw->promptlen) {
55                         pw->promptofst = 0;
56                         bw->offset = 0;
57                 } else if (piscol(bw->cursor) >= w->w) {
58                         pw->promptofst = pw->promptlen;
59                         bw->offset = piscol(bw->cursor) - (w->w - 1);
60                 } else {
61                         pw->promptofst = pw->promptlen - (w->w - piscol(bw->cursor) - 1);
62                         bw->offset = piscol(bw->cursor) - (w->w - (pw->promptlen - pw->promptofst) - 1);
63                 }
64         }
65
66         /* Set cursor position */
67         w->curx = piscol(bw->cursor) - bw->offset + pw->promptlen - pw->promptofst;
68         w->cury = 0;
69
70         /* Generate prompt */
71         w->t->t->updtab[w->y] = 1;
72         genfmt(w->t->t, w->x, w->y, pw->promptofst, pw->prompt, 0);
73
74         /* Position and size buffer */
75         bwmove(bw, w->x + pw->promptlen - pw->promptofst, w->y);
76         bwresz(bw, w->w - (pw->promptlen - pw->promptofst), 1);
77
78         /* Generate buffer */
79         bwgen(bw, 0);
80 }
81
82 /* When user hits return in a prompt window */
83
84 extern volatile int dostaupd;
85
86 static int rtnpw(BW *bw)
87 {
88         W *w = bw->parent;
89         PW *pw = (PW *) bw->object;
90         unsigned char *s;
91         W *win;
92         int *notify;
93         int (*pfunc) ();
94         void *object;
95         long byte;
96
97         p_goto_eol(bw->cursor);
98         byte = bw->cursor->byte;
99         p_goto_bol(bw->cursor);
100         s = brvs(bw->cursor, (int) (byte - bw->cursor->byte));
101         if (pw->hist) {
102                 if (bw->b->changed) {
103                         P *q = pdup(pw->hist->eof);
104
105                         binsm(q, s, (int) (byte - bw->cursor->byte));
106                         p_goto_eof(q);
107                         binsc(q, '\n');
108                         prm(q);
109                 } else {
110                         P *q = pdup(pw->hist->bof);
111                         P *r;
112                         P *t;
113
114                         pline(q, bw->cursor->line);
115                         r = pdup(q);
116                         pnextl(r);
117                         t = pdup(pw->hist->eof);
118                         binsb(t, bcpy(q, r));
119                         bdel(q, r);
120                         prm(q);
121                         prm(r);
122                         prm(t);
123                 }
124         }
125         win = w->win;
126         pfunc = pw->pfunc;
127         object = pw->object;
128         bwrm(bw);
129         joe_free(pw->prompt);
130         joe_free(pw);
131         w->object = NULL;
132         notify = w->notify;
133         w->notify = 0;
134         wabort(w);
135         dostaupd = 1;
136         if (pfunc) {
137                 return pfunc(win->object, s, object, notify);
138         } else {
139                 return -1;
140         }
141 }
142
143 int ucmplt(BW *bw, int k)
144 {
145         PW *pw = (PW *) bw->object;
146
147         if (pw->tab) {
148                 return pw->tab(bw, k);
149         } else {
150                 return -1;
151         }
152 }
153
154 static void inspw(BW *bw, B *b, long l, long n, int flg)
155 {
156         if (b == bw->b) {
157                 bwins(bw, l, n, flg);
158         }
159 }
160
161 static void delpw(BW *bw, B *b, long l, long n, int flg)
162 {
163         if (b == bw->b) {
164                 bwdel(bw, l, n, flg);
165         }
166 }
167
168 static int abortpw(BW *b)
169 {
170         PW *pw = b->object;
171         void *object = pw->object;
172         int (*abrt) () = pw->abrt;
173
174         W *win = b->parent->win;
175
176         bwrm(b);
177         joe_free(pw->prompt);
178         joe_free(pw);
179         if (abrt) {
180                 return abrt(win->object, object);
181         } else {
182                 return -1;
183         }
184 }
185
186 WATOM watompw = {
187         US "prompt",
188         disppw,
189         bwfllw,
190         abortpw,
191         rtnpw,
192         utypebw,
193         NULL,
194         NULL,
195         inspw,
196         delpw,
197         TYPEPW
198 };
199
200 /* Create a prompt window */
201
202 BW *wmkpw(W *w, unsigned char *prompt, B **history, int (*func) (), const unsigned char *huh, int (*abrt) (), int (*tab) (), void *object, int *notify, struct charmap *map)
203 {
204         W *new;
205         PW *pw;
206         BW *bw;
207
208         new = wcreate(w->t, &watompw, w, w, w->main, 1, huh, notify);
209         if (!new) {
210                 if (notify) {
211                         *notify = 1;
212                 }
213                 return NULL;
214         }
215         wfit(new->t);
216         new->object = (void *) (bw = bwmk(new, bmk(NULL), 1));
217         bw->b->o.charmap = map;
218         bw->object = (void *) (pw = (PW *) joe_malloc(sizeof(PW)));
219         pw->abrt = abrt;
220         pw->tab = tab;
221         pw->object = object;
222         pw->prompt = (unsigned char *)strdup((char *)prompt);
223         pw->promptlen = fmtlen(prompt);
224         pw->promptofst = 0;
225         pw->pfunc = func;
226         if (history) {
227                 if (!*history) {
228                         *history = bmk(NULL);
229                 }
230                 pw->hist = *history;
231                 binsb(bw->cursor, bcpy(pw->hist->bof, pw->hist->eof));
232                 bw->b->changed = 0;
233                 p_goto_eof(bw->cursor);
234                 p_goto_eof(bw->top);
235                 p_goto_bol(bw->top);
236         } else {
237                 pw->hist = NULL;
238         }
239         w->t->curwin = new;
240         return bw;
241 }
242
243 /* Tab completion functions */
244
245 unsigned char **regsub(unsigned char **z, int len, unsigned char *s)
246 {
247         unsigned char **lst = NULL;
248         int x = -1;
249
250         while (++x < len)
251                 if (rmatch(s, z[x]))
252                         lst = vaadd(lst, vsncpy(NULL, 0, sz(z[x])));
253         return lst;
254 }
255
256 void cmplt_ins(BW *bw, unsigned char *line)
257 {
258         P *p = pdup(bw->cursor);
259
260         p_goto_bol(p);
261         p_goto_eol(bw->cursor);
262         bdel(p, bw->cursor);
263         binsm(bw->cursor, sv(line));
264         p_goto_eol(bw->cursor);
265         prm(p);
266         bw->cursor->xcol = piscol(bw->cursor);
267 }
268
269 int cmplt_abrt(BW *bw, int x, unsigned char *line)
270 {
271         if (line) {
272                 cmplt_ins(bw, line);
273                 vsrm(line);
274         }
275         return -1;
276 }
277
278 int cmplt_rtn(MENU *m, int x, unsigned char *line)
279 {
280         cmplt_ins(m->parent->win->object, m->list[x]);
281         vsrm(line);
282         m->object = NULL;
283         wabort(m->parent);
284         return 0;
285 }
286
287 int simple_cmplt(BW *bw,unsigned char **list)
288 {
289         MENU *m;
290         P *p, *q;
291         unsigned char *line;
292         unsigned char *line1;
293         unsigned char **lst;
294
295         p = pdup(bw->cursor);
296         p_goto_bol(p);
297         q = pdup(bw->cursor);
298         p_goto_eol(q);
299         line = brvs(p, (int) (q->byte - p->byte));      /* Assumes short lines :-) */
300         prm(p);
301         prm(q);
302
303         line1 = vsncpy(NULL, 0, sv(line));
304         line1 = vsadd(line1, '*');
305         lst = regsub(list, aLEN(list), line1);
306         vsrm(line1);
307
308         if (!lst) {
309                 ttputc(7);
310                 vsrm(line);
311                 return -1;
312         }
313
314         m = mkmenu(bw->parent, lst, cmplt_rtn, cmplt_abrt, NULL, 0, line, NULL);
315         if (!m) {
316                 varm(lst);
317                 vsrm(line);
318                 return -1;
319         }
320         if (aLEN(lst) == 1)
321                 return cmplt_rtn(m, 0, line);
322         else if (smode || isreg(line))
323                 return 0;
324         else {
325                 unsigned char *com = mcomplete(m);
326
327                 vsrm(m->object);
328                 m->object = com;
329                 wabort(m->parent);
330                 smode = 2;
331                 ttputc(7);
332                 return 0;
333         }
334 }