2001-09-14 Gergely Nagy * src/actions.c (find_command_by_keydesc): new function (resolve_command_from_keydesc): new function (cmd_link): new command (cmd_chdir): new command (user_commands, cmd_help, initialize_default_keybindings): use them (parse_winpos): bail out if data is NULL * src/actions.h: added prototypes for cmd_link and cmd_chdir * src/conf.h: added MAX_LINK_DEPTH constant * src/main.c (main): allow multiple --command arguments, and execute them all, not just the last one diff -urNad ratpoison.orig/doc/ratpoison.texi ratpoison/doc/ratpoison.texi --- ratpoison.orig/doc/ratpoison.texi Thu Sep 13 18:15:24 2001 +++ ratpoison/doc/ratpoison.texi Fri Sep 14 10:29:13 2001 @@ -514,6 +514,15 @@ Split the current window horizontally in two. The last accessed window not occupying a frame will be the second window. address@hidden link @var{key} +Do whatever @var{key} would do. Useful for making command aliases, +for example, to make @kbd{C-t C-c} behave exactly the same as address@hidden c}, no matter what the latter is: + address@hidden +: bind C-c link c address@hidden example + @item title @var{title} Rename the currently active window. This name will remain for the duration of the window's life, unless you change it again. By default, diff -urNad ratpoison.orig/src/actions.c ratpoison/src/actions.c --- ratpoison.orig/src/actions.c Thu Sep 13 18:15:24 2001 +++ ratpoison/src/actions.c Fri Sep 14 10:41:48 2001 @@ -66,6 +66,8 @@ {"vsplit", cmd_v_split, arg_VOID}, {"windows", cmd_windows, arg_VOID}, {"setenv", cmd_setenv, arg_STRING}, + {"link", cmd_link, arg_STRING}, + {"chdir", cmd_chdir, arg_STRING}, /* Commands to set default behavior. */ {"defbarloc", cmd_defbarloc, arg_STRING}, @@ -129,6 +131,45 @@ return NULL; } +static char * +find_command_by_keydesc (char *desc) +{ + int i = 0; + char *keysym_name; + + while (i < key_actions_last) + { + keysym_name = keysym_to_string (key_actions[i].key, key_actions[i].state); + if (!strcmp (keysym_name, desc)) + { + free (keysym_name); + return key_actions[i].data; + } + free (keysym_name); + i++; + } + + return NULL; +} + +static char * +resolve_command_from_keydesc (char *desc, int depth) +{ + char *cmd, *command; + + command = find_command_by_keydesc (desc); + if (!command) + return NULL; + + /* is it a link? */ + if (strncmp (command, "link", 4) || depth > MAX_LINK_DEPTH) + /* it is not */ + return command; + + cmd = resolve_command_from_keydesc (&command[5], depth + 1); + return (cmd != NULL) ? cmd : command; +} + static void add_keybinding (KeySym keysym, int state, char *cmd) { @@ -212,40 +253,40 @@ add_keybinding (XK_9, 0, "select 9"); add_keybinding (XK_minus, 0, "select -"); add_keybinding (XK_A, 0, "title"); - add_keybinding (XK_A, ControlMask, "title"); + add_keybinding (XK_A, ControlMask, "link A"); add_keybinding (XK_K, 0, "kill"); - add_keybinding (XK_K, ControlMask, "kill"); + add_keybinding (XK_K, ControlMask, "link K"); add_keybinding (XK_Return, 0, "next"); - add_keybinding (XK_Return, ControlMask, "next"); + add_keybinding (XK_Return, ControlMask, "link Return"); add_keybinding (XK_a, 0, "clock"); - add_keybinding (XK_a, ControlMask, "clock"); + add_keybinding (XK_a, ControlMask, "link a"); add_keybinding (XK_b, 0, "banish"); - add_keybinding (XK_b, ControlMask, "banish"); + add_keybinding (XK_b, ControlMask, "link b"); add_keybinding (XK_c, 0, "exec " TERM_PROG); - add_keybinding (XK_c, ControlMask, "exec " TERM_PROG); + add_keybinding (XK_c, ControlMask, "link c"); add_keybinding (XK_colon, 0, "colon"); - add_keybinding (XK_exclam, 0, "exec"); - add_keybinding (XK_exclam, ControlMask, "colon exec " TERM_PROG " -e "); + add_keybinding (XK_exclam, 0, "colon exec" TERM_PROG " -e "); + add_keybinding (XK_exclam, ControlMask, "link exclam"); add_keybinding (XK_k, 0, "delete"); - add_keybinding (XK_k, ControlMask, "delete"); + add_keybinding (XK_k, ControlMask, "link k"); add_keybinding (XK_l, 0, "redisplay"); - add_keybinding (XK_l, ControlMask, "redisplay"); + add_keybinding (XK_l, ControlMask, "link l"); add_keybinding (XK_n, 0, "next"); - add_keybinding (XK_n, ControlMask, "next"); + add_keybinding (XK_n, ControlMask, "link n"); add_keybinding (XK_p, 0, "prev"); - add_keybinding (XK_p, ControlMask, "prev"); + add_keybinding (XK_p, ControlMask, "link p"); add_keybinding (XK_quoteright, 0, "select"); - add_keybinding (XK_quoteright, ControlMask, "select"); + add_keybinding (XK_quoteright, ControlMask, "link apostrophe"); add_keybinding (XK_space, 0, "next"); - add_keybinding (XK_space, ControlMask, "next"); + add_keybinding (XK_space, ControlMask, "link space"); add_keybinding (XK_v, 0, "version"); - add_keybinding (XK_v, ControlMask, "version"); + add_keybinding (XK_v, ControlMask, "link v"); add_keybinding (XK_w, 0, "windows"); - add_keybinding (XK_w, ControlMask, "windows"); + add_keybinding (XK_w, ControlMask, "link w"); add_keybinding (XK_s, 0, "split"); - add_keybinding (XK_s, ControlMask, "split"); + add_keybinding (XK_s, ControlMask, "link s"); add_keybinding (XK_S, 0, "vsplit"); - add_keybinding (XK_S, ControlMask, "vsplit"); + add_keybinding (XK_S, ControlMask, "link S"); add_keybinding (XK_Tab, 0, "focus"); add_keybinding (XK_Q, 0, "only"); add_keybinding (XK_R, 0, "remove"); @@ -902,6 +943,20 @@ return NULL; } +char * +cmd_chdir (int interactive, void *data) +{ + if (!data) + { + char *homedir = getenv("HOME"); + if (homedir) + chdir (homedir); + } + + chdir ((char *)data); + return NULL; +} + /* Quit ratpoison. Thanks to "Chr. v. Stuckrad" for the patch. */ char * @@ -1210,22 +1265,24 @@ keysym_name, strlen (keysym_name)); if (XTextWidth (defaults.font, keysym_name, strlen (keysym_name)) > max_width) - { - max_width = XTextWidth (defaults.font, keysym_name, strlen (keysym_name)); - } + max_width = XTextWidth (defaults.font, keysym_name, strlen (keysym_name)); free (keysym_name); } else { - XDrawString (dpy, s->help_window, s->normal_gc, - x, y + defaults.font->max_bounds.ascent, - key_actions[i].data, strlen (key_actions[i].data)); - - if (XTextWidth (defaults.font, key_actions[i].data, strlen (key_actions[i].data)) > max_width) - { - max_width = XTextWidth (defaults.font, key_actions[i].data, strlen (key_actions[i].data)); - } + char *cmd; + cmd = resolve_command_from_keydesc ( + keysym_to_string (key_actions[i].key, + key_actions[i].state), 0); + if (cmd) + { + XDrawString (dpy, s->help_window, s->normal_gc, x, + y + defaults.font->max_bounds.ascent, cmd, + strlen (cmd)); + if (XTextWidth (defaults.font, cmd, strlen (cmd)) > max_width) + max_width = XTextWidth (defaults.font, cmd, strlen (cmd)); + } } y += FONT_HEIGHT (defaults.font); @@ -1299,6 +1356,9 @@ int ret = 0; char *x, *y; + if (!data) + return -3; + x = xmalloc (strlen (data) + 1); y = xmalloc (strlen (data) + 1); @@ -1792,5 +1852,20 @@ free (var); free (string); + return NULL; +} + +char * +cmd_link (int interactive, void *data) +{ + char *cmd = NULL; + + if (!data) + return NULL; + + cmd = resolve_command_from_keydesc ((char *)data, 0); + if (cmd) + command (interactive, cmd); + return NULL; } diff -urNad ratpoison.orig/src/actions.h ratpoison/src/actions.h --- ratpoison.orig/src/actions.h Thu Sep 13 18:15:24 2001 +++ ratpoison/src/actions.h Fri Sep 14 10:41:48 2001 @@ -91,6 +91,8 @@ char * cmd_deffgcolor (int interactive, void *data); char * cmd_defbgcolor (int interactive, void *data); char * cmd_setenv (int interactive, void *data); +char * cmd_link (int interactive, void *data); +char * cmd_chdir (int interactive, void *data); /* void cmd_xterm (void *data); */ diff -urNad ratpoison.orig/src/conf.h ratpoison/src/conf.h --- ratpoison.orig/src/conf.h Mon Sep 10 20:43:30 2001 +++ ratpoison/src/conf.h Fri Sep 14 10:41:28 2001 @@ -47,4 +47,7 @@ mostly for use with hand-helds. */ #define UNMANAGED_WINDOW_LIST "xapm","xclock","xscribble" +/* Maximum depth of a link */ +#define MAX_LINK_DEPTH 16 + #endif /* !_ _RATPOISON_CONF_H */ diff -urNad ratpoison.orig/src/main.c ratpoison/src/main.c --- ratpoison.orig/src/main.c Sun Sep 9 22:32:17 2001 +++ ratpoison/src/main.c Fri Sep 14 10:29:48 2001 @@ -391,8 +391,11 @@ int do_kill = 0; int do_restart = 0; int do_command = 0; - char *command = NULL; + char **command; + int cmd_count = 0; + int cmd_allocated = 0; + command = NULL; myargv = argv; /* Parse the arguments */ @@ -418,8 +421,16 @@ do_restart = 1; break; case 'c': - command = xmalloc (strlen (optarg) + 1); - strcpy (command, optarg); + if (!command) + command = xmalloc (sizeof(char *)); + if (cmd_count >= cmd_allocated) + { + command = xrealloc (command, sizeof(char *) * (cmd_count + 1)); + command[cmd_count] = xmalloc (strlen (optarg) + 1); + cmd_allocated++; + } + strcpy (command[cmd_count], optarg); + cmd_count++; do_command = 1; break; default: @@ -456,8 +467,15 @@ } if (do_command) { - send_command (command); - free (command); + int i; + + for (i = 0; i < cmd_count; i++) + { + send_command (command[i]); + free (command[i]); + sleep (2); + } + free(command); XCloseDisplay (dpy); return EXIT_SUCCESS; }