mirror of
https://github.com/tmux/tmux.git
synced 2024-12-04 19:58:48 +00:00
d and D keys to reset to default in customize mode.
This commit is contained in:
parent
afe4ea4250
commit
1bf9555e4f
@ -151,16 +151,7 @@ cmd_set_option_exec(struct cmd *self, struct cmdq_item *item)
|
||||
if (args_has(args, 'u')) {
|
||||
if (o == NULL)
|
||||
goto out;
|
||||
if (idx == -1) {
|
||||
if (*name == '@')
|
||||
options_remove(o);
|
||||
else if (oo == global_options ||
|
||||
oo == global_s_options ||
|
||||
oo == global_w_options)
|
||||
options_default(oo, options_table_entry(o));
|
||||
else
|
||||
options_remove(o);
|
||||
} else if (options_array_set(o, idx, NULL, 0, &cause) != 0) {
|
||||
if (options_remove_or_default(o, idx, &cause) != 0) {
|
||||
cmdq_error(item, "%s", cause);
|
||||
free(cause);
|
||||
goto fail;
|
||||
|
8
input.c
8
input.c
@ -2347,7 +2347,7 @@ static void
|
||||
input_exit_rename(struct input_ctx *ictx)
|
||||
{
|
||||
struct window_pane *wp = ictx->wp;
|
||||
struct options_entry *oe;
|
||||
struct options_entry *o;
|
||||
|
||||
if (wp == NULL)
|
||||
return;
|
||||
@ -2361,9 +2361,9 @@ input_exit_rename(struct input_ctx *ictx)
|
||||
return;
|
||||
|
||||
if (ictx->input_len == 0) {
|
||||
oe = options_get_only(wp->window->options, "automatic-rename");
|
||||
if (oe != NULL)
|
||||
options_remove(oe);
|
||||
o = options_get_only(wp->window->options, "automatic-rename");
|
||||
if (o != NULL)
|
||||
options_remove_or_default(o, -1, NULL);
|
||||
return;
|
||||
}
|
||||
window_set_name(wp->window, ictx->input_buf);
|
||||
|
@ -231,6 +231,38 @@ key_bindings_remove(const char *name, key_code key)
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
key_bindings_reset(const char *name, key_code key)
|
||||
{
|
||||
struct key_table *table;
|
||||
struct key_binding *bd, *dd;
|
||||
|
||||
table = key_bindings_get_table(name, 0);
|
||||
if (table == NULL)
|
||||
return;
|
||||
|
||||
bd = key_bindings_get(table, key & ~KEYC_MASK_FLAGS);
|
||||
if (bd == NULL)
|
||||
return;
|
||||
|
||||
dd = key_bindings_get_default(table, bd->key);
|
||||
if (dd == NULL) {
|
||||
key_bindings_remove(name, bd->key);
|
||||
return;
|
||||
}
|
||||
|
||||
cmd_list_free(bd->cmdlist);
|
||||
bd->cmdlist = dd->cmdlist;
|
||||
bd->cmdlist->references++;
|
||||
|
||||
free((void *)bd->note);
|
||||
if (dd->note != NULL)
|
||||
bd->note = xstrdup(dd->note);
|
||||
else
|
||||
bd->note = NULL;
|
||||
bd->flags = dd->flags;
|
||||
}
|
||||
|
||||
void
|
||||
key_bindings_remove_table(const char *name)
|
||||
{
|
||||
@ -248,6 +280,23 @@ key_bindings_remove_table(const char *name)
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
key_bindings_reset_table(const char *name)
|
||||
{
|
||||
struct key_table *table;
|
||||
struct key_binding *bd, *bd1;
|
||||
|
||||
table = key_bindings_get_table(name, 0);
|
||||
if (table == NULL)
|
||||
return;
|
||||
if (RB_EMPTY(&table->default_key_bindings)) {
|
||||
key_bindings_remove_table(name);
|
||||
return;
|
||||
}
|
||||
RB_FOREACH_SAFE(bd, key_bindings, &table->key_bindings, bd1)
|
||||
key_bindings_reset(name, bd->key);
|
||||
}
|
||||
|
||||
static enum cmd_retval
|
||||
key_bindings_init_done(__unused struct cmdq_item *item, __unused void *data)
|
||||
{
|
||||
|
15
mode-tree.c
15
mode-tree.c
@ -80,7 +80,9 @@ struct mode_tree_item {
|
||||
|
||||
int expanded;
|
||||
int tagged;
|
||||
|
||||
int draw_as_parent;
|
||||
int no_tag;
|
||||
|
||||
struct mode_tree_list children;
|
||||
TAILQ_ENTRY(mode_tree_item) entry;
|
||||
@ -565,6 +567,12 @@ mode_tree_draw_as_parent(struct mode_tree_item *mti)
|
||||
mti->draw_as_parent = 1;
|
||||
}
|
||||
|
||||
void
|
||||
mode_tree_no_tag(struct mode_tree_item *mti)
|
||||
{
|
||||
mti->no_tag = 1;
|
||||
}
|
||||
|
||||
void
|
||||
mode_tree_remove(struct mode_tree_data *mtd, struct mode_tree_item *mti)
|
||||
{
|
||||
@ -1053,6 +1061,8 @@ mode_tree_key(struct mode_tree_data *mtd, struct client *c, key_code *key,
|
||||
* Do not allow parents and children to both be tagged: untag
|
||||
* all parents and children of current.
|
||||
*/
|
||||
if (current->no_tag)
|
||||
break;
|
||||
if (!current->tagged) {
|
||||
parent = current->parent;
|
||||
while (parent != NULL) {
|
||||
@ -1072,7 +1082,10 @@ mode_tree_key(struct mode_tree_data *mtd, struct client *c, key_code *key,
|
||||
break;
|
||||
case '\024': /* C-t */
|
||||
for (i = 0; i < mtd->line_size; i++) {
|
||||
if (mtd->line_list[i].item->parent == NULL)
|
||||
if ((mtd->line_list[i].item->parent == NULL &&
|
||||
!mtd->line_list[i].item->no_tag) ||
|
||||
(mtd->line_list[i].item->parent != NULL &&
|
||||
mtd->line_list[i].item->parent->no_tag))
|
||||
mtd->line_list[i].item->tagged = 1;
|
||||
else
|
||||
mtd->line_list[i].item->tagged = 0;
|
||||
|
21
options.c
21
options.c
@ -66,6 +66,7 @@ struct options {
|
||||
};
|
||||
|
||||
static struct options_entry *options_add(struct options *, const char *);
|
||||
static void options_remove(struct options_entry *);
|
||||
|
||||
#define OPTIONS_IS_STRING(o) \
|
||||
((o)->tableentry == NULL || \
|
||||
@ -315,7 +316,7 @@ options_add(struct options *oo, const char *name)
|
||||
return (o);
|
||||
}
|
||||
|
||||
void
|
||||
static void
|
||||
options_remove(struct options_entry *o)
|
||||
{
|
||||
struct options *oo = o->owner;
|
||||
@ -1106,3 +1107,21 @@ options_push_changes(const char *name)
|
||||
server_redraw_client(loop);
|
||||
}
|
||||
}
|
||||
|
||||
int
|
||||
options_remove_or_default(struct options_entry *o, int idx, char **cause)
|
||||
{
|
||||
struct options *oo = o->owner;
|
||||
|
||||
if (idx == -1) {
|
||||
if (o->tableentry != NULL &&
|
||||
(oo == global_options ||
|
||||
oo == global_s_options ||
|
||||
oo == global_w_options))
|
||||
options_default(oo, o->tableentry);
|
||||
else
|
||||
options_remove(o);
|
||||
} else if (options_array_set(o, idx, NULL, 0, cause) != 0)
|
||||
return (-1);
|
||||
return (0);
|
||||
}
|
||||
|
2
tmux.1
2
tmux.1
@ -2031,6 +2031,8 @@ The following keys may be used in customize mode:
|
||||
.It Li "s" Ta "Set option value or key attribute"
|
||||
.It Li "S" Ta "Set global option value"
|
||||
.It Li "w" Ta "Set window option value, if option is for pane and window"
|
||||
.It Li "d" Ta "Set an option or key to the default"
|
||||
.It Li "D" Ta "Set tagged options and tagged keys to the default"
|
||||
.It Li "u" Ta "Unset an option (set to default value if global) or unbind a key"
|
||||
.It Li "U" Ta "Unset tagged options and unbind tagged keys"
|
||||
.It Li "C-s" Ta "Search by name"
|
||||
|
6
tmux.h
6
tmux.h
@ -1988,7 +1988,6 @@ struct options *options_owner(struct options_entry *);
|
||||
const struct options_table_entry *options_table_entry(struct options_entry *);
|
||||
struct options_entry *options_get_only(struct options *, const char *);
|
||||
struct options_entry *options_get(struct options *, const char *);
|
||||
void options_remove(struct options_entry *);
|
||||
void options_array_clear(struct options_entry *);
|
||||
union options_value *options_array_get(struct options_entry *, u_int);
|
||||
int options_array_set(struct options_entry *, u_int, const char *,
|
||||
@ -2025,6 +2024,8 @@ int options_from_string(struct options *,
|
||||
const struct options_table_entry *, const char *,
|
||||
const char *, int, char **);
|
||||
void options_push_changes(const char *);
|
||||
int options_remove_or_default(struct options_entry *, int,
|
||||
char **);
|
||||
|
||||
/* options-table.c */
|
||||
extern const struct options_table_entry options_table[];
|
||||
@ -2325,7 +2326,9 @@ struct key_binding *key_bindings_next(struct key_table *, struct key_binding *);
|
||||
void key_bindings_add(const char *, key_code, const char *, int,
|
||||
struct cmd_list *);
|
||||
void key_bindings_remove(const char *, key_code);
|
||||
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);
|
||||
struct cmdq_item *key_bindings_dispatch(struct key_binding *,
|
||||
struct cmdq_item *, struct client *, struct key_event *,
|
||||
@ -2802,6 +2805,7 @@ struct mode_tree_item *mode_tree_add(struct mode_tree_data *,
|
||||
struct mode_tree_item *, void *, uint64_t, const char *,
|
||||
const char *, int);
|
||||
void mode_tree_draw_as_parent(struct mode_tree_item *);
|
||||
void mode_tree_no_tag(struct mode_tree_item *);
|
||||
void mode_tree_remove(struct mode_tree_data *, struct mode_tree_item *);
|
||||
void mode_tree_draw(struct mode_tree_data *);
|
||||
int mode_tree_key(struct mode_tree_data *, struct client *, key_code *,
|
||||
|
@ -76,6 +76,11 @@ enum window_customize_scope {
|
||||
WINDOW_CUSTOMIZE_PANE
|
||||
};
|
||||
|
||||
enum window_customize_change {
|
||||
WINDOW_CUSTOMIZE_UNSET,
|
||||
WINDOW_CUSTOMIZE_RESET,
|
||||
};
|
||||
|
||||
struct window_customize_itemdata {
|
||||
struct window_customize_modedata *data;
|
||||
enum window_customize_scope scope;
|
||||
@ -101,6 +106,7 @@ struct window_customize_modedata {
|
||||
u_int item_size;
|
||||
|
||||
struct cmd_find_state fs;
|
||||
enum window_customize_change change;
|
||||
};
|
||||
|
||||
static uint64_t
|
||||
@ -380,6 +386,7 @@ window_customize_build_options(struct window_customize_modedata *data,
|
||||
enum window_customize_scope scope;
|
||||
|
||||
top = mode_tree_add(data->data, NULL, NULL, tag, title, NULL, 0);
|
||||
mode_tree_no_tag(top);
|
||||
|
||||
/*
|
||||
* We get the options from the first tree, but build it using the
|
||||
@ -452,6 +459,7 @@ window_customize_build_keys(struct window_customize_modedata *data,
|
||||
|
||||
xasprintf(&title, "Key Table - %s", kt->name);
|
||||
top = mode_tree_add(data->data, NULL, NULL, tag, title, NULL, 0);
|
||||
mode_tree_no_tag(top);
|
||||
free(title);
|
||||
|
||||
ft = format_create_from_state(NULL, NULL, fs);
|
||||
@ -476,6 +484,8 @@ window_customize_build_keys(struct window_customize_modedata *data,
|
||||
item->scope = WINDOW_CUSTOMIZE_KEY;
|
||||
item->table = xstrdup(kt->name);
|
||||
item->key = bd->key;
|
||||
item->name = xstrdup(key_string_lookup_key(item->key, 0));
|
||||
item->idx = -1;
|
||||
|
||||
expanded = format_expand(ft, data->format);
|
||||
child = mode_tree_add(data->data, top, item, (uint64_t)bd,
|
||||
@ -488,6 +498,7 @@ window_customize_build_keys(struct window_customize_modedata *data,
|
||||
mti = mode_tree_add(data->data, child, item,
|
||||
tag|(bd->key << 3)|(0 << 1)|1, "Command", text, -1);
|
||||
mode_tree_draw_as_parent(mti);
|
||||
mode_tree_no_tag(mti);
|
||||
free(text);
|
||||
|
||||
if (bd->note != NULL)
|
||||
@ -497,6 +508,7 @@ window_customize_build_keys(struct window_customize_modedata *data,
|
||||
mti = mode_tree_add(data->data, child, item,
|
||||
tag|(bd->key << 3)|(1 << 1)|1, "Note", text, -1);
|
||||
mode_tree_draw_as_parent(mti);
|
||||
mode_tree_no_tag(mti);
|
||||
free(text);
|
||||
|
||||
if (bd->flags & KEY_BINDING_REPEAT)
|
||||
@ -506,6 +518,7 @@ window_customize_build_keys(struct window_customize_modedata *data,
|
||||
mti = mode_tree_add(data->data, child, item,
|
||||
tag|(bd->key << 3)|(2 << 1)|1, "Repeat", flag, -1);
|
||||
mode_tree_draw_as_parent(mti);
|
||||
mode_tree_no_tag(mti);
|
||||
|
||||
bd = key_bindings_next(kt, bd);
|
||||
}
|
||||
@ -1125,8 +1138,7 @@ static void
|
||||
window_customize_unset_option(struct window_customize_modedata *data,
|
||||
struct window_customize_itemdata *item)
|
||||
{
|
||||
struct options_entry *o;
|
||||
const struct options_table_entry *oe;
|
||||
struct options_entry *o;
|
||||
|
||||
if (item == NULL || !window_customize_check_item(data, item, NULL))
|
||||
return;
|
||||
@ -1134,20 +1146,30 @@ window_customize_unset_option(struct window_customize_modedata *data,
|
||||
o = options_get(item->oo, item->name);
|
||||
if (o == NULL)
|
||||
return;
|
||||
if (item->idx != -1) {
|
||||
if (item == mode_tree_get_current(data->data))
|
||||
mode_tree_up(data->data, 0);
|
||||
options_array_set(o, item->idx, NULL, 0, NULL);
|
||||
if (item->idx != -1 && item == mode_tree_get_current(data->data))
|
||||
mode_tree_up(data->data, 0);
|
||||
options_remove_or_default(o, item->idx, NULL);
|
||||
}
|
||||
|
||||
static void
|
||||
window_customize_reset_option(struct window_customize_modedata *data,
|
||||
struct window_customize_itemdata *item)
|
||||
{
|
||||
struct options *oo;
|
||||
struct options_entry *o;
|
||||
|
||||
if (item == NULL || !window_customize_check_item(data, item, NULL))
|
||||
return;
|
||||
if (item->idx != -1)
|
||||
return;
|
||||
|
||||
oo = item->oo;
|
||||
while (oo != NULL) {
|
||||
o = options_get_only(item->oo, item->name);
|
||||
if (o != NULL)
|
||||
options_remove_or_default(o, -1, NULL);
|
||||
oo = options_get_parent(oo);
|
||||
}
|
||||
oe = options_table_entry(o);
|
||||
if (oe != NULL &&
|
||||
options_owner(o) != global_options &&
|
||||
options_owner(o) != global_s_options &&
|
||||
options_owner(o) != global_w_options)
|
||||
options_remove(o);
|
||||
else
|
||||
options_default(options_owner(o), oe);
|
||||
}
|
||||
|
||||
static int
|
||||
@ -1286,21 +1308,52 @@ window_customize_unset_key(struct window_customize_modedata *data,
|
||||
}
|
||||
|
||||
static void
|
||||
window_customize_unset_each(void *modedata, void *itemdata,
|
||||
window_customize_reset_key(struct window_customize_modedata *data,
|
||||
struct window_customize_itemdata *item)
|
||||
{
|
||||
struct key_table *kt;
|
||||
struct key_binding *dd, *bd;
|
||||
|
||||
if (item == NULL || !window_customize_get_key(item, &kt, &bd))
|
||||
return;
|
||||
|
||||
dd = key_bindings_get_default(kt, bd->key);
|
||||
if (dd != NULL && bd->cmdlist == dd->cmdlist)
|
||||
return;
|
||||
if (dd == NULL && item == mode_tree_get_current(data->data)) {
|
||||
mode_tree_collapse_current(data->data);
|
||||
mode_tree_up(data->data, 0);
|
||||
}
|
||||
key_bindings_reset(kt->name, bd->key);
|
||||
}
|
||||
|
||||
static void
|
||||
window_customize_change_each(void *modedata, void *itemdata,
|
||||
__unused struct client *c, __unused key_code key)
|
||||
{
|
||||
struct window_customize_modedata *data = modedata;
|
||||
struct window_customize_itemdata *item = itemdata;
|
||||
|
||||
if (item->scope == WINDOW_CUSTOMIZE_KEY)
|
||||
window_customize_unset_key(modedata, item);
|
||||
else {
|
||||
window_customize_unset_option(modedata, item);
|
||||
options_push_changes(item->name);
|
||||
switch (data->change) {
|
||||
case WINDOW_CUSTOMIZE_UNSET:
|
||||
if (item->scope == WINDOW_CUSTOMIZE_KEY)
|
||||
window_customize_unset_key(data, item);
|
||||
else
|
||||
window_customize_unset_option(data, item);
|
||||
break;
|
||||
case WINDOW_CUSTOMIZE_RESET:
|
||||
if (item->scope == WINDOW_CUSTOMIZE_KEY)
|
||||
window_customize_reset_key(data, item);
|
||||
else
|
||||
window_customize_reset_option(data, item);
|
||||
break;
|
||||
}
|
||||
if (item->scope != WINDOW_CUSTOMIZE_KEY)
|
||||
options_push_changes(item->name);
|
||||
}
|
||||
|
||||
static int
|
||||
window_customize_unset_current_callback(__unused struct client *c,
|
||||
window_customize_change_current_callback(__unused struct client *c,
|
||||
void *modedata, const char *s, __unused int done)
|
||||
{
|
||||
struct window_customize_modedata *data = modedata;
|
||||
@ -1312,12 +1365,22 @@ window_customize_unset_current_callback(__unused struct client *c,
|
||||
return (0);
|
||||
|
||||
item = mode_tree_get_current(data->data);
|
||||
if (item->scope == WINDOW_CUSTOMIZE_KEY)
|
||||
window_customize_unset_key(data, item);
|
||||
else {
|
||||
window_customize_unset_option(data, item);
|
||||
options_push_changes(item->name);
|
||||
switch (data->change) {
|
||||
case WINDOW_CUSTOMIZE_UNSET:
|
||||
if (item->scope == WINDOW_CUSTOMIZE_KEY)
|
||||
window_customize_unset_key(data, item);
|
||||
else
|
||||
window_customize_unset_option(data, item);
|
||||
break;
|
||||
case WINDOW_CUSTOMIZE_RESET:
|
||||
if (item->scope == WINDOW_CUSTOMIZE_KEY)
|
||||
window_customize_reset_key(data, item);
|
||||
else
|
||||
window_customize_reset_option(data, item);
|
||||
break;
|
||||
}
|
||||
if (item->scope != WINDOW_CUSTOMIZE_KEY)
|
||||
options_push_changes(item->name);
|
||||
mode_tree_build(data->data);
|
||||
mode_tree_draw(data->data);
|
||||
data->wp->flags |= PANE_REDRAW;
|
||||
@ -1326,7 +1389,7 @@ window_customize_unset_current_callback(__unused struct client *c,
|
||||
}
|
||||
|
||||
static int
|
||||
window_customize_unset_tagged_callback(struct client *c, void *modedata,
|
||||
window_customize_change_tagged_callback(struct client *c, void *modedata,
|
||||
const char *s, __unused int done)
|
||||
{
|
||||
struct window_customize_modedata *data = modedata;
|
||||
@ -1336,7 +1399,7 @@ window_customize_unset_tagged_callback(struct client *c, void *modedata,
|
||||
if (tolower((u_char) s[0]) != 'y' || s[1] != '\0')
|
||||
return (0);
|
||||
|
||||
mode_tree_each_tagged(data->data, window_customize_unset_each, c,
|
||||
mode_tree_each_tagged(data->data, window_customize_change_each, c,
|
||||
KEYC_NONE, 0);
|
||||
mode_tree_build(data->data);
|
||||
mode_tree_draw(data->data);
|
||||
@ -1353,7 +1416,7 @@ window_customize_key(struct window_mode_entry *wme, struct client *c,
|
||||
struct window_pane *wp = wme->wp;
|
||||
struct window_customize_modedata *data = wme->data;
|
||||
struct window_customize_itemdata *item, *new_item;
|
||||
int finished;
|
||||
int finished, idx;
|
||||
char *prompt;
|
||||
u_int tagged;
|
||||
|
||||
@ -1390,17 +1453,43 @@ window_customize_key(struct window_mode_entry *wme, struct client *c,
|
||||
options_push_changes(item->name);
|
||||
mode_tree_build(data->data);
|
||||
break;
|
||||
case 'd':
|
||||
if (item == NULL || item->idx != -1)
|
||||
break;
|
||||
xasprintf(&prompt, "Reset %s to default? ", item->name);
|
||||
data->references++;
|
||||
data->change = WINDOW_CUSTOMIZE_RESET;
|
||||
status_prompt_set(c, NULL, prompt, "",
|
||||
window_customize_change_current_callback,
|
||||
window_customize_free_callback, data,
|
||||
PROMPT_SINGLE|PROMPT_NOFORMAT);
|
||||
free(prompt);
|
||||
break;
|
||||
case 'D':
|
||||
tagged = mode_tree_count_tagged(data->data);
|
||||
if (tagged == 0)
|
||||
break;
|
||||
xasprintf(&prompt, "Reset %u tagged to default? ", tagged);
|
||||
data->references++;
|
||||
data->change = WINDOW_CUSTOMIZE_RESET;
|
||||
status_prompt_set(c, NULL, prompt, "",
|
||||
window_customize_change_tagged_callback,
|
||||
window_customize_free_callback, data,
|
||||
PROMPT_SINGLE|PROMPT_NOFORMAT);
|
||||
free(prompt);
|
||||
break;
|
||||
case 'u':
|
||||
if (item == NULL)
|
||||
break;
|
||||
if (item->scope == WINDOW_CUSTOMIZE_KEY) {
|
||||
xasprintf(&prompt, "Unbind key %s? ",
|
||||
key_string_lookup_key(item->key, 0));
|
||||
} else
|
||||
xasprintf(&prompt, "Unset option %s? ", item->name);
|
||||
idx = item->idx;
|
||||
if (idx != -1)
|
||||
xasprintf(&prompt, "Unset %s[%d]? ", item->name, idx);
|
||||
else
|
||||
xasprintf(&prompt, "Unset %s? ", item->name);
|
||||
data->references++;
|
||||
data->change = WINDOW_CUSTOMIZE_UNSET;
|
||||
status_prompt_set(c, NULL, prompt, "",
|
||||
window_customize_unset_current_callback,
|
||||
window_customize_change_current_callback,
|
||||
window_customize_free_callback, data,
|
||||
PROMPT_SINGLE|PROMPT_NOFORMAT);
|
||||
free(prompt);
|
||||
@ -1409,10 +1498,11 @@ window_customize_key(struct window_mode_entry *wme, struct client *c,
|
||||
tagged = mode_tree_count_tagged(data->data);
|
||||
if (tagged == 0)
|
||||
break;
|
||||
xasprintf(&prompt, "Unset or unbind %u tagged? ", tagged);
|
||||
xasprintf(&prompt, "Unset %u tagged? ", tagged);
|
||||
data->references++;
|
||||
data->change = WINDOW_CUSTOMIZE_UNSET;
|
||||
status_prompt_set(c, NULL, prompt, "",
|
||||
window_customize_unset_tagged_callback,
|
||||
window_customize_change_tagged_callback,
|
||||
window_customize_free_callback, data,
|
||||
PROMPT_SINGLE|PROMPT_NOFORMAT);
|
||||
free(prompt);
|
||||
|
Loading…
Reference in New Issue
Block a user