]> pd.if.org Git - pd_readline/blob - mg/keymap.c
Added mg from an OpenBSD mirror site. Many thanks to the OpenBSD team and the mg...
[pd_readline] / mg / keymap.c
1 /*      $OpenBSD: keymap.c,v 1.50 2012/06/07 15:15:04 lum Exp $ */
2
3 /* This file is in the public domain. */
4
5 /*
6  * Keyboard maps.  This is character set dependent.  The terminal specific
7  * parts of building the keymap has been moved to a better place.
8  */
9
10 #include "def.h"
11 #include "kbd.h"
12
13 /*
14  * initial keymap declarations, deepest first
15  */
16
17 static PF cHcG[] = {
18         ctrlg,                  /* ^G */
19         help_help               /* ^H */
20 };
21
22 static PF cHa[] = {
23         apropos_command,        /* a */
24         wallchart,              /* b */
25         desckey                 /* c */
26 };
27
28 struct KEYMAPE (2 + IMAPEXT) helpmap = {
29         2,
30         2 + IMAPEXT,
31         rescan,
32         {
33                 {
34                         CCHR('G'), CCHR('H'), cHcG, NULL
35                 },
36                 {
37                         'a', 'c', cHa, NULL
38                 }
39         }
40 };
41
42 static PF cCsc[] = {
43         cscallerfuncs,          /* c */
44         csdefinition,           /* d */
45         csegrep,                /* e */
46         csfindfile,             /* f */
47         rescan,                 /* g */
48         rescan,                 /* h */
49         csfindinc,              /* i */
50         rescan,                 /* j */
51         rescan,                 /* k */
52         rescan,                 /* l */
53         rescan,                 /* m */
54         csnextmatch,            /* n */
55         rescan,                 /* o */
56         csprevmatch,            /* p */
57         rescan,                 /* q */
58         rescan,                 /* r */ 
59         cssymbol,               /* s */
60         csfindtext              /* t */
61 };
62
63 static struct KEYMAPE (1 + IMAPEXT) cCsmap = {
64         1,
65         1 + IMAPEXT,
66         rescan,
67         {
68                 {
69                         'c', 't', cCsc, NULL
70                 }
71         }
72 };
73
74 static PF cCs[] = {
75         NULL                    /* s */
76 };
77
78 struct KEYMAPE (2 + IMAPEXT) ccmap = {
79         2,
80         2 + IMAPEXT,
81         rescan,
82         {
83                 {
84                         CCHR('@'), CCHR('@'), (PF[]){ rescan }, NULL
85                 },
86                 {
87                         's', 's', cCs, (KEYMAP *) & cCsmap
88                 }
89         }
90 };
91
92 static PF cX4cF[] = {
93         poptofile,              /* ^f */
94         ctrlg                   /* ^g */
95 };
96 static PF cX4b[] = {
97         poptobuffer,            /* b */
98         rescan,                 /* c */
99         rescan,                 /* d */
100         rescan,                 /* e */
101         poptofile               /* f */
102 };
103 static struct KEYMAPE (2 + IMAPEXT) cX4map = {
104         2,
105         2 + IMAPEXT,
106         rescan,
107         {
108                 {
109                         CCHR('F'), CCHR('G'), cX4cF, NULL
110                 },
111                 {
112                         'b', 'f', cX4b, NULL
113                 }
114         }
115 };
116
117 static PF cXcB[] = {
118         listbuffers,            /* ^B */
119         quit,                   /* ^C */
120         rescan,                 /* ^D */
121         rescan,                 /* ^E */
122         filevisit,              /* ^F */
123         ctrlg                   /* ^G */
124 };
125
126 static PF cXcL[] = {
127         lowerregion,            /* ^L */
128         rescan,                 /* ^M */
129         rescan,                 /* ^N */
130         deblank,                /* ^O */
131         rescan,                 /* ^P */
132         togglereadonly,         /* ^Q */
133         filevisitro,            /* ^R */
134         filesave,               /* ^S */
135         rescan,                 /* ^T */
136         upperregion,            /* ^U */
137         filevisitalt,           /* ^V */
138         filewrite,              /* ^W */
139         swapmark                /* ^X */
140 };
141
142 static PF cXlp[] = {
143         definemacro,            /* ( */
144         finishmacro             /* ) */
145 };
146
147 static PF cX0[] = {
148         delwind,                /* 0 */
149         onlywind,               /* 1 */
150         splitwind,              /* 2 */
151         rescan,                 /* 3 */
152         NULL                    /* 4 */
153 };
154
155 static PF cXeq[] = {
156         showcpos                /* = */
157 };
158
159 static PF cXcar[] = {
160         enlargewind,            /* ^ */
161         rescan,                 /* _ */
162         next_error,             /* ` */
163         rescan,                 /* a */
164         usebuffer,              /* b */
165         rescan,                 /* c */
166         rescan,                 /* d */
167         executemacro,           /* e */
168         setfillcol,             /* f */
169         gotoline,               /* g */
170         markbuffer,             /* h */
171         fileinsert,             /* i */
172         rescan,                 /* j */
173         killbuffer_cmd,         /* k */
174         rescan,                 /* l */
175         rescan,                 /* m */
176         nextwind,               /* n */
177         nextwind,               /* o */
178         prevwind,               /* p */
179         rescan,                 /* q */
180         rescan,                 /* r */
181         savebuffers,            /* s */
182         rescan,                 /* t */
183         undo                    /* u */
184 };
185
186 struct KEYMAPE (6 + IMAPEXT) cXmap = {
187         6,
188         6 + IMAPEXT,
189         rescan,
190         {
191                 {
192                         CCHR('B'), CCHR('G'), cXcB, NULL
193                 },
194                 {
195                         CCHR('L'), CCHR('X'), cXcL, NULL
196                 },
197                 {
198                         '(', ')', cXlp, NULL
199                 },
200                 {
201                         '0', '4', cX0, (KEYMAP *) & cX4map
202                 },
203                 {
204                         '=', '=', cXeq, NULL
205                 },
206                 {
207                         '^', 'u', cXcar, NULL
208                 }
209         }
210 };
211
212 static PF metacG[] = {
213         ctrlg                   /* ^G */
214 };
215
216 static PF metacV[] = {
217         pagenext                /* ^V */
218 };
219
220 static PF metasp[] = {
221         justone                 /* space */
222 };
223
224 static PF metapct[] = {
225         queryrepl               /* % */
226 };
227
228 static PF metami[] = {
229         poptag,                 /* * */
230         rescan,                 /* + */
231         rescan,                 /* , */
232         negative_argument,      /* - */
233         findtag,                /* . */
234         rescan,                 /* / */
235         digit_argument,         /* 0 */
236         digit_argument,         /* 1 */
237         digit_argument,         /* 2 */
238         digit_argument,         /* 3 */
239         digit_argument,         /* 4 */
240         digit_argument,         /* 5 */
241         digit_argument,         /* 6 */
242         digit_argument,         /* 7 */
243         digit_argument,         /* 8 */
244         digit_argument,         /* 9 */
245         rescan,                 /* : */
246         rescan,                 /* ; */
247         gotobob,                /* < */
248         rescan,                 /* = */
249         gotoeob                 /* > */
250 };
251
252 static PF metasqf[] = {
253         NULL,                   /* [ */
254         delwhite,               /* \ */
255         rescan,                 /* ] */
256         joinline,               /* ^ */
257         rescan,                 /* _ */
258         rescan,                 /* ` */
259         rescan,                 /* a */
260         backword,               /* b */
261         capword,                /* c */
262         delfword,               /* d */
263         rescan,                 /* e */
264         forwword                /* f */
265 };
266
267 static PF metal[] = {
268         lowerword,              /* l */
269         backtoindent,           /* m */
270         rescan,                 /* n */
271         rescan,                 /* o */
272         rescan,                 /* p */
273         fillpara,               /* q */
274         backsearch,             /* r */
275         forwsearch,             /* s */
276         rescan,                 /* t */
277         upperword,              /* u */
278         backpage,               /* v */
279         copyregion,             /* w */
280         extend,                 /* x */
281         rescan,                 /* y */
282         rescan,                 /* z */
283         gotobop,                /* { */
284         piperegion,             /* | */
285         gotoeop                 /* } */
286 };
287
288 static PF metasqlZ[] = {
289         rescan                  /* Z */
290 };
291
292 static PF metatilde[] = {
293         notmodified,            /* ~ */
294         delbword                /* DEL */
295 };
296
297 struct KEYMAPE (1 + IMAPEXT) metasqlmap = {
298         1,
299         1 + IMAPEXT,
300         rescan,
301         {
302                 {
303                         'Z', 'Z', metasqlZ, NULL
304                 }
305         }
306 };
307
308 struct KEYMAPE (8 + IMAPEXT) metamap = {
309         8,
310         8 + IMAPEXT,
311         rescan,
312         {
313                 {
314                         CCHR('G'), CCHR('G'), metacG, NULL
315                 },
316                 {
317                         CCHR('V'), CCHR('V'), metacV, NULL
318                 },
319                 {
320                         ' ', ' ', metasp, NULL
321                 },
322                 {
323                         '%', '%', metapct, NULL
324                 },
325                 {
326                         '*', '>', metami, NULL
327                 },
328                 {
329                         '[', 'f', metasqf, (KEYMAP *) &metasqlmap
330                 },
331                 {
332                         'l', '}', metal, NULL
333                 },
334                 {
335                         '~', CCHR('?'), metatilde, NULL
336                 }
337         }
338 };
339
340 static PF fund_at[] = {
341         setmark,                /* ^@ */
342         gotobol,                /* ^A */
343         backchar,               /* ^B */
344         NULL,                   /* ^C */
345         forwdel,                /* ^D */
346         gotoeol,                /* ^E */
347         forwchar,               /* ^F */
348         ctrlg,                  /* ^G */
349 };
350
351 static PF fund_h[] = {
352         NULL,                   /* ^H */
353 };
354
355
356 /* ^I is selfinsert */
357 static PF fund_CJ[] = {
358         lfindent,               /* ^J */
359         killline,               /* ^K */
360         reposition,             /* ^L */
361         newline,                /* ^M */
362         forwline,               /* ^N */
363         openline,               /* ^O */
364         backline,               /* ^P */
365         quote,                  /* ^Q */
366         backisearch,            /* ^R */
367         forwisearch,            /* ^S */
368         twiddle,                /* ^T */
369         universal_argument,     /* ^U */
370         forwpage,               /* ^V */
371         killregion,             /* ^W */
372         NULL,                   /* ^X */
373         yank,                   /* ^Y */
374         spawncli                /* ^Z */
375 };
376
377 static PF fund_esc[] = {
378         NULL,                   /* esc */
379         rescan,                 /* ^\ selfinsert is default on fundamental */
380         rescan,                 /* ^] */
381         rescan,                 /* ^^ */
382         undo                    /* ^_ */
383 };
384
385 static PF fund_del[] = {
386         backdel                 /* DEL */
387 };
388
389 static PF fund_cb[] = {
390         showmatch               /* )  */
391 };
392
393 #ifndef FUND_XMAPS
394 #define NFUND_XMAPS     0       /* extra map sections after normal ones */
395 #endif
396
397 static struct KEYMAPE (6 + NFUND_XMAPS + IMAPEXT) fundmap = {
398         6 + NFUND_XMAPS,
399         6 + NFUND_XMAPS + IMAPEXT,
400         selfinsert,
401         {
402                 {
403                         CCHR('@'), CCHR('G'), fund_at, (KEYMAP *) & ccmap
404                 },
405                 {
406                         CCHR('H'), CCHR('H'), fund_h, (KEYMAP *) & helpmap
407                 },
408                 {
409                         CCHR('J'), CCHR('Z'), fund_CJ, (KEYMAP *) & cXmap
410                 },
411                 {
412                         CCHR('['), CCHR('_'), fund_esc, (KEYMAP *) & metamap
413                 },
414                 {
415                         ')', ')', fund_cb, NULL
416                 },
417                 {
418                         CCHR('?'), CCHR('?'), fund_del, NULL
419                 },
420 #ifdef FUND_XMAPS
421                 FUND_XMAPS,
422 #endif /* FUND_XMAPS */
423         }
424 };
425
426 static PF fill_sp[] = {
427         fillword                /* ' ' */
428 };
429
430 static struct KEYMAPE (1 + IMAPEXT) fillmap = {
431         1,
432         1 + IMAPEXT,
433         rescan,
434         {
435                 { ' ', ' ', fill_sp, NULL }
436         }
437 };
438
439 static PF indent_lf[] = {
440         newline,                /* ^J */
441         rescan,                 /* ^K */
442         rescan,                 /* ^L */
443         lfindent                /* ^M */
444 };
445
446 static struct KEYMAPE (1 + IMAPEXT) indntmap = {
447         1,
448         1 + IMAPEXT,
449         rescan,
450         {
451                 {
452                         CCHR('J'), CCHR('M'), indent_lf, NULL
453                 }
454         }
455 };
456
457 #ifdef NOTAB
458 static PF notab_tab[] = {
459         space_to_tabstop        /* ^I */
460 };
461
462 static struct KEYMAPE (1 + IMAPEXT) notabmap = {
463         1,
464         1 + IMAPEXT,
465         rescan,
466         {
467                 {
468                         CCHR('I'), CCHR('I'), notab_tab, NULL
469                 }
470         }
471 };
472 #endif /* NOTAB */
473
474 static struct KEYMAPE (1 + IMAPEXT) overwmap = {
475         0,
476         1 + IMAPEXT,            /* 1 to avoid 0 sized array */
477         rescan,
478         {
479                 /* unused dummy entry for VMS C */
480                 {
481                         (KCHAR)0, (KCHAR)0, NULL, NULL
482                 }
483         }
484 };
485
486
487 /*
488  * The basic (root) keyboard map
489  */
490 struct maps_s   fundamental_mode = { (KEYMAP *)&fundmap, "fundamental" };
491
492 /*
493  * give names to the maps, for use by help etc. If the map is to be bindable,
494  * it must also be listed in the function name table below with the same
495  * name. Maps created dynamically currently don't get added here, thus are
496  * unnamed. Modes are just named keymaps with functions to add/subtract them
497  * from a buffer's list of modes.  If you change a mode name, change it in
498  * modes.c also.
499  */
500
501 static struct maps_s map_table[] = {
502         {(KEYMAP *) &fillmap, "fill",},
503         {(KEYMAP *) &indntmap, "indent",},
504 #ifdef NOTAB
505         {(KEYMAP *) &notabmap, "notab",},
506 #endif /* NOTAB */
507         {(KEYMAP *) &overwmap, "overwrite",},
508         {(KEYMAP *) &metamap, "esc prefix",},
509         {(KEYMAP *) &cXmap, "c-x prefix",},
510         {(KEYMAP *) &cX4map, "c-x 4 prefix",},
511         {(KEYMAP *) &helpmap, "help",},
512         {NULL, NULL}
513 };
514
515 struct maps_s *maps;
516
517 void
518 maps_init(void)
519 {
520         int      i;
521         struct maps_s   *mp;
522
523         maps = &fundamental_mode;
524         for (i = 0; map_table[i].p_name != NULL; i++) {
525                 mp = &map_table[i];
526                 mp->p_next = maps;
527                 maps = mp;
528         }
529 }
530
531 /*
532  * Insert a new (named) keymap at the head of the keymap list.
533  */
534 int
535 maps_add(KEYMAP *map, const char *name)
536 {
537         struct maps_s   *mp;
538
539         if ((mp = malloc(sizeof(*mp))) == NULL)
540                 return (FALSE);
541
542         mp->p_name = name;
543         mp->p_map = map;
544         mp->p_next = maps;
545         maps = mp;
546
547         return (TRUE);
548 }
549
550 struct maps_s *
551 name_mode(const char *name)
552 {
553         struct maps_s   *mp;
554
555         for (mp = maps; mp != NULL; mp = mp->p_next)
556                 if (strcmp(mp->p_name, name) == 0)
557                         return (mp);
558         return (NULL);
559 }
560
561 KEYMAP *
562 name_map(const char *name)
563 {
564         struct maps_s   *mp;
565
566         return ((mp = name_mode(name)) == NULL ? NULL : mp->p_map);
567 }