mirror of
https://github.com/MidnightCommander/mc
synced 2024-12-23 04:46:55 +03:00
WInput: use GString for buffer.
Signed-off-by: Andrew Borodin <aborodin@vmail.ru>
This commit is contained in:
parent
f91d894f9b
commit
bf0dd8efb1
@ -156,9 +156,9 @@ delete_region (WInput * in, int start, int end)
|
|||||||
|
|
||||||
input_mark_cmd (in, FALSE);
|
input_mark_cmd (in, FALSE);
|
||||||
in->point = first;
|
in->point = first;
|
||||||
last = str_offset_to_pos (in->buffer, last);
|
last = str_offset_to_pos (in->buffer->str, last);
|
||||||
first = str_offset_to_pos (in->buffer, first);
|
first = str_offset_to_pos (in->buffer->str, first);
|
||||||
str_move (in->buffer + first, in->buffer + last);
|
g_string_erase (in->buffer, first, last - first);
|
||||||
in->charpoint = 0;
|
in->charpoint = 0;
|
||||||
in->need_push = TRUE;
|
in->need_push = TRUE;
|
||||||
}
|
}
|
||||||
@ -277,18 +277,15 @@ push_history (WInput * in, const char *text)
|
|||||||
static void
|
static void
|
||||||
move_buffer_backward (WInput * in, int start, int end)
|
move_buffer_backward (WInput * in, int start, int end)
|
||||||
{
|
{
|
||||||
int i, pos, len;
|
|
||||||
int str_len;
|
int str_len;
|
||||||
|
|
||||||
str_len = str_length (in->buffer);
|
str_len = str_length (in->buffer->str);
|
||||||
if (start >= str_len || end > str_len + 1)
|
if (start >= str_len || end > str_len + 1)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
pos = str_offset_to_pos (in->buffer, start);
|
start = str_offset_to_pos (in->buffer->str, start);
|
||||||
len = str_offset_to_pos (in->buffer, end) - pos;
|
end = str_offset_to_pos (in->buffer->str, end);
|
||||||
|
g_string_erase (in->buffer, start, end - start);
|
||||||
for (i = pos; in->buffer[i + len - 1]; i++)
|
|
||||||
in->buffer[i] = in->buffer[i + len];
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/* --------------------------------------------------------------------------------------------- */
|
/* --------------------------------------------------------------------------------------------- */
|
||||||
@ -298,6 +295,7 @@ insert_char (WInput * in, int c_code)
|
|||||||
{
|
{
|
||||||
int res;
|
int res;
|
||||||
long m1, m2;
|
long m1, m2;
|
||||||
|
size_t ins_point;
|
||||||
|
|
||||||
if (input_eval_marks (in, &m1, &m2))
|
if (input_eval_marks (in, &m1, &m2))
|
||||||
delete_region (in, m1, m2);
|
delete_region (in, m1, m2);
|
||||||
@ -320,37 +318,11 @@ insert_char (WInput * in, int c_code)
|
|||||||
}
|
}
|
||||||
|
|
||||||
in->need_push = TRUE;
|
in->need_push = TRUE;
|
||||||
if (strlen (in->buffer) + 1 + in->charpoint >= in->current_max_size)
|
ins_point = str_offset_to_pos (in->buffer->str, in->point);
|
||||||
{
|
g_string_insert_len (in->buffer, ins_point, in->charbuf, in->charpoint);
|
||||||
/* Expand the buffer */
|
in->point++;
|
||||||
size_t new_length;
|
|
||||||
char *narea;
|
|
||||||
|
|
||||||
new_length = in->current_max_size + WIDGET (in)->cols + in->charpoint;
|
|
||||||
narea = g_try_renew (char, in->buffer, new_length);
|
|
||||||
if (narea != NULL)
|
|
||||||
{
|
|
||||||
in->buffer = narea;
|
|
||||||
in->current_max_size = new_length;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if (strlen (in->buffer) + in->charpoint < in->current_max_size)
|
|
||||||
{
|
|
||||||
size_t i;
|
|
||||||
/* bytes from begin */
|
|
||||||
size_t ins_point = str_offset_to_pos (in->buffer, in->point);
|
|
||||||
/* move chars */
|
|
||||||
size_t rest_bytes = strlen (in->buffer + ins_point);
|
|
||||||
|
|
||||||
for (i = rest_bytes + 1; i > 0; i--)
|
|
||||||
in->buffer[ins_point + i + in->charpoint - 1] = in->buffer[ins_point + i - 1];
|
|
||||||
|
|
||||||
memcpy (in->buffer + ins_point, in->charbuf, in->charpoint);
|
|
||||||
in->point++;
|
|
||||||
}
|
|
||||||
|
|
||||||
in->charpoint = 0;
|
in->charpoint = 0;
|
||||||
|
|
||||||
return MSG_HANDLED;
|
return MSG_HANDLED;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -368,7 +340,7 @@ beginning_of_line (WInput * in)
|
|||||||
static void
|
static void
|
||||||
end_of_line (WInput * in)
|
end_of_line (WInput * in)
|
||||||
{
|
{
|
||||||
in->point = str_length (in->buffer);
|
in->point = str_length (in->buffer->str);
|
||||||
in->charpoint = 0;
|
in->charpoint = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -377,11 +349,14 @@ end_of_line (WInput * in)
|
|||||||
static void
|
static void
|
||||||
backward_char (WInput * in)
|
backward_char (WInput * in)
|
||||||
{
|
{
|
||||||
const char *act;
|
|
||||||
|
|
||||||
act = in->buffer + str_offset_to_pos (in->buffer, in->point);
|
|
||||||
if (in->point > 0)
|
if (in->point > 0)
|
||||||
in->point -= str_cprev_noncomb_char (&act, in->buffer);
|
{
|
||||||
|
const char *act;
|
||||||
|
|
||||||
|
act = in->buffer->str + str_offset_to_pos (in->buffer->str, in->point);
|
||||||
|
in->point -= str_cprev_noncomb_char (&act, in->buffer->str);
|
||||||
|
}
|
||||||
|
|
||||||
in->charpoint = 0;
|
in->charpoint = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -392,7 +367,7 @@ forward_char (WInput * in)
|
|||||||
{
|
{
|
||||||
const char *act;
|
const char *act;
|
||||||
|
|
||||||
act = in->buffer + str_offset_to_pos (in->buffer, in->point);
|
act = in->buffer->str + str_offset_to_pos (in->buffer->str, in->point);
|
||||||
if (act[0] != '\0')
|
if (act[0] != '\0')
|
||||||
in->point += str_cnext_noncomb_char (&act);
|
in->point += str_cnext_noncomb_char (&act);
|
||||||
in->charpoint = 0;
|
in->charpoint = 0;
|
||||||
@ -405,17 +380,13 @@ forward_word (WInput * in)
|
|||||||
{
|
{
|
||||||
const char *p;
|
const char *p;
|
||||||
|
|
||||||
p = in->buffer + str_offset_to_pos (in->buffer, in->point);
|
p = in->buffer->str + str_offset_to_pos (in->buffer->str, in->point);
|
||||||
while (p[0] != '\0' && (str_isspace (p) || str_ispunct (p)))
|
|
||||||
{
|
for (; p[0] != '\0' && (str_isspace (p) || str_ispunct (p)); in->point++)
|
||||||
str_cnext_char (&p);
|
str_cnext_char (&p);
|
||||||
in->point++;
|
|
||||||
}
|
for (; p[0] != '\0' && !str_isspace (p) && !str_ispunct (p); in->point++)
|
||||||
while (p[0] != '\0' && !str_isspace (p) && !str_ispunct (p))
|
|
||||||
{
|
|
||||||
str_cnext_char (&p);
|
str_cnext_char (&p);
|
||||||
in->point++;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/* --------------------------------------------------------------------------------------------- */
|
/* --------------------------------------------------------------------------------------------- */
|
||||||
@ -425,9 +396,9 @@ backward_word (WInput * in)
|
|||||||
{
|
{
|
||||||
const char *p;
|
const char *p;
|
||||||
|
|
||||||
p = in->buffer + str_offset_to_pos (in->buffer, in->point);
|
p = in->buffer->str + str_offset_to_pos (in->buffer->str, in->point);
|
||||||
|
|
||||||
while (p != in->buffer)
|
for (; p != in->buffer->str; in->point--)
|
||||||
{
|
{
|
||||||
const char *p_tmp;
|
const char *p_tmp;
|
||||||
|
|
||||||
@ -438,15 +409,13 @@ backward_word (WInput * in)
|
|||||||
p = p_tmp;
|
p = p_tmp;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
in->point--;
|
|
||||||
}
|
}
|
||||||
while (p != in->buffer)
|
|
||||||
|
for (; p != in->buffer->str; in->point--)
|
||||||
{
|
{
|
||||||
str_cprev_char (&p);
|
str_cprev_char (&p);
|
||||||
if (str_isspace (p) || str_ispunct (p))
|
if (str_isspace (p) || str_ispunct (p))
|
||||||
break;
|
break;
|
||||||
|
|
||||||
in->point--;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -455,13 +424,14 @@ backward_word (WInput * in)
|
|||||||
static void
|
static void
|
||||||
backward_delete (WInput * in)
|
backward_delete (WInput * in)
|
||||||
{
|
{
|
||||||
const char *act = in->buffer + str_offset_to_pos (in->buffer, in->point);
|
const char *act;
|
||||||
int start;
|
int start;
|
||||||
|
|
||||||
if (in->point == 0)
|
if (in->point == 0)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
start = in->point - str_cprev_noncomb_char (&act, in->buffer);
|
act = in->buffer->str + str_offset_to_pos (in->buffer->str, in->point);
|
||||||
|
start = in->point - str_cprev_noncomb_char (&act, in->buffer->str);
|
||||||
move_buffer_backward (in, start, in->point);
|
move_buffer_backward (in, start, in->point);
|
||||||
in->charpoint = 0;
|
in->charpoint = 0;
|
||||||
in->need_push = TRUE;
|
in->need_push = TRUE;
|
||||||
@ -474,11 +444,10 @@ static void
|
|||||||
delete_char (WInput * in)
|
delete_char (WInput * in)
|
||||||
{
|
{
|
||||||
const char *act;
|
const char *act;
|
||||||
int end = in->point;
|
int end;
|
||||||
|
|
||||||
act = in->buffer + str_offset_to_pos (in->buffer, in->point);
|
|
||||||
end += str_cnext_noncomb_char (&act);
|
|
||||||
|
|
||||||
|
act = in->buffer->str + str_offset_to_pos (in->buffer->str, in->point);
|
||||||
|
end = in->point + str_cnext_noncomb_char (&act);
|
||||||
move_buffer_backward (in, in->point, end);
|
move_buffer_backward (in, in->point, end);
|
||||||
in->charpoint = 0;
|
in->charpoint = 0;
|
||||||
in->need_push = TRUE;
|
in->need_push = TRUE;
|
||||||
@ -503,10 +472,10 @@ copy_region (WInput * in, int start, int end)
|
|||||||
|
|
||||||
g_free (kill_buffer);
|
g_free (kill_buffer);
|
||||||
|
|
||||||
first = str_offset_to_pos (in->buffer, first);
|
first = str_offset_to_pos (in->buffer->str, first);
|
||||||
last = str_offset_to_pos (in->buffer, last);
|
last = str_offset_to_pos (in->buffer->str, last);
|
||||||
|
|
||||||
kill_buffer = g_strndup (in->buffer + first, last - first);
|
kill_buffer = g_strndup (in->buffer->str + first, last - first);
|
||||||
|
|
||||||
mc_event_raise (MCEVENT_GROUP_CORE, "clipboard_text_to_file", kill_buffer);
|
mc_event_raise (MCEVENT_GROUP_CORE, "clipboard_text_to_file", kill_buffer);
|
||||||
/* try use external clipboard utility */
|
/* try use external clipboard utility */
|
||||||
@ -569,10 +538,10 @@ kill_line (WInput * in)
|
|||||||
{
|
{
|
||||||
int chp;
|
int chp;
|
||||||
|
|
||||||
chp = str_offset_to_pos (in->buffer, in->point);
|
chp = str_offset_to_pos (in->buffer->str, in->point);
|
||||||
g_free (kill_buffer);
|
g_free (kill_buffer);
|
||||||
kill_buffer = g_strdup (&in->buffer[chp]);
|
kill_buffer = g_strndup (in->buffer->str + chp, in->buffer->len - chp);
|
||||||
in->buffer[chp] = '\0';
|
g_string_set_size (in->buffer, chp);
|
||||||
in->charpoint = 0;
|
in->charpoint = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -582,7 +551,7 @@ static void
|
|||||||
clear_line (WInput * in)
|
clear_line (WInput * in)
|
||||||
{
|
{
|
||||||
in->need_push = TRUE;
|
in->need_push = TRUE;
|
||||||
in->buffer[0] = '\0';
|
g_string_set_size (in->buffer, 0);
|
||||||
in->point = 0;
|
in->point = 0;
|
||||||
in->mark = -1;
|
in->mark = -1;
|
||||||
in->charpoint = 0;
|
in->charpoint = 0;
|
||||||
@ -623,7 +592,7 @@ hist_prev (WInput * in)
|
|||||||
return;
|
return;
|
||||||
|
|
||||||
if (in->need_push)
|
if (in->need_push)
|
||||||
push_history (in, in->buffer);
|
push_history (in, in->buffer->str);
|
||||||
|
|
||||||
prev = g_list_previous (in->history.current);
|
prev = g_list_previous (in->history.current);
|
||||||
if (prev != NULL)
|
if (prev != NULL)
|
||||||
@ -644,7 +613,7 @@ hist_next (WInput * in)
|
|||||||
|
|
||||||
if (in->need_push)
|
if (in->need_push)
|
||||||
{
|
{
|
||||||
push_history (in, in->buffer);
|
push_history (in, in->buffer->str);
|
||||||
input_assign_text (in, "");
|
input_assign_text (in, "");
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
@ -672,7 +641,7 @@ hist_next (WInput * in)
|
|||||||
static void
|
static void
|
||||||
port_region_marked_for_delete (WInput * in)
|
port_region_marked_for_delete (WInput * in)
|
||||||
{
|
{
|
||||||
in->buffer[0] = '\0';
|
g_string_set_size (in->buffer, 0);
|
||||||
in->point = 0;
|
in->point = 0;
|
||||||
in->first = FALSE;
|
in->first = FALSE;
|
||||||
in->charpoint = 0;
|
in->charpoint = 0;
|
||||||
@ -875,7 +844,7 @@ input_save_history (const gchar * event_group_name, const gchar * event_name,
|
|||||||
{
|
{
|
||||||
ev_history_load_save_t *ev = (ev_history_load_save_t *) data;
|
ev_history_load_save_t *ev = (ev_history_load_save_t *) data;
|
||||||
|
|
||||||
push_history (in, in->buffer);
|
push_history (in, in->buffer->str);
|
||||||
if (in->history.changed)
|
if (in->history.changed)
|
||||||
mc_config_history_save (ev->cfg, in->history.name, in->history.list);
|
mc_config_history_save (ev->cfg, in->history.name, in->history.list);
|
||||||
in->history.changed = FALSE;
|
in->history.changed = FALSE;
|
||||||
@ -905,7 +874,7 @@ input_destroy (WInput * in)
|
|||||||
g_list_free_full (in->history.list, g_free);
|
g_list_free_full (in->history.list, g_free);
|
||||||
}
|
}
|
||||||
g_free (in->history.name);
|
g_free (in->history.name);
|
||||||
g_free (in->buffer);
|
g_string_free (in->buffer, TRUE);
|
||||||
MC_PTR_FREE (kill_buffer);
|
MC_PTR_FREE (kill_buffer);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -922,10 +891,10 @@ input_screen_to_point (const WInput * in, int x)
|
|||||||
if (x < 0)
|
if (x < 0)
|
||||||
return 0;
|
return 0;
|
||||||
|
|
||||||
if (x < str_term_width1 (in->buffer))
|
if (x < str_term_width1 (in->buffer->str))
|
||||||
return str_column_to_pos (in->buffer, x);
|
return str_column_to_pos (in->buffer->str, x);
|
||||||
|
|
||||||
return str_length (in->buffer);
|
return str_length (in->buffer->str);
|
||||||
}
|
}
|
||||||
|
|
||||||
/* --------------------------------------------------------------------------------------------- */
|
/* --------------------------------------------------------------------------------------------- */
|
||||||
@ -1006,8 +975,7 @@ input_new (int y, int x, const int *colors, int width, const char *def_text,
|
|||||||
in->strip_password = FALSE;
|
in->strip_password = FALSE;
|
||||||
|
|
||||||
/* in->buffer will be corrected in "history_load" event handler */
|
/* in->buffer will be corrected in "history_load" event handler */
|
||||||
in->current_max_size = width + 1;
|
in->buffer = g_string_sized_new (width);
|
||||||
in->buffer = g_new0 (char, in->current_max_size);
|
|
||||||
|
|
||||||
/* init completions before input_assign_text() call */
|
/* init completions before input_assign_text() call */
|
||||||
in->completions = NULL;
|
in->completions = NULL;
|
||||||
@ -1093,7 +1061,7 @@ input_callback (Widget * w, Widget * sender, widget_msg_t msg, int parm, void *d
|
|||||||
return MSG_HANDLED;
|
return MSG_HANDLED;
|
||||||
|
|
||||||
case MSG_CURSOR:
|
case MSG_CURSOR:
|
||||||
widget_gotoyx (in, 0, str_term_width2 (in->buffer, in->point) - in->term_first_shown);
|
widget_gotoyx (in, 0, str_term_width2 (in->buffer->str, in->point) - in->term_first_shown);
|
||||||
return MSG_HANDLED;
|
return MSG_HANDLED;
|
||||||
|
|
||||||
case MSG_DESTROY:
|
case MSG_DESTROY:
|
||||||
@ -1170,9 +1138,6 @@ input_handle_char (WInput * in, int key)
|
|||||||
void
|
void
|
||||||
input_assign_text (WInput * in, const char *text)
|
input_assign_text (WInput * in, const char *text)
|
||||||
{
|
{
|
||||||
Widget *w = WIDGET (in);
|
|
||||||
size_t text_len, buffer_len;
|
|
||||||
|
|
||||||
if (text == NULL)
|
if (text == NULL)
|
||||||
text = "";
|
text = "";
|
||||||
|
|
||||||
@ -1180,14 +1145,8 @@ input_assign_text (WInput * in, const char *text)
|
|||||||
in->mark = -1;
|
in->mark = -1;
|
||||||
in->need_push = TRUE;
|
in->need_push = TRUE;
|
||||||
in->charpoint = 0;
|
in->charpoint = 0;
|
||||||
|
g_string_assign (in->buffer, text);
|
||||||
text_len = strlen (text);
|
in->point = str_length (in->buffer->str);
|
||||||
buffer_len = 1 + MAX ((size_t) w->cols, text_len);
|
|
||||||
in->current_max_size = buffer_len;
|
|
||||||
if (buffer_len > (size_t) w->cols)
|
|
||||||
in->buffer = g_realloc (in->buffer, buffer_len);
|
|
||||||
memmove (in->buffer, text, text_len + 1);
|
|
||||||
in->point = str_length (in->buffer);
|
|
||||||
input_update (in, TRUE);
|
input_update (in, TRUE);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1207,7 +1166,7 @@ input_get_text (const WInput * in)
|
|||||||
if (input_is_empty (in))
|
if (input_is_empty (in))
|
||||||
return NULL;
|
return NULL;
|
||||||
|
|
||||||
return g_strdup (in->buffer);
|
return g_strndup (in->buffer->str, in->buffer->len);
|
||||||
}
|
}
|
||||||
|
|
||||||
/* --------------------------------------------------------------------------------------------- */
|
/* --------------------------------------------------------------------------------------------- */
|
||||||
@ -1221,7 +1180,7 @@ input_is_empty (const WInput * in)
|
|||||||
/* if in != NULL, in->buffer must be created */
|
/* if in != NULL, in->buffer must be created */
|
||||||
g_assert (in->buffer != NULL);
|
g_assert (in->buffer != NULL);
|
||||||
|
|
||||||
return in->buffer[0] == '\0';
|
return in->buffer->len == 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* --------------------------------------------------------------------------------------------- */
|
/* --------------------------------------------------------------------------------------------- */
|
||||||
@ -1246,7 +1205,7 @@ input_set_point (WInput * in, int pos)
|
|||||||
{
|
{
|
||||||
int max_pos;
|
int max_pos;
|
||||||
|
|
||||||
max_pos = str_length (in->buffer);
|
max_pos = str_length (in->buffer->str);
|
||||||
pos = MIN (pos, max_pos);
|
pos = MIN (pos, max_pos);
|
||||||
if (pos != in->point)
|
if (pos != in->point)
|
||||||
input_complete_free (in);
|
input_complete_free (in);
|
||||||
@ -1279,12 +1238,12 @@ input_update (WInput * in, gboolean clear_first)
|
|||||||
if (should_show_history_button (in))
|
if (should_show_history_button (in))
|
||||||
has_history = HISTORY_BUTTON_WIDTH;
|
has_history = HISTORY_BUTTON_WIDTH;
|
||||||
|
|
||||||
buf_len = str_length (in->buffer);
|
buf_len = str_length (in->buffer->str);
|
||||||
|
|
||||||
/* Adjust the mark */
|
/* Adjust the mark */
|
||||||
in->mark = MIN (in->mark, buf_len);
|
in->mark = MIN (in->mark, buf_len);
|
||||||
|
|
||||||
pw = str_term_width2 (in->buffer, in->point);
|
pw = str_term_width2 (in->buffer->str, in->point);
|
||||||
|
|
||||||
/* Make the point visible */
|
/* Make the point visible */
|
||||||
if ((pw < in->term_first_shown) || (pw >= in->term_first_shown + w->cols - has_history))
|
if ((pw < in->term_first_shown) || (pw >= in->term_first_shown + w->cols - has_history))
|
||||||
@ -1309,7 +1268,7 @@ input_update (WInput * in, gboolean clear_first)
|
|||||||
if (!in->is_password)
|
if (!in->is_password)
|
||||||
{
|
{
|
||||||
if (in->mark < 0)
|
if (in->mark < 0)
|
||||||
tty_print_string (str_term_substring (in->buffer, in->term_first_shown,
|
tty_print_string (str_term_substring (in->buffer->str, in->term_first_shown,
|
||||||
w->cols - has_history));
|
w->cols - has_history));
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
@ -1318,26 +1277,27 @@ input_update (WInput * in, gboolean clear_first)
|
|||||||
if (input_eval_marks (in, &m1, &m2))
|
if (input_eval_marks (in, &m1, &m2))
|
||||||
{
|
{
|
||||||
tty_setcolor (in->color[WINPUTC_MAIN]);
|
tty_setcolor (in->color[WINPUTC_MAIN]);
|
||||||
cp = str_term_substring (in->buffer, in->term_first_shown, w->cols - has_history);
|
cp = str_term_substring (in->buffer->str, in->term_first_shown,
|
||||||
|
w->cols - has_history);
|
||||||
tty_print_string (cp);
|
tty_print_string (cp);
|
||||||
tty_setcolor (in->color[WINPUTC_MARK]);
|
tty_setcolor (in->color[WINPUTC_MARK]);
|
||||||
if (m1 < in->term_first_shown)
|
if (m1 < in->term_first_shown)
|
||||||
{
|
{
|
||||||
widget_gotoyx (in, 0, 0);
|
widget_gotoyx (in, 0, 0);
|
||||||
tty_print_string (str_term_substring
|
m1 = in->term_first_shown;
|
||||||
(in->buffer, in->term_first_shown,
|
m2 -= m1;
|
||||||
m2 - in->term_first_shown));
|
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
int sel_width, buf_width;
|
int buf_width;
|
||||||
|
|
||||||
widget_gotoyx (in, 0, m1 - in->term_first_shown);
|
widget_gotoyx (in, 0, m1 - in->term_first_shown);
|
||||||
buf_width = str_term_width2 (in->buffer, m1);
|
buf_width = str_term_width2 (in->buffer->str, m1);
|
||||||
sel_width =
|
m2 = MIN (m2 - m1,
|
||||||
MIN (m2 - m1, (w->cols - has_history) - (buf_width - in->term_first_shown));
|
(w->cols - has_history) - (buf_width - in->term_first_shown));
|
||||||
tty_print_string (str_term_substring (in->buffer, m1, sel_width));
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
tty_print_string (str_term_substring (in->buffer->str, m1, m2));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -1345,7 +1305,7 @@ input_update (WInput * in, gboolean clear_first)
|
|||||||
{
|
{
|
||||||
int i;
|
int i;
|
||||||
|
|
||||||
cp = str_term_substring (in->buffer, in->term_first_shown, w->cols - has_history);
|
cp = str_term_substring (in->buffer->str, in->term_first_shown, w->cols - has_history);
|
||||||
tty_setcolor (in->color[WINPUTC_MAIN]);
|
tty_setcolor (in->color[WINPUTC_MAIN]);
|
||||||
for (i = 0; i < w->cols - has_history; i++)
|
for (i = 0; i < w->cols - has_history; i++)
|
||||||
{
|
{
|
||||||
@ -1386,9 +1346,9 @@ input_disable_update (WInput * in)
|
|||||||
void
|
void
|
||||||
input_clean (WInput * in)
|
input_clean (WInput * in)
|
||||||
{
|
{
|
||||||
push_history (in, in->buffer);
|
push_history (in, in->buffer->str);
|
||||||
in->need_push = TRUE;
|
in->need_push = TRUE;
|
||||||
in->buffer[0] = '\0';
|
g_string_set_size (in->buffer, 0);
|
||||||
in->point = 0;
|
in->point = 0;
|
||||||
in->charpoint = 0;
|
in->charpoint = 0;
|
||||||
in->mark = -1;
|
in->mark = -1;
|
||||||
|
@ -46,16 +46,16 @@ typedef int input_colors_t[WINPUTC_COUNT_COLORS];
|
|||||||
typedef struct
|
typedef struct
|
||||||
{
|
{
|
||||||
Widget widget;
|
Widget widget;
|
||||||
|
|
||||||
|
GString *buffer;
|
||||||
const int *color;
|
const int *color;
|
||||||
int point; /* cursor position in the input line in characters */
|
int point; /* cursor position in the input line in characters */
|
||||||
int mark; /* the mark position in characters; negative value means no marked text */
|
int mark; /* the mark position in characters; negative value means no marked text */
|
||||||
int term_first_shown; /* column of the first shown character */
|
int term_first_shown; /* column of the first shown character */
|
||||||
size_t current_max_size; /* maximum length of input line (bytes) */
|
|
||||||
gboolean first; /* is first keystroke? */
|
gboolean first; /* is first keystroke? */
|
||||||
int disable_update; /* do we want to skip updates? */
|
int disable_update; /* do we want to skip updates? */
|
||||||
gboolean is_password; /* is this a password input line? */
|
gboolean is_password; /* is this a password input line? */
|
||||||
gboolean init_from_history; /* init text will be get from history */
|
gboolean init_from_history; /* init text will be get from history */
|
||||||
char *buffer; /* pointer to editing buffer */
|
|
||||||
gboolean need_push; /* need to push the current Input on hist? */
|
gboolean need_push; /* need to push the current Input on hist? */
|
||||||
gboolean strip_password; /* need to strip password before placing string to history */
|
gboolean strip_password; /* need to strip password before placing string to history */
|
||||||
char **completions; /* possible completions array */
|
char **completions; /* possible completions array */
|
||||||
|
@ -8,7 +8,7 @@
|
|||||||
Written by:
|
Written by:
|
||||||
Jakub Jelinek, 1995
|
Jakub Jelinek, 1995
|
||||||
Slava Zanko <slavazanko@gmail.com>, 2013
|
Slava Zanko <slavazanko@gmail.com>, 2013
|
||||||
Andrew Borodin <aborodin@vmail.ru>, 2013
|
Andrew Borodin <aborodin@vmail.ru>, 2013-2022
|
||||||
|
|
||||||
This file is part of the Midnight Commander.
|
This file is part of the Midnight Commander.
|
||||||
|
|
||||||
@ -980,38 +980,47 @@ insert_text (WInput * in, char *text, ssize_t size)
|
|||||||
{
|
{
|
||||||
size_t text_len;
|
size_t text_len;
|
||||||
int buff_len;
|
int buff_len;
|
||||||
|
ssize_t new_size;
|
||||||
|
|
||||||
text_len = strlen (text);
|
text_len = strlen (text);
|
||||||
buff_len = str_length (in->buffer);
|
buff_len = str_length (in->buffer->str);
|
||||||
if (size < 0)
|
if (size < 0)
|
||||||
size = (ssize_t) text_len;
|
size = (ssize_t) text_len;
|
||||||
else
|
else
|
||||||
size = MIN (size, (ssize_t) text_len);
|
size = MIN (size, (ssize_t) text_len);
|
||||||
size += start - end;
|
|
||||||
if (strlen (in->buffer) + size >= (size_t) in->current_max_size)
|
|
||||||
{
|
|
||||||
/* Expand the buffer */
|
|
||||||
char *narea;
|
|
||||||
Widget *w = WIDGET (in);
|
|
||||||
|
|
||||||
narea = g_try_realloc (in->buffer, in->current_max_size + size + w->cols);
|
new_size = size + start - end;
|
||||||
if (narea != NULL)
|
if (new_size != 0)
|
||||||
|
{
|
||||||
|
/* make a hole within buffer */
|
||||||
|
|
||||||
|
size_t tail_len;
|
||||||
|
|
||||||
|
tail_len = in->buffer->len - end;
|
||||||
|
if (tail_len != 0)
|
||||||
{
|
{
|
||||||
in->buffer = narea;
|
char *tail;
|
||||||
in->current_max_size += size + w->cols;
|
size_t hole_end;
|
||||||
|
|
||||||
|
tail = g_strndup (in->buffer->str + end, tail_len);
|
||||||
|
|
||||||
|
hole_end = end + new_size;
|
||||||
|
if (in->buffer->len < hole_end)
|
||||||
|
g_string_set_size (in->buffer, hole_end + tail_len);
|
||||||
|
|
||||||
|
g_string_overwrite_len (in->buffer, hole_end, tail, tail_len);
|
||||||
|
|
||||||
|
g_free (tail);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (strlen (in->buffer) + 1 < (size_t) in->current_max_size)
|
|
||||||
{
|
|
||||||
if (size != 0)
|
|
||||||
memmove (in->buffer + end + size, in->buffer + end, strlen (&in->buffer[end]) + 1);
|
|
||||||
memmove (in->buffer + start, text, size - (start - end));
|
|
||||||
in->point += str_length (in->buffer) - buff_len;
|
|
||||||
input_update (in, TRUE);
|
|
||||||
end += size;
|
|
||||||
}
|
|
||||||
|
|
||||||
return size != 0;
|
g_string_overwrite_len (in->buffer, start, text, size);
|
||||||
|
|
||||||
|
in->point += str_length (in->buffer->str) - buff_len;
|
||||||
|
input_update (in, TRUE);
|
||||||
|
end += new_size;
|
||||||
|
|
||||||
|
return new_size != 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* --------------------------------------------------------------------------------------------- */
|
/* --------------------------------------------------------------------------------------------- */
|
||||||
@ -1047,7 +1056,7 @@ complete_callback (Widget * w, Widget * sender, widget_msg_t msg, int parm, void
|
|||||||
/* Refill the list box and start again */
|
/* Refill the list box and start again */
|
||||||
else if (end == min_end)
|
else if (end == min_end)
|
||||||
{
|
{
|
||||||
end = str_get_prev_char (&input->buffer[end]) - input->buffer;
|
end = str_get_prev_char (input->buffer->str + end) - input->buffer->str;
|
||||||
input_handle_char (input, parm);
|
input_handle_char (input, parm);
|
||||||
h->ret_value = B_USER;
|
h->ret_value = B_USER;
|
||||||
dlg_stop (h);
|
dlg_stop (h);
|
||||||
@ -1058,14 +1067,14 @@ complete_callback (Widget * w, Widget * sender, widget_msg_t msg, int parm, void
|
|||||||
int i;
|
int i;
|
||||||
GList *e;
|
GList *e;
|
||||||
|
|
||||||
new_end = str_get_prev_char (&input->buffer[end]) - input->buffer;
|
new_end = str_get_prev_char (input->buffer->str + end) - input->buffer->str;
|
||||||
|
|
||||||
for (i = 0, e = listbox_get_first_link (LISTBOX (g->current->data));
|
for (i = 0, e = listbox_get_first_link (LISTBOX (g->current->data));
|
||||||
e != NULL; i++, e = g_list_next (e))
|
e != NULL; i++, e = g_list_next (e))
|
||||||
{
|
{
|
||||||
WLEntry *le = LENTRY (e->data);
|
WLEntry *le = LENTRY (e->data);
|
||||||
|
|
||||||
if (strncmp (input->buffer + start, le->text, new_end - start) == 0)
|
if (strncmp (input->buffer->str + start, le->text, new_end - start) == 0)
|
||||||
{
|
{
|
||||||
listbox_select_entry (LISTBOX (g->current->data), i);
|
listbox_select_entry (LISTBOX (g->current->data), i);
|
||||||
end = new_end;
|
end = new_end;
|
||||||
@ -1119,8 +1128,8 @@ complete_callback (Widget * w, Widget * sender, widget_msg_t msg, int parm, void
|
|||||||
{
|
{
|
||||||
WLEntry *le = LENTRY (e->data);
|
WLEntry *le = LENTRY (e->data);
|
||||||
|
|
||||||
if (strncmp (input->buffer + start, le->text, end - start) == 0
|
if (strncmp (input->buffer->str + start, le->text, end - start) == 0
|
||||||
&& strncmp (&le->text[end - start], buff, bl) == 0)
|
&& strncmp (le->text + end - start, buff, bl) == 0)
|
||||||
{
|
{
|
||||||
if (need_redraw == 0)
|
if (need_redraw == 0)
|
||||||
{
|
{
|
||||||
@ -1199,7 +1208,7 @@ complete_callback (Widget * w, Widget * sender, widget_msg_t msg, int parm, void
|
|||||||
static gboolean
|
static gboolean
|
||||||
complete_engine (WInput * in, int what_to_do)
|
complete_engine (WInput * in, int what_to_do)
|
||||||
{
|
{
|
||||||
if (in->completions != NULL && str_offset_to_pos (in->buffer, in->point) != end)
|
if (in->completions != NULL && str_offset_to_pos (in->buffer->str, in->point) != end)
|
||||||
input_complete_free (in);
|
input_complete_free (in);
|
||||||
|
|
||||||
if (in->completions == NULL)
|
if (in->completions == NULL)
|
||||||
@ -1408,9 +1417,9 @@ complete_engine_fill_completions (WInput * in)
|
|||||||
|
|
||||||
word_separators = (in->completion_flags & INPUT_COMPLETE_SHELL_ESC) ? " \t;|<>" : "\t;|<>";
|
word_separators = (in->completion_flags & INPUT_COMPLETE_SHELL_ESC) ? " \t;|<>" : "\t;|<>";
|
||||||
|
|
||||||
end = str_offset_to_pos (in->buffer, in->point);
|
end = str_offset_to_pos (in->buffer->str, in->point);
|
||||||
|
|
||||||
s = in->buffer;
|
s = in->buffer->str;
|
||||||
if (in->point != 0)
|
if (in->point != 0)
|
||||||
{
|
{
|
||||||
/* get symbol before in->point */
|
/* get symbol before in->point */
|
||||||
@ -1420,20 +1429,20 @@ complete_engine_fill_completions (WInput * in)
|
|||||||
str_next_char (&s);
|
str_next_char (&s);
|
||||||
}
|
}
|
||||||
|
|
||||||
for (; s >= in->buffer; str_prev_char (&s))
|
for (; s >= in->buffer->str; str_prev_char (&s))
|
||||||
{
|
{
|
||||||
start = s - in->buffer;
|
start = s - in->buffer->str;
|
||||||
if (strchr (word_separators, *s) != NULL && !strutils_is_char_escaped (in->buffer, s))
|
if (strchr (word_separators, *s) != NULL && !strutils_is_char_escaped (in->buffer->str, s))
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (start < end)
|
if (start < end)
|
||||||
{
|
{
|
||||||
str_next_char (&s);
|
str_next_char (&s);
|
||||||
start = s - in->buffer;
|
start = s - in->buffer->str;
|
||||||
}
|
}
|
||||||
|
|
||||||
in->completions = try_complete (in->buffer, &start, &end, in->completion_flags);
|
in->completions = try_complete (in->buffer->str, &start, &end, in->completion_flags);
|
||||||
}
|
}
|
||||||
|
|
||||||
/* --------------------------------------------------------------------------------------------- */
|
/* --------------------------------------------------------------------------------------------- */
|
||||||
@ -1444,7 +1453,7 @@ input_complete (WInput * in)
|
|||||||
{
|
{
|
||||||
int engine_flags;
|
int engine_flags;
|
||||||
|
|
||||||
if (!str_is_valid_string (in->buffer))
|
if (!str_is_valid_string (in->buffer->str))
|
||||||
return;
|
return;
|
||||||
|
|
||||||
if (in->completions != NULL)
|
if (in->completions != NULL)
|
||||||
|
@ -597,7 +597,7 @@ quick_dialog_skip (quick_dialog_t * quick_dlg, int nskip)
|
|||||||
case quick_input:
|
case quick_input:
|
||||||
if ((item->quick_widget->u.input.completion_flags & INPUT_COMPLETE_CD) != 0)
|
if ((item->quick_widget->u.input.completion_flags & INPUT_COMPLETE_CD) != 0)
|
||||||
*item->quick_widget->u.input.result =
|
*item->quick_widget->u.input.result =
|
||||||
tilde_expand (INPUT (item->widget)->buffer);
|
tilde_expand (INPUT (item->widget)->buffer->str);
|
||||||
else
|
else
|
||||||
*item->quick_widget->u.input.result = input_get_text (INPUT (item->widget));
|
*item->quick_widget->u.input.result = input_get_text (INPUT (item->widget));
|
||||||
break;
|
break;
|
||||||
|
@ -6,7 +6,7 @@
|
|||||||
Free Software Foundation, Inc.
|
Free Software Foundation, Inc.
|
||||||
|
|
||||||
Written by:
|
Written by:
|
||||||
Andrew Borodin <aborodin@vmail.ru>, 2013-2015
|
Andrew Borodin <aborodin@vmail.ru>, 2013-2022
|
||||||
|
|
||||||
This file is part of the Midnight Commander.
|
This file is part of the Midnight Commander.
|
||||||
|
|
||||||
@ -622,7 +622,7 @@ view_filtered_cmd (const WPanel * panel)
|
|||||||
if (input_is_empty (cmdline))
|
if (input_is_empty (cmdline))
|
||||||
initial_command = selection (panel)->fname->str;
|
initial_command = selection (panel)->fname->str;
|
||||||
else
|
else
|
||||||
initial_command = cmdline->buffer;
|
initial_command = cmdline->buffer->str;
|
||||||
|
|
||||||
command =
|
command =
|
||||||
input_dialog (_("Filtered view"),
|
input_dialog (_("Filtered view"),
|
||||||
|
@ -9,7 +9,7 @@
|
|||||||
|
|
||||||
Written by:
|
Written by:
|
||||||
Slava Zanko <slavazanko@gmail.com>, 2013
|
Slava Zanko <slavazanko@gmail.com>, 2013
|
||||||
Andrew Borodin <aborodin@vmail.ru>, 2020
|
Andrew Borodin <aborodin@vmail.ru>, 2011-2022
|
||||||
|
|
||||||
This file is part of the Midnight Commander.
|
This file is part of the Midnight Commander.
|
||||||
|
|
||||||
@ -81,7 +81,7 @@ static input_colors_t command_colors;
|
|||||||
static cb_ret_t
|
static cb_ret_t
|
||||||
enter (WInput * lc_cmdline)
|
enter (WInput * lc_cmdline)
|
||||||
{
|
{
|
||||||
char *cmd = lc_cmdline->buffer;
|
const char *cmd = lc_cmdline->buffer->str;
|
||||||
|
|
||||||
if (!command_prompt)
|
if (!command_prompt)
|
||||||
return MSG_HANDLED;
|
return MSG_HANDLED;
|
||||||
|
@ -1462,10 +1462,10 @@ handle_cmdline_enter (void)
|
|||||||
{
|
{
|
||||||
size_t i;
|
size_t i;
|
||||||
|
|
||||||
for (i = 0; cmdline->buffer[i] != '\0' && whitespace (cmdline->buffer[i]); i++)
|
for (i = 0; i < cmdline->buffer->len && whitespace (cmdline->buffer->str[i]); i++)
|
||||||
;
|
;
|
||||||
|
|
||||||
if (cmdline->buffer[i] != '\0')
|
if (i != cmdline->buffer->len)
|
||||||
{
|
{
|
||||||
send_message (cmdline, NULL, MSG_KEY, '\n', NULL);
|
send_message (cmdline, NULL, MSG_KEY, '\n', NULL);
|
||||||
return TRUE;
|
return TRUE;
|
||||||
|
@ -501,7 +501,7 @@ find_parm_callback (Widget * w, Widget * sender, widget_msg_t msg, int parm, voi
|
|||||||
|
|
||||||
/* check filename regexp */
|
/* check filename regexp */
|
||||||
if (!file_pattern_cbox->state && !input_is_empty (in_name)
|
if (!file_pattern_cbox->state && !input_is_empty (in_name)
|
||||||
&& !find_check_regexp (in_name->buffer))
|
&& !find_check_regexp (in_name->buffer->str))
|
||||||
{
|
{
|
||||||
/* Don't stop the dialog */
|
/* Don't stop the dialog */
|
||||||
widget_set_state (w, WST_ACTIVE, TRUE);
|
widget_set_state (w, WST_ACTIVE, TRUE);
|
||||||
@ -511,7 +511,8 @@ find_parm_callback (Widget * w, Widget * sender, widget_msg_t msg, int parm, voi
|
|||||||
}
|
}
|
||||||
|
|
||||||
/* check content regexp */
|
/* check content regexp */
|
||||||
if (content_regexp_cbox->state && !content_is_empty && !find_check_regexp (in_with->buffer))
|
if (content_regexp_cbox->state && !content_is_empty
|
||||||
|
&& !find_check_regexp (in_with->buffer->str))
|
||||||
{
|
{
|
||||||
/* Don't stop the dialog */
|
/* Don't stop the dialog */
|
||||||
widget_set_state (w, WST_ACTIVE, TRUE);
|
widget_set_state (w, WST_ACTIVE, TRUE);
|
||||||
@ -784,10 +785,10 @@ find_parameters (WPanel * panel, char **start_dir, ssize_t * start_dir_len,
|
|||||||
{
|
{
|
||||||
const char *temp_dir;
|
const char *temp_dir;
|
||||||
|
|
||||||
if (input_is_empty (in_start) || DIR_IS_DOT (in_start->buffer))
|
if (input_is_empty (in_start) || DIR_IS_DOT (in_start->buffer->str))
|
||||||
temp_dir = vfs_path_as_str (panel->cwd_vpath);
|
temp_dir = vfs_path_as_str (panel->cwd_vpath);
|
||||||
else
|
else
|
||||||
temp_dir = in_start->buffer;
|
temp_dir = in_start->buffer->str;
|
||||||
|
|
||||||
if (in_start_dir != INPUT_LAST_TEXT)
|
if (in_start_dir != INPUT_LAST_TEXT)
|
||||||
g_free (in_start_dir);
|
g_free (in_start_dir);
|
||||||
@ -826,7 +827,7 @@ find_parameters (WPanel * panel, char **start_dir, ssize_t * start_dir_len,
|
|||||||
*pattern = input_get_text (in_name);
|
*pattern = input_get_text (in_name);
|
||||||
if (*pattern == NULL)
|
if (*pattern == NULL)
|
||||||
*pattern = g_strdup (options.file_pattern ? "*" : ".*");
|
*pattern = g_strdup (options.file_pattern ? "*" : ".*");
|
||||||
*start_dir = !input_is_empty (in_start) ? in_start->buffer : (char *) ".";
|
*start_dir = !input_is_empty (in_start) ? in_start->buffer->str : (char *) ".";
|
||||||
if (in_start_dir != INPUT_LAST_TEXT)
|
if (in_start_dir != INPUT_LAST_TEXT)
|
||||||
g_free (in_start_dir);
|
g_free (in_start_dir);
|
||||||
in_start_dir = g_strdup (*start_dir);
|
in_start_dir = g_strdup (*start_dir);
|
||||||
@ -857,7 +858,7 @@ find_parameters (WPanel * panel, char **start_dir, ssize_t * start_dir_len,
|
|||||||
}
|
}
|
||||||
|
|
||||||
if (!options.ignore_dirs_enable || input_is_empty (in_ignore)
|
if (!options.ignore_dirs_enable || input_is_empty (in_ignore)
|
||||||
|| DIR_IS_DOT (in_ignore->buffer))
|
|| DIR_IS_DOT (in_ignore->buffer->str))
|
||||||
*ignore_dirs = NULL;
|
*ignore_dirs = NULL;
|
||||||
else
|
else
|
||||||
*ignore_dirs = input_get_text (in_ignore);
|
*ignore_dirs = input_get_text (in_ignore);
|
||||||
|
@ -1467,16 +1467,16 @@ invoke_subshell (const char *command, int how, vfs_path_t ** new_dir_vpath)
|
|||||||
|
|
||||||
/* Check to make sure there are no non text characters in the command buffer,
|
/* Check to make sure there are no non text characters in the command buffer,
|
||||||
* such as tab, or newline, as this could cause problems. */
|
* such as tab, or newline, as this could cause problems. */
|
||||||
for (i = 0; cmdline->buffer[i] != '\0'; i++)
|
for (i = 0; i < cmdline->buffer->len; i++)
|
||||||
if ((unsigned char) cmdline->buffer[i] < 32
|
if ((unsigned char) cmdline->buffer->str[i] < 32
|
||||||
|| (unsigned char) cmdline->buffer[i] == 127)
|
|| (unsigned char) cmdline->buffer->str[i] == 127)
|
||||||
cmdline->buffer[i] = ' ';
|
g_string_overwrite_len (cmdline->buffer, i, " ", 1);
|
||||||
|
|
||||||
/* Write the command buffer to the subshell. */
|
/* Write the command buffer to the subshell. */
|
||||||
write_all (mc_global.tty.subshell_pty, cmdline->buffer, strlen (cmdline->buffer));
|
write_all (mc_global.tty.subshell_pty, cmdline->buffer->str, cmdline->buffer->len);
|
||||||
|
|
||||||
/* Put the cursor in the correct place in the subshell. */
|
/* Put the cursor in the correct place in the subshell. */
|
||||||
pos = str_length (cmdline->buffer) - cmdline->point;
|
pos = str_length (cmdline->buffer->str) - cmdline->point;
|
||||||
for (i = 0; i < (size_t) pos; i++)
|
for (i = 0; i < (size_t) pos; i++)
|
||||||
write_all (mc_global.tty.subshell_pty, ESC_STR "[D", 3);
|
write_all (mc_global.tty.subshell_pty, ESC_STR "[D", 3);
|
||||||
}
|
}
|
||||||
|
@ -198,10 +198,8 @@ START_PARAMETRIZED_TEST (test_complete_engine_fill_completions,
|
|||||||
/* given */
|
/* given */
|
||||||
WInput *w_input;
|
WInput *w_input;
|
||||||
|
|
||||||
w_input = g_new (WInput, 1);
|
w_input = input_new (1, 1, NULL, 100, data->input_buffer, NULL, data->input_completion_flags);
|
||||||
w_input->buffer = g_strdup (data->input_buffer);
|
|
||||||
w_input->point = data->input_point;
|
w_input->point = data->input_point;
|
||||||
w_input->completion_flags = data->input_completion_flags;
|
|
||||||
|
|
||||||
/* when */
|
/* when */
|
||||||
complete_engine_fill_completions (w_input);
|
complete_engine_fill_completions (w_input);
|
||||||
|
Loading…
Reference in New Issue
Block a user