mirror of
https://github.com/tmux/tmux.git
synced 2026-03-05 23:35:35 +00:00
Merge branch 'obsd-master'
This commit is contained in:
@@ -106,6 +106,7 @@ dist_tmux_SOURCES = \
|
||||
cmd-kill-window.c \
|
||||
cmd-list-buffers.c \
|
||||
cmd-list-clients.c \
|
||||
cmd-list-commands.c \
|
||||
cmd-list-keys.c \
|
||||
cmd-list-panes.c \
|
||||
cmd-list-sessions.c \
|
||||
|
||||
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);
|
||||
}
|
||||
451
cmd-list-keys.c
451
cmd-list-keys.c
@@ -27,122 +27,140 @@
|
||||
* 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 *,
|
||||
struct cmdq_item *);
|
||||
static enum cmd_retval cmd_list_keys_exec(struct cmd *, struct cmdq_item *);
|
||||
|
||||
const struct cmd_entry cmd_list_keys_entry = {
|
||||
.name = "list-keys",
|
||||
.alias = "lsk",
|
||||
|
||||
.args = { "1aNP:T:", 0, 1, NULL },
|
||||
.usage = "[-1aN] [-P prefix-string] [-T key-table] [key]",
|
||||
.args = { "1aF:NO:P:rT:", 0, 1, NULL },
|
||||
.usage = "[-1aNr] [-F format] [-O order] [-P prefix-string]"
|
||||
"[-T key-table] [key]",
|
||||
|
||||
.flags = CMD_STARTSERVER|CMD_AFTERHOOK,
|
||||
.exec = cmd_list_keys_exec
|
||||
};
|
||||
|
||||
const struct cmd_entry cmd_list_commands_entry = {
|
||||
.name = "list-commands",
|
||||
.alias = "lscm",
|
||||
static char *
|
||||
cmd_list_keys_get_prefix(struct args *args)
|
||||
{
|
||||
key_code prefix;
|
||||
|
||||
.args = { "F:", 0, 1, NULL },
|
||||
.usage = "[-F format] [command]",
|
||||
if (args_has(args, 'P'))
|
||||
return (xstrdup(args_get(args, 'P')));
|
||||
|
||||
.flags = CMD_STARTSERVER|CMD_AFTERHOOK,
|
||||
.exec = cmd_list_keys_exec
|
||||
};
|
||||
prefix = options_get_number(global_s_options, "prefix");
|
||||
if (prefix == KEYC_NONE)
|
||||
return (xstrdup(""));
|
||||
return (xstrdup(key_string_lookup_key(prefix, 0)));
|
||||
}
|
||||
|
||||
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;
|
||||
struct key_binding *bd;
|
||||
u_int width, keywidth = 0;
|
||||
u_int i, width, keywidth = 0;
|
||||
|
||||
table = key_bindings_get_table(tablename, 0);
|
||||
if (table == NULL)
|
||||
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));
|
||||
for (i = 0; i < n; i++) {
|
||||
width = utf8_cstrwidth(key_string_lookup_key(l[i]->key, 0));
|
||||
if (width > keywidth)
|
||||
keywidth = width;
|
||||
|
||||
bd = key_bindings_next(table, bd);
|
||||
}
|
||||
return (keywidth);
|
||||
}
|
||||
|
||||
static int
|
||||
cmd_list_keys_print_notes(struct cmdq_item *item, struct args *args,
|
||||
const char *tablename, u_int keywidth, key_code only, const char *prefix)
|
||||
static u_int
|
||||
cmd_list_keys_get_table_width(struct key_binding **l, u_int n)
|
||||
{
|
||||
struct client *tc = cmdq_get_target_client(item);
|
||||
struct key_table *table;
|
||||
struct key_binding *bd;
|
||||
const char *key;
|
||||
char *tmp, *note;
|
||||
int found = 0;
|
||||
u_int i, width, tablewidth = 0;
|
||||
|
||||
table = key_bindings_get_table(tablename, 0);
|
||||
if (table == NULL)
|
||||
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') &&
|
||||
!args_has(args, 'a'))) {
|
||||
bd = key_bindings_next(table, bd);
|
||||
continue;
|
||||
for (i = 0; i < n; i++) {
|
||||
width = utf8_cstrwidth(l[i]->tablename);
|
||||
if (width > tablewidth)
|
||||
tablewidth = width;
|
||||
}
|
||||
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 *
|
||||
cmd_list_keys_get_prefix(struct args *args, key_code *prefix)
|
||||
static struct key_binding **
|
||||
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");
|
||||
if (!args_has(args, 'P')) {
|
||||
if (*prefix != KEYC_NONE)
|
||||
xasprintf(&s, "%s ", key_string_lookup_key(*prefix, 0));
|
||||
for (i = 0; i < nitems(tables); i++) {
|
||||
t = key_bindings_get_table(tables[i], 0);
|
||||
lt = sort_get_key_bindings_table(t, <sz, sort_crit);
|
||||
len += ltsz;
|
||||
if (lsz <= len) {
|
||||
lsz = len + 100;
|
||||
l = xreallocarray(l, lsz, sizeof *l);
|
||||
}
|
||||
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
|
||||
s = xstrdup("");
|
||||
} else
|
||||
s = xstrdup(args_get(args, 'P'));
|
||||
return (s);
|
||||
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
|
||||
@@ -150,16 +168,16 @@ cmd_list_keys_exec(struct cmd *self, struct cmdq_item *item)
|
||||
{
|
||||
struct args *args = cmd_get_args(self);
|
||||
struct client *tc = cmdq_get_target_client(item);
|
||||
struct key_table *table;
|
||||
struct key_binding *bd;
|
||||
const char *tablename, *r, *keystr;
|
||||
char *key, *cp, *tmp, *start, *empty;
|
||||
key_code prefix, only = KEYC_UNKNOWN;
|
||||
int repeat, width, tablewidth, keywidth, found = 0;
|
||||
size_t tmpsize, tmpused, cplen;
|
||||
|
||||
if (cmd_get_entry(self) == &cmd_list_commands_entry)
|
||||
return (cmd_list_keys_commands(self, item));
|
||||
struct format_tree *ft;
|
||||
struct key_table *table = NULL;
|
||||
struct key_binding **l;
|
||||
key_code only = KEYC_UNKNOWN;
|
||||
const char *template, *tablename, *keystr;
|
||||
char *line;
|
||||
char *prefix = NULL;
|
||||
u_int i, n;
|
||||
int single, notes_only, filter_notes, filter_key;
|
||||
struct sort_criteria sort_crit;
|
||||
|
||||
if ((keystr = args_string(args, 0)) != NULL) {
|
||||
only = key_string_lookup_string(keystr);
|
||||
@@ -170,219 +188,60 @@ cmd_list_keys_exec(struct cmd *self, struct cmdq_item *item)
|
||||
only &= (KEYC_MASK_KEY|KEYC_MASK_MODIFIERS);
|
||||
}
|
||||
|
||||
tablename = args_get(args, 'T');
|
||||
if (tablename != NULL && key_bindings_get_table(tablename, 0) == NULL) {
|
||||
sort_crit.order = sort_order_from_string(args_get(args, 'O'));
|
||||
sort_crit.reversed = args_has(args, 'r');
|
||||
|
||||
prefix = cmd_list_keys_get_prefix(args);
|
||||
single = args_has(args, '1');
|
||||
notes_only = args_has(args, 'N');
|
||||
|
||||
if ((tablename = args_get(args, 'T')) != NULL) {
|
||||
table = key_bindings_get_table(tablename, 0);
|
||||
if (table == NULL) {
|
||||
cmdq_error(item, "table %s doesn't exist", tablename);
|
||||
return (CMD_RETURN_ERROR);
|
||||
}
|
||||
|
||||
if (args_has(args, 'N')) {
|
||||
if (tablename == NULL) {
|
||||
start = cmd_list_keys_get_prefix(args, &prefix);
|
||||
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",
|
||||
keywidth, only, empty);
|
||||
if (prefix != KEYC_NONE) {
|
||||
if (cmd_list_keys_print_notes(item, args,
|
||||
"prefix", keywidth, only, start))
|
||||
found = 1;
|
||||
}
|
||||
free(empty);
|
||||
} else {
|
||||
if (args_has(args, 'P'))
|
||||
start = xstrdup(args_get(args, 'P'));
|
||||
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
|
||||
start = xstrdup("");
|
||||
keywidth = cmd_list_keys_get_width(tablename, only);
|
||||
found = cmd_list_keys_print_notes(item, args, tablename,
|
||||
keywidth, only, start);
|
||||
l = sort_get_key_bindings(&n, &sort_crit);
|
||||
|
||||
}
|
||||
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}";
|
||||
}
|
||||
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);
|
||||
|
||||
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);
|
||||
}
|
||||
}
|
||||
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);
|
||||
free(prefix);
|
||||
|
||||
return (CMD_RETURN_NORMAL);
|
||||
}
|
||||
|
||||
@@ -33,8 +33,8 @@ const struct cmd_entry cmd_paste_buffer_entry = {
|
||||
.name = "paste-buffer",
|
||||
.alias = "pasteb",
|
||||
|
||||
.args = { "db:prs:t:", 0, 0, NULL },
|
||||
.usage = "[-dpr] [-s separator] " CMD_BUFFER_USAGE " "
|
||||
.args = { "db:prSs:t:", 0, 0, NULL },
|
||||
.usage = "[-dprS] [-s separator] " CMD_BUFFER_USAGE " "
|
||||
CMD_TARGET_PANE_USAGE,
|
||||
|
||||
.target = { 't', CMD_FIND_PANE, 0 },
|
||||
@@ -43,6 +43,17 @@ const struct cmd_entry cmd_paste_buffer_entry = {
|
||||
.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);
|
||||
bufferevent_write(wp->event, cp, n);
|
||||
free(cp);
|
||||
}
|
||||
|
||||
static enum cmd_retval
|
||||
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 paste_buffer *pb;
|
||||
const char *sepstr, *bufname, *bufdata, *bufend, *line;
|
||||
size_t seplen, bufsize;
|
||||
size_t seplen, bufsize, len;
|
||||
int bracket = args_has(args, 'p');
|
||||
|
||||
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);
|
||||
if (line == NULL)
|
||||
break;
|
||||
|
||||
bufferevent_write(wp->event, bufdata, line - bufdata);
|
||||
len = 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);
|
||||
|
||||
bufdata = line + 1;
|
||||
}
|
||||
if (bufdata != bufend)
|
||||
bufferevent_write(wp->event, bufdata, bufend - bufdata);
|
||||
if (bufdata != bufend) {
|
||||
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))
|
||||
bufferevent_write(wp->event, "\033[201~", 6);
|
||||
|
||||
6
format.c
6
format.c
@@ -5239,11 +5239,13 @@ format_replace(struct format_expand_state *es, const char *key, size_t keylen,
|
||||
done:
|
||||
/* Expand again if required. */
|
||||
if (modifiers & FORMAT_EXPAND) {
|
||||
new = format_expand1(es, value);
|
||||
format_copy_state(&next, es, FORMAT_EXPAND_NOJOBS);
|
||||
new = format_expand1(&next, value);
|
||||
free(value);
|
||||
value = new;
|
||||
} else if (modifiers & FORMAT_EXPANDTIME) {
|
||||
format_copy_state(&next, es, FORMAT_EXPAND_TIME);
|
||||
format_copy_state(&next, es, FORMAT_EXPAND_TIME|
|
||||
FORMAT_EXPAND_NOJOBS);
|
||||
new = format_expand1(&next, value);
|
||||
free(value);
|
||||
value = new;
|
||||
|
||||
12
input.c
12
input.c
@@ -1625,10 +1625,6 @@ input_csi_dispatch(struct input_ctx *ictx)
|
||||
}
|
||||
input_reply(ictx, 1, "\033[?12;%d$y", n);
|
||||
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 */
|
||||
n = (s->mode & MODE_FOCUSON) ? 1 : 2;
|
||||
input_reply(ictx, 1, "\033[?1004;%d$y", n);
|
||||
@@ -1637,6 +1633,14 @@ input_csi_dispatch(struct input_ctx *ictx)
|
||||
n = (s->mode & MODE_MOUSE_SGR) ? 1 : 2;
|
||||
input_reply(ictx, 1, "\033[?1006;%d$y", n);
|
||||
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:
|
||||
input_reply(ictx, 1, "\033[?2031;2$y");
|
||||
break;
|
||||
|
||||
@@ -215,6 +215,7 @@ key_bindings_add(const char *name, key_code key, const char *note, int repeat,
|
||||
|
||||
bd = xcalloc(1, sizeof *bd);
|
||||
bd->key = (key & ~KEYC_MASK_FLAGS);
|
||||
bd->tablename = table->name;
|
||||
if (note != NULL)
|
||||
bd->note = xstrdup(note);
|
||||
RB_INSERT(key_bindings, &table->key_bindings, bd);
|
||||
@@ -702,3 +703,15 @@ key_bindings_dispatch(struct key_binding *bd, struct cmdq_item *item,
|
||||
new_item = cmdq_append(c, 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);
|
||||
}
|
||||
|
||||
101
sort.c
101
sort.c
@@ -72,6 +72,7 @@ sort_buffer_cmp(const void *a0, const void *b0)
|
||||
break;
|
||||
case SORT_ACTIVITY:
|
||||
case SORT_INDEX:
|
||||
case SORT_MODIFIER:
|
||||
case SORT_ORDER:
|
||||
case SORT_END:
|
||||
break;
|
||||
@@ -117,6 +118,7 @@ sort_client_cmp(const void *a0, const void *b0)
|
||||
result = 1;
|
||||
break;
|
||||
case SORT_INDEX:
|
||||
case SORT_MODIFIER:
|
||||
case SORT_ORDER:
|
||||
case SORT_END:
|
||||
break;
|
||||
@@ -167,6 +169,7 @@ sort_session_cmp(const void *a0, const void *b0)
|
||||
case SORT_NAME:
|
||||
result = strcmp(sa->name, sb->name);
|
||||
break;
|
||||
case SORT_MODIFIER:
|
||||
case SORT_ORDER:
|
||||
case SORT_SIZE:
|
||||
case SORT_END:
|
||||
@@ -208,6 +211,7 @@ sort_pane_cmp(const void *a0, const void *b0)
|
||||
case SORT_NAME:
|
||||
result = strcmp(a->screen->title, b->screen->title);
|
||||
break;
|
||||
case SORT_MODIFIER:
|
||||
case SORT_ORDER:
|
||||
case SORT_END:
|
||||
break;
|
||||
@@ -263,6 +267,7 @@ sort_winlink_cmp(const void *a0, const void *b0)
|
||||
case SORT_SIZE:
|
||||
result = wa->sx * wa->sy - wb->sx * wb->sy;
|
||||
break;
|
||||
case SORT_MODIFIER:
|
||||
case SORT_ORDER:
|
||||
case SORT_END:
|
||||
break;
|
||||
@@ -276,6 +281,41 @@ sort_winlink_cmp(const void *a0, const void *b0)
|
||||
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
|
||||
sort_next_order(struct sort_criteria *sort_crit)
|
||||
{
|
||||
@@ -306,8 +346,11 @@ sort_order_from_string(const char* order)
|
||||
return (SORT_ACTIVITY);
|
||||
if (strcasecmp(order, "creation") == 0)
|
||||
return (SORT_CREATION);
|
||||
if (strcasecmp(order, "index") == 0)
|
||||
if (strcasecmp(order, "index") == 0 ||
|
||||
strcasecmp(order, "key") == 0)
|
||||
return (SORT_INDEX);
|
||||
if (strcasecmp(order, "modifier") == 0)
|
||||
return (SORT_MODIFIER);
|
||||
if (strcasecmp(order, "name") == 0 ||
|
||||
strcasecmp(order, "title") == 0)
|
||||
return (SORT_NAME);
|
||||
@@ -328,6 +371,8 @@ sort_order_to_string(enum sort_order order)
|
||||
return "creation";
|
||||
if (order == SORT_INDEX)
|
||||
return "index";
|
||||
if (order == SORT_MODIFIER)
|
||||
return "modifier";
|
||||
if (order == SORT_NAME)
|
||||
return "name";
|
||||
if (order == SORT_ORDER)
|
||||
@@ -548,3 +593,57 @@ sort_get_winlinks_session(struct session *s, u_int *n,
|
||||
|
||||
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);
|
||||
}
|
||||
|
||||
65
tmux.1
65
tmux.1
@@ -2247,6 +2247,18 @@ Same as
|
||||
.Ic scroll-down
|
||||
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.
|
||||
.Ic scroll-middle
|
||||
(vi: z)
|
||||
.Xc
|
||||
@@ -3827,24 +3839,45 @@ To view the default bindings and possible commands, see the
|
||||
command.
|
||||
.Tg lsk
|
||||
.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 T Ar key-table
|
||||
.Op Ar key
|
||||
.Xc
|
||||
.D1 Pq alias: Ic lsk
|
||||
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
|
||||
commands;
|
||||
.Fl N
|
||||
lists only keys with attached notes and shows only the key and note for each
|
||||
key.
|
||||
.Pp
|
||||
With the default form, all key tables are listed by default.
|
||||
.Fl T
|
||||
lists only keys in
|
||||
.Ar key-table .
|
||||
With the default form, all key tables are listed unless specified otherwise.
|
||||
.Pp
|
||||
With the
|
||||
.Fl N
|
||||
@@ -3857,9 +3890,7 @@ key tables are listed by default;
|
||||
also lists only keys in
|
||||
.Ar key-table .
|
||||
.Fl P
|
||||
specifies a prefix to print before each key and
|
||||
.Fl 1
|
||||
lists only the first matching key.
|
||||
specifies a prefix to print before each key.
|
||||
.Fl a
|
||||
lists the command for keys that do not have a note rather than skipping them.
|
||||
.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_short" Ta "#h" Ta "Hostname of local host (no domain name)"
|
||||
.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_flag" Ta "" Ta "Pane keypad flag"
|
||||
.It Li "last_window_index" Ta "" Ta "Index of last window in session"
|
||||
@@ -7411,7 +7451,7 @@ is
|
||||
the contents are read from stdin.
|
||||
.Tg pasteb
|
||||
.It Xo Ic paste-buffer
|
||||
.Op Fl dpr
|
||||
.Op Fl dprS
|
||||
.Op Fl b Ar buffer-name
|
||||
.Op Fl s Ar separator
|
||||
.Op Fl t Ar target-pane
|
||||
@@ -7419,9 +7459,14 @@ the contents are read from stdin.
|
||||
.D1 Pq alias: Ic pasteb
|
||||
Insert the contents of a paste buffer into the specified pane.
|
||||
If not specified, paste into the current one.
|
||||
By default, control characters are sanitized with
|
||||
.Xr vis 3 ;
|
||||
.Fl S
|
||||
disables this.
|
||||
With
|
||||
.Fl d ,
|
||||
also delete the paste buffer.
|
||||
.Pp
|
||||
When output, any linefeed (LF) characters in the paste buffer are replaced with
|
||||
a separator, by default carriage return (CR).
|
||||
A custom separator may be specified using the
|
||||
|
||||
13
tmux.h
13
tmux.h
@@ -2146,6 +2146,7 @@ struct key_binding {
|
||||
key_code key;
|
||||
struct cmd_list *cmdlist;
|
||||
const char *note;
|
||||
const char *tablename;
|
||||
|
||||
int flags;
|
||||
#define KEY_BINDING_REPEAT 0x1
|
||||
@@ -2284,6 +2285,7 @@ enum sort_order {
|
||||
SORT_ACTIVITY,
|
||||
SORT_CREATION,
|
||||
SORT_INDEX,
|
||||
SORT_MODIFIER,
|
||||
SORT_NAME,
|
||||
SORT_ORDER,
|
||||
SORT_SIZE,
|
||||
@@ -2382,6 +2384,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_session(struct session *, u_int *,
|
||||
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 */
|
||||
#define FORMAT_STATUS 0x1
|
||||
@@ -2894,6 +2900,7 @@ void key_bindings_reset(const char *, key_code);
|
||||
void key_bindings_remove_table(const char *);
|
||||
void key_bindings_reset_table(const char *);
|
||||
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 *, struct client *, struct key_event *,
|
||||
struct cmd_find_state *);
|
||||
@@ -3615,9 +3622,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_append(struct utf8_data *, u_char);
|
||||
int utf8_isvalid(const char *);
|
||||
int utf8_strvis(char *, const char *, size_t, int);
|
||||
int utf8_stravis(char **, const char *, int);
|
||||
int utf8_stravisx(char **, const char *, size_t, int);
|
||||
size_t utf8_strvis(char *, const char *, size_t, int);
|
||||
size_t utf8_stravis(char **, const char *, int);
|
||||
size_t utf8_stravisx(char **, const char *, size_t, int);
|
||||
char *utf8_sanitize(const char *);
|
||||
size_t utf8_strlen(const struct utf8_data *);
|
||||
u_int utf8_strwidth(const struct utf8_data *, ssize_t);
|
||||
|
||||
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
|
||||
* for \0.
|
||||
*/
|
||||
int
|
||||
size_t
|
||||
utf8_strvis(char *dst, const char *src, size_t len, int flag)
|
||||
{
|
||||
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. */
|
||||
int
|
||||
size_t
|
||||
utf8_stravis(char **dst, const char *src, int flag)
|
||||
{
|
||||
char *buf;
|
||||
int len;
|
||||
size_t len;
|
||||
|
||||
buf = xreallocarray(NULL, 4, strlen(src) + 1);
|
||||
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. */
|
||||
int
|
||||
size_t
|
||||
utf8_stravisx(char **dst, const char *src, size_t srclen, int flag)
|
||||
{
|
||||
char *buf;
|
||||
int len;
|
||||
size_t len;
|
||||
|
||||
buf = xreallocarray(NULL, 4, srclen + 1);
|
||||
len = utf8_strvis(buf, src, srclen, flag);
|
||||
|
||||
@@ -2127,6 +2127,36 @@ window_copy_cmd_rectangle_toggle(struct window_copy_cmd_state *cs)
|
||||
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
|
||||
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_pane *wp = wme->swp;
|
||||
struct window_copy_mode_data *data = wme->data;
|
||||
u_int oy_from_top;
|
||||
|
||||
if (data->viewmode)
|
||||
return (WINDOW_COPY_CMD_NOTHING);
|
||||
oy_from_top = screen_hsize(data->backing) - data->oy;
|
||||
|
||||
screen_free(data->backing);
|
||||
free(data->backing);
|
||||
data->backing = window_copy_clone_screen(&wp->base, &data->screen, NULL,
|
||||
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->oy = screen_hsize(data->backing);
|
||||
}
|
||||
@@ -3073,6 +3107,21 @@ static const struct {
|
||||
.clear = WINDOW_COPY_CMD_CLEAR_ALWAYS,
|
||||
.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",
|
||||
.args = { "", 0, 0, NULL },
|
||||
.clear = WINDOW_COPY_CMD_CLEAR_ALWAYS,
|
||||
|
||||
Reference in New Issue
Block a user