1 /* $OpenBSD: extend.c,v 1.53 2012/05/25 04:56:58 lum Exp $ */
3 /* This file is in the public domain. */
6 * Extended (M-X) commands, rebinding, and startup file processing.
13 #include <sys/types.h>
21 #define BINDKEY /* bindkey is used by FKEYS startup code */
27 static int remap(KEYMAP *, int, PF, KEYMAP *);
28 static KEYMAP *reallocmap(KEYMAP *);
29 static void fixmap(KEYMAP *, KEYMAP *, KEYMAP *);
30 static int dobind(KEYMAP *, const char *, int);
31 static char *skipwhite(char *);
32 static char *parsetoken(char *);
34 static int bindkey(KEYMAP **, const char *, KCHAR *, int);
38 * Insert a string, mainly for use from macros (created by selfinsert).
44 char buf[128], *bufp, *cp;
49 for (count = 0; count < maclcur->l_used; count++) {
50 if ((((c = maclcur->l_text[count]) == '\n')
51 ? lnewline() : linsert(1, c)) != TRUE)
55 maclcur = maclcur->l_fp;
59 /* CFINS means selfinsert can tack on the end */
62 if ((bufp = eread("Insert: ", buf, sizeof(buf), EFNEW)) == NULL)
64 else if (bufp[0] == '\0')
69 if (((*cp == '\n') ? lnewline() : linsert(1, *cp))
79 * Bind a key to a function. Cases range from the trivial (replacing an
80 * existing binding) to the extremely complex (creating a new prefix in a
81 * map_element that already has one, so the map_element must be split,
82 * but the keymap doesn't have enough room for another map_element, so
83 * the keymap is reallocated). No attempt is made to reclaim space no
84 * longer used, if this is a problem flags must be added to indicate
85 * malloced versus static storage in both keymaps and map_elements.
86 * Structure assignments would come in real handy, but K&R based compilers
87 * don't have them. Care is taken so running out of memory will leave
88 * the keymap in a usable state.
90 * curmap: pointer to the map being changed
91 * c: character being changed
92 * funct: function being changed to
93 * pref_map: if funct==NULL, map to bind to or NULL for new
96 remap(KEYMAP *curmap, int c, PF funct, KEYMAP *pref_map)
101 struct map_element *mep;
103 if (ele >= &curmap->map_element[curmap->map_num] || c < ele->k_base) {
104 if (ele > &curmap->map_element[0] && (funct != NULL ||
105 (ele - 1)->k_prefmap == NULL))
106 n1 = c - (ele - 1)->k_num;
109 if (ele < &curmap->map_element[curmap->map_num] &&
110 (funct != NULL || ele->k_prefmap == NULL))
111 n2 = ele->k_base - c;
114 if (n1 <= MAPELEDEF && n1 <= n2) {
116 if ((pfp = calloc(c - ele->k_base + 1,
117 sizeof(PF))) == NULL) {
118 ewprintf("Out of memory");
121 nold = ele->k_num - ele->k_base + 1;
122 for (i = 0; i < nold; i++)
123 pfp[i] = ele->k_funcp[i];
125 pfp[i++] = curmap->map_default;
129 } else if (n2 <= MAPELEDEF) {
130 if ((pfp = calloc(ele->k_num - c + 1,
131 sizeof(PF))) == NULL) {
132 ewprintf("Out of memory");
135 nold = ele->k_num - ele->k_base + 1;
136 for (i = 0; i < nold; i++)
137 pfp[i + n2] = ele->k_funcp[i];
139 pfp[n2] = curmap->map_default;
144 if (curmap->map_num >= curmap->map_max) {
145 if ((newmap = reallocmap(curmap)) == NULL)
149 if ((pfp = malloc(sizeof(PF))) == NULL) {
150 ewprintf("Out of memory");
154 for (mep = &curmap->map_element[curmap->map_num];
156 mep->k_base = (mep - 1)->k_base;
157 mep->k_num = (mep - 1)->k_num;
158 mep->k_funcp = (mep - 1)->k_funcp;
159 mep->k_prefmap = (mep - 1)->k_prefmap;
164 ele->k_prefmap = NULL;
168 if (pref_map != NULL)
169 ele->k_prefmap = pref_map;
171 if ((mp = malloc(sizeof(KEYMAP) +
172 (MAPINIT - 1) * sizeof(struct map_element))) == NULL) {
173 ewprintf("Out of memory");
174 ele->k_funcp[c - ele->k_base] =
179 mp->map_max = MAPINIT;
180 mp->map_default = rescan;
185 n1 = c - ele->k_base;
186 if (ele->k_funcp[n1] == funct && (funct != NULL ||
187 pref_map == NULL || pref_map == ele->k_prefmap))
190 if (funct != NULL || ele->k_prefmap == NULL) {
191 if (ele->k_funcp[n1] == NULL)
192 ele->k_prefmap = NULL;
194 ele->k_funcp[n1] = funct;
196 if (pref_map != NULL)
197 ele->k_prefmap = pref_map;
199 if ((mp = malloc(sizeof(KEYMAP) +
201 sizeof(struct map_element))) == NULL) {
202 ewprintf("Out of memory");
203 ele->k_funcp[c - ele->k_base] =
208 mp->map_max = MAPINIT;
209 mp->map_default = rescan;
215 * This case is the splits.
216 * Determine which side of the break c goes on
217 * 0 = after break; 1 = before break
220 for (i = 0; n2 && i < n1; i++)
221 n2 &= ele->k_funcp[i] != NULL;
222 if (curmap->map_num >= curmap->map_max) {
223 if ((newmap = reallocmap(curmap)) == NULL)
227 if ((pfp = calloc(ele->k_num - c + !n2,
228 sizeof(PF))) == NULL) {
229 ewprintf("Out of memory");
232 ele->k_funcp[n1] = NULL;
233 for (i = n1 + n2; i <= ele->k_num - ele->k_base; i++)
234 pfp[i - n1 - n2] = ele->k_funcp[i];
235 for (mep = &curmap->map_element[curmap->map_num];
237 mep->k_base = (mep - 1)->k_base;
238 mep->k_num = (mep - 1)->k_num;
239 mep->k_funcp = (mep - 1)->k_funcp;
240 mep->k_prefmap = (mep - 1)->k_prefmap;
242 ele->k_num = c - !n2;
243 (ele + 1)->k_base = c + n2;
244 (ele + 1)->k_funcp = pfp;
246 ele->k_prefmap = NULL;
248 if (pref_map == NULL) {
249 if ((mp = malloc(sizeof(KEYMAP) + (MAPINIT - 1)
250 * sizeof(struct map_element))) == NULL) {
251 ewprintf("Out of memory");
252 ele->k_funcp[c - ele->k_base] =
257 mp->map_max = MAPINIT;
258 mp->map_default = rescan;
261 ele->k_prefmap = pref_map;
268 * Reallocate a keymap. Returns NULL (without trashing the current map)
272 reallocmap(KEYMAP *curmap)
278 if (curmap->map_max > SHRT_MAX - MAPGROW) {
279 ewprintf("keymap too large");
282 if ((mp = malloc(sizeof(KEYMAP) + (curmap->map_max + (MAPGROW - 1)) *
283 sizeof(struct map_element))) == NULL) {
284 ewprintf("Out of memory");
287 mp->map_num = curmap->map_num;
288 mp->map_max = curmap->map_max + MAPGROW;
289 mp->map_default = curmap->map_default;
290 for (i = curmap->map_num; i--;) {
291 mp->map_element[i].k_base = curmap->map_element[i].k_base;
292 mp->map_element[i].k_num = curmap->map_element[i].k_num;
293 mp->map_element[i].k_funcp = curmap->map_element[i].k_funcp;
294 mp->map_element[i].k_prefmap = curmap->map_element[i].k_prefmap;
296 for (mps = maps; mps != NULL; mps = mps->p_next) {
297 if (mps->p_map == curmap)
300 fixmap(curmap, mp, mps->p_map);
302 ele = &mp->map_element[ele - &curmap->map_element[0]];
307 * Fix references to a reallocated keymap (recursive).
310 fixmap(KEYMAP *curmap, KEYMAP *mp, KEYMAP *mt)
314 for (i = mt->map_num; i--;) {
315 if (mt->map_element[i].k_prefmap != NULL) {
316 if (mt->map_element[i].k_prefmap == curmap)
317 mt->map_element[i].k_prefmap = mp;
319 fixmap(curmap, mp, mt->map_element[i].k_prefmap);
325 * Do the input for local-set-key, global-set-key and define-key
326 * then call remap to do the work.
329 dobind(KEYMAP *curmap, const char *p, int unbind)
331 KEYMAP *pref_map = NULL;
333 char bprompt[80], *bufp, *pep;
338 * Keystrokes aren't collected. Not hard, but pretty useless.
339 * Would not work for function keys in any case.
341 ewprintf("Can't rebind key in macro");
345 for (s = 0; s < maclcur->l_used - 1; s++) {
346 if (doscan(curmap, c = CHARMASK(maclcur->l_text[s]), &curmap)
348 if (remap(curmap, c, NULL, NULL)
353 (void)doscan(curmap, c = maclcur->l_text[s], NULL);
354 maclcur = maclcur->l_fp;
356 n = strlcpy(bprompt, p, sizeof(bprompt));
357 if (n >= sizeof(bprompt))
358 n = sizeof(bprompt) - 1;
361 ewprintf("%s", bprompt);
363 pep = getkeyname(pep, sizeof(bprompt) -
364 (pep - bprompt), c = getkey(FALSE));
365 if (doscan(curmap, c, &curmap) != NULL)
374 if ((bufp = eread("%s to command: ", bprompt, sizeof(bprompt),
375 EFFUNC | EFNEW, bprompt)) == NULL)
377 else if (bufp[0] == '\0')
379 if (((funct = name_function(bprompt)) == NULL) ?
380 (pref_map = name_map(bprompt)) == NULL : funct == NULL) {
381 ewprintf("[No match]");
385 return (remap(curmap, c, funct, pref_map));
389 * bindkey: bind key sequence to a function in the specified map. Used by
390 * excline so it can bind function keys. To close to release to change
391 * calling sequence, should just pass KEYMAP *curmap rather than
396 bindkey(KEYMAP **mapp, const char *fname, KCHAR *keys, int kcount)
398 KEYMAP *curmap = *mapp;
399 KEYMAP *pref_map = NULL;
405 else if (((funct = name_function(fname)) == NULL) ?
406 (pref_map = name_map(fname)) == NULL : funct == NULL) {
407 ewprintf("[No match: %s]", fname);
411 if (doscan(curmap, c = *keys++, &curmap) != NULL) {
412 if (remap(curmap, c, NULL, NULL) != TRUE)
415 * XXX - Bizzarreness. remap creates an empty KEYMAP
416 * that the last key is supposed to point to.
418 curmap = ele->k_prefmap;
421 (void)doscan(curmap, c = *keys, NULL);
422 return (remap(curmap, c, funct, pref_map));
427 * Wrapper for bindkey() that converts escapes.
430 dobindkey(KEYMAP *map, const char *func, const char *str)
434 for (i = 0; *str && i < MAXKEY; i++) {
435 /* XXX - convert numbers w/ strol()? */
436 if (*str == '^' && *(str + 1) != '\0') {
437 key.k_chars[i] = CCHR(toupper(*++str));
438 } else if (*str == '\\' && *(str + 1) != '\0') {
441 key.k_chars[i] = '^';
445 key.k_chars[i] = '\t';
449 key.k_chars[i] = '\n';
453 key.k_chars[i] = '\r';
457 key.k_chars[i] = CCHR('[');
460 key.k_chars[i] = '\\';
464 key.k_chars[i] = *str;
468 return (bindkey(&map, func, key.k_chars, key.k_count));
474 * This function modifies the fundamental keyboard map.
478 bindtokey(int f, int n)
480 return (dobind(fundamental_map, "Global set key: ", FALSE));
484 * This function modifies the current mode's keyboard map.
488 localbind(int f, int n)
490 return (dobind(curbp->b_modes[curbp->b_nmodes]->p_map,
491 "Local set key: ", FALSE));
495 * This function redefines a key in any keymap.
499 redefine_key(int f, int n)
505 (void)strlcpy(buf, "Define key map: ", sizeof(buf));
506 if ((bufp = eread(buf, tmp, sizeof(tmp), EFNEW)) == NULL)
508 else if (bufp[0] == '\0')
510 (void)strlcat(buf, tmp, sizeof(buf));
511 if ((mp = name_map(tmp)) == NULL) {
512 ewprintf("Unknown map %s", tmp);
515 if (strlcat(buf, "key: ", sizeof(buf)) >= sizeof(buf))
518 return (dobind(mp, buf, FALSE));
523 unbindtokey(int f, int n)
525 return (dobind(fundamental_map, "Global unset key: ", TRUE));
530 localunbind(int f, int n)
532 return (dobind(curbp->b_modes[curbp->b_nmodes]->p_map,
533 "Local unset key: ", TRUE));
537 * Extended command. Call the message line routine to read in the command
538 * name and apply autocompletion to it. When it comes back, look the name
539 * up in the symbol table and run the command if it is found. Print an
540 * error if there is anything wrong.
546 char xname[NXNAME], *bufp;
549 bufp = eread("M-x ", xname, NXNAME, EFNEW | EFFUNC);
551 bufp = eread("%d M-x ", xname, NXNAME, EFNEW | EFFUNC, n);
554 else if (bufp[0] == '\0')
556 if ((funct = name_function(bufp)) != NULL) {
558 struct line *lp = maclcur;
559 macro[macrocount - 1].m_funct = funct;
561 maclcur->l_fp = lp->l_fp;
564 return ((*funct)(f, n));
566 ewprintf("[No match]");
571 * Define the commands needed to do startup-file processing.
572 * This code is mostly a kludge just so we can get startup-file processing.
574 * If you're serious about having this code, you should rewrite it.
576 * It has lots of funny things in it to make the startup-file look
577 * like a GNU startup file; mostly dealing with parens and semicolons.
578 * This should all vanish.
580 * We define eval-expression because it's easy. It can make
581 * *-set-key or define-key set an arbitrary key sequence, so it isn't
586 * evalexpr - get one line from the user, and run it.
590 evalexpr(int f, int n)
592 char exbuf[128], *bufp;
594 if ((bufp = eread("Eval: ", exbuf, sizeof(exbuf),
595 EFNEW | EFCR)) == NULL)
597 else if (bufp[0] == '\0')
599 return (excline(exbuf));
603 * evalbuffer - evaluate the current buffer as line commands. Useful for
604 * testing startup files.
608 evalbuffer(int f, int n)
611 struct buffer *bp = curbp;
613 static char excbuf[128];
615 for (lp = bfirstlp(bp); lp != bp->b_headp; lp = lforw(lp)) {
616 if (llength(lp) >= 128)
618 (void)strncpy(excbuf, ltext(lp), llength(lp));
620 /* make sure it's terminated */
621 excbuf[llength(lp)] = '\0';
622 if ((s = excline(excbuf)) != TRUE)
629 * evalfile - go get a file and evaluate it as line commands. You can
630 * go get your own startup file if need be.
634 evalfile(int f, int n)
636 char fname[NFILEN], *bufp;
638 if ((bufp = eread("Load file: ", fname, NFILEN,
639 EFNEW | EFCR)) == NULL)
641 else if (bufp[0] == '\0')
643 return (load(fname));
647 * load - go load the file name we got passed.
650 load(const char *fname)
657 if ((fname = adjustname(fname, TRUE)) == NULL)
658 /* just to be careful */
661 if (ffropen(&ffp, fname, NULL) != FIOSUC)
665 while ((s = ffgetline(ffp, excbuf, sizeof(excbuf) - 1, &nbytes))
668 excbuf[nbytes] = '\0';
669 if (excline(excbuf) != TRUE) {
671 ewprintf("Error loading file %s at line %d", fname, line);
675 (void)ffclose(ffp, NULL);
676 excbuf[nbytes] = '\0';
677 if (s != FIOEOF || (nbytes && excline(excbuf) != TRUE))
683 * excline - run a line from a load file or eval-expression. If FKEYS is
684 * defined, duplicate functionality of dobind so function key values don't
685 * have to fit in type char.
691 struct line *lp, *np;
699 #define BINDARG 0 /* this arg is key to bind (local/global set key) */
700 #define BINDNO 1 /* not binding or non-quoted BINDARG */
701 #define BINDNEXT 2 /* next arg " (define-key) */
702 #define BINDDO 3 /* already found key to bind */
703 #define BINDEXT 1 /* space for trailing \0 */
710 if (macrodef || inmacro) {
711 ewprintf("Not now!");
716 funcp = skipwhite(line);
718 return (TRUE); /* No error on blank lines */
719 line = parsetoken(funcp);
722 line = skipwhite(line);
723 if (ISDIGIT(*line) || *line == '-') {
725 line = parsetoken(line);
730 nl = strtol(argp, &tmp, 10);
733 if (nl >= INT_MAX || nl <= INT_MIN)
737 if ((fp = name_function(funcp)) == NULL) {
738 ewprintf("Unknown function: %s", funcp);
742 if (fp == bindtokey || fp == unbindtokey) {
744 curmap = fundamental_map;
745 } else if (fp == localbind || fp == localunbind) {
747 curmap = curbp->b_modes[curbp->b_nmodes]->p_map;
748 } else if (fp == redefine_key)
753 /* Pack away all the args now... */
754 if ((np = lalloc(0)) == FALSE)
756 np->l_fp = np->l_bp = maclcur = np;
757 while (*line != '\0') {
758 argp = skipwhite(line);
761 line = parsetoken(argp);
765 if ((lp = lalloc((int) (line - argp) + BINDEXT)) ==
770 bcopy(argp, ltext(lp), (int)(line - argp));
772 /* don't count BINDEXT */
778 /* quoted strings are special */
781 if (bind != BINDARG) {
783 lp = lalloc((int)(line - argp) + BINDEXT);
793 while (*argp != '"' && *argp != '\0') {
816 * split into two statements
817 * due to bug in OSK cpp
819 c = CHARMASK(*++argp);
821 CCHR(TOUPPER(c)) : CCHR(c);
832 if (argp[1] <= '7' &&
836 if (argp[1] <= '7' &&
848 if (ISDIGIT(argp[1])) {
863 key.k_chars[key.k_count++] = c;
866 lp->l_text[lp->l_used++] = c;
877 lp->l_text[lp->l_used] = '\0';
878 if ((curmap = name_map(lp->l_text)) == NULL) {
879 ewprintf("No such mode: %s", lp->l_text);
900 ewprintf("Bad args to set key");
904 if (fp != unbindtokey && fp != localunbind) {
905 lp->l_text[lp->l_used] = '\0';
906 status = bindkey(&curmap, lp->l_text, key.k_chars,
909 status = bindkey(&curmap, NULL, key.k_chars,
915 maclcur = maclcur->l_fp;
916 status = (*fp)(f, n);
923 while (lp != maclcur) {
933 * a pair of utility functions for the above
938 while (*s == ' ' || *s == '\t' || *s == ')' || *s == '(')
949 while (*s && *s != ' ' && *s != '\t' && *s != ')' && *s != '(')
956 * Strings get special treatment.
957 * Beware: You can \ out the end of the string!
961 } while (*++s != '"' && *s != '\0');