mirror of
https://github.com/tmux/tmux.git
synced 2026-03-06 07:45:35 +00:00
Merge branch 'master' into floating_panes
This commit is contained in:
2
.github/README.md
vendored
2
.github/README.md
vendored
@@ -79,7 +79,7 @@ A small example configuration is in `example_tmux.conf`.
|
|||||||
|
|
||||||
And a bash(1) completion file at:
|
And a bash(1) completion file at:
|
||||||
|
|
||||||
https://github.com/scop/bash-completion/blob/main/completions/tmux
|
https://github.com/scop/bash-completion/blob/main/completions-core/tmux.bash
|
||||||
|
|
||||||
For debugging, run tmux with `-v` or `-vv` to generate server and client log
|
For debugging, run tmux with `-v` or `-vv` to generate server and client log
|
||||||
files in the current directory.
|
files in the current directory.
|
||||||
|
|||||||
1
.mailmap
1
.mailmap
@@ -29,6 +29,7 @@ Ted Unangst <tedu@openbsd.org> tedu <tedu>
|
|||||||
Theo de Raadt <deraadt@openbsd.org> Theo Deraadt <deraadt@openbsd.org>
|
Theo de Raadt <deraadt@openbsd.org> Theo Deraadt <deraadt@openbsd.org>
|
||||||
Theo de Raadt <deraadt@openbsd.org> deraadt <deraadt>
|
Theo de Raadt <deraadt@openbsd.org> deraadt <deraadt>
|
||||||
Thomas Adam <thomas@xteddy.org> Thomas <thomas@xteddy.org>
|
Thomas Adam <thomas@xteddy.org> Thomas <thomas@xteddy.org>
|
||||||
|
Thomas Adam <thomas@xteddy.org> Thomas Adam <thomas.adam22@gmail.com>
|
||||||
Thomas Adam <thomas@xteddy.org> Thomas Adam <thomas.adam@smoothwall.net>
|
Thomas Adam <thomas@xteddy.org> Thomas Adam <thomas.adam@smoothwall.net>
|
||||||
Thomas Adam <thomas@xteddy.org> n6tadam <n6tadam@xteddy.org>
|
Thomas Adam <thomas@xteddy.org> n6tadam <n6tadam@xteddy.org>
|
||||||
Tim van der Molen <tim@openbsd.org> tim <tim>
|
Tim van der Molen <tim@openbsd.org> tim <tim>
|
||||||
|
|||||||
@@ -106,6 +106,7 @@ dist_tmux_SOURCES = \
|
|||||||
cmd-kill-window.c \
|
cmd-kill-window.c \
|
||||||
cmd-list-buffers.c \
|
cmd-list-buffers.c \
|
||||||
cmd-list-clients.c \
|
cmd-list-clients.c \
|
||||||
|
cmd-list-commands.c \
|
||||||
cmd-list-keys.c \
|
cmd-list-keys.c \
|
||||||
cmd-list-panes.c \
|
cmd-list-panes.c \
|
||||||
cmd-list-sessions.c \
|
cmd-list-sessions.c \
|
||||||
|
|||||||
@@ -98,6 +98,13 @@ cmd_choose_tree_exec(struct cmd *self, struct cmdq_item *item)
|
|||||||
struct cmd_find_state *target = cmdq_get_target(item);
|
struct cmd_find_state *target = cmdq_get_target(item);
|
||||||
struct window_pane *wp = target->wp;
|
struct window_pane *wp = target->wp;
|
||||||
const struct window_mode *mode;
|
const struct window_mode *mode;
|
||||||
|
enum sort_order order;
|
||||||
|
|
||||||
|
order = sort_order_from_string(args_get(args, 'O'));
|
||||||
|
if (order == SORT_END && args_has(args, 'O')) {
|
||||||
|
cmdq_error(item, "invalid sort order");
|
||||||
|
return (CMD_RETURN_ERROR);
|
||||||
|
}
|
||||||
|
|
||||||
if (cmd_get_entry(self) == &cmd_choose_buffer_entry) {
|
if (cmd_get_entry(self) == &cmd_choose_buffer_entry) {
|
||||||
if (paste_is_empty())
|
if (paste_is_empty())
|
||||||
|
|||||||
@@ -92,6 +92,7 @@ cmd_confirm_before_exec(struct cmd *self, struct cmdq_item *item)
|
|||||||
cdata->confirm_key = confirm_key[0];
|
cdata->confirm_key = confirm_key[0];
|
||||||
else {
|
else {
|
||||||
cmdq_error(item, "invalid confirm key");
|
cmdq_error(item, "invalid confirm key");
|
||||||
|
cmd_list_free(cdata->cmdlist);
|
||||||
free(cdata);
|
free(cdata);
|
||||||
return (CMD_RETURN_ERROR);
|
return (CMD_RETURN_ERROR);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -36,7 +36,7 @@ const struct cmd_entry cmd_copy_mode_entry = {
|
|||||||
.source = { 's', CMD_FIND_PANE, 0 },
|
.source = { 's', CMD_FIND_PANE, 0 },
|
||||||
.target = { 't', CMD_FIND_PANE, 0 },
|
.target = { 't', CMD_FIND_PANE, 0 },
|
||||||
|
|
||||||
.flags = CMD_AFTERHOOK,
|
.flags = CMD_AFTERHOOK|CMD_READONLY,
|
||||||
.exec = cmd_copy_mode_exec
|
.exec = cmd_copy_mode_exec
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|||||||
@@ -294,7 +294,7 @@ cmd_display_menu_exec(struct cmd *self, struct cmdq_item *item)
|
|||||||
const char *border_style = args_get(args, 'S');
|
const char *border_style = args_get(args, 'S');
|
||||||
const char *selected_style = args_get(args, 'H');
|
const char *selected_style = args_get(args, 'H');
|
||||||
enum box_lines lines = BOX_LINES_DEFAULT;
|
enum box_lines lines = BOX_LINES_DEFAULT;
|
||||||
char *title, *cause;
|
char *title, *cause = NULL;
|
||||||
int flags = 0, starting_choice = 0;
|
int flags = 0, starting_choice = 0;
|
||||||
u_int px, py, i, count = args_count(args);
|
u_int px, py, i, count = args_count(args);
|
||||||
struct options *o = target->s->curw->window->options;
|
struct options *o = target->s->curw->window->options;
|
||||||
@@ -312,8 +312,7 @@ cmd_display_menu_exec(struct cmd *self, struct cmdq_item *item)
|
|||||||
&cause);
|
&cause);
|
||||||
if (cause != NULL) {
|
if (cause != NULL) {
|
||||||
cmdq_error(item, "starting choice %s", cause);
|
cmdq_error(item, "starting choice %s", cause);
|
||||||
free(cause);
|
goto fail;
|
||||||
return (CMD_RETURN_ERROR);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -334,8 +333,7 @@ cmd_display_menu_exec(struct cmd *self, struct cmdq_item *item)
|
|||||||
|
|
||||||
if (count - i < 2) {
|
if (count - i < 2) {
|
||||||
cmdq_error(item, "not enough arguments");
|
cmdq_error(item, "not enough arguments");
|
||||||
menu_free(menu);
|
goto fail;
|
||||||
return (CMD_RETURN_ERROR);
|
|
||||||
}
|
}
|
||||||
key = args_string(args, i++);
|
key = args_string(args, i++);
|
||||||
|
|
||||||
@@ -347,17 +345,13 @@ cmd_display_menu_exec(struct cmd *self, struct cmdq_item *item)
|
|||||||
}
|
}
|
||||||
if (menu == NULL) {
|
if (menu == NULL) {
|
||||||
cmdq_error(item, "invalid menu arguments");
|
cmdq_error(item, "invalid menu arguments");
|
||||||
return (CMD_RETURN_ERROR);
|
goto fail;
|
||||||
}
|
|
||||||
if (menu->count == 0) {
|
|
||||||
menu_free(menu);
|
|
||||||
return (CMD_RETURN_NORMAL);
|
|
||||||
}
|
}
|
||||||
|
if (menu->count == 0)
|
||||||
|
goto out;
|
||||||
if (!cmd_display_menu_get_pos(tc, item, args, &px, &py, menu->width + 4,
|
if (!cmd_display_menu_get_pos(tc, item, args, &px, &py, menu->width + 4,
|
||||||
menu->count + 2)) {
|
menu->count + 2))
|
||||||
menu_free(menu);
|
goto out;
|
||||||
return (CMD_RETURN_NORMAL);
|
|
||||||
}
|
|
||||||
|
|
||||||
value = args_get(args, 'b');
|
value = args_get(args, 'b');
|
||||||
if (value != NULL) {
|
if (value != NULL) {
|
||||||
@@ -366,8 +360,7 @@ cmd_display_menu_exec(struct cmd *self, struct cmdq_item *item)
|
|||||||
&cause);
|
&cause);
|
||||||
if (lines == -1) {
|
if (lines == -1) {
|
||||||
cmdq_error(item, "menu-border-lines %s", cause);
|
cmdq_error(item, "menu-border-lines %s", cause);
|
||||||
free(cause);
|
goto fail;
|
||||||
return (CMD_RETURN_ERROR);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -379,6 +372,15 @@ cmd_display_menu_exec(struct cmd *self, struct cmdq_item *item)
|
|||||||
style, selected_style, border_style, target, NULL, NULL) != 0)
|
style, selected_style, border_style, target, NULL, NULL) != 0)
|
||||||
return (CMD_RETURN_NORMAL);
|
return (CMD_RETURN_NORMAL);
|
||||||
return (CMD_RETURN_WAIT);
|
return (CMD_RETURN_WAIT);
|
||||||
|
|
||||||
|
out:
|
||||||
|
menu_free(menu);
|
||||||
|
return (CMD_RETURN_NORMAL);
|
||||||
|
|
||||||
|
fail:
|
||||||
|
free(cause);
|
||||||
|
menu_free(menu);
|
||||||
|
return (CMD_RETURN_ERROR);
|
||||||
}
|
}
|
||||||
|
|
||||||
static enum cmd_retval
|
static enum cmd_retval
|
||||||
@@ -393,7 +395,7 @@ cmd_display_popup_exec(struct cmd *self, struct cmdq_item *item)
|
|||||||
const char *style = args_get(args, 's');
|
const char *style = args_get(args, 's');
|
||||||
const char *border_style = args_get(args, 'S');
|
const char *border_style = args_get(args, 'S');
|
||||||
char *cwd = NULL, *cause = NULL, **argv = NULL;
|
char *cwd = NULL, *cause = NULL, **argv = NULL;
|
||||||
char *title;
|
char *title = NULL;
|
||||||
int modify = popup_present(tc);
|
int modify = popup_present(tc);
|
||||||
int flags = -1, argc = 0;
|
int flags = -1, argc = 0;
|
||||||
enum box_lines lines = BOX_LINES_DEFAULT;
|
enum box_lines lines = BOX_LINES_DEFAULT;
|
||||||
@@ -417,8 +419,7 @@ cmd_display_popup_exec(struct cmd *self, struct cmdq_item *item)
|
|||||||
&cause);
|
&cause);
|
||||||
if (cause != NULL) {
|
if (cause != NULL) {
|
||||||
cmdq_error(item, "height %s", cause);
|
cmdq_error(item, "height %s", cause);
|
||||||
free(cause);
|
goto fail;
|
||||||
return (CMD_RETURN_ERROR);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -428,8 +429,7 @@ cmd_display_popup_exec(struct cmd *self, struct cmdq_item *item)
|
|||||||
&cause);
|
&cause);
|
||||||
if (cause != NULL) {
|
if (cause != NULL) {
|
||||||
cmdq_error(item, "width %s", cause);
|
cmdq_error(item, "width %s", cause);
|
||||||
free(cause);
|
goto fail;
|
||||||
return (CMD_RETURN_ERROR);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -438,7 +438,7 @@ cmd_display_popup_exec(struct cmd *self, struct cmdq_item *item)
|
|||||||
if (h > tty->sy)
|
if (h > tty->sy)
|
||||||
h = tty->sy;
|
h = tty->sy;
|
||||||
if (!cmd_display_menu_get_pos(tc, item, args, &px, &py, w, h))
|
if (!cmd_display_menu_get_pos(tc, item, args, &px, &py, w, h))
|
||||||
return (CMD_RETURN_NORMAL);
|
goto out;
|
||||||
|
|
||||||
value = args_get(args, 'd');
|
value = args_get(args, 'd');
|
||||||
if (value != NULL)
|
if (value != NULL)
|
||||||
@@ -478,8 +478,7 @@ cmd_display_popup_exec(struct cmd *self, struct cmdq_item *item)
|
|||||||
&cause);
|
&cause);
|
||||||
if (cause != NULL) {
|
if (cause != NULL) {
|
||||||
cmdq_error(item, "popup-border-lines %s", cause);
|
cmdq_error(item, "popup-border-lines %s", cause);
|
||||||
free(cause);
|
goto fail;
|
||||||
return (CMD_RETURN_ERROR);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -507,22 +506,29 @@ cmd_display_popup_exec(struct cmd *self, struct cmdq_item *item)
|
|||||||
|
|
||||||
if (modify) {
|
if (modify) {
|
||||||
popup_modify(tc, title, style, border_style, lines, flags);
|
popup_modify(tc, title, style, border_style, lines, flags);
|
||||||
free(title);
|
goto out;
|
||||||
return (CMD_RETURN_NORMAL);
|
|
||||||
}
|
}
|
||||||
if (popup_display(flags, lines, item, px, py, w, h, env, shellcmd, argc,
|
if (popup_display(flags, lines, item, px, py, w, h, env, shellcmd, argc,
|
||||||
argv, cwd, title, tc, s, style, border_style, NULL, NULL) != 0) {
|
argv, cwd, title, tc, s, style, border_style, NULL, NULL) != 0)
|
||||||
cmd_free_argv(argc, argv);
|
goto out;
|
||||||
if (env != NULL)
|
environ_free(env);
|
||||||
environ_free(env);
|
|
||||||
free(cwd);
|
|
||||||
free(title);
|
|
||||||
return (CMD_RETURN_NORMAL);
|
|
||||||
}
|
|
||||||
if (env != NULL)
|
|
||||||
environ_free(env);
|
|
||||||
free(cwd);
|
free(cwd);
|
||||||
free(title);
|
free(title);
|
||||||
cmd_free_argv(argc, argv);
|
cmd_free_argv(argc, argv);
|
||||||
return (CMD_RETURN_WAIT);
|
return (CMD_RETURN_WAIT);
|
||||||
|
|
||||||
|
out:
|
||||||
|
cmd_free_argv(argc, argv);
|
||||||
|
environ_free(env);
|
||||||
|
free(cwd);
|
||||||
|
free(title);
|
||||||
|
return (CMD_RETURN_NORMAL);
|
||||||
|
|
||||||
|
fail:
|
||||||
|
free(cause);
|
||||||
|
cmd_free_argv(argc, argv);
|
||||||
|
environ_free(env);
|
||||||
|
free(cwd);
|
||||||
|
free(title);
|
||||||
|
return (CMD_RETURN_ERROR);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -131,6 +131,7 @@ cmd_display_message_exec(struct cmd *self, struct cmdq_item *item)
|
|||||||
|
|
||||||
if (args_has(args, 'a')) {
|
if (args_has(args, 'a')) {
|
||||||
format_each(ft, cmd_display_message_each, item);
|
format_each(ft, cmd_display_message_each, item);
|
||||||
|
format_free(ft);
|
||||||
return (CMD_RETURN_NORMAL);
|
return (CMD_RETURN_NORMAL);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -155,6 +156,5 @@ cmd_display_message_exec(struct cmd *self, struct cmdq_item *item)
|
|||||||
free(msg);
|
free(msg);
|
||||||
|
|
||||||
format_free(ft);
|
format_free(ft);
|
||||||
|
|
||||||
return (CMD_RETURN_NORMAL);
|
return (CMD_RETURN_NORMAL);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -60,6 +60,10 @@ cmd_list_buffers_exec(struct cmd *self, struct cmdq_item *item)
|
|||||||
filter = args_get(args, 'f');
|
filter = args_get(args, 'f');
|
||||||
|
|
||||||
sort_crit.order = sort_order_from_string(args_get(args, 'O'));
|
sort_crit.order = sort_order_from_string(args_get(args, 'O'));
|
||||||
|
if (sort_crit.order == SORT_END && args_has(args, 'O')) {
|
||||||
|
cmdq_error(item, "invalid sort order");
|
||||||
|
return (CMD_RETURN_ERROR);
|
||||||
|
}
|
||||||
sort_crit.reversed = args_has(args, 'r');
|
sort_crit.reversed = args_has(args, 'r');
|
||||||
|
|
||||||
l = sort_get_buffers(&n, &sort_crit);
|
l = sort_get_buffers(&n, &sort_crit);
|
||||||
|
|||||||
@@ -74,6 +74,10 @@ cmd_list_clients_exec(struct cmd *self, struct cmdq_item *item)
|
|||||||
filter = args_get(args, 'f');
|
filter = args_get(args, 'f');
|
||||||
|
|
||||||
sort_crit.order = sort_order_from_string(args_get(args, 'O'));
|
sort_crit.order = sort_order_from_string(args_get(args, 'O'));
|
||||||
|
if (sort_crit.order == SORT_END && args_has(args, 'O')) {
|
||||||
|
cmdq_error(item, "invalid sort order");
|
||||||
|
return (CMD_RETURN_ERROR);
|
||||||
|
}
|
||||||
sort_crit.reversed = args_has(args, 'r');
|
sort_crit.reversed = args_has(args, 'r');
|
||||||
|
|
||||||
l = sort_get_clients(&n, &sort_crit);
|
l = sort_get_clients(&n, &sort_crit);
|
||||||
|
|||||||
107
cmd-list-commands.c
Normal file
107
cmd-list-commands.c
Normal file
@@ -0,0 +1,107 @@
|
|||||||
|
/* $OpenBSD$ */
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Copyright (c) 2007 Nicholas Marriott <nicholas.marriott@gmail.com>
|
||||||
|
*
|
||||||
|
* Permission to use, copy, modify, and distribute this software for any
|
||||||
|
* purpose with or without fee is hereby granted, provided that the above
|
||||||
|
* copyright notice and this permission notice appear in all copies.
|
||||||
|
*
|
||||||
|
* THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
|
||||||
|
* WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
|
||||||
|
* MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
|
||||||
|
* ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
|
||||||
|
* WHATSOEVER RESULTING FROM LOSS OF MIND, USE, DATA OR PROFITS, WHETHER
|
||||||
|
* IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING
|
||||||
|
* OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include <sys/types.h>
|
||||||
|
|
||||||
|
#include <stdlib.h>
|
||||||
|
#include <string.h>
|
||||||
|
|
||||||
|
#include "tmux.h"
|
||||||
|
|
||||||
|
/*
|
||||||
|
* List all commands.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#define LIST_COMMANDS_TEMPLATE \
|
||||||
|
"#{command_list_name}" \
|
||||||
|
"#{?command_list_alias, (#{command_list_alias}),} " \
|
||||||
|
"#{command_list_usage}"
|
||||||
|
|
||||||
|
static enum cmd_retval cmd_list_commands(struct cmd *, struct cmdq_item *);
|
||||||
|
|
||||||
|
const struct cmd_entry cmd_list_commands_entry = {
|
||||||
|
.name = "list-commands",
|
||||||
|
.alias = "lscm",
|
||||||
|
|
||||||
|
.args = { "F:", 0, 1, NULL },
|
||||||
|
.usage = "[-F format] [command]",
|
||||||
|
|
||||||
|
.flags = CMD_STARTSERVER|CMD_AFTERHOOK,
|
||||||
|
.exec = cmd_list_commands
|
||||||
|
};
|
||||||
|
|
||||||
|
static void
|
||||||
|
cmd_list_single_command(const struct cmd_entry *entry, struct format_tree *ft,
|
||||||
|
const char *template, struct cmdq_item *item)
|
||||||
|
{
|
||||||
|
const char *s;
|
||||||
|
char *line;
|
||||||
|
|
||||||
|
format_add(ft, "command_list_name", "%s", entry->name);
|
||||||
|
if (entry->alias != NULL)
|
||||||
|
s = entry->alias;
|
||||||
|
else
|
||||||
|
s = "";
|
||||||
|
format_add(ft, "command_list_alias", "%s", s);
|
||||||
|
if (entry->usage != NULL)
|
||||||
|
s = entry->usage;
|
||||||
|
else
|
||||||
|
s = "";
|
||||||
|
format_add(ft, "command_list_usage", "%s", s);
|
||||||
|
|
||||||
|
line = format_expand(ft, template);
|
||||||
|
if (*line != '\0')
|
||||||
|
cmdq_print(item, "%s", line);
|
||||||
|
free(line);
|
||||||
|
}
|
||||||
|
|
||||||
|
static enum cmd_retval
|
||||||
|
cmd_list_commands(struct cmd *self, struct cmdq_item *item)
|
||||||
|
{
|
||||||
|
struct args *args = cmd_get_args(self);
|
||||||
|
const struct cmd_entry **entryp;
|
||||||
|
const struct cmd_entry *entry;
|
||||||
|
struct format_tree *ft;
|
||||||
|
const char *template, *command;
|
||||||
|
char *cause;
|
||||||
|
|
||||||
|
if ((template = args_get(args, 'F')) == NULL)
|
||||||
|
template = LIST_COMMANDS_TEMPLATE;
|
||||||
|
|
||||||
|
ft = format_create(cmdq_get_client(item), item, FORMAT_NONE, 0);
|
||||||
|
format_defaults(ft, NULL, NULL, NULL, NULL);
|
||||||
|
|
||||||
|
command = args_string(args, 0);
|
||||||
|
if (command == NULL) {
|
||||||
|
for (entryp = cmd_table; *entryp != NULL; entryp++)
|
||||||
|
cmd_list_single_command(*entryp, ft, template, item);
|
||||||
|
} else {
|
||||||
|
entry = cmd_find(command, &cause);
|
||||||
|
if (entry != NULL)
|
||||||
|
cmd_list_single_command(entry, ft, template, item);
|
||||||
|
else {
|
||||||
|
cmdq_error(item, "%s", cause);
|
||||||
|
free(cause);
|
||||||
|
format_free(ft);
|
||||||
|
return (CMD_RETURN_ERROR);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
format_free(ft);
|
||||||
|
return (CMD_RETURN_NORMAL);
|
||||||
|
}
|
||||||
465
cmd-list-keys.c
465
cmd-list-keys.c
@@ -27,122 +27,140 @@
|
|||||||
* List key bindings.
|
* List key bindings.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
static enum cmd_retval cmd_list_keys_exec(struct cmd *, struct cmdq_item *);
|
#define LIST_KEYS_TEMPLATE \
|
||||||
|
"#{?notes_only," \
|
||||||
|
"#{key_prefix} " \
|
||||||
|
"#{p|#{key_string_width}:key_string} " \
|
||||||
|
"#{?key_note,#{key_note},#{key_command}}" \
|
||||||
|
"," \
|
||||||
|
"bind-key #{?key_has_repeat,#{?key_repeat,-r, },} " \
|
||||||
|
"-T #{p|#{key_table_width}:key_table} " \
|
||||||
|
"#{p|#{key_string_width}:key_string} " \
|
||||||
|
"#{key_command}}"
|
||||||
|
|
||||||
static enum cmd_retval cmd_list_keys_commands(struct cmd *,
|
static enum cmd_retval cmd_list_keys_exec(struct cmd *, struct cmdq_item *);
|
||||||
struct cmdq_item *);
|
|
||||||
|
|
||||||
const struct cmd_entry cmd_list_keys_entry = {
|
const struct cmd_entry cmd_list_keys_entry = {
|
||||||
.name = "list-keys",
|
.name = "list-keys",
|
||||||
.alias = "lsk",
|
.alias = "lsk",
|
||||||
|
|
||||||
.args = { "1aNP:T:", 0, 1, NULL },
|
.args = { "1aF:NO:P:rT:", 0, 1, NULL },
|
||||||
.usage = "[-1aN] [-P prefix-string] [-T key-table] [key]",
|
.usage = "[-1aNr] [-F format] [-O order] [-P prefix-string]"
|
||||||
|
"[-T key-table] [key]",
|
||||||
|
|
||||||
.flags = CMD_STARTSERVER|CMD_AFTERHOOK,
|
.flags = CMD_STARTSERVER|CMD_AFTERHOOK,
|
||||||
.exec = cmd_list_keys_exec
|
.exec = cmd_list_keys_exec
|
||||||
};
|
};
|
||||||
|
|
||||||
const struct cmd_entry cmd_list_commands_entry = {
|
static char *
|
||||||
.name = "list-commands",
|
cmd_list_keys_get_prefix(struct args *args)
|
||||||
.alias = "lscm",
|
{
|
||||||
|
key_code prefix;
|
||||||
|
|
||||||
.args = { "F:", 0, 1, NULL },
|
if (args_has(args, 'P'))
|
||||||
.usage = "[-F format] [command]",
|
return (xstrdup(args_get(args, 'P')));
|
||||||
|
|
||||||
.flags = CMD_STARTSERVER|CMD_AFTERHOOK,
|
prefix = options_get_number(global_s_options, "prefix");
|
||||||
.exec = cmd_list_keys_exec
|
if (prefix == KEYC_NONE)
|
||||||
};
|
return (xstrdup(""));
|
||||||
|
return (xstrdup(key_string_lookup_key(prefix, 0)));
|
||||||
|
}
|
||||||
|
|
||||||
static u_int
|
static u_int
|
||||||
cmd_list_keys_get_width(const char *tablename, key_code only)
|
cmd_list_keys_get_width(struct key_binding **l, u_int n)
|
||||||
{
|
{
|
||||||
struct key_table *table;
|
u_int i, width, keywidth = 0;
|
||||||
struct key_binding *bd;
|
|
||||||
u_int width, keywidth = 0;
|
|
||||||
|
|
||||||
table = key_bindings_get_table(tablename, 0);
|
for (i = 0; i < n; i++) {
|
||||||
if (table == NULL)
|
width = utf8_cstrwidth(key_string_lookup_key(l[i]->key, 0));
|
||||||
return (0);
|
|
||||||
bd = key_bindings_first(table);
|
|
||||||
while (bd != NULL) {
|
|
||||||
if ((only != KEYC_UNKNOWN && bd->key != only) ||
|
|
||||||
KEYC_IS_MOUSE(bd->key) ||
|
|
||||||
bd->note == NULL ||
|
|
||||||
*bd->note == '\0') {
|
|
||||||
bd = key_bindings_next(table, bd);
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
width = utf8_cstrwidth(key_string_lookup_key(bd->key, 0));
|
|
||||||
if (width > keywidth)
|
if (width > keywidth)
|
||||||
keywidth = width;
|
keywidth = width;
|
||||||
|
|
||||||
bd = key_bindings_next(table, bd);
|
|
||||||
}
|
}
|
||||||
return (keywidth);
|
return (keywidth);
|
||||||
}
|
}
|
||||||
|
|
||||||
static int
|
static u_int
|
||||||
cmd_list_keys_print_notes(struct cmdq_item *item, struct args *args,
|
cmd_list_keys_get_table_width(struct key_binding **l, u_int n)
|
||||||
const char *tablename, u_int keywidth, key_code only, const char *prefix)
|
|
||||||
{
|
{
|
||||||
struct client *tc = cmdq_get_target_client(item);
|
u_int i, width, tablewidth = 0;
|
||||||
struct key_table *table;
|
|
||||||
struct key_binding *bd;
|
|
||||||
const char *key;
|
|
||||||
char *tmp, *note;
|
|
||||||
int found = 0;
|
|
||||||
|
|
||||||
table = key_bindings_get_table(tablename, 0);
|
for (i = 0; i < n; i++) {
|
||||||
if (table == NULL)
|
width = utf8_cstrwidth(l[i]->tablename);
|
||||||
return (0);
|
if (width > tablewidth)
|
||||||
bd = key_bindings_first(table);
|
tablewidth = width;
|
||||||
while (bd != NULL) {
|
|
||||||
if ((only != KEYC_UNKNOWN && bd->key != only) ||
|
|
||||||
KEYC_IS_MOUSE(bd->key) ||
|
|
||||||
((bd->note == NULL || *bd->note == '\0') &&
|
|
||||||
!args_has(args, 'a'))) {
|
|
||||||
bd = key_bindings_next(table, bd);
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
found = 1;
|
|
||||||
key = key_string_lookup_key(bd->key, 0);
|
|
||||||
|
|
||||||
if (bd->note == NULL || *bd->note == '\0')
|
|
||||||
note = cmd_list_print(bd->cmdlist,
|
|
||||||
CMD_LIST_PRINT_ESCAPED|CMD_LIST_PRINT_NO_GROUPS);
|
|
||||||
else
|
|
||||||
note = xstrdup(bd->note);
|
|
||||||
tmp = utf8_padcstr(key, keywidth + 1);
|
|
||||||
if (args_has(args, '1') && tc != NULL) {
|
|
||||||
status_message_set(tc, -1, 1, 0, 0, "%s%s%s", prefix,
|
|
||||||
tmp, note);
|
|
||||||
} else
|
|
||||||
cmdq_print(item, "%s%s%s", prefix, tmp, note);
|
|
||||||
free(tmp);
|
|
||||||
free(note);
|
|
||||||
|
|
||||||
if (args_has(args, '1'))
|
|
||||||
break;
|
|
||||||
bd = key_bindings_next(table, bd);
|
|
||||||
}
|
}
|
||||||
return (found);
|
return (tablewidth);
|
||||||
}
|
}
|
||||||
|
|
||||||
static char *
|
static struct key_binding **
|
||||||
cmd_list_keys_get_prefix(struct args *args, key_code *prefix)
|
cmd_get_root_and_prefix(u_int *n, struct sort_criteria *sort_crit)
|
||||||
{
|
{
|
||||||
char *s;
|
const char *tables[] = { "prefix", "root" };
|
||||||
|
struct key_table *t;
|
||||||
|
struct key_binding **lt;
|
||||||
|
u_int i, ltsz, len = 0, offset = 0;
|
||||||
|
static struct key_binding **l = NULL;
|
||||||
|
static u_int lsz = 0;
|
||||||
|
|
||||||
*prefix = options_get_number(global_s_options, "prefix");
|
for (i = 0; i < nitems(tables); i++) {
|
||||||
if (!args_has(args, 'P')) {
|
t = key_bindings_get_table(tables[i], 0);
|
||||||
if (*prefix != KEYC_NONE)
|
lt = sort_get_key_bindings_table(t, <sz, sort_crit);
|
||||||
xasprintf(&s, "%s ", key_string_lookup_key(*prefix, 0));
|
len += ltsz;
|
||||||
else
|
if (lsz <= len) {
|
||||||
s = xstrdup("");
|
lsz = len + 100;
|
||||||
} else
|
l = xreallocarray(l, lsz, sizeof *l);
|
||||||
s = xstrdup(args_get(args, 'P'));
|
}
|
||||||
return (s);
|
memcpy(l + offset, lt, ltsz * sizeof *l);
|
||||||
|
offset += ltsz;
|
||||||
|
}
|
||||||
|
|
||||||
|
*n = len;
|
||||||
|
return (l);
|
||||||
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
cmd_filter_key_list(int filter_notes, int filter_key, key_code only,
|
||||||
|
struct key_binding **l, u_int *n)
|
||||||
|
{
|
||||||
|
key_code key;
|
||||||
|
u_int i, j = 0;
|
||||||
|
|
||||||
|
for (i = 0; i < *n; i++) {
|
||||||
|
key = l[i]->key & (KEYC_MASK_KEY|KEYC_MASK_MODIFIERS);
|
||||||
|
if (filter_key && only != key)
|
||||||
|
continue;
|
||||||
|
if (filter_notes && l[i]->note == NULL)
|
||||||
|
continue;
|
||||||
|
l[j++] = l[i];
|
||||||
|
}
|
||||||
|
*n = j;
|
||||||
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
cmd_format_add_key_binding(struct format_tree *ft,
|
||||||
|
const struct key_binding *bd, const char *prefix)
|
||||||
|
{
|
||||||
|
const char *s;
|
||||||
|
|
||||||
|
if (bd->flags & KEY_BINDING_REPEAT)
|
||||||
|
format_add(ft, "key_repeat", "1");
|
||||||
|
else
|
||||||
|
format_add(ft, "key_repeat", "0");
|
||||||
|
|
||||||
|
if (bd->note != NULL)
|
||||||
|
format_add(ft, "key_note", "%s", bd->note);
|
||||||
|
else
|
||||||
|
format_add(ft, "key_note", "%s", "");
|
||||||
|
|
||||||
|
format_add(ft, "key_prefix", "%s", prefix);
|
||||||
|
format_add(ft, "key_table", "%s", bd->tablename);
|
||||||
|
|
||||||
|
s = key_string_lookup_key(bd->key, 0);
|
||||||
|
format_add(ft, "key_string", "%s", s);
|
||||||
|
|
||||||
|
s = cmd_list_print(bd->cmdlist,
|
||||||
|
CMD_LIST_PRINT_ESCAPED|CMD_LIST_PRINT_NO_GROUPS);
|
||||||
|
format_add(ft, "key_command", "%s", s);
|
||||||
}
|
}
|
||||||
|
|
||||||
static enum cmd_retval
|
static enum cmd_retval
|
||||||
@@ -150,16 +168,16 @@ cmd_list_keys_exec(struct cmd *self, struct cmdq_item *item)
|
|||||||
{
|
{
|
||||||
struct args *args = cmd_get_args(self);
|
struct args *args = cmd_get_args(self);
|
||||||
struct client *tc = cmdq_get_target_client(item);
|
struct client *tc = cmdq_get_target_client(item);
|
||||||
struct key_table *table;
|
struct format_tree *ft;
|
||||||
struct key_binding *bd;
|
struct key_table *table = NULL;
|
||||||
const char *tablename, *r, *keystr;
|
struct key_binding **l;
|
||||||
char *key, *cp, *tmp, *start, *empty;
|
key_code only = KEYC_UNKNOWN;
|
||||||
key_code prefix, only = KEYC_UNKNOWN;
|
const char *template, *tablename, *keystr;
|
||||||
int repeat, width, tablewidth, keywidth, found = 0;
|
char *line;
|
||||||
size_t tmpsize, tmpused, cplen;
|
char *prefix = NULL;
|
||||||
|
u_int i, n;
|
||||||
if (cmd_get_entry(self) == &cmd_list_commands_entry)
|
int single, notes_only, filter_notes, filter_key;
|
||||||
return (cmd_list_keys_commands(self, item));
|
struct sort_criteria sort_crit;
|
||||||
|
|
||||||
if ((keystr = args_string(args, 0)) != NULL) {
|
if ((keystr = args_string(args, 0)) != NULL) {
|
||||||
only = key_string_lookup_string(keystr);
|
only = key_string_lookup_string(keystr);
|
||||||
@@ -170,219 +188,64 @@ cmd_list_keys_exec(struct cmd *self, struct cmdq_item *item)
|
|||||||
only &= (KEYC_MASK_KEY|KEYC_MASK_MODIFIERS);
|
only &= (KEYC_MASK_KEY|KEYC_MASK_MODIFIERS);
|
||||||
}
|
}
|
||||||
|
|
||||||
tablename = args_get(args, 'T');
|
sort_crit.order = sort_order_from_string(args_get(args, 'O'));
|
||||||
if (tablename != NULL && key_bindings_get_table(tablename, 0) == NULL) {
|
if (sort_crit.order == SORT_END && args_has(args, 'O')) {
|
||||||
cmdq_error(item, "table %s doesn't exist", tablename);
|
cmdq_error(item, "invalid sort order");
|
||||||
return (CMD_RETURN_ERROR);
|
return (CMD_RETURN_ERROR);
|
||||||
}
|
}
|
||||||
|
sort_crit.reversed = args_has(args, 'r');
|
||||||
|
|
||||||
if (args_has(args, 'N')) {
|
prefix = cmd_list_keys_get_prefix(args);
|
||||||
if (tablename == NULL) {
|
single = args_has(args, '1');
|
||||||
start = cmd_list_keys_get_prefix(args, &prefix);
|
notes_only = args_has(args, 'N');
|
||||||
keywidth = cmd_list_keys_get_width("root", only);
|
|
||||||
if (prefix != KEYC_NONE) {
|
|
||||||
width = cmd_list_keys_get_width("prefix", only);
|
|
||||||
if (width == 0)
|
|
||||||
prefix = KEYC_NONE;
|
|
||||||
else if (width > keywidth)
|
|
||||||
keywidth = width;
|
|
||||||
}
|
|
||||||
empty = utf8_padcstr("", utf8_cstrwidth(start));
|
|
||||||
|
|
||||||
found = cmd_list_keys_print_notes(item, args, "root",
|
if ((tablename = args_get(args, 'T')) != NULL) {
|
||||||
keywidth, only, empty);
|
table = key_bindings_get_table(tablename, 0);
|
||||||
if (prefix != KEYC_NONE) {
|
if (table == NULL) {
|
||||||
if (cmd_list_keys_print_notes(item, args,
|
cmdq_error(item, "table %s doesn't exist", tablename);
|
||||||
"prefix", keywidth, only, start))
|
|
||||||
found = 1;
|
|
||||||
}
|
|
||||||
free(empty);
|
|
||||||
} else {
|
|
||||||
if (args_has(args, 'P'))
|
|
||||||
start = xstrdup(args_get(args, 'P'));
|
|
||||||
else
|
|
||||||
start = xstrdup("");
|
|
||||||
keywidth = cmd_list_keys_get_width(tablename, only);
|
|
||||||
found = cmd_list_keys_print_notes(item, args, tablename,
|
|
||||||
keywidth, only, start);
|
|
||||||
|
|
||||||
}
|
|
||||||
free(start);
|
|
||||||
goto out;
|
|
||||||
}
|
|
||||||
|
|
||||||
repeat = 0;
|
|
||||||
tablewidth = keywidth = 0;
|
|
||||||
table = key_bindings_first_table();
|
|
||||||
while (table != NULL) {
|
|
||||||
if (tablename != NULL && strcmp(table->name, tablename) != 0) {
|
|
||||||
table = key_bindings_next_table(table);
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
bd = key_bindings_first(table);
|
|
||||||
while (bd != NULL) {
|
|
||||||
if (only != KEYC_UNKNOWN && bd->key != only) {
|
|
||||||
bd = key_bindings_next(table, bd);
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
key = args_escape(key_string_lookup_key(bd->key, 0));
|
|
||||||
|
|
||||||
if (bd->flags & KEY_BINDING_REPEAT)
|
|
||||||
repeat = 1;
|
|
||||||
|
|
||||||
width = utf8_cstrwidth(table->name);
|
|
||||||
if (width > tablewidth)
|
|
||||||
tablewidth = width;
|
|
||||||
width = utf8_cstrwidth(key);
|
|
||||||
if (width > keywidth)
|
|
||||||
keywidth = width;
|
|
||||||
|
|
||||||
free(key);
|
|
||||||
bd = key_bindings_next(table, bd);
|
|
||||||
}
|
|
||||||
table = key_bindings_next_table(table);
|
|
||||||
}
|
|
||||||
|
|
||||||
tmpsize = 256;
|
|
||||||
tmp = xmalloc(tmpsize);
|
|
||||||
|
|
||||||
table = key_bindings_first_table();
|
|
||||||
while (table != NULL) {
|
|
||||||
if (tablename != NULL && strcmp(table->name, tablename) != 0) {
|
|
||||||
table = key_bindings_next_table(table);
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
bd = key_bindings_first(table);
|
|
||||||
while (bd != NULL) {
|
|
||||||
if (only != KEYC_UNKNOWN && bd->key != only) {
|
|
||||||
bd = key_bindings_next(table, bd);
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
found = 1;
|
|
||||||
key = args_escape(key_string_lookup_key(bd->key, 0));
|
|
||||||
|
|
||||||
if (!repeat)
|
|
||||||
r = "";
|
|
||||||
else if (bd->flags & KEY_BINDING_REPEAT)
|
|
||||||
r = "-r ";
|
|
||||||
else
|
|
||||||
r = " ";
|
|
||||||
tmpused = xsnprintf(tmp, tmpsize, "%s-T ", r);
|
|
||||||
|
|
||||||
cp = utf8_padcstr(table->name, tablewidth);
|
|
||||||
cplen = strlen(cp) + 1;
|
|
||||||
while (tmpused + cplen + 1 >= tmpsize) {
|
|
||||||
tmpsize *= 2;
|
|
||||||
tmp = xrealloc(tmp, tmpsize);
|
|
||||||
}
|
|
||||||
strlcat(tmp, cp, tmpsize);
|
|
||||||
tmpused = strlcat(tmp, " ", tmpsize);
|
|
||||||
free(cp);
|
|
||||||
|
|
||||||
cp = utf8_padcstr(key, keywidth);
|
|
||||||
cplen = strlen(cp) + 1;
|
|
||||||
while (tmpused + cplen + 1 >= tmpsize) {
|
|
||||||
tmpsize *= 2;
|
|
||||||
tmp = xrealloc(tmp, tmpsize);
|
|
||||||
}
|
|
||||||
strlcat(tmp, cp, tmpsize);
|
|
||||||
tmpused = strlcat(tmp, " ", tmpsize);
|
|
||||||
free(cp);
|
|
||||||
|
|
||||||
cp = cmd_list_print(bd->cmdlist,
|
|
||||||
CMD_LIST_PRINT_ESCAPED|CMD_LIST_PRINT_NO_GROUPS);
|
|
||||||
cplen = strlen(cp);
|
|
||||||
while (tmpused + cplen + 1 >= tmpsize) {
|
|
||||||
tmpsize *= 2;
|
|
||||||
tmp = xrealloc(tmp, tmpsize);
|
|
||||||
}
|
|
||||||
strlcat(tmp, cp, tmpsize);
|
|
||||||
free(cp);
|
|
||||||
|
|
||||||
if (args_has(args, '1') && tc != NULL) {
|
|
||||||
status_message_set(tc, -1, 1, 0, 0,
|
|
||||||
"bind-key %s", tmp);
|
|
||||||
} else
|
|
||||||
cmdq_print(item, "bind-key %s", tmp);
|
|
||||||
free(key);
|
|
||||||
|
|
||||||
if (args_has(args, '1'))
|
|
||||||
break;
|
|
||||||
bd = key_bindings_next(table, bd);
|
|
||||||
}
|
|
||||||
table = key_bindings_next_table(table);
|
|
||||||
}
|
|
||||||
|
|
||||||
free(tmp);
|
|
||||||
|
|
||||||
out:
|
|
||||||
if (only != KEYC_UNKNOWN && !found) {
|
|
||||||
cmdq_error(item, "unknown key: %s", args_string(args, 0));
|
|
||||||
return (CMD_RETURN_ERROR);
|
|
||||||
}
|
|
||||||
return (CMD_RETURN_NORMAL);
|
|
||||||
}
|
|
||||||
|
|
||||||
static void
|
|
||||||
cmd_list_single_command(const struct cmd_entry *entry, struct format_tree *ft,
|
|
||||||
const char *template, struct cmdq_item *item)
|
|
||||||
{
|
|
||||||
const char *s;
|
|
||||||
char *line;
|
|
||||||
|
|
||||||
format_add(ft, "command_list_name", "%s", entry->name);
|
|
||||||
if (entry->alias != NULL)
|
|
||||||
s = entry->alias;
|
|
||||||
else
|
|
||||||
s = "";
|
|
||||||
format_add(ft, "command_list_alias", "%s", s);
|
|
||||||
if (entry->usage != NULL)
|
|
||||||
s = entry->usage;
|
|
||||||
else
|
|
||||||
s = "";
|
|
||||||
format_add(ft, "command_list_usage", "%s", s);
|
|
||||||
|
|
||||||
line = format_expand(ft, template);
|
|
||||||
if (*line != '\0')
|
|
||||||
cmdq_print(item, "%s", line);
|
|
||||||
free(line);
|
|
||||||
}
|
|
||||||
|
|
||||||
static enum cmd_retval
|
|
||||||
cmd_list_keys_commands(struct cmd *self, struct cmdq_item *item)
|
|
||||||
{
|
|
||||||
struct args *args = cmd_get_args(self);
|
|
||||||
const struct cmd_entry **entryp;
|
|
||||||
const struct cmd_entry *entry;
|
|
||||||
struct format_tree *ft;
|
|
||||||
const char *template, *command;
|
|
||||||
char *cause;
|
|
||||||
|
|
||||||
if ((template = args_get(args, 'F')) == NULL) {
|
|
||||||
template = "#{command_list_name}"
|
|
||||||
"#{?command_list_alias, (#{command_list_alias}),} "
|
|
||||||
"#{command_list_usage}";
|
|
||||||
}
|
|
||||||
|
|
||||||
ft = format_create(cmdq_get_client(item), item, FORMAT_NONE, 0);
|
|
||||||
format_defaults(ft, NULL, NULL, NULL, NULL);
|
|
||||||
|
|
||||||
command = args_string(args, 0);
|
|
||||||
if (command == NULL) {
|
|
||||||
for (entryp = cmd_table; *entryp != NULL; entryp++)
|
|
||||||
cmd_list_single_command(*entryp, ft, template, item);
|
|
||||||
} else {
|
|
||||||
entry = cmd_find(command, &cause);
|
|
||||||
if (entry != NULL)
|
|
||||||
cmd_list_single_command(entry, ft, template, item);
|
|
||||||
else {
|
|
||||||
cmdq_error(item, "%s", cause);
|
|
||||||
free(cause);
|
|
||||||
format_free(ft);
|
|
||||||
return (CMD_RETURN_ERROR);
|
return (CMD_RETURN_ERROR);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if ((template = args_get(args, 'F')) == NULL)
|
||||||
|
template = LIST_KEYS_TEMPLATE;
|
||||||
|
|
||||||
|
if (table)
|
||||||
|
l = sort_get_key_bindings_table(table, &n, &sort_crit);
|
||||||
|
else if (notes_only)
|
||||||
|
l = cmd_get_root_and_prefix(&n, &sort_crit);
|
||||||
|
else
|
||||||
|
l = sort_get_key_bindings(&n, &sort_crit);
|
||||||
|
|
||||||
|
filter_notes = notes_only && !args_has(args, 'a');
|
||||||
|
filter_key = only != KEYC_UNKNOWN;
|
||||||
|
if (filter_notes || filter_key)
|
||||||
|
cmd_filter_key_list(filter_notes, filter_key, only, l, &n);
|
||||||
|
if (single)
|
||||||
|
n = 1;
|
||||||
|
|
||||||
|
ft = format_create(cmdq_get_client(item), item, FORMAT_NONE, 0);
|
||||||
|
format_defaults(ft, NULL, NULL, NULL, NULL);
|
||||||
|
format_add(ft, "notes_only", "%d", notes_only);
|
||||||
|
format_add(ft, "key_has_repeat", "%d", key_bindings_has_repeat(l, n));
|
||||||
|
format_add(ft, "key_string_width", "%u", cmd_list_keys_get_width(l, n));
|
||||||
|
format_add(ft, "key_table_width", "%u",
|
||||||
|
cmd_list_keys_get_table_width(l, n));
|
||||||
|
for (i = 0; i < n; i++) {
|
||||||
|
cmd_format_add_key_binding(ft, l[i], prefix);
|
||||||
|
|
||||||
|
line = format_expand(ft, template);
|
||||||
|
if ((single && tc != NULL) || n == 1)
|
||||||
|
status_message_set(tc, -1, 1, 0, 0, "%s", line);
|
||||||
|
else if (*line != '\0')
|
||||||
|
cmdq_print(item, "%s", line);
|
||||||
|
free(line);
|
||||||
|
|
||||||
|
if (single)
|
||||||
|
break;
|
||||||
|
}
|
||||||
format_free(ft);
|
format_free(ft);
|
||||||
|
free(prefix);
|
||||||
|
|
||||||
return (CMD_RETURN_NORMAL);
|
return (CMD_RETURN_NORMAL);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -55,6 +55,13 @@ cmd_list_panes_exec(struct cmd *self, struct cmdq_item *item)
|
|||||||
struct cmd_find_state *target = cmdq_get_target(item);
|
struct cmd_find_state *target = cmdq_get_target(item);
|
||||||
struct session *s = target->s;
|
struct session *s = target->s;
|
||||||
struct winlink *wl = target->wl;
|
struct winlink *wl = target->wl;
|
||||||
|
enum sort_order order;
|
||||||
|
|
||||||
|
order = sort_order_from_string(args_get(args, 'O'));
|
||||||
|
if (order == SORT_END && args_has(args, 'O')) {
|
||||||
|
cmdq_error(item, "invalid sort order");
|
||||||
|
return (CMD_RETURN_ERROR);
|
||||||
|
}
|
||||||
|
|
||||||
if (args_has(args, 'a'))
|
if (args_has(args, 'a'))
|
||||||
cmd_list_panes_server(self, item);
|
cmd_list_panes_server(self, item);
|
||||||
|
|||||||
@@ -66,6 +66,10 @@ cmd_list_sessions_exec(struct cmd *self, struct cmdq_item *item)
|
|||||||
filter = args_get(args, 'f');
|
filter = args_get(args, 'f');
|
||||||
|
|
||||||
sort_crit.order = sort_order_from_string(args_get(args, 'O'));
|
sort_crit.order = sort_order_from_string(args_get(args, 'O'));
|
||||||
|
if (sort_crit.order == SORT_END && args_has(args, 'O')) {
|
||||||
|
cmdq_error(item, "invalid sort order");
|
||||||
|
return (CMD_RETURN_ERROR);
|
||||||
|
}
|
||||||
sort_crit.reversed = args_has(args, 'r');
|
sort_crit.reversed = args_has(args, 'r');
|
||||||
|
|
||||||
l = sort_get_sessions(&n, &sort_crit);
|
l = sort_get_sessions(&n, &sort_crit);
|
||||||
|
|||||||
@@ -73,6 +73,10 @@ cmd_list_windows_exec(struct cmd *self, struct cmdq_item *item)
|
|||||||
filter = args_get(args, 'f');
|
filter = args_get(args, 'f');
|
||||||
|
|
||||||
sort_crit.order = sort_order_from_string(args_get(args, 'O'));
|
sort_crit.order = sort_order_from_string(args_get(args, 'O'));
|
||||||
|
if (sort_crit.order == SORT_END && args_has(args, 'O')) {
|
||||||
|
cmdq_error(item, "invalid sort order");
|
||||||
|
return (CMD_RETURN_ERROR);
|
||||||
|
}
|
||||||
sort_crit.reversed = args_has(args, 'r');
|
sort_crit.reversed = args_has(args, 'r');
|
||||||
|
|
||||||
if (args_has(args, 'a')) {
|
if (args_has(args, 'a')) {
|
||||||
|
|||||||
@@ -117,8 +117,9 @@ cmd_new_session_exec(struct cmd *self, struct cmdq_item *item)
|
|||||||
as = target->s;
|
as = target->s;
|
||||||
if (as != NULL) {
|
if (as != NULL) {
|
||||||
retval = cmd_attach_session(item, as->name,
|
retval = cmd_attach_session(item, as->name,
|
||||||
args_has(args, 'D'), args_has(args, 'X'), 0, NULL,
|
args_has(args, 'D'), args_has(args, 'X'), 0,
|
||||||
args_has(args, 'E'), args_get(args, 'f'));
|
args_get(args, 'c'), args_has(args, 'E'),
|
||||||
|
args_get(args, 'f'));
|
||||||
free(newname);
|
free(newname);
|
||||||
return (retval);
|
return (retval);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -33,8 +33,8 @@ const struct cmd_entry cmd_paste_buffer_entry = {
|
|||||||
.name = "paste-buffer",
|
.name = "paste-buffer",
|
||||||
.alias = "pasteb",
|
.alias = "pasteb",
|
||||||
|
|
||||||
.args = { "db:prs:t:", 0, 0, NULL },
|
.args = { "db:prSs:t:", 0, 0, NULL },
|
||||||
.usage = "[-dpr] [-s separator] " CMD_BUFFER_USAGE " "
|
.usage = "[-dprS] [-s separator] " CMD_BUFFER_USAGE " "
|
||||||
CMD_TARGET_PANE_USAGE,
|
CMD_TARGET_PANE_USAGE,
|
||||||
|
|
||||||
.target = { 't', CMD_FIND_PANE, 0 },
|
.target = { 't', CMD_FIND_PANE, 0 },
|
||||||
@@ -43,6 +43,17 @@ const struct cmd_entry cmd_paste_buffer_entry = {
|
|||||||
.exec = cmd_paste_buffer_exec
|
.exec = cmd_paste_buffer_exec
|
||||||
};
|
};
|
||||||
|
|
||||||
|
static void
|
||||||
|
cmd_paste_buffer_paste(struct window_pane *wp, const char *buf, size_t len)
|
||||||
|
{
|
||||||
|
char *cp;
|
||||||
|
size_t n;
|
||||||
|
|
||||||
|
n = utf8_stravisx(&cp, buf, len, VIS_SAFE|VIS_NOSLASH);
|
||||||
|
bufferevent_write(wp->event, cp, n);
|
||||||
|
free(cp);
|
||||||
|
}
|
||||||
|
|
||||||
static enum cmd_retval
|
static enum cmd_retval
|
||||||
cmd_paste_buffer_exec(struct cmd *self, struct cmdq_item *item)
|
cmd_paste_buffer_exec(struct cmd *self, struct cmdq_item *item)
|
||||||
{
|
{
|
||||||
@@ -51,7 +62,7 @@ cmd_paste_buffer_exec(struct cmd *self, struct cmdq_item *item)
|
|||||||
struct window_pane *wp = target->wp;
|
struct window_pane *wp = target->wp;
|
||||||
struct paste_buffer *pb;
|
struct paste_buffer *pb;
|
||||||
const char *sepstr, *bufname, *bufdata, *bufend, *line;
|
const char *sepstr, *bufname, *bufdata, *bufend, *line;
|
||||||
size_t seplen, bufsize;
|
size_t seplen, bufsize, len;
|
||||||
int bracket = args_has(args, 'p');
|
int bracket = args_has(args, 'p');
|
||||||
|
|
||||||
if (window_pane_exited(wp)) {
|
if (window_pane_exited(wp)) {
|
||||||
@@ -93,14 +104,22 @@ cmd_paste_buffer_exec(struct cmd *self, struct cmdq_item *item)
|
|||||||
line = memchr(bufdata, '\n', bufend - bufdata);
|
line = memchr(bufdata, '\n', bufend - bufdata);
|
||||||
if (line == NULL)
|
if (line == NULL)
|
||||||
break;
|
break;
|
||||||
|
len = line - bufdata;
|
||||||
bufferevent_write(wp->event, bufdata, line - bufdata);
|
if (args_has(args, 'S'))
|
||||||
|
bufferevent_write(wp->event, bufdata, len);
|
||||||
|
else
|
||||||
|
cmd_paste_buffer_paste(wp, bufdata, len);
|
||||||
bufferevent_write(wp->event, sepstr, seplen);
|
bufferevent_write(wp->event, sepstr, seplen);
|
||||||
|
|
||||||
bufdata = line + 1;
|
bufdata = line + 1;
|
||||||
}
|
}
|
||||||
if (bufdata != bufend)
|
if (bufdata != bufend) {
|
||||||
bufferevent_write(wp->event, bufdata, bufend - bufdata);
|
len = bufend - bufdata;
|
||||||
|
if (args_has(args, 'S'))
|
||||||
|
bufferevent_write(wp->event, bufdata, len);
|
||||||
|
else
|
||||||
|
cmd_paste_buffer_paste(wp, bufdata, len);
|
||||||
|
}
|
||||||
|
|
||||||
if (bracket && (wp->screen->mode & MODE_BRACKETPASTE))
|
if (bracket && (wp->screen->mode & MODE_BRACKETPASTE))
|
||||||
bufferevent_write(wp->event, "\033[201~", 6);
|
bufferevent_write(wp->event, "\033[201~", 6);
|
||||||
|
|||||||
@@ -39,7 +39,8 @@ const struct cmd_entry cmd_send_keys_entry = {
|
|||||||
|
|
||||||
.target = { 't', CMD_FIND_PANE, 0 },
|
.target = { 't', CMD_FIND_PANE, 0 },
|
||||||
|
|
||||||
.flags = CMD_AFTERHOOK|CMD_CLIENT_CFLAG|CMD_CLIENT_CANFAIL,
|
.flags = CMD_AFTERHOOK|CMD_CLIENT_CFLAG|CMD_CLIENT_CANFAIL|
|
||||||
|
CMD_READONLY,
|
||||||
.exec = cmd_send_keys_exec
|
.exec = cmd_send_keys_exec
|
||||||
};
|
};
|
||||||
|
|
||||||
@@ -167,6 +168,11 @@ cmd_send_keys_exec(struct cmd *self, struct cmdq_item *item)
|
|||||||
u_int count = args_count(args);
|
u_int count = args_count(args);
|
||||||
char *cause = NULL;
|
char *cause = NULL;
|
||||||
|
|
||||||
|
if (tc != NULL && tc->flags & CLIENT_READONLY && !args_has(args, 'X')) {
|
||||||
|
cmdq_error(item, "client is read-only");
|
||||||
|
return (CMD_RETURN_ERROR);
|
||||||
|
}
|
||||||
|
|
||||||
if (args_has(args, 'N')) {
|
if (args_has(args, 'N')) {
|
||||||
np = args_strtonum_and_expand(args, 'N', 1, UINT_MAX, item,
|
np = args_strtonum_and_expand(args, 'N', 1, UINT_MAX, item,
|
||||||
&cause);
|
&cause);
|
||||||
|
|||||||
@@ -90,6 +90,7 @@ cmd_server_access_exec(struct cmd *self, struct cmdq_item *item)
|
|||||||
pw = getpwnam(name);
|
pw = getpwnam(name);
|
||||||
if (pw == NULL) {
|
if (pw == NULL) {
|
||||||
cmdq_error(item, "unknown user: %s", name);
|
cmdq_error(item, "unknown user: %s", name);
|
||||||
|
free(name);
|
||||||
return (CMD_RETURN_ERROR);
|
return (CMD_RETURN_ERROR);
|
||||||
}
|
}
|
||||||
free(name);
|
free(name);
|
||||||
|
|||||||
@@ -60,6 +60,9 @@ cmd_show_prompt_history_exec(struct cmd *self, struct cmdq_item *item)
|
|||||||
if (cmd_get_entry(self) == &cmd_clear_prompt_history_entry) {
|
if (cmd_get_entry(self) == &cmd_clear_prompt_history_entry) {
|
||||||
if (typestr == NULL) {
|
if (typestr == NULL) {
|
||||||
for (tidx = 0; tidx < PROMPT_NTYPES; tidx++) {
|
for (tidx = 0; tidx < PROMPT_NTYPES; tidx++) {
|
||||||
|
for (hidx = 0; hidx < status_prompt_hsize[tidx];
|
||||||
|
hidx++)
|
||||||
|
free(status_prompt_hlist[tidx][hidx]);
|
||||||
free(status_prompt_hlist[tidx]);
|
free(status_prompt_hlist[tidx]);
|
||||||
status_prompt_hlist[tidx] = NULL;
|
status_prompt_hlist[tidx] = NULL;
|
||||||
status_prompt_hsize[tidx] = 0;
|
status_prompt_hsize[tidx] = 0;
|
||||||
@@ -70,6 +73,8 @@ cmd_show_prompt_history_exec(struct cmd *self, struct cmdq_item *item)
|
|||||||
cmdq_error(item, "invalid type: %s", typestr);
|
cmdq_error(item, "invalid type: %s", typestr);
|
||||||
return (CMD_RETURN_ERROR);
|
return (CMD_RETURN_ERROR);
|
||||||
}
|
}
|
||||||
|
for (hidx = 0; hidx < status_prompt_hsize[type]; hidx++)
|
||||||
|
free(status_prompt_hlist[type][hidx]);
|
||||||
free(status_prompt_hlist[type]);
|
free(status_prompt_hlist[type]);
|
||||||
status_prompt_hlist[type] = NULL;
|
status_prompt_hlist[type] = NULL;
|
||||||
status_prompt_hsize[type] = 0;
|
status_prompt_hsize[type] = 0;
|
||||||
|
|||||||
@@ -97,6 +97,10 @@ cmd_switch_client_exec(struct cmd *self, struct cmdq_item *item)
|
|||||||
}
|
}
|
||||||
|
|
||||||
sort_crit.order = sort_order_from_string(args_get(args, 'O'));
|
sort_crit.order = sort_order_from_string(args_get(args, 'O'));
|
||||||
|
if (sort_crit.order == SORT_END && args_has(args, 'O')) {
|
||||||
|
cmdq_error(item, "invalid sort order");
|
||||||
|
return (CMD_RETURN_ERROR);
|
||||||
|
}
|
||||||
sort_crit.reversed = args_has(args, 'r');
|
sort_crit.reversed = args_has(args, 'r');
|
||||||
|
|
||||||
if (args_has(args, 'n')) {
|
if (args_has(args, 'n')) {
|
||||||
|
|||||||
2
compat.h
2
compat.h
@@ -388,7 +388,7 @@ int clock_gettime(int, struct timespec *);
|
|||||||
/* base64.c */
|
/* base64.c */
|
||||||
#undef b64_ntop
|
#undef b64_ntop
|
||||||
#undef b64_pton
|
#undef b64_pton
|
||||||
int b64_ntop(const char *, size_t, char *, size_t);
|
int b64_ntop(const u_char *, size_t, char *, size_t);
|
||||||
int b64_pton(const char *, u_char *, size_t);
|
int b64_pton(const char *, u_char *, size_t);
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
|||||||
@@ -1,4 +1,4 @@
|
|||||||
/* $OpenBSD: base64.c,v 1.8 2015/01/16 16:48:51 deraadt Exp $ */
|
/* $OpenBSD: base64.c,v 1.15 2021/10/25 14:41:09 jca Exp $ */
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Copyright (c) 1996 by Internet Software Consortium.
|
* Copyright (c) 1996 by Internet Software Consortium.
|
||||||
@@ -46,15 +46,15 @@
|
|||||||
#include <sys/socket.h>
|
#include <sys/socket.h>
|
||||||
#include <netinet/in.h>
|
#include <netinet/in.h>
|
||||||
#include <arpa/inet.h>
|
#include <arpa/inet.h>
|
||||||
#include <arpa/nameser.h>
|
|
||||||
|
|
||||||
#include <ctype.h>
|
#include <ctype.h>
|
||||||
#include <resolv.h>
|
#include <resolv.h>
|
||||||
#include <stdio.h>
|
|
||||||
|
|
||||||
#include <stdlib.h>
|
#include <stdlib.h>
|
||||||
#include <string.h>
|
#include <string.h>
|
||||||
|
|
||||||
|
#include "compat.h"
|
||||||
|
|
||||||
static const char Base64[] =
|
static const char Base64[] =
|
||||||
"ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/";
|
"ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/";
|
||||||
static const char Pad64 = '=';
|
static const char Pad64 = '=';
|
||||||
@@ -107,9 +107,9 @@ static const char Pad64 = '=';
|
|||||||
end of the data is performed using the '=' character.
|
end of the data is performed using the '=' character.
|
||||||
|
|
||||||
Since all base64 input is an integral number of octets, only the
|
Since all base64 input is an integral number of octets, only the
|
||||||
-------------------------------------------------
|
-------------------------------------------------
|
||||||
following cases can arise:
|
following cases can arise:
|
||||||
|
|
||||||
(1) the final quantum of encoding input is an integral
|
(1) the final quantum of encoding input is an integral
|
||||||
multiple of 24 bits; here, the final unit of encoded
|
multiple of 24 bits; here, the final unit of encoded
|
||||||
output will be an integral multiple of 4 characters
|
output will be an integral multiple of 4 characters
|
||||||
@@ -123,15 +123,12 @@ static const char Pad64 = '=';
|
|||||||
*/
|
*/
|
||||||
|
|
||||||
int
|
int
|
||||||
b64_ntop(src, srclength, target, targsize)
|
b64_ntop(unsigned char const *src, size_t srclength, char *target,
|
||||||
u_char const *src;
|
size_t targsize)
|
||||||
size_t srclength;
|
|
||||||
char *target;
|
|
||||||
size_t targsize;
|
|
||||||
{
|
{
|
||||||
size_t datalength = 0;
|
size_t datalength = 0;
|
||||||
u_char input[3];
|
unsigned char input[3];
|
||||||
u_char output[4];
|
unsigned char output[4];
|
||||||
int i;
|
int i;
|
||||||
|
|
||||||
while (2 < srclength) {
|
while (2 < srclength) {
|
||||||
@@ -152,14 +149,14 @@ b64_ntop(src, srclength, target, targsize)
|
|||||||
target[datalength++] = Base64[output[2]];
|
target[datalength++] = Base64[output[2]];
|
||||||
target[datalength++] = Base64[output[3]];
|
target[datalength++] = Base64[output[3]];
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Now we worry about padding. */
|
/* Now we worry about padding. */
|
||||||
if (0 != srclength) {
|
if (0 != srclength) {
|
||||||
/* Get what's left. */
|
/* Get what's left. */
|
||||||
input[0] = input[1] = input[2] = '\0';
|
input[0] = input[1] = input[2] = '\0';
|
||||||
for (i = 0; i < srclength; i++)
|
for (i = 0; i < srclength; i++)
|
||||||
input[i] = *src++;
|
input[i] = *src++;
|
||||||
|
|
||||||
output[0] = input[0] >> 2;
|
output[0] = input[0] >> 2;
|
||||||
output[1] = ((input[0] & 0x03) << 4) + (input[1] >> 4);
|
output[1] = ((input[0] & 0x03) << 4) + (input[1] >> 4);
|
||||||
output[2] = ((input[1] & 0x0f) << 2) + (input[2] >> 6);
|
output[2] = ((input[1] & 0x0f) << 2) + (input[2] >> 6);
|
||||||
@@ -187,13 +184,10 @@ b64_ntop(src, srclength, target, targsize)
|
|||||||
*/
|
*/
|
||||||
|
|
||||||
int
|
int
|
||||||
b64_pton(src, target, targsize)
|
b64_pton(char const *src, unsigned char *target, size_t targsize)
|
||||||
char const *src;
|
|
||||||
u_char *target;
|
|
||||||
size_t targsize;
|
|
||||||
{
|
{
|
||||||
int tarindex, state, ch;
|
int tarindex, state, ch;
|
||||||
u_char nextbyte;
|
unsigned char nextbyte;
|
||||||
char *pos;
|
char *pos;
|
||||||
|
|
||||||
state = 0;
|
state = 0;
|
||||||
@@ -207,7 +201,7 @@ b64_pton(src, target, targsize)
|
|||||||
break;
|
break;
|
||||||
|
|
||||||
pos = strchr(Base64, ch);
|
pos = strchr(Base64, ch);
|
||||||
if (pos == 0) /* A non-base64 character. */
|
if (pos == 0) /* A non-base64 character. */
|
||||||
return (-1);
|
return (-1);
|
||||||
|
|
||||||
switch (state) {
|
switch (state) {
|
||||||
|
|||||||
@@ -57,6 +57,9 @@ environ_free(struct environ *env)
|
|||||||
{
|
{
|
||||||
struct environ_entry *envent, *envent1;
|
struct environ_entry *envent, *envent1;
|
||||||
|
|
||||||
|
if (env == NULL)
|
||||||
|
return;
|
||||||
|
|
||||||
RB_FOREACH_SAFE(envent, environ, env, envent1) {
|
RB_FOREACH_SAFE(envent, environ, env, envent1) {
|
||||||
RB_REMOVE(environ, env, envent);
|
RB_REMOVE(environ, env, envent);
|
||||||
free(envent->name);
|
free(envent->name);
|
||||||
|
|||||||
1
file.c
1
file.c
@@ -55,6 +55,7 @@ file_get_path(struct client *c, const char *file)
|
|||||||
if (*path == '/')
|
if (*path == '/')
|
||||||
return (path);
|
return (path);
|
||||||
xasprintf(&full_path, "%s/%s", server_client_get_cwd(c, NULL), path);
|
xasprintf(&full_path, "%s/%s", server_client_get_cwd(c, NULL), path);
|
||||||
|
free(path);
|
||||||
return (full_path);
|
return (full_path);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
3
format.c
3
format.c
@@ -4447,6 +4447,9 @@ format_loop_sessions(struct format_expand_state *es, const char *fmt)
|
|||||||
free(expanded);
|
free(expanded);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
free(active);
|
||||||
|
free(all);
|
||||||
|
|
||||||
return (value);
|
return (value);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -44,7 +44,7 @@ LLVMFuzzerTestOneInput(const u_char *data, size_t size)
|
|||||||
w = window_create(PANE_WIDTH, PANE_HEIGHT, 0, 0);
|
w = window_create(PANE_WIDTH, PANE_HEIGHT, 0, 0);
|
||||||
wp = window_add_pane(w, NULL, 0, 0);
|
wp = window_add_pane(w, NULL, 0, 0);
|
||||||
bufferevent_pair_new(libevent, BEV_OPT_CLOSE_ON_FREE, vpty);
|
bufferevent_pair_new(libevent, BEV_OPT_CLOSE_ON_FREE, vpty);
|
||||||
wp->ictx = input_init(wp, vpty[0], NULL);
|
wp->ictx = input_init(wp, vpty[0], NULL, NULL);
|
||||||
window_add_ref(w, __func__);
|
window_add_ref(w, __func__);
|
||||||
|
|
||||||
wp->fd = open("/dev/null", O_WRONLY);
|
wp->fd = open("/dev/null", O_WRONLY);
|
||||||
|
|||||||
22
grid.c
22
grid.c
@@ -209,13 +209,15 @@ grid_clear_cell(struct grid *gd, u_int px, u_int py, u_int bg)
|
|||||||
int had_extd = (gce->flags & GRID_FLAG_EXTENDED);
|
int had_extd = (gce->flags & GRID_FLAG_EXTENDED);
|
||||||
|
|
||||||
memcpy(gce, &grid_cleared_entry, sizeof *gce);
|
memcpy(gce, &grid_cleared_entry, sizeof *gce);
|
||||||
if (bg != 8) {
|
if (had_extd && old_offset < gl->extdsize) {
|
||||||
|
gce->flags |= GRID_FLAG_EXTENDED;
|
||||||
|
gce->offset = old_offset;
|
||||||
|
gee = grid_extended_cell(gl, gce, &grid_cleared_cell);
|
||||||
|
if (bg != 8)
|
||||||
|
gee->bg = bg;
|
||||||
|
} else if (bg != 8) {
|
||||||
if (bg & COLOUR_FLAG_RGB) {
|
if (bg & COLOUR_FLAG_RGB) {
|
||||||
if (had_extd && old_offset < gl->extdsize) {
|
grid_get_extended_cell(gl, gce, gce->flags);
|
||||||
gce->flags |= GRID_FLAG_EXTENDED;
|
|
||||||
gce->offset = old_offset;
|
|
||||||
} else
|
|
||||||
grid_get_extended_cell(gl, gce, gce->flags);
|
|
||||||
gee = grid_extended_cell(gl, gce, &grid_cleared_cell);
|
gee = grid_extended_cell(gl, gce, &grid_cleared_cell);
|
||||||
gee->bg = bg;
|
gee->bg = bg;
|
||||||
} else {
|
} else {
|
||||||
@@ -493,7 +495,7 @@ static void
|
|||||||
grid_expand_line(struct grid *gd, u_int py, u_int sx, u_int bg)
|
grid_expand_line(struct grid *gd, u_int py, u_int sx, u_int bg)
|
||||||
{
|
{
|
||||||
struct grid_line *gl;
|
struct grid_line *gl;
|
||||||
u_int xx;
|
u_int xx, old_cellsize;
|
||||||
|
|
||||||
gl = &gd->linedata[py];
|
gl = &gd->linedata[py];
|
||||||
if (sx <= gl->cellsize)
|
if (sx <= gl->cellsize)
|
||||||
@@ -506,8 +508,10 @@ grid_expand_line(struct grid *gd, u_int py, u_int sx, u_int bg)
|
|||||||
else if (gd->sx > sx)
|
else if (gd->sx > sx)
|
||||||
sx = gd->sx;
|
sx = gd->sx;
|
||||||
|
|
||||||
gl->celldata = xreallocarray(gl->celldata, sx, sizeof *gl->celldata);
|
old_cellsize = gl->cellsize;
|
||||||
for (xx = gl->cellsize; xx < sx; xx++)
|
gl->celldata = xrecallocarray(gl->celldata, old_cellsize, sx,
|
||||||
|
sizeof *gl->celldata);
|
||||||
|
for (xx = old_cellsize; xx < sx; xx++)
|
||||||
grid_clear_cell(gd, xx, py, bg);
|
grid_clear_cell(gd, xx, py, bg);
|
||||||
gl->cellsize = sx;
|
gl->cellsize = sx;
|
||||||
}
|
}
|
||||||
|
|||||||
56
input.c
56
input.c
@@ -1139,11 +1139,9 @@ input_get(struct input_ctx *ictx, u_int validx, int minval, int defval)
|
|||||||
static void
|
static void
|
||||||
input_send_reply(struct input_ctx *ictx, const char *reply)
|
input_send_reply(struct input_ctx *ictx, const char *reply)
|
||||||
{
|
{
|
||||||
struct bufferevent *bev = ictx->event;
|
if (ictx->event != NULL) {
|
||||||
|
|
||||||
if (bev != NULL) {
|
|
||||||
log_debug("%s: %s", __func__, reply);
|
log_debug("%s: %s", __func__, reply);
|
||||||
bufferevent_write(bev, reply, strlen(reply));
|
bufferevent_write(ictx->event, reply, strlen(reply));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -1627,10 +1625,6 @@ input_csi_dispatch(struct input_ctx *ictx)
|
|||||||
}
|
}
|
||||||
input_reply(ictx, 1, "\033[?12;%d$y", n);
|
input_reply(ictx, 1, "\033[?12;%d$y", n);
|
||||||
break;
|
break;
|
||||||
case 2004: /* bracketed paste */
|
|
||||||
n = (s->mode & MODE_BRACKETPASTE) ? 1 : 2;
|
|
||||||
input_reply(ictx, 1, "\033[?2004;%d$y", n);
|
|
||||||
break;
|
|
||||||
case 1004: /* focus reporting */
|
case 1004: /* focus reporting */
|
||||||
n = (s->mode & MODE_FOCUSON) ? 1 : 2;
|
n = (s->mode & MODE_FOCUSON) ? 1 : 2;
|
||||||
input_reply(ictx, 1, "\033[?1004;%d$y", n);
|
input_reply(ictx, 1, "\033[?1004;%d$y", n);
|
||||||
@@ -1639,6 +1633,14 @@ input_csi_dispatch(struct input_ctx *ictx)
|
|||||||
n = (s->mode & MODE_MOUSE_SGR) ? 1 : 2;
|
n = (s->mode & MODE_MOUSE_SGR) ? 1 : 2;
|
||||||
input_reply(ictx, 1, "\033[?1006;%d$y", n);
|
input_reply(ictx, 1, "\033[?1006;%d$y", n);
|
||||||
break;
|
break;
|
||||||
|
case 2004: /* bracketed paste */
|
||||||
|
n = (s->mode & MODE_BRACKETPASTE) ? 1 : 2;
|
||||||
|
input_reply(ictx, 1, "\033[?2004;%d$y", n);
|
||||||
|
break;
|
||||||
|
case 2026: /* synchronized output */
|
||||||
|
n = (s->mode & MODE_SYNC) ? 1 : 2;
|
||||||
|
input_reply(ictx, 1, "\033[?2026;%d$y", n);
|
||||||
|
break;
|
||||||
case 2031:
|
case 2031:
|
||||||
input_reply(ictx, 1, "\033[?2031;2$y");
|
input_reply(ictx, 1, "\033[?2031;2$y");
|
||||||
break;
|
break;
|
||||||
@@ -3089,8 +3091,9 @@ input_osc_133(struct input_ctx *ictx, const char *p)
|
|||||||
|
|
||||||
/* Handle OSC 52 reply. */
|
/* Handle OSC 52 reply. */
|
||||||
static void
|
static void
|
||||||
input_osc_52_reply(struct input_ctx *ictx)
|
input_osc_52_reply(struct input_ctx *ictx, char clip)
|
||||||
{
|
{
|
||||||
|
struct bufferevent *ev = ictx->event;
|
||||||
struct paste_buffer *pb;
|
struct paste_buffer *pb;
|
||||||
int state;
|
int state;
|
||||||
const char *buf;
|
const char *buf;
|
||||||
@@ -3104,9 +3107,9 @@ input_osc_52_reply(struct input_ctx *ictx)
|
|||||||
return;
|
return;
|
||||||
buf = paste_buffer_data(pb, &len);
|
buf = paste_buffer_data(pb, &len);
|
||||||
if (ictx->input_end == INPUT_END_BEL)
|
if (ictx->input_end == INPUT_END_BEL)
|
||||||
input_reply_clipboard(ictx->event, buf, len, "\007");
|
input_reply_clipboard(ev, buf, len, "\007", clip);
|
||||||
else
|
else
|
||||||
input_reply_clipboard(ictx->event, buf, len, "\033\\");
|
input_reply_clipboard(ev, buf, len, "\033\\", clip);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
input_add_request(ictx, INPUT_REQUEST_CLIPBOARD, ictx->input_end);
|
input_add_request(ictx, INPUT_REQUEST_CLIPBOARD, ictx->input_end);
|
||||||
@@ -3119,7 +3122,7 @@ input_osc_52_reply(struct input_ctx *ictx)
|
|||||||
*/
|
*/
|
||||||
static int
|
static int
|
||||||
input_osc_52_parse(struct input_ctx *ictx, const char *p, u_char **out,
|
input_osc_52_parse(struct input_ctx *ictx, const char *p, u_char **out,
|
||||||
int *outlen, char *flags)
|
int *outlen, char *clip)
|
||||||
{
|
{
|
||||||
char *end;
|
char *end;
|
||||||
size_t len;
|
size_t len;
|
||||||
@@ -3137,13 +3140,13 @@ input_osc_52_parse(struct input_ctx *ictx, const char *p, u_char **out,
|
|||||||
log_debug("%s: %s", __func__, end);
|
log_debug("%s: %s", __func__, end);
|
||||||
|
|
||||||
for (i = 0; p + i != end; i++) {
|
for (i = 0; p + i != end; i++) {
|
||||||
if (strchr(allow, p[i]) != NULL && strchr(flags, p[i]) == NULL)
|
if (strchr(allow, p[i]) != NULL && strchr(clip, p[i]) == NULL)
|
||||||
flags[j++] = p[i];
|
clip[j++] = p[i];
|
||||||
}
|
}
|
||||||
log_debug("%s: %.*s %s", __func__, (int)(end - p - 1), p, flags);
|
log_debug("%s: %.*s %s", __func__, (int)(end - p - 1), p, clip);
|
||||||
|
|
||||||
if (strcmp(end, "?") == 0) {
|
if (strcmp(end, "?") == 0) {
|
||||||
input_osc_52_reply(ictx);
|
input_osc_52_reply(ictx, *clip);
|
||||||
return (0);
|
return (0);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -3169,9 +3172,9 @@ input_osc_52(struct input_ctx *ictx, const char *p)
|
|||||||
struct screen_write_ctx ctx;
|
struct screen_write_ctx ctx;
|
||||||
u_char *out;
|
u_char *out;
|
||||||
int outlen;
|
int outlen;
|
||||||
char flags[sizeof "cpqs01234567"] = "";
|
char clip[sizeof "cpqs01234567"] = "";
|
||||||
|
|
||||||
if (!input_osc_52_parse(ictx, p, &out, &outlen, flags))
|
if (!input_osc_52_parse(ictx, p, &out, &outlen, clip))
|
||||||
return;
|
return;
|
||||||
|
|
||||||
if (wp == NULL) {
|
if (wp == NULL) {
|
||||||
@@ -3180,17 +3183,16 @@ input_osc_52(struct input_ctx *ictx, const char *p)
|
|||||||
free(out);
|
free(out);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
tty_set_selection(&ictx->c->tty, flags, out, outlen);
|
tty_set_selection(&ictx->c->tty, clip, out, outlen);
|
||||||
paste_add(NULL, out, outlen);
|
paste_add(NULL, out, outlen);
|
||||||
} else {
|
} else {
|
||||||
/* Normal window. */
|
/* Normal window. */
|
||||||
screen_write_start_pane(&ctx, wp, NULL);
|
screen_write_start_pane(&ctx, wp, NULL);
|
||||||
screen_write_setselection(&ctx, flags, out, outlen);
|
screen_write_setselection(&ctx, clip, out, outlen);
|
||||||
screen_write_stop(&ctx);
|
screen_write_stop(&ctx);
|
||||||
notify_pane("pane-set-clipboard", wp);
|
notify_pane("pane-set-clipboard", wp);
|
||||||
paste_add(NULL, out, outlen);
|
paste_add(NULL, out, outlen);
|
||||||
}
|
}
|
||||||
free(out);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Handle the OSC 104 sequence for unsetting (multiple) palette entries. */
|
/* Handle the OSC 104 sequence for unsetting (multiple) palette entries. */
|
||||||
@@ -3233,7 +3235,7 @@ input_osc_104(struct input_ctx *ictx, const char *p)
|
|||||||
/* Send a clipboard reply. */
|
/* Send a clipboard reply. */
|
||||||
void
|
void
|
||||||
input_reply_clipboard(struct bufferevent *bev, const char *buf, size_t len,
|
input_reply_clipboard(struct bufferevent *bev, const char *buf, size_t len,
|
||||||
const char *end)
|
const char *end, char clip)
|
||||||
{
|
{
|
||||||
char *out = NULL;
|
char *out = NULL;
|
||||||
int outlen = 0;
|
int outlen = 0;
|
||||||
@@ -3249,7 +3251,10 @@ input_reply_clipboard(struct bufferevent *bev, const char *buf, size_t len,
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
bufferevent_write(bev, "\033]52;;", 6);
|
bufferevent_write(bev, "\033]52;", 5);
|
||||||
|
if (clip != 0)
|
||||||
|
bufferevent_write(bev, &clip, 1);
|
||||||
|
bufferevent_write(bev, ";", 1);
|
||||||
if (outlen != 0)
|
if (outlen != 0)
|
||||||
bufferevent_write(bev, out, outlen);
|
bufferevent_write(bev, out, outlen);
|
||||||
bufferevent_write(bev, end, strlen(end));
|
bufferevent_write(bev, end, strlen(end));
|
||||||
@@ -3391,6 +3396,7 @@ static void
|
|||||||
input_request_clipboard_reply(struct input_request *ir, void *data)
|
input_request_clipboard_reply(struct input_request *ir, void *data)
|
||||||
{
|
{
|
||||||
struct input_ctx *ictx = ir->ictx;
|
struct input_ctx *ictx = ir->ictx;
|
||||||
|
struct bufferevent *ev = ictx->event;
|
||||||
struct input_request_clipboard_data *cd = data;
|
struct input_request_clipboard_data *cd = data;
|
||||||
int state;
|
int state;
|
||||||
char *copy;
|
char *copy;
|
||||||
@@ -3405,9 +3411,9 @@ input_request_clipboard_reply(struct input_request *ir, void *data)
|
|||||||
}
|
}
|
||||||
|
|
||||||
if (ir->idx == INPUT_END_BEL)
|
if (ir->idx == INPUT_END_BEL)
|
||||||
input_reply_clipboard(ictx->event, cd->buf, cd->len, "\007");
|
input_reply_clipboard(ev, cd->buf, cd->len, "\007", cd->clip);
|
||||||
else
|
else
|
||||||
input_reply_clipboard(ictx->event, cd->buf, cd->len, "\033\\");
|
input_reply_clipboard(ev, cd->buf, cd->len, "\033\\", cd->clip);
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Handle a reply to a request. */
|
/* Handle a reply to a request. */
|
||||||
|
|||||||
@@ -215,6 +215,7 @@ key_bindings_add(const char *name, key_code key, const char *note, int repeat,
|
|||||||
|
|
||||||
bd = xcalloc(1, sizeof *bd);
|
bd = xcalloc(1, sizeof *bd);
|
||||||
bd->key = (key & ~KEYC_MASK_FLAGS);
|
bd->key = (key & ~KEYC_MASK_FLAGS);
|
||||||
|
bd->tablename = table->name;
|
||||||
if (note != NULL)
|
if (note != NULL)
|
||||||
bd->note = xstrdup(note);
|
bd->note = xstrdup(note);
|
||||||
RB_INSERT(key_bindings, &table->key_bindings, bd);
|
RB_INSERT(key_bindings, &table->key_bindings, bd);
|
||||||
@@ -695,6 +696,7 @@ key_bindings_dispatch(struct key_binding *bd, struct cmdq_item *item,
|
|||||||
readonly = 1;
|
readonly = 1;
|
||||||
else
|
else
|
||||||
readonly = cmd_list_all_have(bd->cmdlist, CMD_READONLY);
|
readonly = cmd_list_all_have(bd->cmdlist, CMD_READONLY);
|
||||||
|
|
||||||
if (!readonly)
|
if (!readonly)
|
||||||
new_item = cmdq_get_callback(key_bindings_read_only, NULL);
|
new_item = cmdq_get_callback(key_bindings_read_only, NULL);
|
||||||
else {
|
else {
|
||||||
@@ -710,3 +712,15 @@ key_bindings_dispatch(struct key_binding *bd, struct cmdq_item *item,
|
|||||||
new_item = cmdq_append(c, new_item);
|
new_item = cmdq_append(c, new_item);
|
||||||
return (new_item);
|
return (new_item);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
int
|
||||||
|
key_bindings_has_repeat(struct key_binding **l, u_int n)
|
||||||
|
{
|
||||||
|
u_int i;
|
||||||
|
|
||||||
|
for (i = 0; i < n; i++) {
|
||||||
|
if (l[i]->flags & KEY_BINDING_REPEAT)
|
||||||
|
return (1);
|
||||||
|
}
|
||||||
|
return (0);
|
||||||
|
}
|
||||||
|
|||||||
4
menu.c
4
menu.c
@@ -90,6 +90,7 @@ menu_add_item(struct menu *menu, const struct menu_item *item,
|
|||||||
else
|
else
|
||||||
s = format_single(qitem, item->name, c, NULL, NULL, NULL);
|
s = format_single(qitem, item->name, c, NULL, NULL, NULL);
|
||||||
if (*s == '\0') { /* no item if empty after format expanded */
|
if (*s == '\0') { /* no item if empty after format expanded */
|
||||||
|
free(s);
|
||||||
menu->count--;
|
menu->count--;
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
@@ -161,6 +162,9 @@ menu_free(struct menu *menu)
|
|||||||
{
|
{
|
||||||
u_int i;
|
u_int i;
|
||||||
|
|
||||||
|
if (menu == NULL)
|
||||||
|
return;
|
||||||
|
|
||||||
for (i = 0; i < menu->count; i++) {
|
for (i = 0; i < menu->count; i++) {
|
||||||
free((void *)menu->items[i].name);
|
free((void *)menu->items[i].name);
|
||||||
free((void *)menu->items[i].command);
|
free((void *)menu->items[i].command);
|
||||||
|
|||||||
82
regress/decrqm-sync.sh
Normal file
82
regress/decrqm-sync.sh
Normal file
@@ -0,0 +1,82 @@
|
|||||||
|
#!/bin/sh
|
||||||
|
|
||||||
|
# Test DECRPM response for mode 2026 (synchronized output).
|
||||||
|
#
|
||||||
|
# DECRQM (ESC[?2026$p) should elicit DECRPM (ESC[?2026;Ps$y) where
|
||||||
|
# Ps=1 when MODE_SYNC is active, Ps=2 when reset.
|
||||||
|
|
||||||
|
PATH=/bin:/usr/bin
|
||||||
|
TERM=screen
|
||||||
|
|
||||||
|
[ -z "$TEST_TMUX" ] && TEST_TMUX=$(readlink -f ../tmux)
|
||||||
|
TMUX="$TEST_TMUX -Ltest"
|
||||||
|
$TMUX kill-server 2>/dev/null
|
||||||
|
sleep 1
|
||||||
|
|
||||||
|
TMP=$(mktemp)
|
||||||
|
TMP2=$(mktemp)
|
||||||
|
trap "rm -f $TMP $TMP2; $TMUX kill-server 2>/dev/null" 0 1 15
|
||||||
|
|
||||||
|
$TMUX -f/dev/null new -d -x80 -y24 || exit 1
|
||||||
|
sleep 1
|
||||||
|
|
||||||
|
# Keep the session alive regardless of pane exits.
|
||||||
|
$TMUX set -g remain-on-exit on
|
||||||
|
|
||||||
|
exit_status=0
|
||||||
|
|
||||||
|
# query_decrpm <outfile> [setup_seq]
|
||||||
|
# Spawn a pane that optionally sends setup_seq, then sends DECRQM for
|
||||||
|
# mode 2026 and captures the response into outfile in cat -v form.
|
||||||
|
query_decrpm () {
|
||||||
|
_outfile=$1
|
||||||
|
_setup=$2
|
||||||
|
|
||||||
|
$TMUX respawnw -k -t:0 -- sh -c "
|
||||||
|
exec 2>/dev/null
|
||||||
|
stty raw -echo
|
||||||
|
${_setup:+printf '$_setup'; sleep 0.2}
|
||||||
|
printf '\033[?2026\$p'
|
||||||
|
dd bs=1 count=11 2>/dev/null | cat -v > $_outfile
|
||||||
|
sleep 0.2
|
||||||
|
" || exit 1
|
||||||
|
sleep 2
|
||||||
|
}
|
||||||
|
|
||||||
|
# ------------------------------------------------------------------
|
||||||
|
# Test 1: mode 2026 should be reset by default (Ps=2)
|
||||||
|
# ------------------------------------------------------------------
|
||||||
|
query_decrpm "$TMP"
|
||||||
|
|
||||||
|
actual=$(cat "$TMP")
|
||||||
|
expected='^[[?2026;2$y'
|
||||||
|
|
||||||
|
if [ "$actual" = "$expected" ]; then
|
||||||
|
if [ -n "$VERBOSE" ]; then
|
||||||
|
echo "[PASS] DECRQM 2026 (default/reset) -> $actual"
|
||||||
|
fi
|
||||||
|
else
|
||||||
|
echo "[FAIL] DECRQM 2026 (default/reset): expected '$expected', got '$actual'"
|
||||||
|
exit_status=1
|
||||||
|
fi
|
||||||
|
|
||||||
|
# ------------------------------------------------------------------
|
||||||
|
# Test 2: set mode 2026 (SM ?2026), then query (expect Ps=1)
|
||||||
|
# ------------------------------------------------------------------
|
||||||
|
query_decrpm "$TMP2" '\033[?2026h'
|
||||||
|
|
||||||
|
actual=$(cat "$TMP2")
|
||||||
|
expected='^[[?2026;1$y'
|
||||||
|
|
||||||
|
if [ "$actual" = "$expected" ]; then
|
||||||
|
if [ -n "$VERBOSE" ]; then
|
||||||
|
echo "[PASS] DECRQM 2026 (set) -> $actual"
|
||||||
|
fi
|
||||||
|
else
|
||||||
|
echo "[FAIL] DECRQM 2026 (set): expected '$expected', got '$actual'"
|
||||||
|
exit_status=1
|
||||||
|
fi
|
||||||
|
|
||||||
|
$TMUX kill-server 2>/dev/null
|
||||||
|
|
||||||
|
exit $exit_status
|
||||||
70
regress/session-group-resize.sh
Executable file
70
regress/session-group-resize.sh
Executable file
@@ -0,0 +1,70 @@
|
|||||||
|
#!/bin/sh
|
||||||
|
|
||||||
|
# Test that window-size=latest resizes windows correctly when switching
|
||||||
|
# windows in session groups. When a client switches to a window, it should
|
||||||
|
# resize immediately to match that client's size.
|
||||||
|
#
|
||||||
|
# Tests both switch-client and select-window, which use different code paths.
|
||||||
|
|
||||||
|
PATH=/bin:/usr/bin
|
||||||
|
TERM=screen
|
||||||
|
|
||||||
|
[ -z "$TEST_TMUX" ] && TEST_TMUX=$(readlink -f ../tmux)
|
||||||
|
TMUX="$TEST_TMUX -Ltest"
|
||||||
|
$TMUX kill-server 2>/dev/null
|
||||||
|
|
||||||
|
TMP1=$(mktemp)
|
||||||
|
TMP2=$(mktemp)
|
||||||
|
TMP3=$(mktemp)
|
||||||
|
trap "rm -f $TMP1 $TMP2 $TMP3" 0 1 15
|
||||||
|
|
||||||
|
# Create a session with two windows, staying on window 0.
|
||||||
|
$TMUX -f/dev/null new -d -s test -x 20 -y 6 || exit 1
|
||||||
|
$TMUX neww -t test || exit 1
|
||||||
|
$TMUX selectw -t test:0 || exit 1
|
||||||
|
|
||||||
|
# Attach a small 20x6 client in control-mode and have it select window 1. This makes
|
||||||
|
# the small client the "latest" for window 1. The sleep keeps stdin open so the
|
||||||
|
# control client stays attached.
|
||||||
|
(echo "refresh-client -C 20,6"; echo "selectw -t :1"; sleep 5) |
|
||||||
|
$TMUX -f/dev/null -C attach -t test >$TMP1 2>&1 &
|
||||||
|
|
||||||
|
# Wait for small client to be on window 1.
|
||||||
|
n=0
|
||||||
|
while [ $n -lt 20 ]; do
|
||||||
|
$TMUX lsc -F '#{client_name} #{window_index}' 2>/dev/null | grep -q " 1$" && break
|
||||||
|
sleep 0.1
|
||||||
|
n=$((n + 1))
|
||||||
|
done
|
||||||
|
|
||||||
|
# Create a grouped session with a larger 30x10 client, also in control mode. It
|
||||||
|
# starts on window 0 (inherited), then switches to window 1 with
|
||||||
|
# `switch-client`.
|
||||||
|
(echo "refresh-client -C 30,10"; echo "switch-client -t :=1"; sleep 5) |
|
||||||
|
$TMUX -f/dev/null -C new -t test -x 30 -y 10 >$TMP2 2>&1 &
|
||||||
|
|
||||||
|
# Wait briefly for the switch-client command to execute, then check.
|
||||||
|
# The resize should happen immediately (within 0.2s).
|
||||||
|
sleep 0.2
|
||||||
|
OUT1=$($TMUX display -t test:1 -p '#{window_width}x#{window_height}' 2>/dev/null)
|
||||||
|
|
||||||
|
# Also test selectw (select-window) which uses a different code path.
|
||||||
|
# Create a third grouped session with a 25x8 client, switch to window 1
|
||||||
|
# using selectw instead of switch-client.
|
||||||
|
(echo "refresh-client -C 25,8"; echo "selectw -t :1"; sleep 5) |
|
||||||
|
$TMUX -f/dev/null -C new -t test -x 25 -y 8 >$TMP3 2>&1 &
|
||||||
|
|
||||||
|
sleep 0.2
|
||||||
|
OUT2=$($TMUX display -t test:1 -p '#{window_width}x#{window_height}' 2>/dev/null)
|
||||||
|
|
||||||
|
# Clean up - kill server (terminates clients). Don't wait for background
|
||||||
|
# sleeps; they'll be orphaned but harmless.
|
||||||
|
$TMUX kill-server 2>/dev/null
|
||||||
|
|
||||||
|
# Window 1 should have resized to 30x10 (the second client's size).
|
||||||
|
[ "$OUT1" = "30x10" ] || { echo "switch-client resize failed: $OUT1"; exit 1; }
|
||||||
|
|
||||||
|
# Window 1 should have resized to 25x8 (the third client's size).
|
||||||
|
[ "$OUT2" = "25x8" ] || { echo "selectw resize failed: $OUT2"; exit 1; }
|
||||||
|
|
||||||
|
exit 0
|
||||||
@@ -2510,14 +2510,14 @@ screen_write_overwrite(struct screen_write_ctx *ctx, struct grid_cell *gc,
|
|||||||
|
|
||||||
/* Set external clipboard. */
|
/* Set external clipboard. */
|
||||||
void
|
void
|
||||||
screen_write_setselection(struct screen_write_ctx *ctx, const char *flags,
|
screen_write_setselection(struct screen_write_ctx *ctx, const char *clip,
|
||||||
u_char *str, u_int len)
|
u_char *str, u_int len)
|
||||||
{
|
{
|
||||||
struct tty_ctx ttyctx;
|
struct tty_ctx ttyctx;
|
||||||
|
|
||||||
screen_write_initctx(ctx, &ttyctx, 0);
|
screen_write_initctx(ctx, &ttyctx, 0);
|
||||||
ttyctx.ptr = str;
|
ttyctx.ptr = str;
|
||||||
ttyctx.ptr2 = (void *)flags;
|
ttyctx.ptr2 = (void *)clip;
|
||||||
ttyctx.num = len;
|
ttyctx.num = len;
|
||||||
|
|
||||||
tty_write(tty_cmd_setselection, &ttyctx);
|
tty_write(tty_cmd_setselection, &ttyctx);
|
||||||
|
|||||||
@@ -96,7 +96,9 @@ server_redraw_window(struct window *w)
|
|||||||
struct client *c;
|
struct client *c;
|
||||||
|
|
||||||
TAILQ_FOREACH(c, &clients, entry) {
|
TAILQ_FOREACH(c, &clients, entry) {
|
||||||
if (c->session != NULL && c->session->curw->window == w)
|
if (c->session != NULL &&
|
||||||
|
c->session->curw != NULL &&
|
||||||
|
c->session->curw->window == w)
|
||||||
server_redraw_client(c);
|
server_redraw_client(c);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -107,7 +109,9 @@ server_redraw_window_borders(struct window *w)
|
|||||||
struct client *c;
|
struct client *c;
|
||||||
|
|
||||||
TAILQ_FOREACH(c, &clients, entry) {
|
TAILQ_FOREACH(c, &clients, entry) {
|
||||||
if (c->session != NULL && c->session->curw->window == w)
|
if (c->session != NULL &&
|
||||||
|
c->session->curw != NULL &&
|
||||||
|
c->session->curw->window == w)
|
||||||
c->flags |= CLIENT_REDRAWBORDERS;
|
c->flags |= CLIENT_REDRAWBORDERS;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
101
sort.c
101
sort.c
@@ -72,6 +72,7 @@ sort_buffer_cmp(const void *a0, const void *b0)
|
|||||||
break;
|
break;
|
||||||
case SORT_ACTIVITY:
|
case SORT_ACTIVITY:
|
||||||
case SORT_INDEX:
|
case SORT_INDEX:
|
||||||
|
case SORT_MODIFIER:
|
||||||
case SORT_ORDER:
|
case SORT_ORDER:
|
||||||
case SORT_END:
|
case SORT_END:
|
||||||
break;
|
break;
|
||||||
@@ -117,6 +118,7 @@ sort_client_cmp(const void *a0, const void *b0)
|
|||||||
result = 1;
|
result = 1;
|
||||||
break;
|
break;
|
||||||
case SORT_INDEX:
|
case SORT_INDEX:
|
||||||
|
case SORT_MODIFIER:
|
||||||
case SORT_ORDER:
|
case SORT_ORDER:
|
||||||
case SORT_END:
|
case SORT_END:
|
||||||
break;
|
break;
|
||||||
@@ -167,6 +169,7 @@ sort_session_cmp(const void *a0, const void *b0)
|
|||||||
case SORT_NAME:
|
case SORT_NAME:
|
||||||
result = strcmp(sa->name, sb->name);
|
result = strcmp(sa->name, sb->name);
|
||||||
break;
|
break;
|
||||||
|
case SORT_MODIFIER:
|
||||||
case SORT_ORDER:
|
case SORT_ORDER:
|
||||||
case SORT_SIZE:
|
case SORT_SIZE:
|
||||||
case SORT_END:
|
case SORT_END:
|
||||||
@@ -208,6 +211,7 @@ sort_pane_cmp(const void *a0, const void *b0)
|
|||||||
case SORT_NAME:
|
case SORT_NAME:
|
||||||
result = strcmp(a->screen->title, b->screen->title);
|
result = strcmp(a->screen->title, b->screen->title);
|
||||||
break;
|
break;
|
||||||
|
case SORT_MODIFIER:
|
||||||
case SORT_ORDER:
|
case SORT_ORDER:
|
||||||
case SORT_END:
|
case SORT_END:
|
||||||
break;
|
break;
|
||||||
@@ -263,6 +267,7 @@ sort_winlink_cmp(const void *a0, const void *b0)
|
|||||||
case SORT_SIZE:
|
case SORT_SIZE:
|
||||||
result = wa->sx * wa->sy - wb->sx * wb->sy;
|
result = wa->sx * wa->sy - wb->sx * wb->sy;
|
||||||
break;
|
break;
|
||||||
|
case SORT_MODIFIER:
|
||||||
case SORT_ORDER:
|
case SORT_ORDER:
|
||||||
case SORT_END:
|
case SORT_END:
|
||||||
break;
|
break;
|
||||||
@@ -276,6 +281,41 @@ sort_winlink_cmp(const void *a0, const void *b0)
|
|||||||
return (result);
|
return (result);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static int
|
||||||
|
sort_key_binding_cmp(const void *a0, const void *b0)
|
||||||
|
{
|
||||||
|
struct sort_criteria *sort_crit = sort_criteria;
|
||||||
|
const struct key_binding *a = *(struct key_binding **)a0;
|
||||||
|
const struct key_binding *b = *(struct key_binding **)b0;
|
||||||
|
int result = 0;
|
||||||
|
|
||||||
|
switch (sort_crit->order) {
|
||||||
|
case SORT_INDEX:
|
||||||
|
result = a->key - b->key;
|
||||||
|
break;
|
||||||
|
case SORT_MODIFIER:
|
||||||
|
result = (a->key & KEYC_MASK_MODIFIERS) -
|
||||||
|
(b->key & KEYC_MASK_MODIFIERS);
|
||||||
|
break;
|
||||||
|
case SORT_NAME:
|
||||||
|
result = strcasecmp(a->tablename, b->tablename) == 0;
|
||||||
|
break;
|
||||||
|
case SORT_ACTIVITY:
|
||||||
|
case SORT_CREATION:
|
||||||
|
case SORT_ORDER:
|
||||||
|
case SORT_SIZE:
|
||||||
|
case SORT_END:
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (result == 0)
|
||||||
|
result = strcasecmp(a->tablename, b->tablename) == 0;
|
||||||
|
|
||||||
|
if (sort_crit->reversed)
|
||||||
|
result = -result;
|
||||||
|
return (result);
|
||||||
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
sort_next_order(struct sort_criteria *sort_crit)
|
sort_next_order(struct sort_criteria *sort_crit)
|
||||||
{
|
{
|
||||||
@@ -306,8 +346,11 @@ sort_order_from_string(const char* order)
|
|||||||
return (SORT_ACTIVITY);
|
return (SORT_ACTIVITY);
|
||||||
if (strcasecmp(order, "creation") == 0)
|
if (strcasecmp(order, "creation") == 0)
|
||||||
return (SORT_CREATION);
|
return (SORT_CREATION);
|
||||||
if (strcasecmp(order, "index") == 0)
|
if (strcasecmp(order, "index") == 0 ||
|
||||||
|
strcasecmp(order, "key") == 0)
|
||||||
return (SORT_INDEX);
|
return (SORT_INDEX);
|
||||||
|
if (strcasecmp(order, "modifier") == 0)
|
||||||
|
return (SORT_MODIFIER);
|
||||||
if (strcasecmp(order, "name") == 0 ||
|
if (strcasecmp(order, "name") == 0 ||
|
||||||
strcasecmp(order, "title") == 0)
|
strcasecmp(order, "title") == 0)
|
||||||
return (SORT_NAME);
|
return (SORT_NAME);
|
||||||
@@ -328,6 +371,8 @@ sort_order_to_string(enum sort_order order)
|
|||||||
return "creation";
|
return "creation";
|
||||||
if (order == SORT_INDEX)
|
if (order == SORT_INDEX)
|
||||||
return "index";
|
return "index";
|
||||||
|
if (order == SORT_MODIFIER)
|
||||||
|
return "modifier";
|
||||||
if (order == SORT_NAME)
|
if (order == SORT_NAME)
|
||||||
return "name";
|
return "name";
|
||||||
if (order == SORT_ORDER)
|
if (order == SORT_ORDER)
|
||||||
@@ -548,3 +593,57 @@ sort_get_winlinks_session(struct session *s, u_int *n,
|
|||||||
|
|
||||||
return (l);
|
return (l);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
struct key_binding **
|
||||||
|
sort_get_key_bindings(u_int *n, struct sort_criteria *sort_crit)
|
||||||
|
{
|
||||||
|
struct key_table *table;
|
||||||
|
struct key_binding *bd;
|
||||||
|
u_int i = 0;
|
||||||
|
static struct key_binding **l = NULL;
|
||||||
|
static u_int lsz = 0;
|
||||||
|
|
||||||
|
table = key_bindings_first_table();
|
||||||
|
while (table != NULL) {
|
||||||
|
bd = key_bindings_first(table);
|
||||||
|
while (bd != NULL) {
|
||||||
|
if (lsz <= i) {
|
||||||
|
lsz += 100;
|
||||||
|
l = xreallocarray(l, lsz, sizeof *l);
|
||||||
|
}
|
||||||
|
l[i++] = bd;
|
||||||
|
bd = key_bindings_next(table, bd);
|
||||||
|
}
|
||||||
|
table = key_bindings_next_table(table);
|
||||||
|
}
|
||||||
|
|
||||||
|
sort_qsort(l, i, sizeof *l, sort_key_binding_cmp, sort_crit);
|
||||||
|
*n = i;
|
||||||
|
|
||||||
|
return (l);
|
||||||
|
}
|
||||||
|
|
||||||
|
struct key_binding **
|
||||||
|
sort_get_key_bindings_table(struct key_table *table, u_int *n,
|
||||||
|
struct sort_criteria *sort_crit)
|
||||||
|
{
|
||||||
|
struct key_binding *bd;
|
||||||
|
u_int i = 0;
|
||||||
|
static struct key_binding **l = NULL;
|
||||||
|
static u_int lsz = 0;
|
||||||
|
|
||||||
|
bd = key_bindings_first(table);
|
||||||
|
while (bd != NULL) {
|
||||||
|
if (lsz <= i) {
|
||||||
|
lsz += 100;
|
||||||
|
l = xreallocarray(l, lsz, sizeof *l);
|
||||||
|
}
|
||||||
|
l[i++] = bd;
|
||||||
|
bd = key_bindings_next(table, bd);
|
||||||
|
}
|
||||||
|
|
||||||
|
sort_qsort(l, i, sizeof *l, sort_key_binding_cmp, sort_crit);
|
||||||
|
*n = i;
|
||||||
|
|
||||||
|
return (l);
|
||||||
|
}
|
||||||
|
|||||||
5
status.c
5
status.c
@@ -1890,7 +1890,7 @@ status_prompt_complete_window_menu(struct client *c, struct session *s,
|
|||||||
struct winlink *wl;
|
struct winlink *wl;
|
||||||
char **list = NULL, *tmp;
|
char **list = NULL, *tmp;
|
||||||
u_int lines = status_line_size(c), height;
|
u_int lines = status_line_size(c), height;
|
||||||
u_int py, size = 0;
|
u_int py, size = 0, i;
|
||||||
|
|
||||||
if (c->tty.sy - lines < 3)
|
if (c->tty.sy - lines < 3)
|
||||||
return (NULL);
|
return (NULL);
|
||||||
@@ -1969,6 +1969,9 @@ status_prompt_complete_window_menu(struct client *c, struct session *s,
|
|||||||
BOX_LINES_DEFAULT, NULL, NULL, NULL, NULL,
|
BOX_LINES_DEFAULT, NULL, NULL, NULL, NULL,
|
||||||
status_prompt_menu_callback, spm) != 0) {
|
status_prompt_menu_callback, spm) != 0) {
|
||||||
menu_free(menu);
|
menu_free(menu);
|
||||||
|
for (i = 0; i < size; i++)
|
||||||
|
free(list[i]);
|
||||||
|
free(list);
|
||||||
free(spm);
|
free(spm);
|
||||||
return (NULL);
|
return (NULL);
|
||||||
}
|
}
|
||||||
|
|||||||
65
tmux.1
65
tmux.1
@@ -2247,6 +2247,18 @@ Same as
|
|||||||
.Ic scroll-down
|
.Ic scroll-down
|
||||||
but also exit copy mode if the cursor reaches the bottom.
|
but also exit copy mode if the cursor reaches the bottom.
|
||||||
.It Xo
|
.It Xo
|
||||||
|
.Ic scroll-exit-on
|
||||||
|
.Xc
|
||||||
|
Turn on exiting copy mode when scrolling to the end of the buffer.
|
||||||
|
.It Xo
|
||||||
|
.Ic scroll-exit-off
|
||||||
|
.Xc
|
||||||
|
Turn off exiting copy mode when scrolling to the end of the buffer.
|
||||||
|
.It Xo
|
||||||
|
.Ic scroll-exit-toggle
|
||||||
|
.Xc
|
||||||
|
Toggle exiting copy mode when scrolling to the end of the buffer.
|
||||||
|
.It Xo
|
||||||
.Ic scroll-middle
|
.Ic scroll-middle
|
||||||
(vi: z)
|
(vi: z)
|
||||||
.Xc
|
.Xc
|
||||||
@@ -3827,24 +3839,45 @@ To view the default bindings and possible commands, see the
|
|||||||
command.
|
command.
|
||||||
.Tg lsk
|
.Tg lsk
|
||||||
.It Xo Ic list-keys
|
.It Xo Ic list-keys
|
||||||
.Op Fl 1aN
|
.Op Fl 1aNr
|
||||||
|
.Op Fl F Ar format
|
||||||
|
.Op Fl O Ar sort-order
|
||||||
.Op Fl P Ar prefix-string
|
.Op Fl P Ar prefix-string
|
||||||
.Op Fl T Ar key-table
|
.Op Fl T Ar key-table
|
||||||
.Op Ar key
|
.Op Ar key
|
||||||
.Xc
|
.Xc
|
||||||
.D1 Pq alias: Ic lsk
|
.D1 Pq alias: Ic lsk
|
||||||
List key bindings.
|
List key bindings.
|
||||||
There are two forms: the default lists keys as
|
.Fl F
|
||||||
|
specifies the format of each line.
|
||||||
|
See the
|
||||||
|
.Sx FORMATS
|
||||||
|
section.
|
||||||
|
.Fl T
|
||||||
|
specifies a
|
||||||
|
.Ar key-table
|
||||||
|
to list from.
|
||||||
|
.Fl 1
|
||||||
|
lists only the first matching key.
|
||||||
|
.Fl O
|
||||||
|
specifies the sort order: one of
|
||||||
|
.Ql key ,
|
||||||
|
.Ql modifier ,
|
||||||
|
.Ql name
|
||||||
|
(table name).
|
||||||
|
.Fl r
|
||||||
|
reverses the sort order.
|
||||||
|
.Pp
|
||||||
|
If no
|
||||||
|
.Ar format
|
||||||
|
is given, there are two forms: the default lists keys as
|
||||||
.Ic bind-key
|
.Ic bind-key
|
||||||
commands;
|
commands;
|
||||||
.Fl N
|
.Fl N
|
||||||
lists only keys with attached notes and shows only the key and note for each
|
lists only keys with attached notes and shows only the key and note for each
|
||||||
key.
|
key.
|
||||||
.Pp
|
.Pp
|
||||||
With the default form, all key tables are listed by default.
|
With the default form, all key tables are listed unless specified otherwise.
|
||||||
.Fl T
|
|
||||||
lists only keys in
|
|
||||||
.Ar key-table .
|
|
||||||
.Pp
|
.Pp
|
||||||
With the
|
With the
|
||||||
.Fl N
|
.Fl N
|
||||||
@@ -3857,9 +3890,7 @@ key tables are listed by default;
|
|||||||
also lists only keys in
|
also lists only keys in
|
||||||
.Ar key-table .
|
.Ar key-table .
|
||||||
.Fl P
|
.Fl P
|
||||||
specifies a prefix to print before each key and
|
specifies a prefix to print before each key.
|
||||||
.Fl 1
|
|
||||||
lists only the first matching key.
|
|
||||||
.Fl a
|
.Fl a
|
||||||
lists the command for keys that do not have a note rather than skipping them.
|
lists the command for keys that do not have a note rather than skipping them.
|
||||||
.Tg send
|
.Tg send
|
||||||
@@ -6236,6 +6267,15 @@ The following variables are available, where appropriate:
|
|||||||
.It Li "host" Ta "#H" Ta "Hostname of local host"
|
.It Li "host" Ta "#H" Ta "Hostname of local host"
|
||||||
.It Li "host_short" Ta "#h" Ta "Hostname of local host (no domain name)"
|
.It Li "host_short" Ta "#h" Ta "Hostname of local host (no domain name)"
|
||||||
.It Li "insert_flag" Ta "" Ta "Pane insert flag"
|
.It Li "insert_flag" Ta "" Ta "Pane insert flag"
|
||||||
|
.It Li "key_string" Ta "" Ta "String representation of the key binding"
|
||||||
|
.It Li "key_repeat" Ta "" Ta "1 if key binding is repeatable"
|
||||||
|
.It Li "key_note" Ta "" Ta "Note of the key binding"
|
||||||
|
.It Li "key_prefix" Ta "" Ta "Global key prefix"
|
||||||
|
.It Li "key_table" Ta "" Ta "Table name of the key binding"
|
||||||
|
.It Li "key_command" Ta "" Ta "Command of the key binding"
|
||||||
|
.It Li "key_has_repeat" Ta "" Ta "1 if list contain a repeatable key"
|
||||||
|
.It Li "key_string_width" Ta "" Ta "Maximum key_string width in list"
|
||||||
|
.It Li "key_table_width" Ta "" Ta "Maximum key_table width in list"
|
||||||
.It Li "keypad_cursor_flag" Ta "" Ta "Pane keypad cursor flag"
|
.It Li "keypad_cursor_flag" Ta "" Ta "Pane keypad cursor flag"
|
||||||
.It Li "keypad_flag" Ta "" Ta "Pane keypad flag"
|
.It Li "keypad_flag" Ta "" Ta "Pane keypad flag"
|
||||||
.It Li "last_window_index" Ta "" Ta "Index of last window in session"
|
.It Li "last_window_index" Ta "" Ta "Index of last window in session"
|
||||||
@@ -7411,7 +7451,7 @@ is
|
|||||||
the contents are read from stdin.
|
the contents are read from stdin.
|
||||||
.Tg pasteb
|
.Tg pasteb
|
||||||
.It Xo Ic paste-buffer
|
.It Xo Ic paste-buffer
|
||||||
.Op Fl dpr
|
.Op Fl dprS
|
||||||
.Op Fl b Ar buffer-name
|
.Op Fl b Ar buffer-name
|
||||||
.Op Fl s Ar separator
|
.Op Fl s Ar separator
|
||||||
.Op Fl t Ar target-pane
|
.Op Fl t Ar target-pane
|
||||||
@@ -7419,9 +7459,14 @@ the contents are read from stdin.
|
|||||||
.D1 Pq alias: Ic pasteb
|
.D1 Pq alias: Ic pasteb
|
||||||
Insert the contents of a paste buffer into the specified pane.
|
Insert the contents of a paste buffer into the specified pane.
|
||||||
If not specified, paste into the current one.
|
If not specified, paste into the current one.
|
||||||
|
By default, control characters are sanitized with
|
||||||
|
.Xr vis 3 ;
|
||||||
|
.Fl S
|
||||||
|
disables this.
|
||||||
With
|
With
|
||||||
.Fl d ,
|
.Fl d ,
|
||||||
also delete the paste buffer.
|
also delete the paste buffer.
|
||||||
|
.Pp
|
||||||
When output, any linefeed (LF) characters in the paste buffer are replaced with
|
When output, any linefeed (LF) characters in the paste buffer are replaced with
|
||||||
a separator, by default carriage return (CR).
|
a separator, by default carriage return (CR).
|
||||||
A custom separator may be specified using the
|
A custom separator may be specified using the
|
||||||
|
|||||||
16
tmux.h
16
tmux.h
@@ -1146,6 +1146,7 @@ struct input_request_palette_data {
|
|||||||
struct input_request_clipboard_data {
|
struct input_request_clipboard_data {
|
||||||
char *buf;
|
char *buf;
|
||||||
size_t len;
|
size_t len;
|
||||||
|
char clip;
|
||||||
};
|
};
|
||||||
|
|
||||||
/* Request sent to client on behalf of pane. */
|
/* Request sent to client on behalf of pane. */
|
||||||
@@ -2157,6 +2158,7 @@ struct key_binding {
|
|||||||
key_code key;
|
key_code key;
|
||||||
struct cmd_list *cmdlist;
|
struct cmd_list *cmdlist;
|
||||||
const char *note;
|
const char *note;
|
||||||
|
const char *tablename;
|
||||||
|
|
||||||
int flags;
|
int flags;
|
||||||
#define KEY_BINDING_REPEAT 0x1
|
#define KEY_BINDING_REPEAT 0x1
|
||||||
@@ -2296,6 +2298,7 @@ enum sort_order {
|
|||||||
SORT_ACTIVITY,
|
SORT_ACTIVITY,
|
||||||
SORT_CREATION,
|
SORT_CREATION,
|
||||||
SORT_INDEX,
|
SORT_INDEX,
|
||||||
|
SORT_MODIFIER,
|
||||||
SORT_NAME,
|
SORT_NAME,
|
||||||
SORT_ORDER,
|
SORT_ORDER,
|
||||||
SORT_SIZE,
|
SORT_SIZE,
|
||||||
@@ -2394,6 +2397,10 @@ struct window_pane **sort_get_panes_window(struct window *, u_int *,
|
|||||||
struct winlink **sort_get_winlinks(u_int *, struct sort_criteria *);
|
struct winlink **sort_get_winlinks(u_int *, struct sort_criteria *);
|
||||||
struct winlink **sort_get_winlinks_session(struct session *, u_int *,
|
struct winlink **sort_get_winlinks_session(struct session *, u_int *,
|
||||||
struct sort_criteria *);
|
struct sort_criteria *);
|
||||||
|
struct key_binding **sort_get_key_bindings(u_int *,
|
||||||
|
struct sort_criteria *);
|
||||||
|
struct key_binding **sort_get_key_bindings_table(struct key_table *,
|
||||||
|
u_int *, struct sort_criteria *);
|
||||||
|
|
||||||
/* format.c */
|
/* format.c */
|
||||||
#define FORMAT_STATUS 0x1
|
#define FORMAT_STATUS 0x1
|
||||||
@@ -2906,6 +2913,7 @@ void key_bindings_reset(const char *, key_code);
|
|||||||
void key_bindings_remove_table(const char *);
|
void key_bindings_remove_table(const char *);
|
||||||
void key_bindings_reset_table(const char *);
|
void key_bindings_reset_table(const char *);
|
||||||
void key_bindings_init(void);
|
void key_bindings_init(void);
|
||||||
|
int key_bindings_has_repeat(struct key_binding **, u_int);
|
||||||
struct cmdq_item *key_bindings_dispatch(struct key_binding *,
|
struct cmdq_item *key_bindings_dispatch(struct key_binding *,
|
||||||
struct cmdq_item *, struct client *, struct key_event *,
|
struct cmdq_item *, struct client *, struct key_event *,
|
||||||
struct cmd_find_state *);
|
struct cmd_find_state *);
|
||||||
@@ -3079,7 +3087,7 @@ void input_parse_buffer(struct window_pane *, u_char *, size_t);
|
|||||||
void input_parse_screen(struct input_ctx *, struct screen *,
|
void input_parse_screen(struct input_ctx *, struct screen *,
|
||||||
screen_write_init_ctx_cb, void *, u_char *, size_t);
|
screen_write_init_ctx_cb, void *, u_char *, size_t);
|
||||||
void input_reply_clipboard(struct bufferevent *, const char *, size_t,
|
void input_reply_clipboard(struct bufferevent *, const char *, size_t,
|
||||||
const char *);
|
const char *, char);
|
||||||
void input_set_buffer_size(size_t);
|
void input_set_buffer_size(size_t);
|
||||||
void input_request_reply(struct client *, enum input_request_type, void *);
|
void input_request_reply(struct client *, enum input_request_type, void *);
|
||||||
void input_cancel_requests(struct client *);
|
void input_cancel_requests(struct client *);
|
||||||
@@ -3637,9 +3645,9 @@ void utf8_copy(struct utf8_data *, const struct utf8_data *);
|
|||||||
enum utf8_state utf8_open(struct utf8_data *, u_char);
|
enum utf8_state utf8_open(struct utf8_data *, u_char);
|
||||||
enum utf8_state utf8_append(struct utf8_data *, u_char);
|
enum utf8_state utf8_append(struct utf8_data *, u_char);
|
||||||
int utf8_isvalid(const char *);
|
int utf8_isvalid(const char *);
|
||||||
int utf8_strvis(char *, const char *, size_t, int);
|
size_t utf8_strvis(char *, const char *, size_t, int);
|
||||||
int utf8_stravis(char **, const char *, int);
|
size_t utf8_stravis(char **, const char *, int);
|
||||||
int utf8_stravisx(char **, const char *, size_t, int);
|
size_t utf8_stravisx(char **, const char *, size_t, int);
|
||||||
char *utf8_sanitize(const char *);
|
char *utf8_sanitize(const char *);
|
||||||
size_t utf8_strlen(const struct utf8_data *);
|
size_t utf8_strlen(const struct utf8_data *);
|
||||||
u_int utf8_strwidth(const struct utf8_data *, ssize_t);
|
u_int utf8_strwidth(const struct utf8_data *, ssize_t);
|
||||||
|
|||||||
14
tty-keys.c
14
tty-keys.c
@@ -1310,7 +1310,7 @@ tty_keys_clipboard(struct tty *tty, const char *buf, size_t len, size_t *size)
|
|||||||
{
|
{
|
||||||
struct client *c = tty->client;
|
struct client *c = tty->client;
|
||||||
size_t end, terminator = 0, needed;
|
size_t end, terminator = 0, needed;
|
||||||
char *copy, *out;
|
char *copy, *out, clip = 0;
|
||||||
int outlen;
|
int outlen;
|
||||||
struct input_request_clipboard_data cd;
|
struct input_request_clipboard_data cd;
|
||||||
|
|
||||||
@@ -1360,7 +1360,14 @@ tty_keys_clipboard(struct tty *tty, const char *buf, size_t len, size_t *size)
|
|||||||
/* Adjust end so that it points to the start of the terminator. */
|
/* Adjust end so that it points to the start of the terminator. */
|
||||||
end -= terminator - 1;
|
end -= terminator - 1;
|
||||||
|
|
||||||
/* Get the second argument. */
|
/*
|
||||||
|
* Save which clipboard was used from the second argument. If more than
|
||||||
|
* one is specified (should not happen), ignore the argument.
|
||||||
|
*/
|
||||||
|
if (end >= 2 && buf[0] != ';' && buf[1] == ';')
|
||||||
|
clip = buf[0];
|
||||||
|
|
||||||
|
/* Skip the second argument. */
|
||||||
while (end != 0 && *buf != ';') {
|
while (end != 0 && *buf != ';') {
|
||||||
buf++;
|
buf++;
|
||||||
end--;
|
end--;
|
||||||
@@ -1382,7 +1389,7 @@ tty_keys_clipboard(struct tty *tty, const char *buf, size_t len, size_t *size)
|
|||||||
return (0);
|
return (0);
|
||||||
}
|
}
|
||||||
out = xmalloc(needed);
|
out = xmalloc(needed);
|
||||||
if ((outlen = b64_pton(copy, out, len)) == -1) {
|
if ((outlen = b64_pton(copy, out, needed)) == -1) {
|
||||||
free(out);
|
free(out);
|
||||||
free(copy);
|
free(copy);
|
||||||
return (0);
|
return (0);
|
||||||
@@ -1393,6 +1400,7 @@ tty_keys_clipboard(struct tty *tty, const char *buf, size_t len, size_t *size)
|
|||||||
/* Set reply if any. */
|
/* Set reply if any. */
|
||||||
cd.buf = out;
|
cd.buf = out;
|
||||||
cd.len = outlen;
|
cd.len = outlen;
|
||||||
|
cd.clip = clip;
|
||||||
input_request_reply(c, INPUT_REQUEST_CLIPBOARD, &cd);
|
input_request_reply(c, INPUT_REQUEST_CLIPBOARD, &cd);
|
||||||
|
|
||||||
/* Create a buffer if requested. */
|
/* Create a buffer if requested. */
|
||||||
|
|||||||
4
tty.c
4
tty.c
@@ -2135,7 +2135,7 @@ tty_cmd_setselection(struct tty *tty, const struct tty_ctx *ctx)
|
|||||||
}
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
tty_set_selection(struct tty *tty, const char *flags, const char *buf,
|
tty_set_selection(struct tty *tty, const char *clip, const char *buf,
|
||||||
size_t len)
|
size_t len)
|
||||||
{
|
{
|
||||||
char *encoded;
|
char *encoded;
|
||||||
@@ -2151,7 +2151,7 @@ tty_set_selection(struct tty *tty, const char *flags, const char *buf,
|
|||||||
|
|
||||||
b64_ntop(buf, len, encoded, size);
|
b64_ntop(buf, len, encoded, size);
|
||||||
tty->flags |= TTY_NOBLOCK;
|
tty->flags |= TTY_NOBLOCK;
|
||||||
tty_putcode_ss(tty, TTYC_MS, flags, encoded);
|
tty_putcode_ss(tty, TTYC_MS, clip, encoded);
|
||||||
|
|
||||||
free(encoded);
|
free(encoded);
|
||||||
}
|
}
|
||||||
|
|||||||
10
utf8.c
10
utf8.c
@@ -652,7 +652,7 @@ utf8_append(struct utf8_data *ud, u_char ch)
|
|||||||
* bytes available for each character from src (for \abc or UTF-8) plus space
|
* bytes available for each character from src (for \abc or UTF-8) plus space
|
||||||
* for \0.
|
* for \0.
|
||||||
*/
|
*/
|
||||||
int
|
size_t
|
||||||
utf8_strvis(char *dst, const char *src, size_t len, int flag)
|
utf8_strvis(char *dst, const char *src, size_t len, int flag)
|
||||||
{
|
{
|
||||||
struct utf8_data ud;
|
struct utf8_data ud;
|
||||||
@@ -690,11 +690,11 @@ utf8_strvis(char *dst, const char *src, size_t len, int flag)
|
|||||||
}
|
}
|
||||||
|
|
||||||
/* Same as utf8_strvis but allocate the buffer. */
|
/* Same as utf8_strvis but allocate the buffer. */
|
||||||
int
|
size_t
|
||||||
utf8_stravis(char **dst, const char *src, int flag)
|
utf8_stravis(char **dst, const char *src, int flag)
|
||||||
{
|
{
|
||||||
char *buf;
|
char *buf;
|
||||||
int len;
|
size_t len;
|
||||||
|
|
||||||
buf = xreallocarray(NULL, 4, strlen(src) + 1);
|
buf = xreallocarray(NULL, 4, strlen(src) + 1);
|
||||||
len = utf8_strvis(buf, src, strlen(src), flag);
|
len = utf8_strvis(buf, src, strlen(src), flag);
|
||||||
@@ -704,11 +704,11 @@ utf8_stravis(char **dst, const char *src, int flag)
|
|||||||
}
|
}
|
||||||
|
|
||||||
/* Same as utf8_strvis but allocate the buffer. */
|
/* Same as utf8_strvis but allocate the buffer. */
|
||||||
int
|
size_t
|
||||||
utf8_stravisx(char **dst, const char *src, size_t srclen, int flag)
|
utf8_stravisx(char **dst, const char *src, size_t srclen, int flag)
|
||||||
{
|
{
|
||||||
char *buf;
|
char *buf;
|
||||||
int len;
|
size_t len;
|
||||||
|
|
||||||
buf = xreallocarray(NULL, 4, srclen + 1);
|
buf = xreallocarray(NULL, 4, srclen + 1);
|
||||||
len = utf8_strvis(buf, src, srclen, flag);
|
len = utf8_strvis(buf, src, srclen, flag);
|
||||||
|
|||||||
152
window-copy.c
152
window-copy.c
@@ -2127,6 +2127,36 @@ window_copy_cmd_rectangle_toggle(struct window_copy_cmd_state *cs)
|
|||||||
return (WINDOW_COPY_CMD_NOTHING);
|
return (WINDOW_COPY_CMD_NOTHING);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static enum window_copy_cmd_action
|
||||||
|
window_copy_cmd_scroll_exit_on(struct window_copy_cmd_state *cs)
|
||||||
|
{
|
||||||
|
struct window_copy_mode_data *data = cs->wme->data;
|
||||||
|
|
||||||
|
data->scroll_exit = 1;
|
||||||
|
|
||||||
|
return (WINDOW_COPY_CMD_NOTHING);
|
||||||
|
}
|
||||||
|
|
||||||
|
static enum window_copy_cmd_action
|
||||||
|
window_copy_cmd_scroll_exit_off(struct window_copy_cmd_state *cs)
|
||||||
|
{
|
||||||
|
struct window_copy_mode_data *data = cs->wme->data;
|
||||||
|
|
||||||
|
data->scroll_exit = 0;
|
||||||
|
|
||||||
|
return (WINDOW_COPY_CMD_NOTHING);
|
||||||
|
}
|
||||||
|
|
||||||
|
static enum window_copy_cmd_action
|
||||||
|
window_copy_cmd_scroll_exit_toggle(struct window_copy_cmd_state *cs)
|
||||||
|
{
|
||||||
|
struct window_copy_mode_data *data = cs->wme->data;
|
||||||
|
|
||||||
|
data->scroll_exit = !data->scroll_exit;
|
||||||
|
|
||||||
|
return (WINDOW_COPY_CMD_NOTHING);
|
||||||
|
}
|
||||||
|
|
||||||
static enum window_copy_cmd_action
|
static enum window_copy_cmd_action
|
||||||
window_copy_cmd_scroll_down(struct window_copy_cmd_state *cs)
|
window_copy_cmd_scroll_down(struct window_copy_cmd_state *cs)
|
||||||
{
|
{
|
||||||
@@ -2702,16 +2732,20 @@ window_copy_cmd_refresh_from_pane(struct window_copy_cmd_state *cs)
|
|||||||
struct window_mode_entry *wme = cs->wme;
|
struct window_mode_entry *wme = cs->wme;
|
||||||
struct window_pane *wp = wme->swp;
|
struct window_pane *wp = wme->swp;
|
||||||
struct window_copy_mode_data *data = wme->data;
|
struct window_copy_mode_data *data = wme->data;
|
||||||
|
u_int oy_from_top;
|
||||||
|
|
||||||
if (data->viewmode)
|
if (data->viewmode)
|
||||||
return (WINDOW_COPY_CMD_NOTHING);
|
return (WINDOW_COPY_CMD_NOTHING);
|
||||||
|
oy_from_top = screen_hsize(data->backing) - data->oy;
|
||||||
|
|
||||||
screen_free(data->backing);
|
screen_free(data->backing);
|
||||||
free(data->backing);
|
free(data->backing);
|
||||||
data->backing = window_copy_clone_screen(&wp->base, &data->screen, NULL,
|
data->backing = window_copy_clone_screen(&wp->base, &data->screen, NULL,
|
||||||
NULL, wme->swp != wme->wp);
|
NULL, wme->swp != wme->wp);
|
||||||
|
|
||||||
if (data->oy > screen_hsize(data->backing)) {
|
if (oy_from_top <= screen_hsize(data->backing))
|
||||||
|
data->oy = screen_hsize(data->backing) - oy_from_top;
|
||||||
|
else {
|
||||||
data->cy = 0;
|
data->cy = 0;
|
||||||
data->oy = screen_hsize(data->backing);
|
data->oy = screen_hsize(data->backing);
|
||||||
}
|
}
|
||||||
@@ -2725,451 +2759,559 @@ static const struct {
|
|||||||
u_int minargs;
|
u_int minargs;
|
||||||
u_int maxargs;
|
u_int maxargs;
|
||||||
struct args_parse args;
|
struct args_parse args;
|
||||||
|
|
||||||
|
#define WINDOW_COPY_CMD_FLAG_READONLY 0x1
|
||||||
|
int flags;
|
||||||
|
|
||||||
enum window_copy_cmd_clear clear;
|
enum window_copy_cmd_clear clear;
|
||||||
enum window_copy_cmd_action (*f)(struct window_copy_cmd_state *);
|
enum window_copy_cmd_action (*f)(struct window_copy_cmd_state *);
|
||||||
} window_copy_cmd_table[] = {
|
} window_copy_cmd_table[] = {
|
||||||
{ .command = "append-selection",
|
{ .command = "append-selection",
|
||||||
.args = { "", 0, 0, NULL },
|
.args = { "", 0, 0, NULL },
|
||||||
|
.flags = 0,
|
||||||
.clear = WINDOW_COPY_CMD_CLEAR_ALWAYS,
|
.clear = WINDOW_COPY_CMD_CLEAR_ALWAYS,
|
||||||
.f = window_copy_cmd_append_selection
|
.f = window_copy_cmd_append_selection
|
||||||
},
|
},
|
||||||
{ .command = "append-selection-and-cancel",
|
{ .command = "append-selection-and-cancel",
|
||||||
.args = { "", 0, 0, NULL },
|
.args = { "", 0, 0, NULL },
|
||||||
|
.flags = 0,
|
||||||
.clear = WINDOW_COPY_CMD_CLEAR_ALWAYS,
|
.clear = WINDOW_COPY_CMD_CLEAR_ALWAYS,
|
||||||
.f = window_copy_cmd_append_selection_and_cancel
|
.f = window_copy_cmd_append_selection_and_cancel
|
||||||
},
|
},
|
||||||
{ .command = "back-to-indentation",
|
{ .command = "back-to-indentation",
|
||||||
.args = { "", 0, 0, NULL },
|
.args = { "", 0, 0, NULL },
|
||||||
|
.flags = WINDOW_COPY_CMD_FLAG_READONLY,
|
||||||
.clear = WINDOW_COPY_CMD_CLEAR_ALWAYS,
|
.clear = WINDOW_COPY_CMD_CLEAR_ALWAYS,
|
||||||
.f = window_copy_cmd_back_to_indentation
|
.f = window_copy_cmd_back_to_indentation
|
||||||
},
|
},
|
||||||
{ .command = "begin-selection",
|
{ .command = "begin-selection",
|
||||||
.args = { "", 0, 0, NULL },
|
.args = { "", 0, 0, NULL },
|
||||||
|
.flags = 0,
|
||||||
.clear = WINDOW_COPY_CMD_CLEAR_ALWAYS,
|
.clear = WINDOW_COPY_CMD_CLEAR_ALWAYS,
|
||||||
.f = window_copy_cmd_begin_selection
|
.f = window_copy_cmd_begin_selection
|
||||||
},
|
},
|
||||||
{ .command = "bottom-line",
|
{ .command = "bottom-line",
|
||||||
.args = { "", 0, 0, NULL },
|
.args = { "", 0, 0, NULL },
|
||||||
|
.flags = WINDOW_COPY_CMD_FLAG_READONLY,
|
||||||
.clear = WINDOW_COPY_CMD_CLEAR_EMACS_ONLY,
|
.clear = WINDOW_COPY_CMD_CLEAR_EMACS_ONLY,
|
||||||
.f = window_copy_cmd_bottom_line
|
.f = window_copy_cmd_bottom_line
|
||||||
},
|
},
|
||||||
{ .command = "cancel",
|
{ .command = "cancel",
|
||||||
.args = { "", 0, 0, NULL },
|
.args = { "", 0, 0, NULL },
|
||||||
|
.flags = WINDOW_COPY_CMD_FLAG_READONLY,
|
||||||
.clear = WINDOW_COPY_CMD_CLEAR_ALWAYS,
|
.clear = WINDOW_COPY_CMD_CLEAR_ALWAYS,
|
||||||
.f = window_copy_cmd_cancel
|
.f = window_copy_cmd_cancel
|
||||||
},
|
},
|
||||||
{ .command = "clear-selection",
|
{ .command = "clear-selection",
|
||||||
.args = { "", 0, 0, NULL },
|
.args = { "", 0, 0, NULL },
|
||||||
|
.flags = 0,
|
||||||
.clear = WINDOW_COPY_CMD_CLEAR_ALWAYS,
|
.clear = WINDOW_COPY_CMD_CLEAR_ALWAYS,
|
||||||
.f = window_copy_cmd_clear_selection
|
.f = window_copy_cmd_clear_selection
|
||||||
},
|
},
|
||||||
{ .command = "copy-end-of-line",
|
{ .command = "copy-end-of-line",
|
||||||
.args = { "CP", 0, 1, NULL },
|
.args = { "CP", 0, 1, NULL },
|
||||||
|
.flags = 0,
|
||||||
.clear = WINDOW_COPY_CMD_CLEAR_ALWAYS,
|
.clear = WINDOW_COPY_CMD_CLEAR_ALWAYS,
|
||||||
.f = window_copy_cmd_copy_end_of_line
|
.f = window_copy_cmd_copy_end_of_line
|
||||||
},
|
},
|
||||||
{ .command = "copy-end-of-line-and-cancel",
|
{ .command = "copy-end-of-line-and-cancel",
|
||||||
.args = { "CP", 0, 1, NULL },
|
.args = { "CP", 0, 1, NULL },
|
||||||
|
.flags = 0,
|
||||||
.clear = WINDOW_COPY_CMD_CLEAR_ALWAYS,
|
.clear = WINDOW_COPY_CMD_CLEAR_ALWAYS,
|
||||||
.f = window_copy_cmd_copy_end_of_line_and_cancel
|
.f = window_copy_cmd_copy_end_of_line_and_cancel
|
||||||
},
|
},
|
||||||
{ .command = "copy-pipe-end-of-line",
|
{ .command = "copy-pipe-end-of-line",
|
||||||
.args = { "CP", 0, 2, NULL },
|
.args = { "CP", 0, 2, NULL },
|
||||||
|
.flags = 0,
|
||||||
.clear = WINDOW_COPY_CMD_CLEAR_ALWAYS,
|
.clear = WINDOW_COPY_CMD_CLEAR_ALWAYS,
|
||||||
.f = window_copy_cmd_copy_pipe_end_of_line
|
.f = window_copy_cmd_copy_pipe_end_of_line
|
||||||
},
|
},
|
||||||
{ .command = "copy-pipe-end-of-line-and-cancel",
|
{ .command = "copy-pipe-end-of-line-and-cancel",
|
||||||
.args = { "CP", 0, 2, NULL },
|
.args = { "CP", 0, 2, NULL },
|
||||||
|
.flags = 0,
|
||||||
.clear = WINDOW_COPY_CMD_CLEAR_ALWAYS,
|
.clear = WINDOW_COPY_CMD_CLEAR_ALWAYS,
|
||||||
.f = window_copy_cmd_copy_pipe_end_of_line_and_cancel
|
.f = window_copy_cmd_copy_pipe_end_of_line_and_cancel
|
||||||
},
|
},
|
||||||
{ .command = "copy-line",
|
{ .command = "copy-line",
|
||||||
.args = { "CP", 0, 1, NULL },
|
.args = { "CP", 0, 1, NULL },
|
||||||
|
.flags = 0,
|
||||||
.clear = WINDOW_COPY_CMD_CLEAR_ALWAYS,
|
.clear = WINDOW_COPY_CMD_CLEAR_ALWAYS,
|
||||||
.f = window_copy_cmd_copy_line
|
.f = window_copy_cmd_copy_line
|
||||||
},
|
},
|
||||||
{ .command = "copy-line-and-cancel",
|
{ .command = "copy-line-and-cancel",
|
||||||
.args = { "CP", 0, 1, NULL },
|
.args = { "CP", 0, 1, NULL },
|
||||||
|
.flags = 0,
|
||||||
.clear = WINDOW_COPY_CMD_CLEAR_ALWAYS,
|
.clear = WINDOW_COPY_CMD_CLEAR_ALWAYS,
|
||||||
.f = window_copy_cmd_copy_line_and_cancel
|
.f = window_copy_cmd_copy_line_and_cancel
|
||||||
},
|
},
|
||||||
{ .command = "copy-pipe-line",
|
{ .command = "copy-pipe-line",
|
||||||
.args = { "CP", 0, 2, NULL },
|
.args = { "CP", 0, 2, NULL },
|
||||||
|
.flags = 0,
|
||||||
.clear = WINDOW_COPY_CMD_CLEAR_ALWAYS,
|
.clear = WINDOW_COPY_CMD_CLEAR_ALWAYS,
|
||||||
.f = window_copy_cmd_copy_pipe_line
|
.f = window_copy_cmd_copy_pipe_line
|
||||||
},
|
},
|
||||||
{ .command = "copy-pipe-line-and-cancel",
|
{ .command = "copy-pipe-line-and-cancel",
|
||||||
.args = { "CP", 0, 2, NULL },
|
.args = { "CP", 0, 2, NULL },
|
||||||
|
.flags = 0,
|
||||||
.clear = WINDOW_COPY_CMD_CLEAR_ALWAYS,
|
.clear = WINDOW_COPY_CMD_CLEAR_ALWAYS,
|
||||||
.f = window_copy_cmd_copy_pipe_line_and_cancel
|
.f = window_copy_cmd_copy_pipe_line_and_cancel
|
||||||
},
|
},
|
||||||
{ .command = "copy-pipe-no-clear",
|
{ .command = "copy-pipe-no-clear",
|
||||||
.args = { "CP", 0, 2, NULL },
|
.args = { "CP", 0, 2, NULL },
|
||||||
|
.flags = 0,
|
||||||
.clear = WINDOW_COPY_CMD_CLEAR_NEVER,
|
.clear = WINDOW_COPY_CMD_CLEAR_NEVER,
|
||||||
.f = window_copy_cmd_copy_pipe_no_clear
|
.f = window_copy_cmd_copy_pipe_no_clear
|
||||||
},
|
},
|
||||||
{ .command = "copy-pipe",
|
{ .command = "copy-pipe",
|
||||||
.args = { "CP", 0, 2, NULL },
|
.args = { "CP", 0, 2, NULL },
|
||||||
|
.flags = 0,
|
||||||
.clear = WINDOW_COPY_CMD_CLEAR_ALWAYS,
|
.clear = WINDOW_COPY_CMD_CLEAR_ALWAYS,
|
||||||
.f = window_copy_cmd_copy_pipe
|
.f = window_copy_cmd_copy_pipe
|
||||||
},
|
},
|
||||||
{ .command = "copy-pipe-and-cancel",
|
{ .command = "copy-pipe-and-cancel",
|
||||||
.args = { "CP", 0, 2, NULL },
|
.args = { "CP", 0, 2, NULL },
|
||||||
|
.flags = 0,
|
||||||
.clear = WINDOW_COPY_CMD_CLEAR_ALWAYS,
|
.clear = WINDOW_COPY_CMD_CLEAR_ALWAYS,
|
||||||
.f = window_copy_cmd_copy_pipe_and_cancel
|
.f = window_copy_cmd_copy_pipe_and_cancel
|
||||||
},
|
},
|
||||||
{ .command = "copy-selection-no-clear",
|
{ .command = "copy-selection-no-clear",
|
||||||
.args = { "CP", 0, 1, NULL },
|
.args = { "CP", 0, 1, NULL },
|
||||||
|
.flags = 0,
|
||||||
.clear = WINDOW_COPY_CMD_CLEAR_NEVER,
|
.clear = WINDOW_COPY_CMD_CLEAR_NEVER,
|
||||||
.f = window_copy_cmd_copy_selection_no_clear
|
.f = window_copy_cmd_copy_selection_no_clear
|
||||||
},
|
},
|
||||||
{ .command = "copy-selection",
|
{ .command = "copy-selection",
|
||||||
.args = { "CP", 0, 1, NULL },
|
.args = { "CP", 0, 1, NULL },
|
||||||
|
.flags = 0,
|
||||||
.clear = WINDOW_COPY_CMD_CLEAR_ALWAYS,
|
.clear = WINDOW_COPY_CMD_CLEAR_ALWAYS,
|
||||||
.f = window_copy_cmd_copy_selection
|
.f = window_copy_cmd_copy_selection
|
||||||
},
|
},
|
||||||
{ .command = "copy-selection-and-cancel",
|
{ .command = "copy-selection-and-cancel",
|
||||||
.args = { "CP", 0, 1, NULL },
|
.args = { "CP", 0, 1, NULL },
|
||||||
|
.flags = 0,
|
||||||
.clear = WINDOW_COPY_CMD_CLEAR_ALWAYS,
|
.clear = WINDOW_COPY_CMD_CLEAR_ALWAYS,
|
||||||
.f = window_copy_cmd_copy_selection_and_cancel
|
.f = window_copy_cmd_copy_selection_and_cancel
|
||||||
},
|
},
|
||||||
{ .command = "cursor-down",
|
{ .command = "cursor-down",
|
||||||
.args = { "", 0, 0, NULL },
|
.args = { "", 0, 0, NULL },
|
||||||
|
.flags = WINDOW_COPY_CMD_FLAG_READONLY,
|
||||||
.clear = WINDOW_COPY_CMD_CLEAR_EMACS_ONLY,
|
.clear = WINDOW_COPY_CMD_CLEAR_EMACS_ONLY,
|
||||||
.f = window_copy_cmd_cursor_down
|
.f = window_copy_cmd_cursor_down
|
||||||
},
|
},
|
||||||
{ .command = "cursor-down-and-cancel",
|
{ .command = "cursor-down-and-cancel",
|
||||||
.args = { "", 0, 0, NULL },
|
.args = { "", 0, 0, NULL },
|
||||||
|
.flags = WINDOW_COPY_CMD_FLAG_READONLY,
|
||||||
.clear = WINDOW_COPY_CMD_CLEAR_ALWAYS,
|
.clear = WINDOW_COPY_CMD_CLEAR_ALWAYS,
|
||||||
.f = window_copy_cmd_cursor_down_and_cancel
|
.f = window_copy_cmd_cursor_down_and_cancel
|
||||||
},
|
},
|
||||||
{ .command = "cursor-left",
|
{ .command = "cursor-left",
|
||||||
.args = { "", 0, 0, NULL },
|
.args = { "", 0, 0, NULL },
|
||||||
|
.flags = WINDOW_COPY_CMD_FLAG_READONLY,
|
||||||
.clear = WINDOW_COPY_CMD_CLEAR_EMACS_ONLY,
|
.clear = WINDOW_COPY_CMD_CLEAR_EMACS_ONLY,
|
||||||
.f = window_copy_cmd_cursor_left
|
.f = window_copy_cmd_cursor_left
|
||||||
},
|
},
|
||||||
{ .command = "cursor-right",
|
{ .command = "cursor-right",
|
||||||
.args = { "", 0, 0, NULL },
|
.args = { "", 0, 0, NULL },
|
||||||
|
.flags = WINDOW_COPY_CMD_FLAG_READONLY,
|
||||||
.clear = WINDOW_COPY_CMD_CLEAR_EMACS_ONLY,
|
.clear = WINDOW_COPY_CMD_CLEAR_EMACS_ONLY,
|
||||||
.f = window_copy_cmd_cursor_right
|
.f = window_copy_cmd_cursor_right
|
||||||
},
|
},
|
||||||
{ .command = "cursor-up",
|
{ .command = "cursor-up",
|
||||||
.args = { "", 0, 0, NULL },
|
.args = { "", 0, 0, NULL },
|
||||||
|
.flags = WINDOW_COPY_CMD_FLAG_READONLY,
|
||||||
.clear = WINDOW_COPY_CMD_CLEAR_EMACS_ONLY,
|
.clear = WINDOW_COPY_CMD_CLEAR_EMACS_ONLY,
|
||||||
.f = window_copy_cmd_cursor_up
|
.f = window_copy_cmd_cursor_up
|
||||||
},
|
},
|
||||||
{ .command = "cursor-centre-vertical",
|
{ .command = "cursor-centre-vertical",
|
||||||
.args = { "", 0, 0, NULL },
|
.args = { "", 0, 0, NULL },
|
||||||
|
.flags = WINDOW_COPY_CMD_FLAG_READONLY,
|
||||||
.clear = WINDOW_COPY_CMD_CLEAR_EMACS_ONLY,
|
.clear = WINDOW_COPY_CMD_CLEAR_EMACS_ONLY,
|
||||||
.f = window_copy_cmd_centre_vertical,
|
.f = window_copy_cmd_centre_vertical,
|
||||||
},
|
},
|
||||||
{ .command = "cursor-centre-horizontal",
|
{ .command = "cursor-centre-horizontal",
|
||||||
.args = { "", 0, 0, NULL },
|
.args = { "", 0, 0, NULL },
|
||||||
|
.flags = WINDOW_COPY_CMD_FLAG_READONLY,
|
||||||
.clear = WINDOW_COPY_CMD_CLEAR_EMACS_ONLY,
|
.clear = WINDOW_COPY_CMD_CLEAR_EMACS_ONLY,
|
||||||
.f = window_copy_cmd_centre_horizontal,
|
.f = window_copy_cmd_centre_horizontal,
|
||||||
},
|
},
|
||||||
{ .command = "end-of-line",
|
{ .command = "end-of-line",
|
||||||
.args = { "", 0, 0, NULL },
|
.args = { "", 0, 0, NULL },
|
||||||
|
.flags = WINDOW_COPY_CMD_FLAG_READONLY,
|
||||||
.clear = WINDOW_COPY_CMD_CLEAR_EMACS_ONLY,
|
.clear = WINDOW_COPY_CMD_CLEAR_EMACS_ONLY,
|
||||||
.f = window_copy_cmd_end_of_line
|
.f = window_copy_cmd_end_of_line
|
||||||
},
|
},
|
||||||
{ .command = "goto-line",
|
{ .command = "goto-line",
|
||||||
.args = { "", 1, 1, NULL },
|
.args = { "", 1, 1, NULL },
|
||||||
|
.flags = WINDOW_COPY_CMD_FLAG_READONLY,
|
||||||
.clear = WINDOW_COPY_CMD_CLEAR_EMACS_ONLY,
|
.clear = WINDOW_COPY_CMD_CLEAR_EMACS_ONLY,
|
||||||
.f = window_copy_cmd_goto_line
|
.f = window_copy_cmd_goto_line
|
||||||
},
|
},
|
||||||
{ .command = "halfpage-down",
|
{ .command = "halfpage-down",
|
||||||
.args = { "", 0, 0, NULL },
|
.args = { "", 0, 0, NULL },
|
||||||
|
.flags = WINDOW_COPY_CMD_FLAG_READONLY,
|
||||||
.clear = WINDOW_COPY_CMD_CLEAR_EMACS_ONLY,
|
.clear = WINDOW_COPY_CMD_CLEAR_EMACS_ONLY,
|
||||||
.f = window_copy_cmd_halfpage_down
|
.f = window_copy_cmd_halfpage_down
|
||||||
},
|
},
|
||||||
{ .command = "halfpage-down-and-cancel",
|
{ .command = "halfpage-down-and-cancel",
|
||||||
.args = { "", 0, 0, NULL },
|
.args = { "", 0, 0, NULL },
|
||||||
|
.flags = WINDOW_COPY_CMD_FLAG_READONLY,
|
||||||
.clear = WINDOW_COPY_CMD_CLEAR_ALWAYS,
|
.clear = WINDOW_COPY_CMD_CLEAR_ALWAYS,
|
||||||
.f = window_copy_cmd_halfpage_down_and_cancel
|
.f = window_copy_cmd_halfpage_down_and_cancel
|
||||||
},
|
},
|
||||||
{ .command = "halfpage-up",
|
{ .command = "halfpage-up",
|
||||||
.args = { "", 0, 0, NULL },
|
.args = { "", 0, 0, NULL },
|
||||||
|
.flags = WINDOW_COPY_CMD_FLAG_READONLY,
|
||||||
.clear = WINDOW_COPY_CMD_CLEAR_EMACS_ONLY,
|
.clear = WINDOW_COPY_CMD_CLEAR_EMACS_ONLY,
|
||||||
.f = window_copy_cmd_halfpage_up
|
.f = window_copy_cmd_halfpage_up
|
||||||
},
|
},
|
||||||
{ .command = "history-bottom",
|
{ .command = "history-bottom",
|
||||||
.args = { "", 0, 0, NULL },
|
.args = { "", 0, 0, NULL },
|
||||||
|
.flags = WINDOW_COPY_CMD_FLAG_READONLY,
|
||||||
.clear = WINDOW_COPY_CMD_CLEAR_EMACS_ONLY,
|
.clear = WINDOW_COPY_CMD_CLEAR_EMACS_ONLY,
|
||||||
.f = window_copy_cmd_history_bottom
|
.f = window_copy_cmd_history_bottom
|
||||||
},
|
},
|
||||||
{ .command = "history-top",
|
{ .command = "history-top",
|
||||||
.args = { "", 0, 0, NULL },
|
.args = { "", 0, 0, NULL },
|
||||||
|
.flags = WINDOW_COPY_CMD_FLAG_READONLY,
|
||||||
.clear = WINDOW_COPY_CMD_CLEAR_EMACS_ONLY,
|
.clear = WINDOW_COPY_CMD_CLEAR_EMACS_ONLY,
|
||||||
.f = window_copy_cmd_history_top
|
.f = window_copy_cmd_history_top
|
||||||
},
|
},
|
||||||
{ .command = "jump-again",
|
{ .command = "jump-again",
|
||||||
.args = { "", 0, 0, NULL },
|
.args = { "", 0, 0, NULL },
|
||||||
|
.flags = 0,
|
||||||
.clear = WINDOW_COPY_CMD_CLEAR_EMACS_ONLY,
|
.clear = WINDOW_COPY_CMD_CLEAR_EMACS_ONLY,
|
||||||
.f = window_copy_cmd_jump_again
|
.f = window_copy_cmd_jump_again
|
||||||
},
|
},
|
||||||
{ .command = "jump-backward",
|
{ .command = "jump-backward",
|
||||||
.args = { "", 1, 1, NULL },
|
.args = { "", 1, 1, NULL },
|
||||||
|
.flags = 0,
|
||||||
.clear = WINDOW_COPY_CMD_CLEAR_EMACS_ONLY,
|
.clear = WINDOW_COPY_CMD_CLEAR_EMACS_ONLY,
|
||||||
.f = window_copy_cmd_jump_backward
|
.f = window_copy_cmd_jump_backward
|
||||||
},
|
},
|
||||||
{ .command = "jump-forward",
|
{ .command = "jump-forward",
|
||||||
.args = { "", 1, 1, NULL },
|
.args = { "", 1, 1, NULL },
|
||||||
|
.flags = 0,
|
||||||
.clear = WINDOW_COPY_CMD_CLEAR_EMACS_ONLY,
|
.clear = WINDOW_COPY_CMD_CLEAR_EMACS_ONLY,
|
||||||
.f = window_copy_cmd_jump_forward
|
.f = window_copy_cmd_jump_forward
|
||||||
},
|
},
|
||||||
{ .command = "jump-reverse",
|
{ .command = "jump-reverse",
|
||||||
.args = { "", 0, 0, NULL },
|
.args = { "", 0, 0, NULL },
|
||||||
|
.flags = 0,
|
||||||
.clear = WINDOW_COPY_CMD_CLEAR_EMACS_ONLY,
|
.clear = WINDOW_COPY_CMD_CLEAR_EMACS_ONLY,
|
||||||
.f = window_copy_cmd_jump_reverse
|
.f = window_copy_cmd_jump_reverse
|
||||||
},
|
},
|
||||||
{ .command = "jump-to-backward",
|
{ .command = "jump-to-backward",
|
||||||
.args = { "", 1, 1, NULL },
|
.args = { "", 1, 1, NULL },
|
||||||
|
.flags = 0,
|
||||||
.clear = WINDOW_COPY_CMD_CLEAR_EMACS_ONLY,
|
.clear = WINDOW_COPY_CMD_CLEAR_EMACS_ONLY,
|
||||||
.f = window_copy_cmd_jump_to_backward
|
.f = window_copy_cmd_jump_to_backward
|
||||||
},
|
},
|
||||||
{ .command = "jump-to-forward",
|
{ .command = "jump-to-forward",
|
||||||
.args = { "", 1, 1, NULL },
|
.args = { "", 1, 1, NULL },
|
||||||
|
.flags = 0,
|
||||||
.clear = WINDOW_COPY_CMD_CLEAR_EMACS_ONLY,
|
.clear = WINDOW_COPY_CMD_CLEAR_EMACS_ONLY,
|
||||||
.f = window_copy_cmd_jump_to_forward
|
.f = window_copy_cmd_jump_to_forward
|
||||||
},
|
},
|
||||||
{ .command = "jump-to-mark",
|
{ .command = "jump-to-mark",
|
||||||
.args = { "", 0, 0, NULL },
|
.args = { "", 0, 0, NULL },
|
||||||
|
.flags = WINDOW_COPY_CMD_FLAG_READONLY,
|
||||||
.clear = WINDOW_COPY_CMD_CLEAR_ALWAYS,
|
.clear = WINDOW_COPY_CMD_CLEAR_ALWAYS,
|
||||||
.f = window_copy_cmd_jump_to_mark
|
.f = window_copy_cmd_jump_to_mark
|
||||||
},
|
},
|
||||||
{ .command = "next-prompt",
|
{ .command = "next-prompt",
|
||||||
.args = { "o", 0, 0, NULL },
|
.args = { "o", 0, 0, NULL },
|
||||||
|
.flags = WINDOW_COPY_CMD_FLAG_READONLY,
|
||||||
.clear = WINDOW_COPY_CMD_CLEAR_ALWAYS,
|
.clear = WINDOW_COPY_CMD_CLEAR_ALWAYS,
|
||||||
.f = window_copy_cmd_next_prompt
|
.f = window_copy_cmd_next_prompt
|
||||||
},
|
},
|
||||||
{ .command = "previous-prompt",
|
{ .command = "previous-prompt",
|
||||||
.args = { "o", 0, 0, NULL },
|
.args = { "o", 0, 0, NULL },
|
||||||
|
.flags = WINDOW_COPY_CMD_FLAG_READONLY,
|
||||||
.clear = WINDOW_COPY_CMD_CLEAR_ALWAYS,
|
.clear = WINDOW_COPY_CMD_CLEAR_ALWAYS,
|
||||||
.f = window_copy_cmd_previous_prompt
|
.f = window_copy_cmd_previous_prompt
|
||||||
},
|
},
|
||||||
{ .command = "middle-line",
|
{ .command = "middle-line",
|
||||||
.args = { "", 0, 0, NULL },
|
.args = { "", 0, 0, NULL },
|
||||||
|
.flags = WINDOW_COPY_CMD_FLAG_READONLY,
|
||||||
.clear = WINDOW_COPY_CMD_CLEAR_EMACS_ONLY,
|
.clear = WINDOW_COPY_CMD_CLEAR_EMACS_ONLY,
|
||||||
.f = window_copy_cmd_middle_line
|
.f = window_copy_cmd_middle_line
|
||||||
},
|
},
|
||||||
{ .command = "next-matching-bracket",
|
{ .command = "next-matching-bracket",
|
||||||
.args = { "", 0, 0, NULL },
|
.args = { "", 0, 0, NULL },
|
||||||
|
.flags = WINDOW_COPY_CMD_FLAG_READONLY,
|
||||||
.clear = WINDOW_COPY_CMD_CLEAR_ALWAYS,
|
.clear = WINDOW_COPY_CMD_CLEAR_ALWAYS,
|
||||||
.f = window_copy_cmd_next_matching_bracket
|
.f = window_copy_cmd_next_matching_bracket
|
||||||
},
|
},
|
||||||
{ .command = "next-paragraph",
|
{ .command = "next-paragraph",
|
||||||
.args = { "", 0, 0, NULL },
|
.args = { "", 0, 0, NULL },
|
||||||
|
.flags = WINDOW_COPY_CMD_FLAG_READONLY,
|
||||||
.clear = WINDOW_COPY_CMD_CLEAR_EMACS_ONLY,
|
.clear = WINDOW_COPY_CMD_CLEAR_EMACS_ONLY,
|
||||||
.f = window_copy_cmd_next_paragraph
|
.f = window_copy_cmd_next_paragraph
|
||||||
},
|
},
|
||||||
{ .command = "next-space",
|
{ .command = "next-space",
|
||||||
.args = { "", 0, 0, NULL },
|
.args = { "", 0, 0, NULL },
|
||||||
|
.flags = WINDOW_COPY_CMD_FLAG_READONLY,
|
||||||
.clear = WINDOW_COPY_CMD_CLEAR_EMACS_ONLY,
|
.clear = WINDOW_COPY_CMD_CLEAR_EMACS_ONLY,
|
||||||
.f = window_copy_cmd_next_space
|
.f = window_copy_cmd_next_space
|
||||||
},
|
},
|
||||||
{ .command = "next-space-end",
|
{ .command = "next-space-end",
|
||||||
.args = { "", 0, 0, NULL },
|
.args = { "", 0, 0, NULL },
|
||||||
|
.flags = WINDOW_COPY_CMD_FLAG_READONLY,
|
||||||
.clear = WINDOW_COPY_CMD_CLEAR_EMACS_ONLY,
|
.clear = WINDOW_COPY_CMD_CLEAR_EMACS_ONLY,
|
||||||
.f = window_copy_cmd_next_space_end
|
.f = window_copy_cmd_next_space_end
|
||||||
},
|
},
|
||||||
{ .command = "next-word",
|
{ .command = "next-word",
|
||||||
.args = { "", 0, 0, NULL },
|
.args = { "", 0, 0, NULL },
|
||||||
|
.flags = WINDOW_COPY_CMD_FLAG_READONLY,
|
||||||
.clear = WINDOW_COPY_CMD_CLEAR_EMACS_ONLY,
|
.clear = WINDOW_COPY_CMD_CLEAR_EMACS_ONLY,
|
||||||
.f = window_copy_cmd_next_word
|
.f = window_copy_cmd_next_word
|
||||||
},
|
},
|
||||||
{ .command = "next-word-end",
|
{ .command = "next-word-end",
|
||||||
.args = { "", 0, 0, NULL },
|
.args = { "", 0, 0, NULL },
|
||||||
|
.flags = WINDOW_COPY_CMD_FLAG_READONLY,
|
||||||
.clear = WINDOW_COPY_CMD_CLEAR_EMACS_ONLY,
|
.clear = WINDOW_COPY_CMD_CLEAR_EMACS_ONLY,
|
||||||
.f = window_copy_cmd_next_word_end
|
.f = window_copy_cmd_next_word_end
|
||||||
},
|
},
|
||||||
{ .command = "other-end",
|
{ .command = "other-end",
|
||||||
.args = { "", 0, 0, NULL },
|
.args = { "", 0, 0, NULL },
|
||||||
|
.flags = 0,
|
||||||
.clear = WINDOW_COPY_CMD_CLEAR_EMACS_ONLY,
|
.clear = WINDOW_COPY_CMD_CLEAR_EMACS_ONLY,
|
||||||
.f = window_copy_cmd_other_end
|
.f = window_copy_cmd_other_end
|
||||||
},
|
},
|
||||||
{ .command = "page-down",
|
{ .command = "page-down",
|
||||||
.args = { "", 0, 0, NULL },
|
.args = { "", 0, 0, NULL },
|
||||||
|
.flags = WINDOW_COPY_CMD_FLAG_READONLY,
|
||||||
.clear = WINDOW_COPY_CMD_CLEAR_EMACS_ONLY,
|
.clear = WINDOW_COPY_CMD_CLEAR_EMACS_ONLY,
|
||||||
.f = window_copy_cmd_page_down
|
.f = window_copy_cmd_page_down
|
||||||
},
|
},
|
||||||
{ .command = "page-down-and-cancel",
|
{ .command = "page-down-and-cancel",
|
||||||
.args = { "", 0, 0, NULL },
|
.args = { "", 0, 0, NULL },
|
||||||
|
.flags = WINDOW_COPY_CMD_FLAG_READONLY,
|
||||||
.clear = WINDOW_COPY_CMD_CLEAR_ALWAYS,
|
.clear = WINDOW_COPY_CMD_CLEAR_ALWAYS,
|
||||||
.f = window_copy_cmd_page_down_and_cancel
|
.f = window_copy_cmd_page_down_and_cancel
|
||||||
},
|
},
|
||||||
{ .command = "page-up",
|
{ .command = "page-up",
|
||||||
.args = { "", 0, 0, NULL },
|
.args = { "", 0, 0, NULL },
|
||||||
|
.flags = WINDOW_COPY_CMD_FLAG_READONLY,
|
||||||
.clear = WINDOW_COPY_CMD_CLEAR_EMACS_ONLY,
|
.clear = WINDOW_COPY_CMD_CLEAR_EMACS_ONLY,
|
||||||
.f = window_copy_cmd_page_up
|
.f = window_copy_cmd_page_up
|
||||||
},
|
},
|
||||||
{ .command = "pipe-no-clear",
|
{ .command = "pipe-no-clear",
|
||||||
.args = { "", 0, 1, NULL },
|
.args = { "", 0, 1, NULL },
|
||||||
|
.flags = 0,
|
||||||
.clear = WINDOW_COPY_CMD_CLEAR_NEVER,
|
.clear = WINDOW_COPY_CMD_CLEAR_NEVER,
|
||||||
.f = window_copy_cmd_pipe_no_clear
|
.f = window_copy_cmd_pipe_no_clear
|
||||||
},
|
},
|
||||||
{ .command = "pipe",
|
{ .command = "pipe",
|
||||||
.args = { "", 0, 1, NULL },
|
.args = { "", 0, 1, NULL },
|
||||||
|
.flags = 0,
|
||||||
.clear = WINDOW_COPY_CMD_CLEAR_ALWAYS,
|
.clear = WINDOW_COPY_CMD_CLEAR_ALWAYS,
|
||||||
.f = window_copy_cmd_pipe
|
.f = window_copy_cmd_pipe
|
||||||
},
|
},
|
||||||
{ .command = "pipe-and-cancel",
|
{ .command = "pipe-and-cancel",
|
||||||
.args = { "", 0, 1, NULL },
|
.args = { "", 0, 1, NULL },
|
||||||
|
.flags = 0,
|
||||||
.clear = WINDOW_COPY_CMD_CLEAR_ALWAYS,
|
.clear = WINDOW_COPY_CMD_CLEAR_ALWAYS,
|
||||||
.f = window_copy_cmd_pipe_and_cancel
|
.f = window_copy_cmd_pipe_and_cancel
|
||||||
},
|
},
|
||||||
{ .command = "previous-matching-bracket",
|
{ .command = "previous-matching-bracket",
|
||||||
.args = { "", 0, 0, NULL },
|
.args = { "", 0, 0, NULL },
|
||||||
|
.flags = WINDOW_COPY_CMD_FLAG_READONLY,
|
||||||
.clear = WINDOW_COPY_CMD_CLEAR_ALWAYS,
|
.clear = WINDOW_COPY_CMD_CLEAR_ALWAYS,
|
||||||
.f = window_copy_cmd_previous_matching_bracket
|
.f = window_copy_cmd_previous_matching_bracket
|
||||||
},
|
},
|
||||||
{ .command = "previous-paragraph",
|
{ .command = "previous-paragraph",
|
||||||
.args = { "", 0, 0, NULL },
|
.args = { "", 0, 0, NULL },
|
||||||
|
.flags = WINDOW_COPY_CMD_FLAG_READONLY,
|
||||||
.clear = WINDOW_COPY_CMD_CLEAR_EMACS_ONLY,
|
.clear = WINDOW_COPY_CMD_CLEAR_EMACS_ONLY,
|
||||||
.f = window_copy_cmd_previous_paragraph
|
.f = window_copy_cmd_previous_paragraph
|
||||||
},
|
},
|
||||||
{ .command = "previous-space",
|
{ .command = "previous-space",
|
||||||
.args = { "", 0, 0, NULL },
|
.args = { "", 0, 0, NULL },
|
||||||
|
.flags = WINDOW_COPY_CMD_FLAG_READONLY,
|
||||||
.clear = WINDOW_COPY_CMD_CLEAR_EMACS_ONLY,
|
.clear = WINDOW_COPY_CMD_CLEAR_EMACS_ONLY,
|
||||||
.f = window_copy_cmd_previous_space
|
.f = window_copy_cmd_previous_space
|
||||||
},
|
},
|
||||||
{ .command = "previous-word",
|
{ .command = "previous-word",
|
||||||
.args = { "", 0, 0, NULL },
|
.args = { "", 0, 0, NULL },
|
||||||
|
.flags = WINDOW_COPY_CMD_FLAG_READONLY,
|
||||||
.clear = WINDOW_COPY_CMD_CLEAR_EMACS_ONLY,
|
.clear = WINDOW_COPY_CMD_CLEAR_EMACS_ONLY,
|
||||||
.f = window_copy_cmd_previous_word
|
.f = window_copy_cmd_previous_word
|
||||||
},
|
},
|
||||||
{ .command = "rectangle-on",
|
{ .command = "rectangle-on",
|
||||||
.args = { "", 0, 0, NULL },
|
.args = { "", 0, 0, NULL },
|
||||||
|
.flags = 0,
|
||||||
.clear = WINDOW_COPY_CMD_CLEAR_ALWAYS,
|
.clear = WINDOW_COPY_CMD_CLEAR_ALWAYS,
|
||||||
.f = window_copy_cmd_rectangle_on
|
.f = window_copy_cmd_rectangle_on
|
||||||
},
|
},
|
||||||
{ .command = "rectangle-off",
|
{ .command = "rectangle-off",
|
||||||
.args = { "", 0, 0, NULL },
|
.args = { "", 0, 0, NULL },
|
||||||
|
.flags = 0,
|
||||||
.clear = WINDOW_COPY_CMD_CLEAR_ALWAYS,
|
.clear = WINDOW_COPY_CMD_CLEAR_ALWAYS,
|
||||||
.f = window_copy_cmd_rectangle_off
|
.f = window_copy_cmd_rectangle_off
|
||||||
},
|
},
|
||||||
{ .command = "rectangle-toggle",
|
{ .command = "rectangle-toggle",
|
||||||
.args = { "", 0, 0, NULL },
|
.args = { "", 0, 0, NULL },
|
||||||
|
.flags = 0,
|
||||||
.clear = WINDOW_COPY_CMD_CLEAR_ALWAYS,
|
.clear = WINDOW_COPY_CMD_CLEAR_ALWAYS,
|
||||||
.f = window_copy_cmd_rectangle_toggle
|
.f = window_copy_cmd_rectangle_toggle
|
||||||
},
|
},
|
||||||
{ .command = "refresh-from-pane",
|
{ .command = "refresh-from-pane",
|
||||||
.args = { "", 0, 0, NULL },
|
.args = { "", 0, 0, NULL },
|
||||||
|
.flags = WINDOW_COPY_CMD_FLAG_READONLY,
|
||||||
.clear = WINDOW_COPY_CMD_CLEAR_ALWAYS,
|
.clear = WINDOW_COPY_CMD_CLEAR_ALWAYS,
|
||||||
.f = window_copy_cmd_refresh_from_pane
|
.f = window_copy_cmd_refresh_from_pane
|
||||||
},
|
},
|
||||||
{ .command = "scroll-bottom",
|
{ .command = "scroll-bottom",
|
||||||
.args = { "", 0, 0, NULL },
|
.args = { "", 0, 0, NULL },
|
||||||
|
.flags = WINDOW_COPY_CMD_FLAG_READONLY,
|
||||||
.clear = WINDOW_COPY_CMD_CLEAR_ALWAYS,
|
.clear = WINDOW_COPY_CMD_CLEAR_ALWAYS,
|
||||||
.f = window_copy_cmd_scroll_bottom
|
.f = window_copy_cmd_scroll_bottom
|
||||||
},
|
},
|
||||||
{ .command = "scroll-down",
|
{ .command = "scroll-down",
|
||||||
.args = { "", 0, 0, NULL },
|
.args = { "", 0, 0, NULL },
|
||||||
|
.flags = WINDOW_COPY_CMD_FLAG_READONLY,
|
||||||
.clear = WINDOW_COPY_CMD_CLEAR_EMACS_ONLY,
|
.clear = WINDOW_COPY_CMD_CLEAR_EMACS_ONLY,
|
||||||
.f = window_copy_cmd_scroll_down
|
.f = window_copy_cmd_scroll_down
|
||||||
},
|
},
|
||||||
{ .command = "scroll-down-and-cancel",
|
{ .command = "scroll-down-and-cancel",
|
||||||
.args = { "", 0, 0, NULL },
|
.args = { "", 0, 0, NULL },
|
||||||
|
.flags = WINDOW_COPY_CMD_FLAG_READONLY,
|
||||||
.clear = WINDOW_COPY_CMD_CLEAR_ALWAYS,
|
.clear = WINDOW_COPY_CMD_CLEAR_ALWAYS,
|
||||||
.f = window_copy_cmd_scroll_down_and_cancel
|
.f = window_copy_cmd_scroll_down_and_cancel
|
||||||
},
|
},
|
||||||
|
{ .command = "scroll-exit-on",
|
||||||
|
.args = { "", 0, 0, NULL },
|
||||||
|
.clear = WINDOW_COPY_CMD_CLEAR_ALWAYS,
|
||||||
|
.f = window_copy_cmd_scroll_exit_on
|
||||||
|
},
|
||||||
|
{ .command = "scroll-exit-off",
|
||||||
|
.args = { "", 0, 0, NULL },
|
||||||
|
.clear = WINDOW_COPY_CMD_CLEAR_ALWAYS,
|
||||||
|
.f = window_copy_cmd_scroll_exit_off
|
||||||
|
},
|
||||||
|
{ .command = "scroll-exit-toggle",
|
||||||
|
.args = { "", 0, 0, NULL },
|
||||||
|
.clear = WINDOW_COPY_CMD_CLEAR_ALWAYS,
|
||||||
|
.f = window_copy_cmd_scroll_exit_toggle
|
||||||
|
},
|
||||||
{ .command = "scroll-middle",
|
{ .command = "scroll-middle",
|
||||||
.args = { "", 0, 0, NULL },
|
.args = { "", 0, 0, NULL },
|
||||||
|
.flags = WINDOW_COPY_CMD_FLAG_READONLY,
|
||||||
.clear = WINDOW_COPY_CMD_CLEAR_ALWAYS,
|
.clear = WINDOW_COPY_CMD_CLEAR_ALWAYS,
|
||||||
.f = window_copy_cmd_scroll_middle
|
.f = window_copy_cmd_scroll_middle
|
||||||
},
|
},
|
||||||
{ .command = "scroll-to-mouse",
|
{ .command = "scroll-to-mouse",
|
||||||
.args = { "e", 0, 0, NULL },
|
.args = { "e", 0, 0, NULL },
|
||||||
|
.flags = WINDOW_COPY_CMD_FLAG_READONLY,
|
||||||
.clear = WINDOW_COPY_CMD_CLEAR_EMACS_ONLY,
|
.clear = WINDOW_COPY_CMD_CLEAR_EMACS_ONLY,
|
||||||
.f = window_copy_cmd_scroll_to_mouse
|
.f = window_copy_cmd_scroll_to_mouse
|
||||||
},
|
},
|
||||||
{ .command = "scroll-top",
|
{ .command = "scroll-top",
|
||||||
.args = { "", 0, 0, NULL },
|
.args = { "", 0, 0, NULL },
|
||||||
|
.flags = WINDOW_COPY_CMD_FLAG_READONLY,
|
||||||
.clear = WINDOW_COPY_CMD_CLEAR_ALWAYS,
|
.clear = WINDOW_COPY_CMD_CLEAR_ALWAYS,
|
||||||
.f = window_copy_cmd_scroll_top
|
.f = window_copy_cmd_scroll_top
|
||||||
},
|
},
|
||||||
{ .command = "scroll-up",
|
{ .command = "scroll-up",
|
||||||
.args = { "", 0, 0, NULL },
|
.args = { "", 0, 0, NULL },
|
||||||
|
.flags = WINDOW_COPY_CMD_FLAG_READONLY,
|
||||||
.clear = WINDOW_COPY_CMD_CLEAR_EMACS_ONLY,
|
.clear = WINDOW_COPY_CMD_CLEAR_EMACS_ONLY,
|
||||||
.f = window_copy_cmd_scroll_up
|
.f = window_copy_cmd_scroll_up
|
||||||
},
|
},
|
||||||
{ .command = "search-again",
|
{ .command = "search-again",
|
||||||
.args = { "", 0, 0, NULL },
|
.args = { "", 0, 0, NULL },
|
||||||
|
.flags = 0,
|
||||||
.clear = WINDOW_COPY_CMD_CLEAR_ALWAYS,
|
.clear = WINDOW_COPY_CMD_CLEAR_ALWAYS,
|
||||||
.f = window_copy_cmd_search_again
|
.f = window_copy_cmd_search_again
|
||||||
},
|
},
|
||||||
{ .command = "search-backward",
|
{ .command = "search-backward",
|
||||||
.args = { "", 0, 1, NULL },
|
.args = { "", 0, 1, NULL },
|
||||||
|
.flags = 0,
|
||||||
.clear = WINDOW_COPY_CMD_CLEAR_ALWAYS,
|
.clear = WINDOW_COPY_CMD_CLEAR_ALWAYS,
|
||||||
.f = window_copy_cmd_search_backward
|
.f = window_copy_cmd_search_backward
|
||||||
},
|
},
|
||||||
{ .command = "search-backward-text",
|
{ .command = "search-backward-text",
|
||||||
.args = { "", 0, 1, NULL },
|
.args = { "", 0, 1, NULL },
|
||||||
|
.flags = 0,
|
||||||
.clear = WINDOW_COPY_CMD_CLEAR_ALWAYS,
|
.clear = WINDOW_COPY_CMD_CLEAR_ALWAYS,
|
||||||
.f = window_copy_cmd_search_backward_text
|
.f = window_copy_cmd_search_backward_text
|
||||||
},
|
},
|
||||||
{ .command = "search-backward-incremental",
|
{ .command = "search-backward-incremental",
|
||||||
.args = { "", 1, 1, NULL },
|
.args = { "", 1, 1, NULL },
|
||||||
|
.flags = 0,
|
||||||
.clear = WINDOW_COPY_CMD_CLEAR_ALWAYS,
|
.clear = WINDOW_COPY_CMD_CLEAR_ALWAYS,
|
||||||
.f = window_copy_cmd_search_backward_incremental
|
.f = window_copy_cmd_search_backward_incremental
|
||||||
},
|
},
|
||||||
{ .command = "search-forward",
|
{ .command = "search-forward",
|
||||||
.args = { "", 0, 1, NULL },
|
.args = { "", 0, 1, NULL },
|
||||||
|
.flags = 0,
|
||||||
.clear = WINDOW_COPY_CMD_CLEAR_ALWAYS,
|
.clear = WINDOW_COPY_CMD_CLEAR_ALWAYS,
|
||||||
.f = window_copy_cmd_search_forward
|
.f = window_copy_cmd_search_forward
|
||||||
},
|
},
|
||||||
{ .command = "search-forward-text",
|
{ .command = "search-forward-text",
|
||||||
.args = { "", 0, 1, NULL },
|
.args = { "", 0, 1, NULL },
|
||||||
|
.flags = 0,
|
||||||
.clear = WINDOW_COPY_CMD_CLEAR_ALWAYS,
|
.clear = WINDOW_COPY_CMD_CLEAR_ALWAYS,
|
||||||
.f = window_copy_cmd_search_forward_text
|
.f = window_copy_cmd_search_forward_text
|
||||||
},
|
},
|
||||||
{ .command = "search-forward-incremental",
|
{ .command = "search-forward-incremental",
|
||||||
.args = { "", 1, 1, NULL },
|
.args = { "", 1, 1, NULL },
|
||||||
|
.flags = 0,
|
||||||
.clear = WINDOW_COPY_CMD_CLEAR_ALWAYS,
|
.clear = WINDOW_COPY_CMD_CLEAR_ALWAYS,
|
||||||
.f = window_copy_cmd_search_forward_incremental
|
.f = window_copy_cmd_search_forward_incremental
|
||||||
},
|
},
|
||||||
{ .command = "search-reverse",
|
{ .command = "search-reverse",
|
||||||
.args = { "", 0, 0, NULL },
|
.args = { "", 0, 0, NULL },
|
||||||
|
.flags = 0,
|
||||||
.clear = WINDOW_COPY_CMD_CLEAR_ALWAYS,
|
.clear = WINDOW_COPY_CMD_CLEAR_ALWAYS,
|
||||||
.f = window_copy_cmd_search_reverse
|
.f = window_copy_cmd_search_reverse
|
||||||
},
|
},
|
||||||
{ .command = "select-line",
|
{ .command = "select-line",
|
||||||
.args = { "", 0, 0, NULL },
|
.args = { "", 0, 0, NULL },
|
||||||
|
.flags = 0,
|
||||||
.clear = WINDOW_COPY_CMD_CLEAR_ALWAYS,
|
.clear = WINDOW_COPY_CMD_CLEAR_ALWAYS,
|
||||||
.f = window_copy_cmd_select_line
|
.f = window_copy_cmd_select_line
|
||||||
},
|
},
|
||||||
{ .command = "select-word",
|
{ .command = "select-word",
|
||||||
.args = { "", 0, 0, NULL },
|
.args = { "", 0, 0, NULL },
|
||||||
|
.flags = 0,
|
||||||
.clear = WINDOW_COPY_CMD_CLEAR_ALWAYS,
|
.clear = WINDOW_COPY_CMD_CLEAR_ALWAYS,
|
||||||
.f = window_copy_cmd_select_word
|
.f = window_copy_cmd_select_word
|
||||||
},
|
},
|
||||||
{ .command = "selection-mode",
|
{ .command = "selection-mode",
|
||||||
.args = { "", 0, 1, NULL },
|
.args = { "", 0, 1, NULL },
|
||||||
|
.flags = 0,
|
||||||
.clear = 0,
|
.clear = 0,
|
||||||
.f = window_copy_cmd_selection_mode
|
.f = window_copy_cmd_selection_mode
|
||||||
},
|
},
|
||||||
{ .command = "set-mark",
|
{ .command = "set-mark",
|
||||||
.args = { "", 0, 0, NULL },
|
.args = { "", 0, 0, NULL },
|
||||||
|
.flags = WINDOW_COPY_CMD_FLAG_READONLY,
|
||||||
.clear = WINDOW_COPY_CMD_CLEAR_ALWAYS,
|
.clear = WINDOW_COPY_CMD_CLEAR_ALWAYS,
|
||||||
.f = window_copy_cmd_set_mark
|
.f = window_copy_cmd_set_mark
|
||||||
},
|
},
|
||||||
{ .command = "start-of-line",
|
{ .command = "start-of-line",
|
||||||
.args = { "", 0, 0, NULL },
|
.args = { "", 0, 0, NULL },
|
||||||
|
.flags = WINDOW_COPY_CMD_FLAG_READONLY,
|
||||||
.clear = WINDOW_COPY_CMD_CLEAR_EMACS_ONLY,
|
.clear = WINDOW_COPY_CMD_CLEAR_EMACS_ONLY,
|
||||||
.f = window_copy_cmd_start_of_line
|
.f = window_copy_cmd_start_of_line
|
||||||
},
|
},
|
||||||
{ .command = "stop-selection",
|
{ .command = "stop-selection",
|
||||||
.args = { "", 0, 0, NULL },
|
.args = { "", 0, 0, NULL },
|
||||||
|
.flags = 0,
|
||||||
.clear = WINDOW_COPY_CMD_CLEAR_ALWAYS,
|
.clear = WINDOW_COPY_CMD_CLEAR_ALWAYS,
|
||||||
.f = window_copy_cmd_stop_selection
|
.f = window_copy_cmd_stop_selection
|
||||||
},
|
},
|
||||||
{ .command = "toggle-position",
|
{ .command = "toggle-position",
|
||||||
.args = { "", 0, 0, NULL },
|
.args = { "", 0, 0, NULL },
|
||||||
|
.flags = WINDOW_COPY_CMD_FLAG_READONLY,
|
||||||
.clear = WINDOW_COPY_CMD_CLEAR_NEVER,
|
.clear = WINDOW_COPY_CMD_CLEAR_NEVER,
|
||||||
.f = window_copy_cmd_toggle_position
|
.f = window_copy_cmd_toggle_position
|
||||||
},
|
},
|
||||||
{ .command = "top-line",
|
{ .command = "top-line",
|
||||||
.args = { "", 0, 0, NULL },
|
.args = { "", 0, 0, NULL },
|
||||||
|
.flags = WINDOW_COPY_CMD_FLAG_READONLY,
|
||||||
.clear = WINDOW_COPY_CMD_CLEAR_EMACS_ONLY,
|
.clear = WINDOW_COPY_CMD_CLEAR_EMACS_ONLY,
|
||||||
.f = window_copy_cmd_top_line
|
.f = window_copy_cmd_top_line
|
||||||
}
|
}
|
||||||
@@ -3209,6 +3351,14 @@ window_copy_command(struct window_mode_entry *wme, struct client *c,
|
|||||||
action = WINDOW_COPY_CMD_NOTHING;
|
action = WINDOW_COPY_CMD_NOTHING;
|
||||||
for (i = 0; i < nitems(window_copy_cmd_table); i++) {
|
for (i = 0; i < nitems(window_copy_cmd_table); i++) {
|
||||||
if (strcmp(window_copy_cmd_table[i].command, command) == 0) {
|
if (strcmp(window_copy_cmd_table[i].command, command) == 0) {
|
||||||
|
if (c->flags & CLIENT_READONLY &&
|
||||||
|
(~window_copy_cmd_table[i].flags &
|
||||||
|
WINDOW_COPY_CMD_FLAG_READONLY)) {
|
||||||
|
status_message_set(c, -1, 1, 0, 0,
|
||||||
|
"client is read-only");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
cs.wargs = args_parse(&window_copy_cmd_table[i].args,
|
cs.wargs = args_parse(&window_copy_cmd_table[i].args,
|
||||||
args_values(args), count, &error);
|
args_values(args), count, &error);
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user