patches by Rostislav Beneš: mc-06-input
in input widget I made a lot of changes: 1. rename some members in WInput to reflect more their functions (field_len -> field_width, ...) 2. buffer for reading multibytes characters - charbuf, (taken from UTF-8 patch) 3. modified insert_char to accept mulstibytes characters, drawing changed 4. works only with valid strings, str_fix_string used to assure that input->buffer is valid changes in complete.c: - some iteration strings with ++/-- replaced with str_next_char, str_prev_char, where was needed. ++ was offset oriented, but str_next_char use directly referecne (char *), so result is not extra beatiful in every cases - other buffer for multibytes characters - complete only valid filenames
Этот коммит содержится в:
родитель
9450950fd4
Коммит
7f71be0d63
244
src/complete.c
244
src/complete.c
@ -41,6 +41,7 @@
|
|||||||
#include "complete.h"
|
#include "complete.h"
|
||||||
#include "main.h"
|
#include "main.h"
|
||||||
#include "key.h" /* XCTRL and ALT macros */
|
#include "key.h" /* XCTRL and ALT macros */
|
||||||
|
#include "strutil.h"
|
||||||
|
|
||||||
typedef char *CompletionFunction (char *, int);
|
typedef char *CompletionFunction (char *, int);
|
||||||
|
|
||||||
@ -97,6 +98,8 @@ filename_completion_function (char *text, int state)
|
|||||||
/* Now that we have some state, we can read the directory. */
|
/* Now that we have some state, we can read the directory. */
|
||||||
|
|
||||||
while (directory && (entry = mc_readdir (directory))){
|
while (directory && (entry = mc_readdir (directory))){
|
||||||
|
if (!str_is_valid_string (entry->d_name)) continue;
|
||||||
|
|
||||||
/* Special case for no filename.
|
/* Special case for no filename.
|
||||||
All entries except "." and ".." match. */
|
All entries except "." and ".." match. */
|
||||||
if (!filename_len){
|
if (!filename_len){
|
||||||
@ -273,20 +276,24 @@ static void fetch_hosts (const char *filename)
|
|||||||
{
|
{
|
||||||
FILE *file = fopen (filename, "r");
|
FILE *file = fopen (filename, "r");
|
||||||
char buffer[256], *name;
|
char buffer[256], *name;
|
||||||
register int i, start;
|
char *start;
|
||||||
|
char *bi;
|
||||||
|
|
||||||
if (!file)
|
if (!file)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
while (fgets (buffer, 255, file) != NULL){
|
while (fgets (buffer, 255, file) != NULL){
|
||||||
/* Skip to first character. */
|
/* Skip to first character. */
|
||||||
for (i = 0; buffer[i] && cr_whitespace (buffer[i]); i++);
|
for (bi = buffer;
|
||||||
|
bi[0] != '\0' && str_isspace (bi);
|
||||||
|
str_next_char (&bi));
|
||||||
|
|
||||||
/* Ignore comments... */
|
/* Ignore comments... */
|
||||||
if (buffer[i] == '#')
|
if (bi[0] == '#')
|
||||||
continue;
|
continue;
|
||||||
/* Handle $include. */
|
/* Handle $include. */
|
||||||
if (!strncmp (buffer + i, "$include ", 9)){
|
if (!strncmp (bi, "$include ", 9)){
|
||||||
char *includefile = buffer + i + 9;
|
char *includefile = bi + 9;
|
||||||
char *t;
|
char *t;
|
||||||
|
|
||||||
/* Find start of filename. */
|
/* Find start of filename. */
|
||||||
@ -295,8 +302,8 @@ static void fetch_hosts (const char *filename)
|
|||||||
t = includefile;
|
t = includefile;
|
||||||
|
|
||||||
/* Find end of filename. */
|
/* Find end of filename. */
|
||||||
while (*t && !cr_whitespace (*t))
|
while (t[0] != '\0' && !str_isspace (t))
|
||||||
t++;
|
str_next_char (&t);
|
||||||
*t = '\0';
|
*t = '\0';
|
||||||
|
|
||||||
fetch_hosts (includefile);
|
fetch_hosts (includefile);
|
||||||
@ -304,19 +311,22 @@ static void fetch_hosts (const char *filename)
|
|||||||
}
|
}
|
||||||
|
|
||||||
/* Skip IP #s. */
|
/* Skip IP #s. */
|
||||||
while (buffer[i] && !cr_whitespace (buffer[i]))
|
while (bi[0] != '\0' && !str_isspace (bi))
|
||||||
i++;
|
str_next_char (&bi);
|
||||||
|
|
||||||
/* Get the host names separated by white space. */
|
/* Get the host names separated by white space. */
|
||||||
while (buffer[i] && buffer[i] != '#'){
|
while (bi[0] != '\0' && bi[0] != '#'){
|
||||||
while (buffer[i] && cr_whitespace (buffer[i]))
|
while (bi[0] != '\0' && str_isspace (bi))
|
||||||
i++;
|
str_next_char (&bi);
|
||||||
if (buffer[i] == '#')
|
if (bi[0] == '#')
|
||||||
continue;
|
continue;
|
||||||
for (start = i; buffer[i] && !cr_whitespace (buffer[i]); i++);
|
for (start = bi;
|
||||||
if (i - start == 0)
|
bi[0] != '\0' && !str_isspace (bi);
|
||||||
continue;
|
str_next_char (&bi));
|
||||||
name = g_strndup (buffer + start, i - start);
|
|
||||||
|
if (bi - start == 0) continue;
|
||||||
|
|
||||||
|
name = g_strndup (start, bi - start);
|
||||||
{
|
{
|
||||||
char **host_p;
|
char **host_p;
|
||||||
|
|
||||||
@ -566,19 +576,30 @@ completion_matches (char *text, CompletionFunction entry_function)
|
|||||||
j = i + 1;
|
j = i + 1;
|
||||||
while (j < matches + 1)
|
while (j < matches + 1)
|
||||||
{
|
{
|
||||||
register int c1, c2, si;
|
char *si, *sj;
|
||||||
|
char *ni, *nj;
|
||||||
|
|
||||||
for (si = 0;(c1 = match_list [i][si]) && (c2 = match_list [j][si]); si++)
|
for (si = match_list[i], sj = match_list[j];
|
||||||
if (c1 != c2) break;
|
si[0] && sj[0];) {
|
||||||
|
|
||||||
|
ni = str_get_next_char (si);
|
||||||
|
nj = str_get_next_char (sj);
|
||||||
|
|
||||||
if (!c1 && !match_list [j][si]){ /* Two equal strings */
|
if (ni - si != nj - sj) break;
|
||||||
|
if (strncmp (si, sj, ni - si) != 0) break;
|
||||||
|
|
||||||
|
si = ni;
|
||||||
|
sj = nj;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (si[0] == '\0' && sj[0] == '\0'){ /* Two equal strings */
|
||||||
g_free (match_list [j]);
|
g_free (match_list [j]);
|
||||||
j++;
|
j++;
|
||||||
if (j > matches)
|
if (j > matches)
|
||||||
break;
|
break;
|
||||||
continue; /* Look for a run of equal strings */
|
continue; /* Look for a run of equal strings */
|
||||||
} else
|
} else
|
||||||
if (low > si) low = si;
|
if (low > si - match_list[i]) low = si - match_list[i];
|
||||||
if (i + 1 != j) /* So there's some gap */
|
if (i + 1 != j) /* So there's some gap */
|
||||||
match_list [i + 1] = match_list [j];
|
match_list [i + 1] = match_list [j];
|
||||||
i++; j++;
|
i++; j++;
|
||||||
@ -598,7 +619,8 @@ completion_matches (char *text, CompletionFunction entry_function)
|
|||||||
static int
|
static int
|
||||||
check_is_cd (const char *text, int start, int flags)
|
check_is_cd (const char *text, int start, int flags)
|
||||||
{
|
{
|
||||||
const char *p, *q;
|
char *p, *q;
|
||||||
|
int test = 0;
|
||||||
|
|
||||||
if (flags & INPUT_COMPLETE_CD)
|
if (flags & INPUT_COMPLETE_CD)
|
||||||
return 1;
|
return 1;
|
||||||
@ -607,14 +629,18 @@ check_is_cd (const char *text, int start, int flags)
|
|||||||
return 0;
|
return 0;
|
||||||
|
|
||||||
/* Skip initial spaces */
|
/* Skip initial spaces */
|
||||||
p = text;
|
p = (char*)text;
|
||||||
q = text + start;
|
q = (char*)text + start;
|
||||||
while (p < q && *p && isspace ((unsigned char) *p))
|
while (p < q && p[0] != '\0' && str_isspace (p))
|
||||||
p++;
|
str_next_char (&p);
|
||||||
|
|
||||||
/* Check if the command is "cd" and the cursor is after it */
|
/* Check if the command is "cd" and the cursor is after it */
|
||||||
if (p[0] == 'c' && p[1] == 'd' && isspace ((unsigned char) p[2])
|
text+= p[0] == 'c';
|
||||||
&& (p + 2 < q))
|
str_next_char (&p);
|
||||||
|
text+= p[0] == 'd';
|
||||||
|
str_next_char (&p);
|
||||||
|
text+= str_isspace (p);
|
||||||
|
if (test == 3 && (p < q))
|
||||||
return 1;
|
return 1;
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
@ -624,44 +650,44 @@ check_is_cd (const char *text, int start, int flags)
|
|||||||
static char **
|
static char **
|
||||||
try_complete (char *text, int *start, int *end, int flags)
|
try_complete (char *text, int *start, int *end, int flags)
|
||||||
{
|
{
|
||||||
int in_command_position = 0, i;
|
int in_command_position = 0;
|
||||||
char *word, c;
|
char *word;
|
||||||
char **matches = NULL;
|
char **matches = NULL;
|
||||||
const char *command_separator_chars = ";|&{(`";
|
const char *command_separator_chars = ";|&{(`";
|
||||||
char *p = NULL, *q = NULL, *r = NULL;
|
char *p = NULL, *q = NULL, *r = NULL;
|
||||||
int is_cd = check_is_cd (text, *start, flags);
|
int is_cd = check_is_cd (text, *start, flags);
|
||||||
|
char *ti;
|
||||||
|
|
||||||
ignore_filenames = 0;
|
ignore_filenames = 0;
|
||||||
c = text [*end];
|
word = g_strndup (text + *start, *end - *start);
|
||||||
text [*end] = 0;
|
|
||||||
word = g_strdup (text + *start);
|
|
||||||
text [*end] = c;
|
|
||||||
|
|
||||||
/* Determine if this could be a command word. It is if it appears at
|
/* Determine if this could be a command word. It is if it appears at
|
||||||
the start of the line (ignoring preceding whitespace), or if it
|
the start of the line (ignoring preceding whitespace), or if it
|
||||||
appears after a character that separates commands. And we have to
|
appears after a character that separates commands. And we have to
|
||||||
be in a INPUT_COMPLETE_COMMANDS flagged Input line. */
|
be in a INPUT_COMPLETE_COMMANDS flagged Input line. */
|
||||||
if (!is_cd && (flags & INPUT_COMPLETE_COMMANDS)){
|
if (!is_cd && (flags & INPUT_COMPLETE_COMMANDS)){
|
||||||
i = *start - 1;
|
ti = str_get_prev_char (&text[*start]);
|
||||||
while (i > -1 && (text[i] == ' ' || text[i] == '\t'))
|
while (ti > text && (ti[0] == ' ' || ti[0] == '\t'))
|
||||||
i--;
|
str_prev_char (&ti);
|
||||||
if (i < 0)
|
|
||||||
|
if (ti <= text&& (ti[0] == ' ' || ti[0] == '\t'))
|
||||||
in_command_position++;
|
in_command_position++;
|
||||||
else if (strchr (command_separator_chars, text[i])){
|
else if (strchr (command_separator_chars, ti[0])){
|
||||||
register int this_char, prev_char;
|
register int this_char, prev_char;
|
||||||
|
|
||||||
in_command_position++;
|
in_command_position++;
|
||||||
|
|
||||||
if (i){
|
if (ti > text){
|
||||||
/* Handle the two character tokens `>&', `<&', and `>|'.
|
/* Handle the two character tokens `>&', `<&', and `>|'.
|
||||||
We are not in a command position after one of these. */
|
We are not in a command position after one of these. */
|
||||||
this_char = text[i];
|
this_char = ti[0];
|
||||||
prev_char = text[i - 1];
|
prev_char = str_get_prev_char (ti)[0];
|
||||||
|
|
||||||
if ((this_char == '&' && (prev_char == '<' || prev_char == '>')) ||
|
if ((this_char == '&' && (prev_char == '<' || prev_char == '>')) ||
|
||||||
(this_char == '|' && prev_char == '>'))
|
(this_char == '|' && prev_char == '>'))
|
||||||
in_command_position = 0;
|
in_command_position = 0;
|
||||||
else if (i > 0 && text [i-1] == '\\') /* Quoted */
|
|
||||||
|
else if (ti > text && str_get_prev_char (ti)[0] == '\\') /* Quoted */
|
||||||
in_command_position = 0;
|
in_command_position = 0;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -675,15 +701,15 @@ try_complete (char *text, int *start, int *end, int flags)
|
|||||||
r = strrchr (word, '@');
|
r = strrchr (word, '@');
|
||||||
if (q && q [1] == '(' && INPUT_COMPLETE_COMMANDS){
|
if (q && q [1] == '(' && INPUT_COMPLETE_COMMANDS){
|
||||||
if (q > p)
|
if (q > p)
|
||||||
p = q + 1;
|
p = str_get_next_char (q);
|
||||||
q = NULL;
|
q = NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Command substitution? */
|
/* Command substitution? */
|
||||||
if (p > q && p > r){
|
if (p > q && p > r){
|
||||||
matches = completion_matches (p + 1, command_completion_function);
|
matches = completion_matches (str_get_next_char (p), command_completion_function);
|
||||||
if (matches)
|
if (matches)
|
||||||
*start += p + 1 - word;
|
*start += str_get_next_char (p) - word;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Variable name? */
|
/* Variable name? */
|
||||||
@ -721,9 +747,9 @@ try_complete (char *text, int *start, int *end, int flags)
|
|||||||
if (!matches && is_cd && *word != PATH_SEP && *word != '~'){
|
if (!matches && is_cd && *word != PATH_SEP && *word != '~'){
|
||||||
char *p, *q = text + *start;
|
char *p, *q = text + *start;
|
||||||
|
|
||||||
for (p = text; *p && p < q && (*p == ' ' || *p == '\t'); p++);
|
for (p = text; *p && p < q && (*p == ' ' || *p == '\t'); str_next_char (&p));
|
||||||
if (!strncmp (p, "cd", 2))
|
if (!strncmp (p, "cd", 2))
|
||||||
for (p += 2; *p && p < q && (*p == ' ' || *p == '\t'); p++);
|
for (p += 2; *p && p < q && (*p == ' ' || *p == '\t'); str_next_char (&p));
|
||||||
if (p == q){
|
if (p == q){
|
||||||
char * const cdpath_ref = g_strdup (getenv ("CDPATH"));
|
char * const cdpath_ref = g_strdup (getenv ("CDPATH"));
|
||||||
char *cdpath = cdpath_ref;
|
char *cdpath = cdpath_ref;
|
||||||
@ -747,7 +773,7 @@ try_complete (char *text, int *start, int *end, int flags)
|
|||||||
g_free (r);
|
g_free (r);
|
||||||
}
|
}
|
||||||
*s = c;
|
*s = c;
|
||||||
cdpath = s + 1;
|
cdpath = str_get_next_char (s);
|
||||||
}
|
}
|
||||||
g_free (cdpath_ref);
|
g_free (cdpath_ref);
|
||||||
}
|
}
|
||||||
@ -776,49 +802,57 @@ static WInput *input;
|
|||||||
static int min_end;
|
static int min_end;
|
||||||
static int start, end;
|
static int start, end;
|
||||||
|
|
||||||
static int insert_text (WInput *in, char *text, ssize_t len)
|
static int insert_text (WInput *in, char *text, ssize_t size)
|
||||||
{
|
{
|
||||||
len = min (len, (ssize_t) strlen (text)) + start - end;
|
int buff_len = str_length (in->buffer);
|
||||||
if (strlen (in->buffer) + len >= (size_t) in->current_max_len){
|
|
||||||
|
size = min (size, (ssize_t) strlen (text)) + start - end;
|
||||||
|
if (strlen (in->buffer) + size >= (size_t) in->current_max_size){
|
||||||
/* Expand the buffer */
|
/* Expand the buffer */
|
||||||
char *narea = g_realloc (in->buffer, in->current_max_len + len + in->field_len);
|
char *narea = g_realloc (in->buffer, in->current_max_size
|
||||||
|
+ size + in->field_width);
|
||||||
if (narea){
|
if (narea){
|
||||||
in->buffer = narea;
|
in->buffer = narea;
|
||||||
in->current_max_len += len + in->field_len;
|
in->current_max_size += size + in->field_width;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (strlen (in->buffer)+1 < (size_t) in->current_max_len){
|
if (strlen (in->buffer)+1 < (size_t) in->current_max_size){
|
||||||
if (len > 0){
|
if (size > 0){
|
||||||
int i = strlen (&in->buffer [end]);
|
int i = strlen (&in->buffer [end]);
|
||||||
for (; i >= 0; i--)
|
for (; i >= 0; i--)
|
||||||
in->buffer [end + len + i] = in->buffer [end + i];
|
in->buffer [end + size + i] = in->buffer [end + i];
|
||||||
} else if (len < 0){
|
} else if (size < 0){
|
||||||
char *p = in->buffer + end + len, *q = in->buffer + end;
|
char *p = in->buffer + end + size, *q = in->buffer + end;
|
||||||
while (*q)
|
while (*q)
|
||||||
*(p++) = *(q++);
|
*(p++) = *(q++);
|
||||||
*p = 0;
|
*p = 0;
|
||||||
}
|
}
|
||||||
memcpy (in->buffer + start, text, len - start + end);
|
memcpy (in->buffer + start, text, size - start + end);
|
||||||
in->point += len;
|
in->point+= str_length (in->buffer) - buff_len;
|
||||||
update_input (in, 1);
|
update_input (in, 1);
|
||||||
end += len;
|
end+= size;
|
||||||
}
|
}
|
||||||
return len != 0;
|
return size != 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
static cb_ret_t
|
static cb_ret_t
|
||||||
query_callback (Dlg_head *h, dlg_msg_t msg, int parm)
|
query_callback (Dlg_head *h, dlg_msg_t msg, int parm)
|
||||||
{
|
{
|
||||||
|
static char buff[MB_LEN_MAX] = "";
|
||||||
|
static int bl = 0;
|
||||||
|
|
||||||
switch (msg) {
|
switch (msg) {
|
||||||
case DLG_KEY:
|
case DLG_KEY:
|
||||||
switch (parm) {
|
switch (parm) {
|
||||||
case KEY_LEFT:
|
case KEY_LEFT:
|
||||||
case KEY_RIGHT:
|
case KEY_RIGHT:
|
||||||
|
bl = 0;
|
||||||
h->ret_value = 0;
|
h->ret_value = 0;
|
||||||
dlg_stop (h);
|
dlg_stop (h);
|
||||||
return MSG_HANDLED;
|
return MSG_HANDLED;
|
||||||
|
|
||||||
case KEY_BACKSPACE:
|
case KEY_BACKSPACE:
|
||||||
|
bl = 0;
|
||||||
if (end == min_end) {
|
if (end == min_end) {
|
||||||
h->ret_value = 0;
|
h->ret_value = 0;
|
||||||
dlg_stop (h);
|
dlg_stop (h);
|
||||||
@ -828,13 +862,13 @@ query_callback (Dlg_head *h, dlg_msg_t msg, int parm)
|
|||||||
|
|
||||||
e1 = e = ((WListbox *) (h->current))->list;
|
e1 = e = ((WListbox *) (h->current))->list;
|
||||||
do {
|
do {
|
||||||
if (!strncmp
|
if (!strncmp (input->buffer + start,
|
||||||
(input->buffer + start, e1->text,
|
e1->text, end - start - 1)) {
|
||||||
end - start - 1)) {
|
|
||||||
listbox_select_entry ((WListbox *) (h->current),
|
listbox_select_entry ((WListbox *) (h->current), e1);
|
||||||
e1);
|
end = str_get_prev_char (&(input->buffer[end]))
|
||||||
|
- input->buffer;
|
||||||
handle_char (input, parm);
|
handle_char (input, parm);
|
||||||
end--;
|
|
||||||
send_message (h->current, WIDGET_DRAW, 0);
|
send_message (h->current, WIDGET_DRAW, 0);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
@ -844,7 +878,8 @@ query_callback (Dlg_head *h, dlg_msg_t msg, int parm)
|
|||||||
return MSG_HANDLED;
|
return MSG_HANDLED;
|
||||||
|
|
||||||
default:
|
default:
|
||||||
if (parm > 0xff || !is_printable (parm)) {
|
if (parm < 32 || parm > 256) {
|
||||||
|
bl = 0;
|
||||||
if (is_in_input_map (input, parm) == 2) {
|
if (is_in_input_map (input, parm) == 2) {
|
||||||
if (end == min_end)
|
if (end == min_end)
|
||||||
return MSG_HANDLED;
|
return MSG_HANDLED;
|
||||||
@ -860,21 +895,43 @@ query_callback (Dlg_head *h, dlg_msg_t msg, int parm)
|
|||||||
int low = 4096;
|
int low = 4096;
|
||||||
char *last_text = NULL;
|
char *last_text = NULL;
|
||||||
|
|
||||||
|
buff[bl] = (char) parm;
|
||||||
|
bl++;
|
||||||
|
buff[bl] = '\0';
|
||||||
|
switch (str_is_valid_char (buff, bl)) {
|
||||||
|
case -1:
|
||||||
|
bl = 0;
|
||||||
|
case -2:
|
||||||
|
return MSG_HANDLED;
|
||||||
|
}
|
||||||
|
|
||||||
e1 = e = ((WListbox *) (h->current))->list;
|
e1 = e = ((WListbox *) (h->current))->list;
|
||||||
do {
|
do {
|
||||||
if (!strncmp
|
if (!strncmp (input->buffer + start,
|
||||||
(input->buffer + start, e1->text, end - start)) {
|
e1->text, end - start)) {
|
||||||
if (e1->text[end - start] == parm) {
|
|
||||||
|
if (strncmp (&e1->text[end - start], buff, bl) == 0) {
|
||||||
if (need_redraw) {
|
if (need_redraw) {
|
||||||
register int c1, c2, si;
|
char *si, *sl;
|
||||||
|
char *ni, *nl;
|
||||||
|
si = &(e1->text[end - start]);
|
||||||
|
sl = &(last_text[end - start]);
|
||||||
|
|
||||||
|
for (; si[0] != '\0' && sl[0] != '\0';) {
|
||||||
|
|
||||||
|
ni = str_get_next_char (si);
|
||||||
|
nl = str_get_next_char (sl);
|
||||||
|
|
||||||
|
if (ni - si != nl - sl) break;
|
||||||
|
if (strncmp (si, sl, ni - si) != 0) break;
|
||||||
|
|
||||||
|
si = ni;
|
||||||
|
sl = nl;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (low > si - &e1->text[start])
|
||||||
|
low = si - &e1->text[start];
|
||||||
|
|
||||||
for (si = end - start + 1;
|
|
||||||
(c1 = last_text[si])
|
|
||||||
&& (c2 = e1->text[si]); si++)
|
|
||||||
if (c1 != c2)
|
|
||||||
break;
|
|
||||||
if (low > si)
|
|
||||||
low = si;
|
|
||||||
last_text = e1->text;
|
last_text = e1->text;
|
||||||
need_redraw = 2;
|
need_redraw = 2;
|
||||||
} else {
|
} else {
|
||||||
@ -895,6 +952,7 @@ query_callback (Dlg_head *h, dlg_msg_t msg, int parm)
|
|||||||
h->ret_value = B_ENTER;
|
h->ret_value = B_ENTER;
|
||||||
dlg_stop (h);
|
dlg_stop (h);
|
||||||
}
|
}
|
||||||
|
bl = 0;
|
||||||
}
|
}
|
||||||
return MSG_HANDLED;
|
return MSG_HANDLED;
|
||||||
}
|
}
|
||||||
@ -911,15 +969,19 @@ query_callback (Dlg_head *h, dlg_msg_t msg, int parm)
|
|||||||
static int
|
static int
|
||||||
complete_engine (WInput *in, int what_to_do)
|
complete_engine (WInput *in, int what_to_do)
|
||||||
{
|
{
|
||||||
if (in->completions && in->point != end)
|
int s;
|
||||||
|
|
||||||
|
if (in->completions && (str_offset_to_pos (in->buffer, in->point)) != end)
|
||||||
free_completions (in);
|
free_completions (in);
|
||||||
if (!in->completions){
|
if (!in->completions){
|
||||||
end = in->point;
|
end = str_offset_to_pos (in->buffer, in->point);
|
||||||
for (start = end ? end - 1 : 0; start > -1; start--)
|
for (s = in->point ? in->point - 1 : 0; s >= 0; s--) {
|
||||||
if (strchr (" \t;|<>", in->buffer [start]))
|
start = str_offset_to_pos (in->buffer, s);
|
||||||
|
if (strchr (" \t;|<>", in->buffer [start])) {
|
||||||
|
if (start < end) start = str_offset_to_pos (in->buffer, s + 1);
|
||||||
break;
|
break;
|
||||||
if (start < end)
|
}
|
||||||
start++;
|
}
|
||||||
in->completions = try_complete (in->buffer, &start, &end, in->completion_flags);
|
in->completions = try_complete (in->buffer, &start, &end, in->completion_flags);
|
||||||
}
|
}
|
||||||
if (in->completions){
|
if (in->completions){
|
||||||
@ -941,7 +1003,7 @@ complete_engine (WInput *in, int what_to_do)
|
|||||||
WListbox *query_list;
|
WListbox *query_list;
|
||||||
|
|
||||||
for (p=in->completions + 1; *p; count++, p++)
|
for (p=in->completions + 1; *p; count++, p++)
|
||||||
if ((i = strlen (*p)) > maxlen)
|
if ((i = str_term_width1 (*p)) > maxlen)
|
||||||
maxlen = i;
|
maxlen = i;
|
||||||
start_x = in->widget.x;
|
start_x = in->widget.x;
|
||||||
start_y = in->widget.y;
|
start_y = in->widget.y;
|
||||||
@ -957,7 +1019,7 @@ complete_engine (WInput *in, int what_to_do)
|
|||||||
h = LINES - start_y - 1;
|
h = LINES - start_y - 1;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
x = start - in->first_shown - 2 + start_x;
|
x = start - in->term_first_shown - 2 + start_x;
|
||||||
w = maxlen + 4;
|
w = maxlen + 4;
|
||||||
if (x + w > COLS)
|
if (x + w > COLS)
|
||||||
x = COLS - w;
|
x = COLS - w;
|
||||||
@ -999,6 +1061,8 @@ void complete (WInput *in)
|
|||||||
{
|
{
|
||||||
int engine_flags;
|
int engine_flags;
|
||||||
|
|
||||||
|
if (!str_is_valid_string (in->buffer)) return;
|
||||||
|
|
||||||
if (in->completions)
|
if (in->completions)
|
||||||
engine_flags = DO_QUERY;
|
engine_flags = DO_QUERY;
|
||||||
else
|
else
|
||||||
|
278
src/widget.c
278
src/widget.c
@ -789,27 +789,21 @@ gauge_new (int y, int x, int shown, int max, int current)
|
|||||||
#endif
|
#endif
|
||||||
|
|
||||||
#define should_show_history_button(in) \
|
#define should_show_history_button(in) \
|
||||||
(in->history && in->field_len > HISTORY_BUTTON_WIDTH * 2 + 1 && in->widget.parent)
|
(in->history && in->field_width > HISTORY_BUTTON_WIDTH * 2 + 1 && in->widget.parent)
|
||||||
|
|
||||||
static void draw_history_button (WInput * in)
|
static void draw_history_button (WInput * in)
|
||||||
{
|
{
|
||||||
char c;
|
char c;
|
||||||
c = in->history->next ? (in->history->prev ? '|' : 'v') : '^';
|
c = in->history->next ? (in->history->prev ? '|' : 'v') : '^';
|
||||||
widget_move (&in->widget, 0, in->field_len - HISTORY_BUTTON_WIDTH);
|
widget_move (&in->widget, 0, in->field_width - HISTORY_BUTTON_WIDTH);
|
||||||
#ifdef LARGE_HISTORY_BUTTON
|
#ifdef LARGE_HISTORY_BUTTON
|
||||||
{
|
{
|
||||||
Dlg_head *h;
|
Dlg_head *h;
|
||||||
h = in->widget.parent;
|
h = in->widget.parent;
|
||||||
#if 0
|
|
||||||
attrset (NORMALC); /* button has the same color as other buttons */
|
|
||||||
addstr ("[ ]");
|
|
||||||
attrset (HOT_NORMALC);
|
|
||||||
#else
|
|
||||||
attrset (NORMAL_COLOR);
|
attrset (NORMAL_COLOR);
|
||||||
addstr ("[ ]");
|
addstr ("[ ]");
|
||||||
/* Too distracting: attrset (MARKED_COLOR); */
|
/* Too distracting: attrset (MARKED_COLOR); */
|
||||||
#endif
|
widget_move (&in->widget, 0, in->field_width - HISTORY_BUTTON_WIDTH + 1);
|
||||||
widget_move (&in->widget, 0, in->field_len - HISTORY_BUTTON_WIDTH + 1);
|
|
||||||
addch (c);
|
addch (c);
|
||||||
}
|
}
|
||||||
#else
|
#else
|
||||||
@ -829,9 +823,10 @@ void
|
|||||||
update_input (WInput *in, int clear_first)
|
update_input (WInput *in, int clear_first)
|
||||||
{
|
{
|
||||||
int has_history = 0;
|
int has_history = 0;
|
||||||
int i, j;
|
int i;
|
||||||
unsigned char c;
|
int buf_len = str_length (in->buffer);
|
||||||
int buf_len = strlen (in->buffer);
|
const char *cp;
|
||||||
|
int pw;
|
||||||
|
|
||||||
if (should_show_history_button (in))
|
if (should_show_history_button (in))
|
||||||
has_history = HISTORY_BUTTON_WIDTH;
|
has_history = HISTORY_BUTTON_WIDTH;
|
||||||
@ -839,12 +834,15 @@ update_input (WInput *in, int clear_first)
|
|||||||
if (in->disable_update)
|
if (in->disable_update)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
|
pw = str_term_width2 (in->buffer, in->point);
|
||||||
|
|
||||||
/* Make the point visible */
|
/* Make the point visible */
|
||||||
if ((in->point < in->first_shown) ||
|
if ((pw < in->term_first_shown) ||
|
||||||
(in->point >= in->first_shown+in->field_len - has_history)){
|
(pw >= in->term_first_shown + in->field_width - has_history)) {
|
||||||
in->first_shown = in->point - (in->field_len / 3);
|
|
||||||
if (in->first_shown < 0)
|
in->term_first_shown = pw - (in->field_width / 3);
|
||||||
in->first_shown = 0;
|
if (in->term_first_shown < 0)
|
||||||
|
in->term_first_shown = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Adjust the mark */
|
/* Adjust the mark */
|
||||||
@ -857,28 +855,29 @@ update_input (WInput *in, int clear_first)
|
|||||||
attrset (in->color);
|
attrset (in->color);
|
||||||
|
|
||||||
widget_move (&in->widget, 0, 0);
|
widget_move (&in->widget, 0, 0);
|
||||||
for (i = 0; i < in->field_len - has_history; i++)
|
|
||||||
addch (' ');
|
|
||||||
widget_move (&in->widget, 0, 0);
|
|
||||||
|
|
||||||
for (i = 0, j = in->first_shown; i < in->field_len - has_history && in->buffer [j]; i++){
|
if (!in->is_password) {
|
||||||
c = in->buffer [j++];
|
addstr (str_term_substring (in->buffer, in->term_first_shown,
|
||||||
c = is_printable (c) ? c : '.';
|
in->field_width - has_history));
|
||||||
if (in->is_password)
|
} else {
|
||||||
c = '*';
|
cp = in->buffer;
|
||||||
addch (c);
|
for (i = -in->term_first_shown; i < in->field_width - has_history; i++){
|
||||||
|
if (i >= 0) {
|
||||||
|
addch ((cp[0] != '\0') ? '*' : ' ');
|
||||||
|
}
|
||||||
|
if (cp[0] != '\0') str_cnext_char (&cp);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
widget_move (&in->widget, 0, in->point - in->first_shown);
|
|
||||||
|
|
||||||
if (clear_first)
|
if (clear_first)
|
||||||
in->first = 0;
|
in->first = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
winput_set_origin (WInput *in, int x, int field_len)
|
winput_set_origin (WInput *in, int x, int field_width)
|
||||||
{
|
{
|
||||||
in->widget.x = x;
|
in->widget.x = x;
|
||||||
in->field_len = in->widget.cols = field_len;
|
in->field_width = in->widget.cols = field_width;
|
||||||
update_input (in, 0);
|
update_input (in, 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -997,11 +996,7 @@ history_put (const char *input_name, GList *h)
|
|||||||
static const char *
|
static const char *
|
||||||
i18n_htitle (void)
|
i18n_htitle (void)
|
||||||
{
|
{
|
||||||
static const char *history_title = NULL;
|
return _(" History ");
|
||||||
|
|
||||||
if (history_title == NULL)
|
|
||||||
history_title = _(" History ");
|
|
||||||
return history_title;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
static WLEntry *listbox_select_pos (WListbox *l, WLEntry *base, int
|
static WLEntry *listbox_select_pos (WListbox *l, WLEntry *base, int
|
||||||
@ -1021,7 +1016,7 @@ char *
|
|||||||
show_hist (GList *history, int widget_x, int widget_y)
|
show_hist (GList *history, int widget_x, int widget_y)
|
||||||
{
|
{
|
||||||
GList *hi, *z;
|
GList *hi, *z;
|
||||||
size_t maxlen = strlen (i18n_htitle ()), i, count = 0;
|
size_t maxlen = str_term_width1 (i18n_htitle ()), i, count = 0;
|
||||||
int x, y, w, h;
|
int x, y, w, h;
|
||||||
char *q, *r = 0;
|
char *q, *r = 0;
|
||||||
Dlg_head *query_dlg;
|
Dlg_head *query_dlg;
|
||||||
@ -1034,7 +1029,7 @@ show_hist (GList *history, int widget_x, int widget_y)
|
|||||||
z = g_list_first (history);
|
z = g_list_first (history);
|
||||||
hi = z;
|
hi = z;
|
||||||
while (hi) {
|
while (hi) {
|
||||||
if ((i = strlen ((char *) hi->data)) > maxlen)
|
if ((i = str_term_width1 ((char *) hi->data)) > maxlen)
|
||||||
maxlen = i;
|
maxlen = i;
|
||||||
count++;
|
count++;
|
||||||
hi = g_list_next (hi);
|
hi = g_list_next (hi);
|
||||||
@ -1202,37 +1197,75 @@ new_input (WInput *in)
|
|||||||
if (in->buffer)
|
if (in->buffer)
|
||||||
push_history (in, in->buffer);
|
push_history (in, in->buffer);
|
||||||
in->need_push = 1;
|
in->need_push = 1;
|
||||||
in->buffer [0] = 0;
|
in->buffer[0] = '\0';
|
||||||
in->point = 0;
|
in->point = 0;
|
||||||
|
in->charpoint = 0;
|
||||||
in->mark = 0;
|
in->mark = 0;
|
||||||
free_completions (in);
|
free_completions (in);
|
||||||
update_input (in, 0);
|
update_input (in, 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
move_buffer_backward (WInput *in, int start, int end)
|
||||||
|
{
|
||||||
|
int i, pos, len;
|
||||||
|
int str_len = str_length (in->buffer);
|
||||||
|
if (start >= str_len || end > str_len + 1) return;
|
||||||
|
|
||||||
|
pos = str_offset_to_pos (in->buffer, start);
|
||||||
|
len = str_offset_to_pos (in->buffer, end) - pos;
|
||||||
|
|
||||||
|
for (i = pos; in->buffer[i + len - 1]; i++)
|
||||||
|
in->buffer[i] = in->buffer[i + len];
|
||||||
|
}
|
||||||
|
|
||||||
static cb_ret_t
|
static cb_ret_t
|
||||||
insert_char (WInput *in, int c_code)
|
insert_char (WInput *in, int c_code)
|
||||||
{
|
{
|
||||||
size_t i;
|
size_t i;
|
||||||
|
int res;
|
||||||
|
|
||||||
if (c_code == -1)
|
if (c_code == -1)
|
||||||
return MSG_NOT_HANDLED;
|
return MSG_NOT_HANDLED;
|
||||||
|
|
||||||
|
if (in->charpoint >= MB_LEN_MAX) return 1;
|
||||||
|
|
||||||
|
in->charbuf[in->charpoint] = c_code;
|
||||||
|
in->charpoint++;
|
||||||
|
|
||||||
|
res = str_is_valid_char (in->charbuf, in->charpoint);
|
||||||
|
if (res < 0) {
|
||||||
|
if (res != -2) in->charpoint = 0; /* broken multibyte char, skip */
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
in->need_push = 1;
|
in->need_push = 1;
|
||||||
if (strlen (in->buffer)+1 == (size_t) in->current_max_len){
|
if (strlen (in->buffer) + 1 + in->charpoint >= in->current_max_size){
|
||||||
/* Expand the buffer */
|
/* Expand the buffer */
|
||||||
char *narea = g_realloc (in->buffer, in->current_max_len + in->field_len);
|
size_t new_length = in->current_max_size +
|
||||||
|
in->field_width + in->charpoint;
|
||||||
|
char *narea = g_try_renew (char, in->buffer, new_length);
|
||||||
if (narea){
|
if (narea){
|
||||||
in->buffer = narea;
|
in->buffer = narea;
|
||||||
in->current_max_len += in->field_len;
|
in->current_max_size = new_length;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (strlen (in->buffer)+1 < (size_t) in->current_max_len){
|
|
||||||
size_t l = strlen (&in->buffer [in->point]);
|
if (strlen (in->buffer) + in->charpoint < in->current_max_size) {
|
||||||
for (i = l+1; i > 0; i--)
|
/* bytes from begin */
|
||||||
in->buffer [in->point+i] = in->buffer [in->point+i-1];
|
size_t ins_point = str_offset_to_pos (in->buffer, in->point);
|
||||||
in->buffer [in->point] = c_code;
|
/* 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->point++;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
in->charpoint = 0;
|
||||||
return MSG_HANDLED;
|
return MSG_HANDLED;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1240,54 +1273,70 @@ static void
|
|||||||
beginning_of_line (WInput *in)
|
beginning_of_line (WInput *in)
|
||||||
{
|
{
|
||||||
in->point = 0;
|
in->point = 0;
|
||||||
|
in->charpoint = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
end_of_line (WInput *in)
|
end_of_line (WInput *in)
|
||||||
{
|
{
|
||||||
in->point = strlen (in->buffer);
|
in->point = str_length (in->buffer);
|
||||||
|
in->charpoint = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
backward_char (WInput *in)
|
backward_char (WInput *in)
|
||||||
{
|
{
|
||||||
if (in->point)
|
const char *act = in->buffer + str_offset_to_pos (in->buffer, in->point);
|
||||||
in->point--;
|
|
||||||
|
if (in->point > 0) {
|
||||||
|
in->point-= str_cprev_noncomb_char (&act, in->buffer);
|
||||||
|
}
|
||||||
|
in->charpoint = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
forward_char (WInput *in)
|
forward_char (WInput *in)
|
||||||
{
|
{
|
||||||
if (in->buffer [in->point])
|
const char *act = in->buffer + str_offset_to_pos (in->buffer, in->point);
|
||||||
in->point++;
|
if (act[0] != '\0') {
|
||||||
|
in->point+= str_cnext_noncomb_char (&act);
|
||||||
|
}
|
||||||
|
in->charpoint = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
forward_word (WInput * in)
|
forward_word (WInput * in)
|
||||||
{
|
{
|
||||||
char *p = in->buffer + in->point;
|
const char *p = in->buffer + str_offset_to_pos (in->buffer, in->point);
|
||||||
|
|
||||||
while (*p
|
while (p[0] != '\0' && (str_isspace (p) || str_ispunct (p))) {
|
||||||
&& (isspace ((unsigned char) *p)
|
str_cnext_char (&p);
|
||||||
|| ispunct ((unsigned char) *p)))
|
in->point++;
|
||||||
p++;
|
}
|
||||||
while (*p && isalnum ((unsigned char) *p))
|
while (p[0] != '\0' && !str_isspace (p) && !str_ispunct (p)) {
|
||||||
p++;
|
str_cnext_char (&p);
|
||||||
in->point = p - in->buffer;
|
in->point++;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
backward_word (WInput *in)
|
backward_word (WInput *in)
|
||||||
{
|
{
|
||||||
char *p = in->buffer + in->point;
|
const char *p = in->buffer + str_offset_to_pos (in->buffer, in->point);
|
||||||
|
|
||||||
while (p - 1 > in->buffer - 1 && (isspace ((unsigned char) *(p - 1))
|
while ((p != in->buffer) && (p[0] == '\0')) {
|
||||||
|| ispunct ((unsigned char)
|
|
||||||
*(p - 1))))
|
|
||||||
p--;
|
p--;
|
||||||
while (p - 1 > in->buffer - 1 && isalnum ((unsigned char) *(p - 1)))
|
in->point--;
|
||||||
p--;
|
}
|
||||||
in->point = p - in->buffer;
|
|
||||||
|
while ((p != in->buffer) && (str_isspace (p) || str_ispunct (p))) {
|
||||||
|
str_cprev_char (&p);
|
||||||
|
in->point--;
|
||||||
|
}
|
||||||
|
while ((p != in->buffer) && !str_isspace (p) && !str_ispunct (p)) {
|
||||||
|
str_cprev_char (&p);
|
||||||
|
in->point--;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
@ -1316,23 +1365,29 @@ key_ctrl_right (WInput *in)
|
|||||||
static void
|
static void
|
||||||
backward_delete (WInput *in)
|
backward_delete (WInput *in)
|
||||||
{
|
{
|
||||||
int i;
|
const char *act = in->buffer + str_offset_to_pos (in->buffer, in->point);
|
||||||
|
int start;
|
||||||
|
|
||||||
if (!in->point)
|
if (in->point == 0)
|
||||||
return;
|
return;
|
||||||
for (i = in->point; in->buffer [i-1]; i++)
|
|
||||||
in->buffer [i-1] = in->buffer [i];
|
start = in->point - str_cprev_noncomb_char (&act, in->buffer);
|
||||||
|
move_buffer_backward(in, start, in->point);
|
||||||
|
in->charpoint = 0;
|
||||||
in->need_push = 1;
|
in->need_push = 1;
|
||||||
in->point--;
|
in->point = start;
|
||||||
}
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
delete_char (WInput *in)
|
delete_char (WInput *in)
|
||||||
{
|
{
|
||||||
int i;
|
const char *act = in->buffer + str_offset_to_pos (in->buffer, in->point);
|
||||||
|
int end = in->point;
|
||||||
|
|
||||||
|
end+= str_cnext_noncomb_char (&act);
|
||||||
|
|
||||||
for (i = in->point; in->buffer [i]; i++)
|
move_buffer_backward(in, in->point, end);
|
||||||
in->buffer [i] = in->buffer [i+1];
|
in->charpoint = 0;
|
||||||
in->need_push = 1;
|
in->need_push = 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1347,7 +1402,10 @@ copy_region (WInput *in, int x_first, int x_last)
|
|||||||
|
|
||||||
g_free (kill_buffer);
|
g_free (kill_buffer);
|
||||||
|
|
||||||
kill_buffer = g_strndup(in->buffer+first,last-first);
|
first = str_offset_to_pos (in->buffer, first);
|
||||||
|
last = str_offset_to_pos (in->buffer, last);
|
||||||
|
|
||||||
|
kill_buffer = g_strndup(in->buffer + first, last - first);
|
||||||
}
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
@ -1355,11 +1413,15 @@ delete_region (WInput *in, int x_first, int x_last)
|
|||||||
{
|
{
|
||||||
int first = min (x_first, x_last);
|
int first = min (x_first, x_last);
|
||||||
int last = max (x_first, x_last);
|
int last = max (x_first, x_last);
|
||||||
size_t len = strlen (&in->buffer [last]) + 1;
|
size_t len;
|
||||||
|
|
||||||
in->point = first;
|
in->point = first;
|
||||||
in->mark = first;
|
in->mark = first;
|
||||||
memmove (&in->buffer [first], &in->buffer [last], len);
|
last = str_offset_to_pos (in->buffer, last);
|
||||||
|
first = str_offset_to_pos (in->buffer, first);
|
||||||
|
len = strlen (&in->buffer[last]) + 1;
|
||||||
|
memmove (&in->buffer[first], &in->buffer[last], len);
|
||||||
|
in->charpoint = 0;
|
||||||
in->need_push = 1;
|
in->need_push = 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1376,6 +1438,8 @@ kill_word (WInput *in)
|
|||||||
copy_region (in, old_point, new_point);
|
copy_region (in, old_point, new_point);
|
||||||
delete_region (in, old_point, new_point);
|
delete_region (in, old_point, new_point);
|
||||||
in->need_push = 1;
|
in->need_push = 1;
|
||||||
|
in->charpoint = 0;
|
||||||
|
in->charpoint = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
@ -1419,16 +1483,20 @@ yank (WInput *in)
|
|||||||
|
|
||||||
if (!kill_buffer)
|
if (!kill_buffer)
|
||||||
return;
|
return;
|
||||||
|
in->charpoint = 0;
|
||||||
for (p = kill_buffer; *p; p++)
|
for (p = kill_buffer; *p; p++)
|
||||||
insert_char (in, *p);
|
insert_char (in, *p);
|
||||||
|
in->charpoint = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
kill_line (WInput *in)
|
kill_line (WInput *in)
|
||||||
{
|
{
|
||||||
|
int chp = str_offset_to_pos (in->buffer, in->point);
|
||||||
g_free (kill_buffer);
|
g_free (kill_buffer);
|
||||||
kill_buffer = g_strdup (&in->buffer [in->point]);
|
kill_buffer = g_strdup (&in->buffer[chp]);
|
||||||
in->buffer [in->point] = 0;
|
in->buffer[chp] = '\0';
|
||||||
|
in->charpoint = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
@ -1437,10 +1505,11 @@ assign_text (WInput *in, const char *text)
|
|||||||
free_completions (in);
|
free_completions (in);
|
||||||
g_free (in->buffer);
|
g_free (in->buffer);
|
||||||
in->buffer = g_strdup (text); /* was in->buffer->text */
|
in->buffer = g_strdup (text); /* was in->buffer->text */
|
||||||
in->current_max_len = strlen (in->buffer) + 1;
|
in->current_max_size = strlen (in->buffer) + 1;
|
||||||
in->point = strlen (in->buffer);
|
in->point = str_length (in->buffer);
|
||||||
in->mark = 0;
|
in->mark = 0;
|
||||||
in->need_push = 1;
|
in->need_push = 1;
|
||||||
|
in->charpoint = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
@ -1564,9 +1633,10 @@ is_in_input_map (WInput *in, int c_code)
|
|||||||
static void
|
static void
|
||||||
port_region_marked_for_delete (WInput *in)
|
port_region_marked_for_delete (WInput *in)
|
||||||
{
|
{
|
||||||
*in->buffer = 0;
|
in->buffer[0] = '\0';
|
||||||
in->point = 0;
|
in->point = 0;
|
||||||
in->first = 0;
|
in->first = 0;
|
||||||
|
in->charpoint = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
cb_ret_t
|
cb_ret_t
|
||||||
@ -1595,7 +1665,7 @@ handle_char (WInput *in, int c_code)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (!input_map [i].fn){
|
if (!input_map [i].fn){
|
||||||
if (c_code > 255 || !is_printable (c_code))
|
if (c_code > 255)
|
||||||
return MSG_NOT_HANDLED;
|
return MSG_NOT_HANDLED;
|
||||||
if (in->first){
|
if (in->first){
|
||||||
port_region_marked_for_delete (in);
|
port_region_marked_for_delete (in);
|
||||||
@ -1623,11 +1693,14 @@ stuff (WInput *in, const char *text, int insert_extra_space)
|
|||||||
void
|
void
|
||||||
input_set_point (WInput *in, int pos)
|
input_set_point (WInput *in, int pos)
|
||||||
{
|
{
|
||||||
if (pos > in->current_max_len)
|
int max_pos = str_length (in->buffer);
|
||||||
pos = in->current_max_len;
|
|
||||||
|
if (pos > max_pos)
|
||||||
|
pos = max_pos;
|
||||||
if (pos != in->point)
|
if (pos != in->point)
|
||||||
free_completions (in);
|
free_completions (in);
|
||||||
in->point = pos;
|
in->point = pos;
|
||||||
|
in->charpoint = 0;
|
||||||
update_input (in, 1);
|
update_input (in, 1);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1668,7 +1741,8 @@ input_callback (Widget *w, widget_msg_t msg, int parm)
|
|||||||
return MSG_HANDLED;
|
return MSG_HANDLED;
|
||||||
|
|
||||||
case WIDGET_CURSOR:
|
case WIDGET_CURSOR:
|
||||||
widget_move (&in->widget, 0, in->point - in->first_shown);
|
widget_move (&in->widget, 0, str_term_width2 (in->buffer, in->point)
|
||||||
|
- in->term_first_shown);
|
||||||
return MSG_HANDLED;
|
return MSG_HANDLED;
|
||||||
|
|
||||||
case WIDGET_DESTROY:
|
case WIDGET_DESTROY:
|
||||||
@ -1688,15 +1762,17 @@ input_event (Gpm_Event * event, void *data)
|
|||||||
if (event->type & (GPM_DOWN | GPM_DRAG)) {
|
if (event->type & (GPM_DOWN | GPM_DRAG)) {
|
||||||
dlg_select_widget (in);
|
dlg_select_widget (in);
|
||||||
|
|
||||||
if (event->x >= in->field_len - HISTORY_BUTTON_WIDTH + 1
|
if (event->x >= in->field_width - HISTORY_BUTTON_WIDTH + 1
|
||||||
&& should_show_history_button (in)) {
|
&& should_show_history_button (in)) {
|
||||||
do_show_hist (in);
|
do_show_hist (in);
|
||||||
} else {
|
} else {
|
||||||
in->point = strlen (in->buffer);
|
in->point = str_length (in->buffer);
|
||||||
if (event->x - in->first_shown - 1 < in->point)
|
if (event->x + in->term_first_shown - 1 <
|
||||||
in->point = event->x - in->first_shown - 1;
|
str_term_width1 (in->buffer))
|
||||||
if (in->point < 0)
|
|
||||||
in->point = 0;
|
in->point = str_column_to_pos (in->buffer, event->x
|
||||||
|
+ in->term_first_shown - 1);
|
||||||
|
|
||||||
}
|
}
|
||||||
update_input (in, 1);
|
update_input (in, 1);
|
||||||
}
|
}
|
||||||
@ -1704,13 +1780,13 @@ input_event (Gpm_Event * event, void *data)
|
|||||||
}
|
}
|
||||||
|
|
||||||
WInput *
|
WInput *
|
||||||
input_new (int y, int x, int color, int len, const char *def_text,
|
input_new (int y, int x, int color, int width, const char *def_text,
|
||||||
const char *histname)
|
const char *histname)
|
||||||
{
|
{
|
||||||
WInput *in = g_new (WInput, 1);
|
WInput *in = g_new (WInput, 1);
|
||||||
int initial_buffer_len;
|
int initial_buffer_len;
|
||||||
|
|
||||||
init_widget (&in->widget, y, x, 1, len, input_callback, input_event);
|
init_widget (&in->widget, y, x, 1, width, input_callback, input_event);
|
||||||
|
|
||||||
/* history setup */
|
/* history setup */
|
||||||
in->history = NULL;
|
in->history = NULL;
|
||||||
@ -1722,7 +1798,7 @@ input_new (int y, int x, int color, int len, const char *def_text,
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!def_text)
|
if (def_text == NULL)
|
||||||
def_text = "";
|
def_text = "";
|
||||||
|
|
||||||
if (def_text == INPUT_LAST_TEXT) {
|
if (def_text == INPUT_LAST_TEXT) {
|
||||||
@ -1731,29 +1807,29 @@ input_new (int y, int x, int color, int len, const char *def_text,
|
|||||||
if (in->history->data)
|
if (in->history->data)
|
||||||
def_text = (char *) in->history->data;
|
def_text = (char *) in->history->data;
|
||||||
}
|
}
|
||||||
initial_buffer_len = 1 + max ((size_t) len, strlen (def_text));
|
initial_buffer_len = 1 + max ((size_t) width, strlen (def_text));
|
||||||
in->widget.options |= W_IS_INPUT;
|
in->widget.options |= W_IS_INPUT;
|
||||||
in->completions = NULL;
|
in->completions = NULL;
|
||||||
in->completion_flags =
|
in->completion_flags =
|
||||||
INPUT_COMPLETE_FILENAMES | INPUT_COMPLETE_HOSTNAMES |
|
INPUT_COMPLETE_FILENAMES | INPUT_COMPLETE_HOSTNAMES |
|
||||||
INPUT_COMPLETE_VARIABLES | INPUT_COMPLETE_USERNAMES;
|
INPUT_COMPLETE_VARIABLES | INPUT_COMPLETE_USERNAMES;
|
||||||
in->current_max_len = initial_buffer_len;
|
in->current_max_size = initial_buffer_len;
|
||||||
in->buffer = g_malloc (initial_buffer_len);
|
in->buffer = g_new (char, initial_buffer_len);
|
||||||
in->color = color;
|
in->color = color;
|
||||||
in->field_len = len;
|
in->field_width = width;
|
||||||
in->first = 1;
|
in->first = 1;
|
||||||
in->first_shown = 0;
|
in->term_first_shown = 0;
|
||||||
in->disable_update = 0;
|
in->disable_update = 0;
|
||||||
in->mark = 0;
|
in->mark = 0;
|
||||||
in->need_push = 1;
|
in->need_push = 1;
|
||||||
in->is_password = 0;
|
in->is_password = 0;
|
||||||
|
|
||||||
strcpy (in->buffer, def_text);
|
strcpy (in->buffer, def_text);
|
||||||
in->point = strlen (in->buffer);
|
in->point = str_length (in->buffer);
|
||||||
|
in->charpoint = 0;
|
||||||
return in;
|
return in;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/* Listbox widget */
|
/* Listbox widget */
|
||||||
|
|
||||||
/* Should draw the scrollbar, but currently draws only
|
/* Should draw the scrollbar, but currently draws only
|
||||||
|
16
src/widget.h
16
src/widget.h
@ -74,11 +74,11 @@ char *show_hist (GList *history, int widget_y, int widget_x);
|
|||||||
|
|
||||||
typedef struct {
|
typedef struct {
|
||||||
Widget widget;
|
Widget widget;
|
||||||
int point; /* cursor position in the input line */
|
int point; /* cursor position in the input line in characters */
|
||||||
int mark; /* The mark position */
|
int mark; /* The mark position in characters */
|
||||||
int first_shown; /* Index of the first shown character */
|
int term_first_shown; /* column of the first shown character */
|
||||||
int current_max_len; /* Maximum length of input line */
|
size_t current_max_size; /* Maximum length of input line (bytes) */
|
||||||
int field_len; /* Length of the editing field */
|
int field_width; /* width of the editing field */
|
||||||
int color; /* color used */
|
int color; /* color used */
|
||||||
int first; /* Is first keystroke? */
|
int first; /* Is first keystroke? */
|
||||||
int disable_update; /* Do we want to skip updates? */
|
int disable_update; /* Do we want to skip updates? */
|
||||||
@ -89,6 +89,8 @@ typedef struct {
|
|||||||
char **completions; /* Possible completions array */
|
char **completions; /* Possible completions array */
|
||||||
int completion_flags; /* INPUT_COMPLETE* bitwise flags(complete.h) */
|
int completion_flags; /* INPUT_COMPLETE* bitwise flags(complete.h) */
|
||||||
char *history_name; /* name of history for loading and saving */
|
char *history_name; /* name of history for loading and saving */
|
||||||
|
char charbuf[MB_LEN_MAX]; /* buffer for multibytes characters */
|
||||||
|
size_t charpoint; /* point to end of mulibyte sequence in charbuf */
|
||||||
} WInput;
|
} WInput;
|
||||||
|
|
||||||
/* For history load-save functions */
|
/* For history load-save functions */
|
||||||
@ -144,14 +146,14 @@ WButton *button_new (int y, int x, int action, int flags, const char *text,
|
|||||||
bcback callback);
|
bcback callback);
|
||||||
WRadio *radio_new (int y, int x, int count, const char **text);
|
WRadio *radio_new (int y, int x, int count, const char **text);
|
||||||
WCheck *check_new (int y, int x, int state, const char *text);
|
WCheck *check_new (int y, int x, int state, const char *text);
|
||||||
WInput *input_new (int y, int x, int color, int len, const char *text, const char *histname);
|
WInput *input_new (int y, int x, int color, int width, const char *text, const char *histname);
|
||||||
WLabel *label_new (int y, int x, const char *text);
|
WLabel *label_new (int y, int x, const char *text);
|
||||||
WGauge *gauge_new (int y, int x, int shown, int max, int current);
|
WGauge *gauge_new (int y, int x, int shown, int max, int current);
|
||||||
WListbox *listbox_new (int x, int y, int width, int height, lcback callback);
|
WListbox *listbox_new (int x, int y, int width, int height, lcback callback);
|
||||||
WGroupbox *groupbox_new (int x, int y, int width, int height, const char *title);
|
WGroupbox *groupbox_new (int x, int y, int width, int height, const char *title);
|
||||||
|
|
||||||
/* Input lines */
|
/* Input lines */
|
||||||
void winput_set_origin (WInput *i, int x, int field_len);
|
void winput_set_origin (WInput *i, int x, int field_width);
|
||||||
cb_ret_t handle_char (WInput *in, int c_code);
|
cb_ret_t handle_char (WInput *in, int c_code);
|
||||||
int is_in_input_map (WInput *in, int c_code);
|
int is_in_input_map (WInput *in, int c_code);
|
||||||
void update_input (WInput *in, int clear_first);
|
void update_input (WInput *in, int clear_first);
|
||||||
|
Загрузка…
x
Ссылка в новой задаче
Block a user