mirror of
https://github.com/tmux/tmux.git
synced 2026-07-03 10:12:31 +00:00
Handle key binding.
This commit is contained in:
18
arguments.c
18
arguments.c
@@ -89,8 +89,7 @@ args_copy_value(struct args_value *to, struct args_value *from)
|
||||
case ARGS_NONE:
|
||||
break;
|
||||
case ARGS_COMMANDS:
|
||||
to->cmdlist = from->cmdlist;
|
||||
to->cmdlist->references++;
|
||||
to->cmd = cmd_parse_add_ref(from->cmd);
|
||||
break;
|
||||
case ARGS_STRING:
|
||||
to->string = xstrdup(from->string);
|
||||
@@ -123,7 +122,7 @@ args_value_as_string(struct args_value *value)
|
||||
return ("");
|
||||
case ARGS_COMMANDS:
|
||||
if (value->cached == NULL)
|
||||
value->cached = cmd_list_print(value->cmdlist, 0);
|
||||
value->cached = cmd_parse_print(value->cmd);
|
||||
return (value->cached);
|
||||
case ARGS_STRING:
|
||||
return (value->string);
|
||||
@@ -367,7 +366,7 @@ args_copy_copy_value(struct args_value *to, struct args_value *from, int argc,
|
||||
to->string = expanded;
|
||||
break;
|
||||
case ARGS_COMMANDS:
|
||||
to->cmdlist = cmd_list_copy(from->cmdlist, argc, argv);
|
||||
to->cmd = cmd_parse_add_ref(from->cmd);
|
||||
break;
|
||||
}
|
||||
}
|
||||
@@ -418,7 +417,7 @@ args_free_value(struct args_value *value)
|
||||
free(value->string);
|
||||
break;
|
||||
case ARGS_COMMANDS:
|
||||
cmd_list_free(value->cmdlist);
|
||||
cmd_parse_free(value->cmd);
|
||||
break;
|
||||
}
|
||||
free(value->cached);
|
||||
@@ -477,7 +476,7 @@ args_to_vector(struct args *args, int *argc, char ***argv)
|
||||
cmd_append_argv(argc, argv, args->values[i].string);
|
||||
break;
|
||||
case ARGS_COMMANDS:
|
||||
s = cmd_list_print(args->values[i].cmdlist, 0);
|
||||
s = cmd_parse_print(args->values[i].cmd);
|
||||
cmd_append_argv(argc, argv, s);
|
||||
free(s);
|
||||
break;
|
||||
@@ -532,7 +531,7 @@ args_print_add_value(char **buf, size_t *len, struct args_value *value)
|
||||
case ARGS_NONE:
|
||||
break;
|
||||
case ARGS_COMMANDS:
|
||||
expanded = cmd_list_print(value->cmdlist, 0);
|
||||
expanded = cmd_parse_print(value->cmd);
|
||||
args_print_add(buf, len, "{ %s }", expanded);
|
||||
break;
|
||||
case ARGS_STRING:
|
||||
@@ -784,9 +783,14 @@ args_make_commands_prepare(struct cmd *self, struct cmdq_item *item, u_int idx,
|
||||
if (idx < args->count) {
|
||||
value = &args->values[idx];
|
||||
if (value->type == ARGS_COMMANDS) {
|
||||
#if 0 /* XXX: command parser conversion */
|
||||
state->cmdlist = value->cmdlist;
|
||||
state->cmdlist->references++;
|
||||
return (state);
|
||||
#else
|
||||
fatalx("XXX: command parser conversion not done for "
|
||||
"ARGS_COMMANDS");
|
||||
#endif
|
||||
}
|
||||
cmd = value->string;
|
||||
} else {
|
||||
|
||||
@@ -54,12 +54,13 @@ cmd_bind_key_args_parse(__unused struct args *args, __unused u_int idx,
|
||||
static enum cmd_retval
|
||||
cmd_bind_key_exec(struct cmd *self, struct cmdq_item *item)
|
||||
{
|
||||
struct args *args = cmd_get_args(self);
|
||||
key_code key;
|
||||
const char *tablename, *note = args_get(args, 'N');
|
||||
int repeat;
|
||||
struct args_value *value;
|
||||
u_int count = args_count(args);
|
||||
struct args *args = cmd_get_args(self);
|
||||
key_code key;
|
||||
const char *tablename, *note = args_get(args, 'N');
|
||||
int repeat;
|
||||
struct args_value *value;
|
||||
u_int count = args_count(args);
|
||||
struct cmd_parse_tree *cmd;
|
||||
|
||||
key = key_string_lookup_string(args_string(args, 0));
|
||||
if (key == KEYC_NONE || key == KEYC_UNKNOWN) {
|
||||
@@ -82,8 +83,8 @@ cmd_bind_key_exec(struct cmd *self, struct cmdq_item *item)
|
||||
|
||||
value = args_value(args, 1);
|
||||
if (count == 2 && value->type == ARGS_COMMANDS) {
|
||||
key_bindings_add(tablename, key, note, repeat, value->cmdlist);
|
||||
value->cmdlist->references++;
|
||||
cmd = cmd_parse_add_ref(value->cmd);
|
||||
key_bindings_add(tablename, key, note, repeat, cmd);
|
||||
return (CMD_RETURN_NORMAL);
|
||||
}
|
||||
|
||||
|
||||
18
cmd-invoke.c
18
cmd-invoke.c
@@ -313,7 +313,7 @@ cmd_invoke_build_command(struct cmdq_item *item, struct cmd_invoke_state *is,
|
||||
struct args_value *values = NULL;
|
||||
struct cmd *cmd;
|
||||
char *cause = NULL;
|
||||
u_int count = 0, i;
|
||||
u_int count = 0;
|
||||
|
||||
child = cmd_parse_node_first_child(node);
|
||||
while (child != NULL) {
|
||||
@@ -328,11 +328,7 @@ cmd_invoke_build_command(struct cmdq_item *item, struct cmd_invoke_state *is,
|
||||
break;
|
||||
case CMD_PARSE_COMMANDS:
|
||||
values[count].type = ARGS_COMMANDS;
|
||||
#if 0 /* XXX: command parser conversion */
|
||||
values[count].cmdparse = child;
|
||||
#else
|
||||
fatalx("XXX: command parser conversion not done for ARGS_COMMANDS");
|
||||
#endif
|
||||
values[count].cmd = cmd_parse_from_node(child);
|
||||
break;
|
||||
default:
|
||||
fatalx("unexpected node type in command");
|
||||
@@ -348,18 +344,12 @@ cmd_invoke_build_command(struct cmdq_item *item, struct cmd_invoke_state *is,
|
||||
free(cause);
|
||||
goto fail;
|
||||
}
|
||||
for (i = 0; i < count; i++) {
|
||||
if (values[i].type == ARGS_STRING)
|
||||
free(values[i].string);
|
||||
}
|
||||
args_free_values(values, count);
|
||||
free(values);
|
||||
return (cmd);
|
||||
|
||||
fail:
|
||||
for (i = 0; i < count; i++) {
|
||||
if (values[i].type == ARGS_STRING)
|
||||
free(values[i].string);
|
||||
}
|
||||
args_free_values(values, count);
|
||||
free(values);
|
||||
return (NULL);
|
||||
}
|
||||
|
||||
@@ -157,8 +157,7 @@ cmd_list_keys_format_add_key_binding(struct format_tree *ft,
|
||||
|
||||
format_add(ft, "key_string", "%s", key_string_lookup_key(bd->key, 0));
|
||||
|
||||
s = cmd_list_print(bd->cmdlist, CMD_LIST_PRINT_ESCAPED|
|
||||
CMD_LIST_PRINT_NO_GROUPS);
|
||||
s = cmd_parse_print(bd->cmd); /* XXX: command parser conversion */
|
||||
format_add(ft, "key_command", "%s", s);
|
||||
free(s);
|
||||
}
|
||||
|
||||
38
cmd-parse.y
38
cmd-parse.y
@@ -88,6 +88,7 @@ struct cmd_parse_scan {
|
||||
static char *cmd_parse_get_error(const char *, u_int, const char *);
|
||||
static struct cmd_parse_node *cmd_parse_new_node(enum cmd_parse_node_type,
|
||||
u_int);
|
||||
static struct cmd_parse_node *cmd_parse_copy_node(struct cmd_parse_node *);
|
||||
static struct cmd_parse_nodes *cmd_parse_new_nodes(void);
|
||||
static void cmd_parse_free_node(struct cmd_parse_node *);
|
||||
static void cmd_parse_append(struct cmd_parse_nodes *,
|
||||
@@ -466,6 +467,24 @@ cmd_parse_free_node(struct cmd_parse_node *node)
|
||||
free(node);
|
||||
}
|
||||
|
||||
/* Recursively copy a node and all of its descendants. */
|
||||
static struct cmd_parse_node *
|
||||
cmd_parse_copy_node(struct cmd_parse_node *node)
|
||||
{
|
||||
struct cmd_parse_node *new, *child, *copy;
|
||||
|
||||
new = cmd_parse_new_node(node->type, node->line);
|
||||
new->end_line = node->end_line;
|
||||
if (node->value != NULL)
|
||||
new->value = xstrdup(node->value);
|
||||
|
||||
TAILQ_FOREACH(child, &node->children, entry) {
|
||||
copy = cmd_parse_copy_node(child);
|
||||
TAILQ_INSERT_TAIL(&new->children, copy, entry);
|
||||
}
|
||||
return (new);
|
||||
}
|
||||
|
||||
/* Move all nodes from src to the tail of dst, then free the src list head. */
|
||||
static void
|
||||
cmd_parse_append(struct cmd_parse_nodes *dst, struct cmd_parse_nodes *src)
|
||||
@@ -674,6 +693,25 @@ cmd_parse_from_string(const char *s, struct cmd_parse_input *pi, char **cause)
|
||||
return (cmd_parse_from_buffer(s, strlen(s), &input, cause));
|
||||
}
|
||||
|
||||
struct cmd_parse_tree *
|
||||
cmd_parse_from_node(struct cmd_parse_node *node)
|
||||
{
|
||||
struct cmd_parse_tree *new;
|
||||
struct cmd_parse_node *root, *child;
|
||||
|
||||
root = cmd_parse_new_node(CMD_PARSE_ROOT, node->line);
|
||||
root->end_line = node->end_line;
|
||||
TAILQ_FOREACH(child, &node->children, entry) {
|
||||
TAILQ_INSERT_TAIL(&root->children, cmd_parse_copy_node(child),
|
||||
entry);
|
||||
}
|
||||
|
||||
new = xcalloc(1, sizeof *new);
|
||||
new->references = 1;
|
||||
new->root = root;
|
||||
return (new);
|
||||
}
|
||||
|
||||
struct cmd_parse_tree *
|
||||
cmd_parse_add_ref(struct cmd_parse_tree *tree)
|
||||
{
|
||||
|
||||
@@ -96,7 +96,7 @@ key_bindings_cmp(struct key_binding *bd1, struct key_binding *bd2)
|
||||
static void
|
||||
key_bindings_free(struct key_binding *bd)
|
||||
{
|
||||
cmd_list_free(bd->cmdlist);
|
||||
cmd_parse_free(bd->cmd);
|
||||
free((void *)bd->note);
|
||||
free(bd);
|
||||
}
|
||||
@@ -188,16 +188,14 @@ key_bindings_next(__unused struct key_table *table, struct key_binding *bd)
|
||||
|
||||
void
|
||||
key_bindings_add(const char *name, key_code key, const char *note, int repeat,
|
||||
struct cmd_list *cmdlist)
|
||||
struct cmd_parse_tree *cmd)
|
||||
{
|
||||
struct key_table *table;
|
||||
struct key_table *table = key_bindings_get_table(name, 1);
|
||||
struct key_binding *bd;
|
||||
char *s;
|
||||
|
||||
table = key_bindings_get_table(name, 1);
|
||||
char *k, *s;
|
||||
|
||||
bd = key_bindings_get(table, key & ~KEYC_MASK_FLAGS);
|
||||
if (cmdlist == NULL) {
|
||||
if (cmd == NULL) {
|
||||
if (bd != NULL) {
|
||||
if (note != NULL) {
|
||||
free((void *)bd->note);
|
||||
@@ -222,11 +220,11 @@ key_bindings_add(const char *name, key_code key, const char *note, int repeat,
|
||||
|
||||
if (repeat)
|
||||
bd->flags |= KEY_BINDING_REPEAT;
|
||||
bd->cmdlist = cmdlist;
|
||||
bd->cmd = cmd;
|
||||
|
||||
s = cmd_list_print(bd->cmdlist, 0);
|
||||
log_debug("%s: %#llx %s = %s", __func__, bd->key,
|
||||
key_string_lookup_key(bd->key, 1), s);
|
||||
k = key_string_lookup_key(bd->key, 1);
|
||||
s = cmd_parse_print(bd->cmd);
|
||||
log_debug("%s: %#llx %s = %s", __func__, bd->key, k, s);
|
||||
free(s);
|
||||
}
|
||||
|
||||
@@ -235,6 +233,7 @@ key_bindings_remove(const char *name, key_code key)
|
||||
{
|
||||
struct key_table *table;
|
||||
struct key_binding *bd;
|
||||
const char *k;
|
||||
|
||||
table = key_bindings_get_table(name, 0);
|
||||
if (table == NULL)
|
||||
@@ -244,8 +243,8 @@ key_bindings_remove(const char *name, key_code key)
|
||||
if (bd == NULL)
|
||||
return;
|
||||
|
||||
log_debug("%s: %#llx %s", __func__, bd->key,
|
||||
key_string_lookup_key(bd->key, 1));
|
||||
k = key_string_lookup_key(bd->key, 1);
|
||||
log_debug("%s: %#llx %s", __func__, bd->key, k);
|
||||
|
||||
RB_REMOVE(key_bindings, &table->key_bindings, bd);
|
||||
key_bindings_free(bd);
|
||||
@@ -277,9 +276,8 @@ key_bindings_reset(const char *name, key_code key)
|
||||
return;
|
||||
}
|
||||
|
||||
cmd_list_free(bd->cmdlist);
|
||||
bd->cmdlist = dd->cmdlist;
|
||||
bd->cmdlist->references++;
|
||||
cmd_parse_free(bd->cmd);
|
||||
bd->cmd = cmd_parse_add_ref(dd->cmd);
|
||||
|
||||
free((void *)bd->note);
|
||||
if (dd->note != NULL)
|
||||
@@ -336,8 +334,7 @@ key_bindings_init_done(__unused struct cmdq_item *item, __unused void *data)
|
||||
if (bd->note != NULL)
|
||||
new_bd->note = xstrdup(bd->note);
|
||||
new_bd->flags = bd->flags;
|
||||
new_bd->cmdlist = bd->cmdlist;
|
||||
new_bd->cmdlist->references++;
|
||||
new_bd->cmd = cmd_parse_add_ref(bd->cmd);
|
||||
RB_INSERT(key_bindings, &table->default_key_bindings,
|
||||
new_bd);
|
||||
}
|
||||
@@ -706,12 +703,18 @@ key_bindings_dispatch(struct key_binding *bd, struct cmdq_item *item,
|
||||
{
|
||||
struct cmdq_item *new_item;
|
||||
struct cmdq_state *new_state;
|
||||
struct cmd_invoke_input ci;
|
||||
int readonly, flags = 0;
|
||||
|
||||
if (c == NULL || (~c->flags & CLIENT_READONLY))
|
||||
readonly = 1;
|
||||
else
|
||||
else {
|
||||
#if 0 /* XXX: command parser conversion */
|
||||
readonly = cmd_list_all_have(bd->cmdlist, CMD_READONLY);
|
||||
#else
|
||||
readonly = 0;
|
||||
#endif
|
||||
}
|
||||
|
||||
if (!readonly)
|
||||
new_item = cmdq_get_callback(key_bindings_read_only, NULL);
|
||||
@@ -719,7 +722,9 @@ key_bindings_dispatch(struct key_binding *bd, struct cmdq_item *item,
|
||||
if (bd->flags & KEY_BINDING_REPEAT)
|
||||
flags |= CMDQ_STATE_REPEAT;
|
||||
new_state = cmdq_new_state(fs, event, flags);
|
||||
new_item = cmdq_get_command(bd->cmdlist, new_state);
|
||||
|
||||
memset(&ci, 0, sizeof ci);
|
||||
new_item = cmd_invoke_get(bd->cmd, new_state, &ci);
|
||||
cmdq_free_state(new_state);
|
||||
}
|
||||
if (item != NULL)
|
||||
|
||||
@@ -77,6 +77,7 @@ struct cmd_parse_tree *cmd_parse_from_buffer(const void *, size_t,
|
||||
struct cmd_parse_input *, char **);
|
||||
struct cmd_parse_tree *cmd_parse_from_string(const char *,
|
||||
struct cmd_parse_input *, char **);
|
||||
struct cmd_parse_tree *cmd_parse_from_node(struct cmd_parse_node *);
|
||||
struct cmd_parse_tree *cmd_parse_add_ref(struct cmd_parse_tree *);
|
||||
void cmd_parse_free(struct cmd_parse_tree *);
|
||||
struct cmd_parse_node *cmd_parse_root(struct cmd_parse_tree *);
|
||||
|
||||
14
tmux.h
14
tmux.h
@@ -1869,13 +1869,13 @@ enum args_type {
|
||||
|
||||
/* Argument value. */
|
||||
struct args_value {
|
||||
enum args_type type;
|
||||
enum args_type type;
|
||||
union {
|
||||
char *string;
|
||||
struct cmd_list *cmdlist;
|
||||
char *string;
|
||||
struct cmd_parse_tree *cmd;
|
||||
};
|
||||
char *cached;
|
||||
TAILQ_ENTRY(args_value) entry;
|
||||
char *cached;
|
||||
TAILQ_ENTRY(args_value) entry;
|
||||
};
|
||||
|
||||
/* Arguments set. */
|
||||
@@ -2311,7 +2311,7 @@ enum control_sub_type {
|
||||
/* Key binding and key table. */
|
||||
struct key_binding {
|
||||
key_code key;
|
||||
struct cmd_list *cmdlist;
|
||||
struct cmd_parse_tree *cmd;
|
||||
const char *note;
|
||||
const char *tablename;
|
||||
|
||||
@@ -3061,7 +3061,7 @@ struct key_binding *key_bindings_get_default(struct key_table *, key_code);
|
||||
struct key_binding *key_bindings_first(struct key_table *);
|
||||
struct key_binding *key_bindings_next(struct key_table *, struct key_binding *);
|
||||
void key_bindings_add(const char *, key_code, const char *, int,
|
||||
struct cmd_list *);
|
||||
struct cmd_parse_tree *);
|
||||
void key_bindings_remove(const char *, key_code);
|
||||
void key_bindings_reset(const char *, key_code);
|
||||
void key_bindings_remove_table(const char *);
|
||||
|
||||
@@ -490,7 +490,7 @@ window_customize_build_keys(struct window_customize_modedata *data,
|
||||
expanded, NULL, 0);
|
||||
free(expanded);
|
||||
|
||||
tmp = cmd_list_print(bd->cmdlist, 0);
|
||||
tmp = cmd_parse_print(bd->cmd); /* XXX: command parser conversion */
|
||||
xasprintf(&text, "#[ignore]%s", tmp);
|
||||
free(tmp);
|
||||
mti = mode_tree_add(data->data, child, item,
|
||||
@@ -625,7 +625,7 @@ window_customize_draw_key(__unused struct window_customize_modedata *data,
|
||||
if (s->cy >= cy + sy - 1)
|
||||
return;
|
||||
|
||||
cmd = cmd_list_print(bd->cmdlist, 0);
|
||||
cmd = cmd_parse_print(bd->cmd); /* XXX: command parser conversion */
|
||||
if (!screen_write_text(ctx, cx, sx, sy - (s->cy - cy), 0,
|
||||
&grid_default_cell, "Command: %s", cmd)) {
|
||||
free(cmd);
|
||||
@@ -633,7 +633,7 @@ window_customize_draw_key(__unused struct window_customize_modedata *data,
|
||||
}
|
||||
default_bd = key_bindings_get_default(kt, bd->key);
|
||||
if (default_bd != NULL) {
|
||||
default_cmd = cmd_list_print(default_bd->cmdlist, 0);
|
||||
default_cmd = cmd_parse_print(default_bd->cmd); /* XXX */
|
||||
if (strcmp(cmd, default_cmd) != 0 &&
|
||||
!screen_write_text(ctx, cx, sx, sy - (s->cy - cy), 0,
|
||||
&grid_default_cell, "The default is: %s", default_cmd)) {
|
||||
@@ -1298,7 +1298,7 @@ window_customize_set_key(struct client *c,
|
||||
bd->flags ^= KEY_BINDING_REPEAT;
|
||||
else if (strcmp(s, "Command") == 0) {
|
||||
xasprintf(&prompt, "(%s) ", key_string_lookup_key(key, 0));
|
||||
value = cmd_list_print(bd->cmdlist, 0);
|
||||
value = cmd_parse_print(bd->cmd); /* XXX: command parser conversion */
|
||||
|
||||
new_item = xcalloc(1, sizeof *new_item);
|
||||
new_item->data = data;
|
||||
@@ -1360,7 +1360,7 @@ window_customize_reset_key(struct window_customize_modedata *data,
|
||||
return;
|
||||
|
||||
dd = key_bindings_get_default(kt, bd->key);
|
||||
if (dd != NULL && bd->cmdlist == dd->cmdlist)
|
||||
if (dd != NULL && bd->cmd == dd->cmd) /* XXX: command parser conversion */
|
||||
return;
|
||||
if (dd == NULL && item == mode_tree_get_current(data->data)) {
|
||||
mode_tree_collapse_current(data->data);
|
||||
|
||||
Reference in New Issue
Block a user