]> git.neil.brown.name Git - edlib.git/blob - lib-keymap.c
menubar: allow ancestor pane to add menus
[edlib.git] / lib-keymap.c
1 /*
2  * Copyright Neil Brown ©2015-2023 <neil@brown.name>
3  * May be distributed under terms of GPLv2 - see file:COPYING
4  *
5  * Keymap management panes for edlib.
6  *
7  * A keymap pane makes it easy to attach keymaps into a pane tree.
8  *   global-set-keymap
9  * is given a command which is used to as all incoming requests.
10  */
11
12 #include <stdlib.h>
13 #include <string.h>
14 #define PANE_DATA_TYPE struct key_data
15 #include "core.h"
16
17 struct key_data {
18         struct command  *globalcmd;
19 };
20 #include "core-pane.h"
21
22 static struct pane *safe do_keymap_attach(struct pane *p safe);
23
24 DEF_CMD_CLOSED(keymap_handle)
25 {
26         struct key_data *kd = ci->home->data;
27
28         if (strcmp(ci->key, "Close") == 0) {
29                 command_put(kd->globalcmd);
30                 return 1;
31         }
32         if (ci->home->damaged & DAMAGED_CLOSED)
33                 return Efallthrough;
34
35         if (strcmp(ci->key, "Clone") == 0) {
36                 struct pane *p = do_keymap_attach(ci->focus);
37                 struct key_data *kd_old = ci->home->data;
38                 struct key_data *kd_new;
39                 if (!p)
40                         return Efail;
41                 kd_new = p->data;
42                 if (kd_old->globalcmd)
43                         kd_new->globalcmd = command_get(kd_old->globalcmd);
44
45                 pane_clone_children(ci->home, p);
46                 return 1;
47         }
48
49         if (kd->globalcmd) {
50                 int ret;
51                 ((struct cmd_info*)ci)->comm = kd->globalcmd;
52                 ret = kd->globalcmd->func(ci);
53                 if (ret)
54                         return ret;
55         }
56         if (strcmp(ci->key, "global-set-keymap") == 0) {
57                 struct command *cm = ci->comm2;
58                 if (!cm)
59                         return Enoarg;
60                 command_put(kd->globalcmd);
61                 kd->globalcmd = command_get(cm);
62                 return 1;
63         }
64
65         return Efallthrough;
66 }
67
68 static struct pane *safe do_keymap_attach(struct pane *p safe)
69 {
70         return pane_register(p, 0, &keymap_handle);
71 }
72
73 DEF_CMD(keymap_attach)
74 {
75         struct pane *p = do_keymap_attach(ci->focus);
76         if (p)
77                 return comm_call(ci->comm2, "callback:attach", p);
78         return Efail;
79 }
80
81 void edlib_init(struct pane *ed safe)
82 {
83         call_comm("global-set-command", ed, &keymap_attach, 0, NULL,
84                   "attach-global-keymap");
85 }