2
* Map some key-sequences to some key-sequences, version 0.3
6
/* Copyright (c) 1995,1996 Sascha Demetrio
9
* Redistribution and use in source and binary forms, with or without
10
* modification, are permitted provided that the following conditions
12
* 1. Redistributions of source code must retain the above copyright
13
* notice, this list of conditions and the following disclaimer.
14
* If you modify any part of HEXER and resitribute it, you must add
15
* a notice to the `README' file and the modified source files containing
16
* information about the changes you made. I do not want to take
17
* credit or be blamed for your modifications.
18
* 2. Redistributions in binary form must reproduce the above copyright
19
* notice, this list of conditions and the following disclaimer in the
20
* documentation and/or other materials provided with the distribution.
21
* If you modify any part of HEXER and resitribute it in binary form,
22
* you must supply a `README' file containing information about the
24
* 3. The name of the developer may not be used to endorse or promote
25
* products derived from this software without specific prior written
28
* HEXER WAS DEVELOPED BY SASCHA DEMETRIO.
29
* THIS SOFTWARE SHOULD NOT BE CONSIDERED TO BE A COMMERCIAL PRODUCT.
30
* THE DEVELOPER URGES THAT USERS WHO REQUIRE A COMMERCIAL PRODUCT
31
* NOT MAKE USE OF THIS WORK.
34
* THIS SOFTWARE IS PROVIDED BY THE DEVELOPER ``AS IS'' AND
35
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
36
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
37
* ARE DISCLAIMED. IN NO EVENT SHALL THE DEVELOPER BE LIABLE
38
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
39
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
40
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
41
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
42
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
43
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
66
#define MAP_MAXLEN 256
70
#define MAP_ESC ((char)27)
72
#define MAP_ESC ('\e')
76
/* if `tio_m_remap == 1', the sequence of keys another sequence is mapped
77
* to may be mapped again, i.e. if `ab' maps to `bcd' and `bc' is mapped
78
* to `cd', then `ab' maps to `cdd'. the default is *not* to allow
88
static struct map_s *map_first[MAP_MAX] = { 0 };
89
static int map_max = 0;
90
static int keys[MAP_MAXLEN];
91
static int keys_n = 0;
93
static int munget[MAP_MAXLEN];
94
static int munget_n = 0;
97
/* operations on strings of keys
102
const int *ks1, *ks2;
104
while (*ks1 && *ks2 && *ks1 == *ks2) ++ks1, ++ks2;
110
key_strncmp(ks1, ks2, n)
111
const int *ks1, *ks2;
114
while (*ks1 && *ks2 && *ks1 == *ks2 && n--) ++ks1, ++ks2;
115
return n && *ks1 != *ks2;
139
for (n = 0, i = ks; *i; ++i) {
141
key = *++i + KEY_BIAS;
144
n += strlen(tio_keyrep(key));
146
s = t = (char *)malloc(n + 1);
147
for (i = ks; *i; ++i) {
149
key = *++i + KEY_BIAS;
152
strcpy(t, tio_keyrep(key)); t += strlen(t);
160
key_strrep_simple(ks)
162
/* like `key_strrep()', but special keys are translated to 0xff.
167
s = t = (char *)malloc(key_strlen(ks) + 1);
168
for (; *ks; ++ks) if (*ks < 0x100) *t++ = *ks; else *t++ = 0xff;
172
/* key_strrep_simple */
177
key_strncpy(ks1, ks2, n)
182
while (*ks2 && n--) *ks1++ = *ks2++;
193
while (*ks2) *ks1++ = *ks2++;
199
string_to_keys(keys, string)
204
if (*string == MAP_ESC) {
207
*keys++ = (int)KEY_ESCAPE;
209
*keys++ = *string + (int)KEY_BIAS;
220
scan_keys(keys, string, mode)
226
if (*string == MAP_ESC) {
229
*keys++ = KEY_ESCAPE;
231
*keys++ = *string + KEY_BIAS;
234
string = tio_keyscan(keys++, string, mode);
246
if (tio_m_remap) tio_ungetch(key); else munget[munget_n++] = key;
257
for (i = 0; keys[i]; ++i);
259
while (i) tio_ungetch(keys[--i]);
261
while (i) munget[munget_n++] = keys[--i];
266
tio_mgetch(map, map_string)
272
char *s = map_string;
273
int ungets[MAP_MAXLEN], ungets_n = 0;
276
extern int *tio_interrupt;
278
if (*tio_interrupt) {
280
return (int)KEY_BREAK;
282
while (map_max < map) map_first[++map_max] = 0;
284
/* create the `map_string' (a string representation of the unmapped keys
287
for (k = 0; k < keys_n; ++k) {
288
strcpy(s, tio_keyrep(keys[k]));
294
if (tio_getmore()) return tio_getch();
295
if (munget_n) return munget[--munget_n];
297
if (key == (int)KEY_ERROR) return (int)KEY_ERROR;
298
if (key == (int)KEY_ESCAPE && !keys_n)
299
if (!tio_readmore()) return (int)KEY_ESCAPE;
300
if (key <= 0) return key;
301
keys[keys_n++] = key;
304
/* check if `keys' matches */
305
for (i = map_first[map]; i; i = i->next)
306
if (!key_strcmp(keys, i->from)) { /* match */
308
ungets[ungets_n] = 0;
310
ungets[ungets_n = 0] = 0;
312
keys[keys_n = 0] = 0;
314
if (map_string) *map_string = 0;
315
return tio_mgetch(map, map_string);
317
/* check if `keys' is a prefix */
318
for (i = map_first[map], prefix = 0; i; i = i->next)
319
if (!key_strncmp(keys, i->from, keys_n)) { prefix = 1; break; }
321
ungets[ungets_n++] = keys[0];
322
if (!--keys_n) break;
323
for (k = 0; k < keys_n; ++k) keys[k] = keys[k + 1];
329
ungets[ungets_n] = 0;
331
ungets[ungets_n = 0] = 0;
334
strcpy(s, tio_keyrep(key));
337
if (munget_n) return munget[--munget_n];
338
return (int)KEY_NONE;
343
tio_map(map, from, to, special_f)
347
/* define a key mapping from `from' to `to' in keymap `map'. if `special_f'
348
* is set, special characters may also be written in ascii (i.e. "~UP" for
349
* cursor up). `special_f' should be set when reading commands from a file.
355
kfrom = (int *)alloca((strlen(from) + 1) * sizeof(int));
357
scan_keys(kfrom, from, 0);
359
string_to_keys(kfrom, from);
360
kto = (int *)alloca((strlen(to) + 1) * sizeof(int));
362
scan_keys(kto, to, 0);
364
string_to_keys(kto, to);
365
while (map_max < map) map_first[++map_max] = 0;
366
for (i = map_first[map], j = 0; i; j = i, i = i->next)
367
if (!key_strcmp(kfrom, i->from)) {
368
key_strcpy(i->to, kto);
371
i = (struct map_s *)malloc(sizeof(struct map_s));
373
key_strcpy(i->from, kfrom);
374
key_strcpy(i->to, kto);
375
if (j) j->next = i; else map_first[map] = i;
381
tio_unmap(map, from, special_f)
385
/* remove the mapping `from' from the keymap `map'. the flag `special_f'
386
* works the same as in `tio_map()'.
392
kfrom = (int *)alloca((strlen(from) + 1) * sizeof(int));
394
scan_keys(kfrom, from, 0);
396
string_to_keys(kfrom, from);
397
if (map > map_max) return -1;
398
for (i = map_first[map], j = 0; i; j = i, i = i->next)
399
if (!key_strcmp(i->from, kfrom)) {
400
if (j) j->next = i->next; else map_first[map] = i->next;
414
char **from, **to, **list;
417
for (i = map_first[map], n = 0; i; i = i->next, ++n);
419
*(list = (char **)malloc(sizeof(char *))) = 0;
422
from = (char **)alloca(n * sizeof(char *));
423
to = (char **)alloca(n * sizeof(char *));
424
list = (char **)malloc((n + 1) * sizeof(char *));
425
for (i = map_first[map], k = 0; i; i = i->next, ++k) {
426
from[k] = key_strrep(i->from);
427
to[k] = key_strrep(i->to);
429
from_maxwidth = strlen(from[0]);
430
for (k = 1; k < n; ++k)
431
if (strlen(from[k]) > from_maxwidth) from_maxwidth = strlen(from[k]);
433
for (k = 0; k < n; ++k) {
434
list[k] = (char *)malloc(from_maxwidth + strlen(to[k]) + 2);
435
strcpy(list[k], from[k]);
436
memset(list[k] + strlen(list[k]), ' ', from_maxwidth - strlen(list[k]));
437
strcpy(list[k] + from_maxwidth, to[k]);
438
list[k][strlen(list[k]) + 1] = 0;
439
list[k][strlen(list[k])] = '\n';
440
free((char *)from[k]);
450
tio_mapentry(map, from)
457
char *rep, *sfrom, *sto;
459
kfrom = (int *)alloca(strlen(from) * sizeof(int));
460
string_to_keys(kfrom, from);
461
if (map > map_max) return -1;
462
for (i = map_first[map], j = 0; i; j = i, i = i->next)
463
if (!key_strcmp(i->from, kfrom)) {
464
length = strlen(sfrom = key_strrep(i->from))
465
+ strlen(sto = key_strrep(i->to)) + 3;
466
rep = (char *)malloc(length);
482
/* VIM configuration: (do not delete this line)
484
* vim:aw:bk:bdir=./bak:ch=2:nodg:ef=make.log:efm=%f\:%l\:%m:et:hid:icon:
485
* vim:sw=2:sc:sm:si:textwidth=79:to:ul=1024:wh=12:wrap:wb: