Some key bits.

This commit is contained in:
Nicholas Marriott
2026-06-30 15:14:54 +01:00
parent b48e2ea8e9
commit 9569c57fc3
7 changed files with 119 additions and 45 deletions

View File

@@ -88,26 +88,7 @@ cmd_bind_key_exec(struct cmd *self, struct cmdq_item *item)
return (CMD_RETURN_NORMAL);
}
#if 0 /* XXX: command parser conversion */
struct cmd_parse_result *pr;
if (count == 2)
pr = cmd_parse_from_string(args_string(args, 1), NULL);
else {
pr = cmd_parse_from_arguments(args_values(args) + 1, count - 1,
NULL);
}
switch (pr->status) {
case CMD_PARSE_ERROR:
cmdq_error(item, "%s", pr->error);
free(pr->error);
return (CMD_RETURN_ERROR);
case CMD_PARSE_SUCCESS:
break;
}
key_bindings_add(tablename, key, note, repeat, pr->cmdlist);
cmd = cmd_parse_from_arguments(args_values(args) + 1, count - 1);
key_bindings_add(tablename, key, note, repeat, cmd);
return (CMD_RETURN_NORMAL);
#else
fatalx("XXX: command parser conversion not done for bind-key");
#endif
}

View File

@@ -252,12 +252,22 @@ cmd_invoke_is_true(struct cmdq_item *item,
return (0);
}
/* Push the selected conditional branch onto the traversal stack. */
static void
cmd_invoke_push_branch(struct cmd_invoke_state *is,
struct cmd_parse_node *node, struct cmd_parse_node *first)
/* Skip else branches. */
static struct cmd_parse_node *
cmd_invoke_if_branch_end(struct cmd_parse_node *first)
{
cmd_invoke_push(is, node, first, NULL);
struct cmd_parse_node *node;
for (node = first; node != NULL; node = cmd_parse_node_next(node)) {
switch (cmd_parse_node_type(node)) {
case CMD_PARSE_ELIF:
case CMD_PARSE_ELSE:
return (node);
default:
break;
}
}
return (NULL);
}
/* Select and queue the branch for a conditional node. */
@@ -275,7 +285,8 @@ cmd_invoke_if(struct cmdq_item *item, struct cmd_invoke_state *is,
if (cmd_invoke_is_true(item, is, next, &r) != 0)
return (-1);
if (r) {
cmd_invoke_push_branch(is, node, first);
next = cmd_invoke_if_branch_end(first);
cmd_invoke_push(is, node, first, next);
return (0);
}
@@ -289,13 +300,13 @@ cmd_invoke_if(struct cmdq_item *item, struct cmd_invoke_state *is,
return (-1);
if (r) {
next = cmd_parse_node_next(next);
cmd_invoke_push_branch(is, child, next);
cmd_invoke_push(is, child, next, NULL);
return (0);
}
break;
case CMD_PARSE_ELSE:
next = cmd_parse_node_first_child(child);
cmd_invoke_push_branch(is, child, next);
cmd_invoke_push(is, child, next, NULL);
return (0);
default:
break;

View File

@@ -697,13 +697,13 @@ struct cmd_parse_tree *
cmd_parse_from_node(struct cmd_parse_node *node)
{
struct cmd_parse_tree *new;
struct cmd_parse_node *root, *child;
struct cmd_parse_node *root, *child, *copy;
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);
copy = cmd_parse_copy_node(child);
TAILQ_INSERT_TAIL(&root->children, copy, entry);
}
new = xcalloc(1, sizeof *new);
@@ -712,6 +712,73 @@ cmd_parse_from_node(struct cmd_parse_node *node)
return (new);
}
/* Build a string node with a single literal text child. */
static struct cmd_parse_node *
cmd_parse_new_string_node(const char *s, u_int line)
{
struct cmd_parse_node *string, *text;
string = cmd_parse_new_node(CMD_PARSE_STRING, line);
if (*s != '\0') {
text = cmd_parse_new_node(CMD_PARSE_TEXT, line);
text->value = xstrdup(s);
TAILQ_INSERT_TAIL(&string->children, text, entry);
}
return (string);
}
/* Build a commands node from a copy of the children of a tree's root. */
static struct cmd_parse_node *
cmd_parse_new_commands_node(struct cmd_parse_tree *tree, u_int line)
{
struct cmd_parse_node *commands, *root, *child, *copy;
commands = cmd_parse_new_node(CMD_PARSE_COMMANDS, line);
root = cmd_parse_root(tree);
TAILQ_FOREACH(child, &root->children, entry) {
copy = cmd_parse_copy_node(child);
TAILQ_INSERT_TAIL(&commands->children, copy, entry);
}
return (commands);
}
/* Build a parse tree directly from existing argument values. */
struct cmd_parse_tree *
cmd_parse_from_arguments(struct args_value *values, u_int count)
{
struct cmd_parse_tree *new;
struct cmd_parse_node *root, *seq, *cmd, *child;
u_int i;
cmd = cmd_parse_new_node(CMD_PARSE_COMMAND, 0);
for (i = 0; i < count; i++) {
switch (values[i].type) {
case ARGS_NONE:
continue;
case ARGS_STRING:
child = cmd_parse_new_string_node(values[i].string, 0);
break;
case ARGS_COMMANDS:
child = cmd_parse_new_commands_node(values[i].cmd, 0);
break;
}
TAILQ_INSERT_TAIL(&cmd->children, child, entry);
}
seq = cmd_parse_new_node(CMD_PARSE_SEQUENCE, 0);
TAILQ_INSERT_TAIL(&seq->children, cmd, entry);
root = cmd_parse_new_node(CMD_PARSE_ROOT, 0);
TAILQ_INSERT_TAIL(&root->children, seq, 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)
{

View File

@@ -192,7 +192,8 @@ key_bindings_add(const char *name, key_code key, const char *note, int repeat,
{
struct key_table *table = key_bindings_get_table(name, 1);
struct key_binding *bd;
char *k, *s;
const char *k;
char *s;
bd = key_bindings_get(table, key & ~KEYC_MASK_FLAGS);
if (cmd == NULL) {
@@ -670,23 +671,21 @@ key_bindings_init(void)
"bind -Tcopy-mode-vi C-Down { send -X scroll-down }",
};
#if 0 /* XXX: command parser conversion */
u_int i;
struct cmd_parse_result *pr;
struct cmd_parse_tree *tree;
struct cmdq_item *new_item;
struct cmd_invoke_input ci = { 0 };
char *cause = NULL;
for (i = 0; i < nitems(defaults); i++) {
pr = cmd_parse_from_string(defaults[i], NULL);
if (pr->status != CMD_PARSE_SUCCESS) {
log_debug("%s", pr->error);
tree = cmd_parse_from_string(defaults[i], NULL, &cause);
if (tree == NULL)
fatalx("bad default key: %s", defaults[i]);
}
cmdq_append(NULL, cmdq_get_command(pr->cmdlist, NULL));
cmd_list_free(pr->cmdlist);
new_item = cmd_invoke_get(tree, NULL, &ci);
cmdq_append(NULL, new_item);
cmd_parse_free(tree);
}
#else
log_debug("XXX: command parser conversion not done for %u default keys",
(u_int)nitems(defaults));
#endif
cmdq_append(NULL, cmdq_get_callback(key_bindings_init_done, NULL));
}

View File

@@ -0,0 +1,9 @@
set -g status off
bind-key F1 {
display-message "parser bind body: F1"
run-shell "echo F1-FIRED >> /tmp/claude-1000/-home-nicholas-tmux-claude/9fb594c3-5fb9-41b2-8a5a-8d3d0b39b009/scratchpad/bindresult.txt"
}
bind-key F2 {
run-shell "echo F2-FIRST >> /tmp/claude-1000/-home-nicholas-tmux-claude/9fb594c3-5fb9-41b2-8a5a-8d3d0b39b009/scratchpad/bindresult.txt"
run-shell "echo F2-SECOND >> /tmp/claude-1000/-home-nicholas-tmux-claude/9fb594c3-5fb9-41b2-8a5a-8d3d0b39b009/scratchpad/bindresult.txt"
}

View File

@@ -0,0 +1,5 @@
bind-key F1 { display-message "parser bind body: F1" }
bind-key F2 {
display-message "parser bind body: first"
display-message "parser bind body: second"
}

View File

@@ -38,6 +38,7 @@
struct cmd_parse_tree;
struct cmd_parse_node;
struct args_value;
struct cmd_parse_input {
int flags;
@@ -78,6 +79,7 @@ struct cmd_parse_tree *cmd_parse_from_buffer(const void *, size_t,
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_from_arguments(struct args_value *, u_int);
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 *);