]> git.neil.brown.name Git - edlib.git/blob - core.h
Ensure we never call anything after "Close".
[edlib.git] / core.h
1 /*
2  * Copyright Neil Brown ©2015-2023 <neil@brown.name>
3  * May be distributed under terms of GPLv2 - see file:COPYING
4  *
5  * Core elements include:
6  * documents
7  * marks and points
8  * attributes
9  * panes
10  * keymaps
11  * commands
12  */
13
14 #include <wchar.h>
15 #include <limits.h>
16 #include <sys/stat.h>
17 #include <stdlib.h>
18 #include <string.h>
19 #include <time.h>
20 #include "safe.h"
21 #include "misc.h"
22
23 #include "list.h"
24 #include "vfunc.h"
25
26 extern char edlib_version[];
27 #ifndef VERSION
28 #define VERSION "unreleased"
29 #endif
30 #ifndef VERS_DATE
31 #define VERS_DATE "unreleased"
32 #endif
33
34 struct doc;
35 struct mark;
36 struct attrset;
37 struct pane;
38 struct command;
39 struct cmd_info;
40
41 extern MEMPOOL_DECL(pane);
42
43 #ifndef PRIVATE_DOC_REF
44 struct doc_ref {
45         void            *p;
46         unsigned int    i;
47 };
48 #endif
49 struct generic_doc_ref {
50         void            *p;
51         unsigned int    i;
52 };
53
54 void LOG(char *fmt, ...);
55 void LOG_BT(void);
56
57 /* The 'editor' contains (by reference) everything else.
58  * This captures and documents the global states, and allows
59  * multiple "editors" in the one process, should that be valuable.
60  *
61  * Each document and contains a reference to the editor which is the root of the
62  * pane tree.
63  */
64 struct pane ;
65
66 struct command {
67         int     (*func)(const struct cmd_info *ci safe);
68         int     refcnt; /* only if 'free' is not NULL */
69         void    (*free)(struct command *c safe);
70         const char *name;
71 };
72
73 enum edlib_errors {
74         Efallthrough = 0,
75         Enoarg = -1000,
76         Einval,
77         Enosup,
78         Efail,
79         /* following errors are soft and don't create exceptions */
80         Efalse,
81         Eunused,
82 };
83
84 static inline struct command *safe command_get(struct command * safe c)
85 {
86         if (!(void*) c)
87                 return c;
88         if (c->free)
89                 c->refcnt += 1;
90         return c;
91 }
92
93 static inline void command_put(struct command *c)
94 {
95         if (c && c->free && c->refcnt-- == 1)
96                 c->free(c);
97 }
98
99 struct notifier {
100         struct pane             *notifiee safe;
101         char                    *notification safe;
102         struct list_head        notifier_link, notifiee_link;
103         int                     noted;
104 };
105 void pane_add_notify(struct pane *target safe, struct pane *source safe,
106                      const char *msg safe);
107 int do_pane_notify(struct pane *home, const char *notification safe,
108                    struct pane *p safe,
109                    int num, struct mark *m, const char *str,
110                    int num2, struct mark *m2, const char *str2,
111                    struct command *comm2);
112 void pane_drop_notifiers(struct pane *p safe, char *notification);
113
114 struct pane *editor_new(const char *comm_name);
115 void * safe memsave(struct pane *p safe, const char *buf, int len);
116 char *strsave(struct pane *p safe, const char *buf);
117 char *strnsave(struct pane *p safe, const char *buf, int len);
118 char * safe do_strconcat(struct pane *p, const char *s1 safe, ...);
119 #define strconcat(p, ...) do_strconcat(p, __VA_ARGS__, NULL)
120 bool edlib_testing(struct pane *p safe);
121
122 /* This is declared here so sparse knows it is global */
123 void edlib_init(struct pane *ed safe);
124
125 struct doc {
126         /* This pointer always points to itelf. It allows
127          * a pane to have a pointer to a doc, or an embedded doc,
128          * and following the pointer at that location will always
129          * lead to the doc.
130          */
131         struct doc              *self;
132         struct hlist_head       marks;
133         struct tlist_head       points;
134         struct docview {
135                 struct tlist_head head;
136                 struct pane       *owner;
137         } /* safe iff nviews > 0 */ *views;
138         int                     nviews;
139         struct mark             *recent_points[8];
140         void                    (*refcnt)(struct mark *m safe, int cnt);
141         char                    *name;
142         bool                    autoclose;
143         bool                    readonly;
144 };
145
146 void doc_free(struct doc *d safe, struct pane *root safe);
147 extern struct map *doc_default_cmd safe;
148
149 #define CHAR_RET(_c) ((_c & 0x1FFFFF) | 0x200000)
150
151 #define is_eol(c) ({int _c = c; _c == '\n' || _c == '\v' || _c == '\f'; })
152
153 /* Points and Marks */
154
155 enum {
156         MARK_POINT = -1,
157         MARK_UNGROUPED = -2
158 };
159
160 enum {
161         GRP_HEAD = 0, // tlist_head list head
162         GRP_MARK = 1, // tlist_head in mark.view
163         GRP_LIST = 2, // tlist_head in point.lists
164 };
165
166 #ifndef MARK_DATA_PTR
167 #define MARK_DATA_PTR void
168 #endif
169 struct mark {
170         struct doc_ref          ref;
171         struct hlist_node       all;
172         struct tlist_head       view;
173         struct attrset          *attrs;
174         int                     seq;
175         short                   viewnum;
176         short                   flags;
177         MARK_DATA_PTR           *mdata;
178         void                    *mtype; /* can be used to validate
179                                          * type of mdata */
180         struct pane             *owner safe; /* document pane which
181                                               * understands .ref
182                                               */
183 };
184 #define MARK_FLAG_WATCHED       1
185
186 static inline bool mark_valid(struct mark *m)
187 {
188         /* When marks are freed, most fields including ->attrs are
189          * set to all 1's.  The memory isn't released until an
190          * idle time.
191          */
192         return m && m->attrs != (void*)~0UL;
193 }
194
195 /* A point uses this for the mdata */
196 struct point_links {
197         unsigned int            size;
198         struct mark             *pt safe;
199         struct tlist_head       lists[];
200 };
201
202 struct mark *safe mark_dup(struct mark *m safe);
203 struct mark *safe mark_dup_view(struct mark *m safe);
204 void mark_free(struct mark *m);
205 void mark_watch(struct mark *m);
206
207 struct mark *mark_first(struct doc *d safe);
208 struct mark *mark_next(struct mark *m safe);
209 struct mark *mark_prev(struct mark *m safe);
210 void mark_reset(struct pane *p safe, struct mark *m safe, int end);
211 void mark_to_end(struct pane *p safe, struct mark *m safe, int end);
212 void doc_check_consistent(struct doc *d safe);
213 void mark_to_mark(struct mark *m safe, struct mark *target safe);
214 void mark_to_mark_noref(struct mark *m safe, struct mark *target safe);
215 wint_t do_doc_step(struct pane *p safe, struct mark *m,
216                    int forward, int move);
217 void mark_step(struct mark *m safe, int forward);
218 void mark_step_sharesref(struct mark *m safe, int forward);
219 bool marks_validate(struct mark *m1 safe, struct mark *m2 safe);
220
221 static inline int mark_same(struct mark *m1 safe, struct mark *m2 safe)
222 {
223         struct generic_doc_ref *r1 = (void*)&m1->ref;
224         struct generic_doc_ref *r2 = (void*)&m2->ref;
225
226         /* Compile-time check that size of doc_ref is correct */
227         switch(0){
228         case 0: break;
229         case (sizeof(struct doc_ref) == sizeof(struct generic_doc_ref)):
230                 break;
231         }
232
233         return r1->p == r2->p && r1->i == r2->i;
234 }
235
236 struct mark *mark_at_point(struct pane *p safe, struct mark *pm, int view);
237 struct mark *vmark_next(struct mark *m safe);
238 struct mark *vmark_prev(struct mark *m safe);
239 struct mark *vmark_matching(struct mark *m safe);
240 struct mark *vmark_first(struct pane *p safe, int view,
241                          struct pane *owner safe);
242 struct mark *vmark_last(struct pane *p safe, int view, struct pane *owner safe);
243 struct mark *vmark_at_or_before(struct pane *p safe, struct mark *m safe,
244                                 int view, struct pane *owner);
245 struct mark *vmark_new(struct pane *p safe, int view, struct pane *owner);
246 static inline struct mark *mark_new(struct pane *p safe)
247 {
248         return vmark_new(p, MARK_UNGROUPED, NULL);
249 }
250 static inline struct mark *point_new(struct pane *p safe)
251 {
252         return vmark_new(p, MARK_POINT, NULL);
253 }
254 void mark_clip(struct mark *m safe, struct mark *start, struct mark *end,
255                bool tostart);
256 void marks_clip(struct pane *p safe, struct mark *start, struct mark *end,
257                 int view, struct pane *owner, bool tostart);
258
259 static inline int mark_ordered_or_same(struct mark *m1 safe,
260                                        struct mark *m2 safe)
261 {
262         return m1->seq < m2->seq || mark_same(m1, m2);
263 }
264
265 static inline int mark_ordered_not_same(struct mark *m1 safe,
266                                         struct mark *m2 safe)
267 {
268         return m1->seq < m2->seq && !mark_same(m1, m2);
269 }
270
271 static inline struct attrset **safe mark_attr(struct mark *m safe)
272 {
273         return &m->attrs;
274 }
275
276 /* Attributes */
277 char *attr_find(struct attrset *set, const char *key safe);
278 bool attr_del(struct attrset **setp safe, const char *key safe);
279 void attr_del_all(struct attrset **setp safe, const char *key safe,
280                   int low, int high);
281 int attr_set_str(struct attrset **setp safe,
282                  const char *key safe, const char *val);
283 int attr_set_str_key(struct attrset **setp safe, const char *key safe,
284                      const char *val, int keynum);
285 char *attr_get_str(struct attrset *setp, const char *key safe, int keynum);
286 const char *attr_get_next_key(struct attrset *set, const char *key safe,
287                               int keynum,
288                               const char **valp safe);
289 int attr_find_int(struct attrset *set, const char *key safe);
290 int attr_set_int(struct attrset **setp safe, const char *key safe, int val);
291 void attr_trim(struct attrset **setp safe, int nkey);
292 struct attrset *attr_copy_tail(struct attrset *set, int nkey);
293 struct attrset *attr_copy(struct attrset *set);
294 struct attrset *attr_collect(struct attrset *set, unsigned int pos, int prefix);
295 void attr_free(struct attrset **setp safe);
296
297 /* Commands */
298 struct lookup_cmd {
299         struct command  c;
300         struct map      **m safe;
301 };
302
303 #define CMD(_name) {.func = _name ## _func ,            \
304                     .refcnt = 0,                        \
305                     .free = NULL,                       \
306                     .name = # _name,                    \
307         }
308 #define CB(_name) {.func = _name ## _func ,             \
309                    .refcnt = 0,                         \
310                    .free = NULL,                        \
311                    .name = # _name,                     \
312         }
313
314 #define DEF_CMD(_name) \
315         static int _name ## _func(const struct cmd_info *ci safe); \
316         static struct command _name = CMD(_name);       \
317         static int _name ## _func(const struct cmd_info *ci safe)
318 #define REDEF_CMD(_name) \
319         static int _name ## _func(const struct cmd_info *ci safe)
320 #define DEF_EXTERN_CMD(_name) \
321         static int _name ## _func(const struct cmd_info *ci safe); \
322         struct command _name = CMD(_name);              \
323         static int _name ## _func(const struct cmd_info *ci safe)
324 #define DECL_EXTERN_CMD(_name) \
325         extern struct command _name;
326 #define DEF_CB(_name) \
327         static int _name ## _func(const struct cmd_info *ci safe); \
328         static struct command _name = CB(_name);        \
329         static int _name ## _func(const struct cmd_info *ci safe)
330 #define REDEF_CB(_name) \
331         static int _name ## _func(const struct cmd_info *ci safe)
332
333 #define DEF_LOOKUP_CMD(_name, _map) \
334         static struct lookup_cmd _name = {              \
335                 .c.func = key_lookup_cmd_func,          \
336                 .c.refcnt = 0,                          \
337                 .c.free = NULL,                         \
338                 .c.name = #_name,                       \
339                 .m = &_map,                             \
340         }
341
342 DECL_EXTERN_CMD(edlib_noop);
343
344 int key_lookup_cmd_func(const struct cmd_info *ci safe);
345
346 struct pfx_cmd {
347         struct command  c;
348         char            *pfx safe;
349 };
350
351 int key_pfx_func(const struct cmd_info *ci safe);
352
353 #define DEF_PFX_CMD(_name, _pfx)                        \
354         static struct pfx_cmd _name = {                 \
355                 .c.func = key_pfx_func,                 \
356                 .c.refcnt = 0,                          \
357                 .c.free = NULL,                         \
358                 .c.name = "prefix" #_pfx,               \
359                 .pfx = _pfx,                            \
360         };
361
362 #define ARRAY_SIZE(ra) (sizeof(ra) / sizeof(ra[0]))
363
364 /* Each event (above) is accompanied by a cmd_info structure.
365  * 'key' and 'home' are always present, others only if relevant.
366  * Num is present for 'key' and 'move'.  INT_MAX/2 means no number was
367  *   requested so is usually treated like '1'.  Negative numbers are quite
368  *   possible.
369  * x,y are present for mouse events
370  * 'str' is inserted by 'replace' and sought by 'search'
371  * 'mark' is moved by 'move' and 'replace' deletes between point and mark.
372  */
373 struct cmd_info {
374         const char      *key safe;
375         struct pane     *home safe, *focus safe;
376         int             num, num2;
377         int             x,y;            /* relative to focus */
378         const char      *str, *str2;
379         struct mark     *mark, *mark2;
380         struct command  *comm safe;
381         struct command  *comm2;
382
383         /* An array of 2 hashes, one for the prefix of the key - all
384          * chars to first '-' or ':'.  One for the whole key.
385          */
386         unsigned int *hash;
387 };
388
389 #define NO_NUMERIC      (INT_MAX/2)
390 #define RPT_NUM(ci)     ((ci)->num == NO_NUMERIC ? 1 :          \
391                          (ci)->num == NO_NUMERIC + 1 ? 4 :      \
392                          (ci)->num == -NO_NUMERIC ? -1 : (ci)->num)
393
394 struct map *safe key_alloc(void);
395 void key_free(struct map *m safe);
396 int key_handle(const struct cmd_info *ci safe);
397 int key_lookup(struct map *m safe, const struct cmd_info *ci safe);
398 int key_lookup_prefix(struct map *m safe, const struct cmd_info *ci safe);
399 struct command *key_lookup_cmd(struct map *m safe, const char *c safe);
400 void key_add(struct map *map safe, const char *k safe, struct command *comm);
401 void key_add_range(struct map *map safe,
402                    const char *first safe, const char *last safe,
403                    struct command *comm);
404 #define key_add_prefix(map, prefix, comm) \
405         key_add_range(map, prefix, prefix "\xFF\xFF\xFF\xFF", comm)
406 void key_add_chain(struct map *map safe, struct map *chain);
407
408 static inline const char *safe ksuffix(const struct cmd_info *ci safe,
409                                        const char *prefix safe)
410 {
411         int l = strlen(prefix);
412         if (strncmp(ci->key, prefix, l) == 0)
413                 return ci->key + l;
414         return "";
415 }
416
417 /* DAMAGED_SIZE propagates down.
418  * If any flag is set on children, DAMAGED_CHILD is set.
419  */
420 #define BIT(n) (1 << (n))
421 enum {
422         DAMAGED_SIZE            = BIT(0), /* Size has changed */
423         DAMAGED_SIZE_CHILD      = BIT(1), /* a child has changed size */
424         DAMAGED_VIEW            = BIT(2), /* content has moved */
425         DAMAGED_VIEW_CHILD      = BIT(3), /* a child needs to adjust the view */
426
427         DAMAGED_REFRESH         = BIT(4), /* Content has changed */
428         DAMAGED_CHILD           = BIT(6), /* CONTENT in child */
429
430         DAMAGED_POSTORDER       = BIT(7), /* Pane wants to be called again */
431         DAMAGED_POSTORDER_CHILD = BIT(8), /* Child pane wants to be called again */
432
433         DAMAGED_CLOSED          = BIT(15),
434         DAMAGED_DEAD            = BIT(14), /* Fully closed, but not freed yet */
435         DAMAGED_NOT_HANDLED     = BIT(13), /* A for() loop is processing
436                                             * children, and this one
437                                             * hasn't been handled yet.
438                                             */
439         DAMAGED_DEBUG           = BIT(12),
440         DAMAGED_NOINIT          = BIT(11), /* Closing before pane_register
441                                             * had a chance to complete.
442                                             */
443 };
444 #define DAMAGED_NEED_CALL (DAMAGED_SIZE | DAMAGED_REFRESH)
445
446 struct xy {short x,y;};
447 struct pane * do_pane_register(struct pane *parent safe, short z,
448                                struct command *handle safe, void *data,
449                                short data_size);
450 #define pane_register(...) VFUNC(pane_register, __VA_ARGS__)
451 #ifdef PANE_DATA_TYPE
452 #define pane_register4(p,z,h,d) do_pane_register(p,z,h,d,sizeof(d))
453 #define pane_register3(p,z,h) do_pane_register(p,z,h,NULL, sizeof(PANE_DATA_TYPE))
454 #ifdef PANE_DATA_TYPE_2
455 #define pane_register_2(p,z,h) do_pane_register(p,z,h,NULL, sizeof(PANE_DATA_TYPE_2))
456 #endif
457 #else
458 #define pane_register4(p,z,h,d) do_pane_register(p,z,h,d,sizeof((d)[0]))
459 #define pane_register3(p,z,h) do_pane_register(p,z,h,NULL, 0)
460 #endif
461
462 void pane_update_handle(struct pane *p safe, struct command *handle safe);
463
464 struct pane *do_doc_register(struct pane *parent safe,
465                              struct command *handle safe,
466                              struct doc *doc,
467                              unsigned short data_size);
468
469 #ifdef DOC_DATA_TYPE
470 #define doc_register(p,h) do_doc_register(p, h, NULL, sizeof(DOC_DATA_TYPE))
471 #else
472 #define doc_register(p,h,d) do_doc_register(p,h,&(d)->doc,sizeof((d)[0]))
473 #endif
474
475 void pane_reparent(struct pane *p safe, struct pane *newparent safe);
476 void pane_move_after(struct pane *p safe, struct pane *after);
477 void pane_subsume(struct pane *p safe, struct pane *parent safe);
478 void pane_close(struct pane *p safe);
479 bool pane_resize(struct pane *p safe, int x, int y, int w, int h);
480 void pane_focus(struct pane *p);
481 bool do_pane_has_focus(struct pane *p, struct pane *root);
482 #define pane_has_focus(...) VFUNC(pane_has_focus, __VA_ARGS__)
483 #define pane_has_focus1(p) do_pane_has_focus(p, NULL)
484 #define pane_has_focus2(p,r) do_pane_has_focus(p, r)
485 void pane_damaged(struct pane *p, int type);
486 void pane_clone_children(struct pane *from, struct pane *to);
487 struct pane *pane_my_child(struct pane *p, struct pane *c);
488
489 char *pane_attr_get(struct pane *p, const char *key safe);
490 char *pane_mark_attr(struct pane *p safe, struct mark *m safe,
491                      const char *key safe);
492 struct xy pane_mapxy(struct pane *orig safe, struct pane *target safe,
493                      short x, short y, bool clip);
494
495 struct xy pane_scale(struct pane *p safe);
496
497 static inline int pane_attr_get_int(struct pane *p safe, const char *key safe,
498                                     int dflt)
499 {
500         char *c = pane_attr_get(p, key);
501         int rv;
502         char *end;
503         if (!c)
504                 return dflt;
505         rv = strtol(c, &end, 10);
506         if (end == c || !end || (*end && *end != ' '))
507                 return dflt;
508         return rv;
509 }
510 void pane_free(struct pane *p safe);
511
512 /* Inlines */
513
514 static inline wint_t doc_next(struct pane *p safe, struct mark *m)
515 {
516         return do_doc_step(p, m, 1, 1);
517 }
518
519 static inline wint_t doc_prev(struct pane *p safe, struct mark *m)
520 {
521         return do_doc_step(p, m, 0, 1);
522 }
523
524 static inline wint_t doc_following(struct pane *p safe, struct mark *m)
525 {
526         return do_doc_step(p, m, 1, 0);
527 }
528
529 static inline wint_t doc_prior(struct pane *p safe, struct mark *m)
530 {
531         return do_doc_step(p, m, 0, 0);
532 }
533
534 static inline wint_t doc_move(struct pane *p safe, struct mark *m, int n)
535 {
536         /* Move 'n' chars (backwards if negative) returning last character
537          * stepped over
538          */
539         wint_t wc = WEOF;
540         while (n < 0 && (wc = doc_prev(p, m)) != WEOF)
541                 n += 1;
542         while (n > 0 && (wc = doc_next(p, m)) != WEOF)
543                 n -= 1;
544         return wc;
545 }
546
547 static inline wint_t doc_pending(struct pane *p safe, struct mark *m, int n)
548 {
549         /* n must be <0 or >0.  Return the next char in that direction */
550         if (n > 0)
551                 return doc_following(p, m);
552         if (n < 0)
553                 return doc_prior(p, m);
554         return WEOF;
555 }
556
557 #if defined(DOC_NEXT)
558 #ifdef DOC_NEXT_DECL
559 static inline wint_t DOC_NEXT_DECL(struct pane *p safe, struct mark *m safe, struct doc_ref *r safe, bool byte);
560 static inline wint_t DOC_PREV_DECL(struct pane *p safe, struct mark *m safe, struct doc_ref *r safe, bool byte);
561 #else
562 static inline wint_t DOC_NEXT(struct pane *p safe, struct mark *m safe, struct doc_ref *r safe, bool byte);
563 static inline wint_t DOC_PREV(struct pane *p safe, struct mark *m safe, struct doc_ref *r safe, bool byte);
564 #endif
565 static inline int do_char_byte(const struct cmd_info *ci safe)
566 {
567         struct mark *m = ci->mark;
568         struct mark *end = ci->mark2;
569         struct pane *p = ci->home;
570         struct doc_ref r;
571         int steps = ci->num;
572         int forward = steps > 0;
573         wint_t ret = ' ';
574         int byte = strcmp(ci->key, "doc:byte") == 0;
575
576         if (!m)
577                 return Enoarg;
578         if (end && mark_same(m, end))
579                 return 1;
580         if (end && (end->seq < m->seq) != (steps < 0))
581                 /* Can never cross 'end' */
582                 return Einval;
583         while (steps && ret != CHAR_RET(WEOF) && (!end || !mark_same(m, end))) {
584                 #ifdef DOC_SHARESREF
585                 mark_step_sharesref(m, forward);
586                 #else
587                 mark_step(m, forward);
588                 #endif
589                 if (forward)
590                         ret = DOC_NEXT(p, m, &m->ref, byte);
591                 else
592                         ret = DOC_PREV(p, m, &m->ref, byte);
593                 steps -= forward*2 - 1;
594         }
595         if (end)
596                 return 1 + (forward ? ci->num - steps : steps - ci->num);
597         if (ret == WEOF || ci->num2 == 0)
598                 return CHAR_RET(ret);
599         if (ci->num && (ci->num2 < 0) == forward)
600                 return CHAR_RET(ret);
601         /* Want the 'next' char */
602         r = m->ref;
603         if (ci->num2 > 0)
604                 ret = DOC_NEXT(p, m, &r, byte);
605         else
606                 ret = DOC_PREV(p, m, &r, byte);
607         return CHAR_RET(ret);
608 }
609 #endif
610
611 struct call_return {
612         struct command c;
613         struct mark *m, *m2;
614         char *s;
615         struct pane *p;
616         int i, i2;
617         int x,y;
618         struct command *comm;
619         int ret;
620 };
621
622 enum target_type {
623         TYPE_focus,
624         TYPE_home,
625         TYPE_pane,
626         TYPE_comm,
627 };
628
629 struct pane *do_call_pane(enum target_type type, struct pane *home,
630                           struct command *comm2a,
631                           const char *key safe, struct pane *focus safe,
632                           int num,  struct mark *m,  const char *str,
633                           int num2, struct mark *m2, const char *str2,
634                           int x, int y, struct command *comm2b);
635 struct mark *do_call_mark(enum target_type type, struct pane *home,
636                           struct command *comm2a,
637                           const char *key safe, struct pane *focus safe,
638                           int num,  struct mark *m,  const char *str,
639                           int num2, struct mark *m2, const char *str2,
640                           int x, int y, struct command *comm2b);
641 struct mark *do_call_mark2(enum target_type type, struct pane *home,
642                            struct command *comm2a,
643                            const char *key safe, struct pane *focus safe,
644                            int num,  struct mark *m,  const char *str,
645                            int num2, struct mark *m2, const char *str2,
646                            int x, int y, struct command *comm2b);
647 struct command *do_call_comm(enum target_type type, struct pane *home,
648                              struct command *comm2a,
649                              const char *key safe, struct pane *focus safe,
650                              int num,  struct mark *m,  const char *str,
651                              int num2, struct mark *m2, const char *str2,
652                              int x, int y, struct command *comm2b);
653 struct call_return do_call_all(enum target_type type, struct pane *home,
654                                struct command *comm2a,
655                                const char *key safe, struct pane *focus safe,
656                                int num,  struct mark *m,  const char *str,
657                                int num2, struct mark *m2, const char *str2,
658                                int x, int y, struct command *comm2b);
659 char *do_call_str(enum target_type type, struct pane *home,
660                   struct command *comm2a,
661                   const char *key safe, struct pane *focus safe,
662                   int num,  struct mark *m,  const char *str,
663                   int num2, struct mark *m2, const char *str2,
664                   int x, int y, struct command *comm2b);
665 struct call_return do_call_bytes(enum target_type type, struct pane *home,
666                                  struct command *comm2a,
667                                  const char *key safe, struct pane *focus safe,
668                                  int num,  struct mark *m,  const char *str,
669                                  int num2, struct mark *m2, const char *str2,
670                                  int x, int y, struct command *comm2b);
671 char *do_call_strsave(enum target_type type, struct pane *home,
672                       struct command *comm2a,
673                       const char *key safe, struct pane *focus safe,
674                       int num,  struct mark *m,  const char *str,
675                       int num2, struct mark *m2, const char *str2,
676                       int x, int y, struct command *comm2b);
677
678 #define T_focus(_p, _c) _p
679 #define T_home(_p, _c) _p
680 #define T_pane(_p, _c) _p
681 #define T_comm(_p, _c) _c
682
683 #define CH(f,a,b) f(a,b)
684
685 #define _doCALL(...) VFUNC(CALL, __VA_ARGS__)
686 #define CALL15(ret, t_type, target, key, comm2a, focus, num, mark, str, \
687                num2, mark2, str2, x, y, comm2) \
688         do_call_##ret(TYPE_##t_type, CH(T_##t_type, target, comm2a), CH(T_##t_type,comm2,target), \
689                       key, focus, num, mark, str, num2, mark2, str2, x, y, comm2)
690 #define CALL14(ret, t_type, target, key, comm2a, focus, num, mark, str, num2, mark2, str2, x, y) \
691         do_call_##ret(TYPE_##t_type, CH(T_##t_type, target, comm2a), CH(T_##t_type,comm2a,target), \
692                       key, focus, num, mark, str, num2, mark2, str2, x, y, NULL)
693 #define CALL12(ret, t_type, target, key, comm2a, focus, num, mark, str, num2, mark2, str2) \
694         do_call_##ret(TYPE_##t_type, CH(T_##t_type, target, comm2a), CH(T_##t_type,comm2a,target), \
695                       key, focus, num, mark, str, num2, mark2, str2, 0, 0, NULL)
696 #define CALL11(ret, t_type, target, key, comm2a, focus, num, mark, str, num2, mark2) \
697         do_call_##ret(TYPE_##t_type, CH(T_##t_type, target, comm2a), CH(T_##t_type,comm2a,target), \
698                       key, focus, num, mark, str, num2, mark2, NULL, 0, 0, NULL)
699 #define CALL10(ret, t_type, target, key, comm2a, focus, num, mark, str, num2) \
700         do_call_##ret(TYPE_##t_type, CH(T_##t_type, target, comm2a), CH(T_##t_type,comm2a,target), \
701                       key, focus, num, mark, str, num2, NULL, NULL, 0, 0, NULL)
702 #define CALL9(ret, t_type, target, key, comm2a, focus, num, mark, str) \
703         do_call_##ret(TYPE_##t_type, CH(T_##t_type, target, comm2a), CH(T_##t_type,comm2a,target), \
704                       key, focus, num, mark, str, 0, NULL, NULL, 0, 0, NULL)
705 #define CALL8(ret, t_type, target, key, comm2a, focus, num, mark) \
706         do_call_##ret(TYPE_##t_type, CH(T_##t_type, target, comm2a), CH(T_##t_type,comm2a,target), \
707                       key, focus, num, mark, NULL, 0, NULL, NULL, 0, 0, NULL)
708 #define CALL7(ret, t_type, target, key, comm2a, focus, num) \
709         do_call_##ret(TYPE_##t_type, CH(T_##t_type, target, comm2a), CH(T_##t_type,comm2a,target), \
710                       key, focus, num, NULL, NULL, 0, NULL, NULL, 0, 0, NULL)
711 #define CALL6(ret, t_type, target, key, comm2a, focus) \
712         do_call_##ret(TYPE_##t_type, CH(T_##t_type,target, comm2a), CH(T_##t_type,comm2a,target), \
713                       key, focus, 0, NULL, NULL, 0, NULL, NULL, 0, 0, NULL)
714
715 #define CALL(ret, t_type, target, key, ...) _doCALL(ret, t_type, target, key, NULL, __VA_ARGS__)
716
717 #define call(key, _focus, ...) CALL(val, focus, _focus, key, _focus, ##__VA_ARGS__)
718 /* comm_call() is only for callbacks
719  * home_comm_call must be used if the focus must be closed already.
720  */
721 #define comm_call(_comm, key, ...) CALL(val, comm, _comm, key, ##__VA_ARGS__)
722 #define home_comm_call(_home, _comm, key, ...) _doCALL(val, comm, _comm, key, _home, __VA_ARGS__)
723
724 #define comm_call_ret(_ret, _comm, key, ...) CALL(_ret, comm, _comm, key, ##__VA_ARGS__)
725 #define home_comm_call_ret(_ret, _comm, key, ...) _doCALL(_ret, comm, _comm, key, _home, ##__VA_ARGS__)
726 /* pane_call() is used when a very specific pane must be informed, rather than
727  * the first responder in a chain of panes.  This mostly used for notifications,
728  * both generic notification, and special things like a child appearing or disappearing
729  * or the pane being closed.
730  */
731 #define pane_call(_pane, key, ...) CALL(val, pane, _pane, key, ##__VA_ARGS__)
732 #define pane_call_ret(_ret, _pane, key, ...) CALL(_ret, pane, _pane, key, ##__VA_ARGS__)
733 #define home_call(_home, key, ...) CALL(val, home, _home, key, ##__VA_ARGS__)
734 #define home_call_comm(_home, key, _focus, comm, ...) _doCALL(val, home, _home, key, comm, _focus, ##__VA_ARGS__)
735 #define home_call_ret(_ret, _home, key, ...) CALL(_ret, home, _home, key, ##__VA_ARGS__)
736 #define call_ret(_ret, key, _focus, ...) CALL(_ret, focus, _focus, key, _focus, ##__VA_ARGS__)
737 #define call_comm(key, _focus, comm, ...) _doCALL(val, focus, _focus, key, comm, _focus, ##__VA_ARGS__)
738
739
740 #define pane_notify(...) VFUNC(NOTIFY, __VA_ARGS__)
741 #define NOTIFY9(not, focus, num, m, str, num2, m2, str2, comm2) \
742         do_pane_notify(NULL, not, focus, num, m, str, num2, m2, str2, comm2)
743 #define NOTIFY8(not, focus, num, m, str, num2, m2, str2) \
744         do_pane_notify(NULL, not, focus, num, m, str, num2, m2, str2, NULL)
745 #define NOTIFY7(not, focus, num, m, str, num2, m2) \
746         do_pane_notify(NULL, not, focus, num, m, str, num2, m2, NULL, NULL)
747 #define NOTIFY6(not, focus, num, m, str, num2) \
748         do_pane_notify(NULL, not, focus, num, m, str, num2, NULL, NULL, NULL)
749 #define NOTIFY5(not, focus, num, m, str) \
750         do_pane_notify(NULL, not, focus, num, m, str, 0, NULL, NULL, NULL)
751 #define NOTIFY4(not, focus, num, m) \
752         do_pane_notify(NULL, not, focus, num, m, NULL, 0, NULL, NULL, NULL)
753 #define NOTIFY3(not, focus, num) \
754         do_pane_notify(NULL, not, focus, num, NULL, NULL, 0, NULL, NULL, NULL)
755 #define NOTIFY2(not, focus) \
756         do_pane_notify(NULL, not, focus, 0, NULL, NULL, 0, NULL, NULL, NULL)
757
758 #define home_pane_notify(...) VFUNC(HOMENOTIFY, __VA_ARGS__)
759 #define HOMENOTIFY10(home, not, focus, num, m, str, num2, m2, str2, comm2) \
760         do_pane_notify(home, not, focus, num, m, str, num2, m2, str2, comm2)
761 #define HOMENOTIFY9(home, not, focus, num, m, str, num2, m2, str2) \
762         do_pane_notify(home, not, focus, num, m, str, num2, m2, str2, NULL)
763 #define HOMENOTIFY8(home, not, focus, num, m, str, num2, m2) \
764         do_pane_notify(home, not, focus, num, m, str, num2, m2, NULL, NULL)
765 #define HOMENOTIFY7(home, not, focus, num, m, str, num2) \
766         do_pane_notify(home, not, focus, num, m, str, num2, NULL, NULL, NULL)
767 #define HOMENOTIFY6(home, not, focus, num, m, str) \
768         do_pane_notify(home, not, focus, num, m, str, 0, NULL, NULL, NULL)
769 #define HOMENOTIFY5(home, not, focus, num, m) \
770         do_pane_notify(home, not, focus, num, m, NULL, 0, NULL, NULL, NULL)
771 #define HOMENOTIFY4(home, not, focus, num) \
772         do_pane_notify(home, not, focus, num, NULL, NULL, 0, NULL, NULL, NULL)
773 #define HOMENOTIFY3(home, not, focus) \
774         do_pane_notify(home, not, focus, 0, NULL, NULL, 0, NULL, NULL, NULL)
775
776 #if !defined(PANE_DATA_TYPE) && !defined(DOC_DATA_TYPE)
777 /* If you define PANE_DATA_TYPEor DOC_DATA_TYPE, you need to include this yourself */
778 #include "core-pane.h"
779 #endif