Clean up and simplify line editing functions.
This greatly simplifies all line editing functions - especially getstring() and showstring(). showcursor() is removed and integrated into showstring(). del_char() and add_char() are simplified as well. add_char() is renamed to ins_char(). Signed-off-by: Lukas Fleischer <calcurse@cryptocrack.de>
This commit is contained in:
parent
355687b644
commit
6f425dc1fa
252
src/utils.c
252
src/utils.c
@ -228,77 +228,51 @@ print_in_middle (WINDOW *win, int starty, int startx, int width, char *string)
|
|||||||
custom_remove_attr (win, ATTR_HIGHEST);
|
custom_remove_attr (win, ATTR_HIGHEST);
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
|
||||||
* Draw the cursor at the correct position in string.
|
|
||||||
* As echoing is not set, we need to know the string we are working on to
|
|
||||||
* handle display correctly.
|
|
||||||
*/
|
|
||||||
static void
|
|
||||||
showcursor (WINDOW *win, int y, int pos, char *str, int l, int offset)
|
|
||||||
{
|
|
||||||
char *nc;
|
|
||||||
|
|
||||||
nc = str + pos;
|
|
||||||
wmove (win, y, pos - offset);
|
|
||||||
(pos >= l) ? waddch (win, SPACE | A_REVERSE) : waddch (win, *nc | A_REVERSE);
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Print the string at the desired position. */
|
/* Print the string at the desired position. */
|
||||||
static void
|
static void
|
||||||
showstring (WINDOW *win, int y, int x, char *str, int len, int pos)
|
showstring (WINDOW *win, int x, int y, char *str, int len, int scroff,
|
||||||
|
int curpos)
|
||||||
{
|
{
|
||||||
const int rec = 30, border = 3;
|
char c = 0;
|
||||||
const int max_col = col - border, max_len = max_col - rec;
|
|
||||||
int page, max_page, offset, c = 0;
|
|
||||||
char *orig;
|
|
||||||
|
|
||||||
orig = str;
|
/* print string */
|
||||||
max_page = (len - rec) / max_len;
|
mvwaddnstr (win, y, x, &str[scroff], -1);
|
||||||
page = (pos - rec) / max_len;
|
|
||||||
offset = page * max_len;
|
|
||||||
str += offset;
|
|
||||||
mvwaddnstr (win, y, x, str, MIN (len, max_col));
|
|
||||||
wclrtoeol (win);
|
wclrtoeol (win);
|
||||||
if (page > 0 && page < max_page)
|
|
||||||
{
|
/* print scrolling indicator */
|
||||||
c = '*';
|
if (scroff > 0 && scroff < len - col) c = '*';
|
||||||
}
|
else if (scroff > 0) c = '<';
|
||||||
else if (page > 0)
|
else if (scroff < len - col) c = '>';
|
||||||
{
|
|
||||||
c = '<';
|
|
||||||
}
|
|
||||||
else if (page < max_page)
|
|
||||||
{
|
|
||||||
c = '>';
|
|
||||||
}
|
|
||||||
else
|
|
||||||
c = 0;
|
|
||||||
mvwprintw (win, y, col - 1, "%c", c);
|
mvwprintw (win, y, col - 1, "%c", c);
|
||||||
showcursor (win, y, pos, orig, len, offset);
|
|
||||||
|
/* print cursor */
|
||||||
|
wmove (win, y, curpos - scroff);
|
||||||
|
|
||||||
|
if (curpos >= len) waddch (win, SPACE | A_REVERSE);
|
||||||
|
else waddch (win, str[curpos] | A_REVERSE);
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Delete a character at the given position in string. */
|
/* Delete a character at the given position in string. */
|
||||||
static void
|
static void
|
||||||
del_char (int pos, char *str)
|
del_char (int pos, char *str)
|
||||||
{
|
{
|
||||||
int len;
|
|
||||||
|
|
||||||
str += pos;
|
str += pos;
|
||||||
len = strlen (str) + 1;
|
memmove (str, str + 1, strlen (str) + 1);
|
||||||
memmove (str, str + 1, len);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Add a character at the given position in string. */
|
/* Add a character at the given position in string. */
|
||||||
static char *
|
static void
|
||||||
add_char (int pos, int ch, char *str)
|
ins_char (int pos, int ch, char *str)
|
||||||
{
|
{
|
||||||
int len;
|
|
||||||
|
|
||||||
str += pos;
|
str += pos;
|
||||||
len = strlen (str) + 1;
|
memmove (str + 1, str, strlen (str) + 1);
|
||||||
memmove (str + 1, str, len);
|
|
||||||
*str = ch;
|
*str = ch;
|
||||||
return (str += len);
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
bell (void)
|
||||||
|
{
|
||||||
|
printf ("\a");
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
@ -312,117 +286,85 @@ add_char (int pos, int ch, char *str)
|
|||||||
enum getstr
|
enum getstr
|
||||||
getstring (WINDOW *win, char *str, int l, int x, int y)
|
getstring (WINDOW *win, char *str, int l, int x, int y)
|
||||||
{
|
{
|
||||||
int ch, newpos, len = 0;
|
const int pgsize = col / 3;
|
||||||
char *orig;
|
|
||||||
|
int len = strlen (str);
|
||||||
|
int curpos = len;
|
||||||
|
int scroff = 0;
|
||||||
|
int ch;
|
||||||
|
|
||||||
orig = str;
|
|
||||||
custom_apply_attr (win, ATTR_HIGHEST);
|
custom_apply_attr (win, ATTR_HIGHEST);
|
||||||
for (; *str; ++str, ++len)
|
|
||||||
;
|
|
||||||
newpos = x + len;
|
|
||||||
showstring (win, y, x, orig, len, newpos);
|
|
||||||
|
|
||||||
while ((ch = wgetch (win)) != '\n')
|
for (;;) {
|
||||||
{
|
while (curpos < scroff) scroff -= pgsize;
|
||||||
switch (ch)
|
while (curpos >= scroff + col - 1) scroff += pgsize;
|
||||||
{
|
|
||||||
case KEY_BACKSPACE: /* delete one character */
|
|
||||||
case 330:
|
|
||||||
case 127:
|
|
||||||
case CTRL ('H'):
|
|
||||||
if (len > 0 && newpos > x)
|
|
||||||
{
|
|
||||||
--newpos;
|
|
||||||
--len;
|
|
||||||
if (newpos >= x + len)
|
|
||||||
--str;
|
|
||||||
else /* to be deleted inside string */
|
|
||||||
del_char (newpos, orig);
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
|
|
||||||
case CTRL ('D'): /* delete next character */
|
showstring (win, x, y, str, len, scroff, curpos);
|
||||||
if (newpos != (x + len))
|
wins_doupdate ();
|
||||||
{
|
|
||||||
--len;
|
|
||||||
if (newpos >= x + len)
|
|
||||||
--str;
|
|
||||||
else
|
|
||||||
del_char (newpos, orig);
|
|
||||||
}
|
|
||||||
else
|
|
||||||
printf ("\a");
|
|
||||||
break;
|
|
||||||
|
|
||||||
case CTRL ('W'): /* delete a word */
|
if ((ch = wgetch (win)) == '\n') break;
|
||||||
while (len > 0 && newpos > x && *(orig + newpos - 1) == ' ') {
|
switch (ch) {
|
||||||
--newpos;
|
case KEY_BACKSPACE: /* delete one character */
|
||||||
--len;
|
case 330:
|
||||||
if (newpos >= x + len)
|
case 127:
|
||||||
--str;
|
case CTRL ('H'):
|
||||||
else
|
if (curpos > 0) {
|
||||||
del_char (newpos, orig);
|
del_char ((--curpos), str);
|
||||||
|
len--;
|
||||||
|
}
|
||||||
|
else bell ();
|
||||||
|
break;
|
||||||
|
case CTRL ('D'): /* delete next character */
|
||||||
|
if (curpos < len) {
|
||||||
|
del_char (curpos, str);
|
||||||
|
len--;
|
||||||
|
}
|
||||||
|
else bell ();
|
||||||
|
break;
|
||||||
|
case CTRL ('W'): /* delete a word */
|
||||||
|
if (curpos > 0) {
|
||||||
|
while (curpos && str[curpos - 1] == ' ') {
|
||||||
|
del_char ((--curpos), str);
|
||||||
|
len--;
|
||||||
|
}
|
||||||
|
while (curpos && str[curpos - 1] != ' ') {
|
||||||
|
del_char ((--curpos), str);
|
||||||
|
len--;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else bell ();
|
||||||
|
break;
|
||||||
|
case CTRL ('K'): /* delete to end-of-line */
|
||||||
|
str[curpos] = 0;
|
||||||
|
len = curpos;
|
||||||
|
break;
|
||||||
|
case CTRL ('A'): /* go to begginning of string */
|
||||||
|
curpos = 0;
|
||||||
|
break;
|
||||||
|
case CTRL ('E'): /* go to end of string */
|
||||||
|
curpos = len;
|
||||||
|
break;
|
||||||
|
case KEY_LEFT: /* move one char backward */
|
||||||
|
case CTRL ('B'):
|
||||||
|
if (curpos > 0) curpos--;
|
||||||
|
break;
|
||||||
|
case KEY_RIGHT: /* move one char forward */
|
||||||
|
case CTRL ('F'):
|
||||||
|
if (curpos < len) curpos++;
|
||||||
|
break;
|
||||||
|
case ESCAPE: /* cancel editing */
|
||||||
|
return (GETSTRING_ESC);
|
||||||
|
break;
|
||||||
|
default: /* insert one character */
|
||||||
|
if (len < l - 1) {
|
||||||
|
ins_char ((curpos++), ch, str);
|
||||||
|
len++;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
while (len > 0 && newpos > x && *(orig + newpos - 1) != ' ') {
|
}
|
||||||
--newpos;
|
|
||||||
--len;
|
|
||||||
if (newpos >= x + len)
|
|
||||||
--str;
|
|
||||||
else
|
|
||||||
del_char (newpos, orig);
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
|
|
||||||
case CTRL ('K'): /* delete to end-of-line */
|
|
||||||
str = orig + newpos;
|
|
||||||
*str = 0;
|
|
||||||
len -= (len - newpos);
|
|
||||||
break;
|
|
||||||
|
|
||||||
case CTRL ('A'): /* go to begginning of string */
|
|
||||||
newpos = x;
|
|
||||||
break;
|
|
||||||
|
|
||||||
case CTRL ('E'): /* go to end of string */
|
|
||||||
newpos = x + len;
|
|
||||||
break;
|
|
||||||
|
|
||||||
case KEY_LEFT: /* move one char backward */
|
|
||||||
case CTRL ('B'):
|
|
||||||
if (newpos > x)
|
|
||||||
newpos--;
|
|
||||||
break;
|
|
||||||
|
|
||||||
case KEY_RIGHT: /* move one char forward */
|
|
||||||
case CTRL ('F'):
|
|
||||||
if (newpos < len)
|
|
||||||
newpos++;
|
|
||||||
break;
|
|
||||||
|
|
||||||
case ESCAPE: /* cancel editing */
|
|
||||||
return (GETSTRING_ESC);
|
|
||||||
break;
|
|
||||||
|
|
||||||
default: /* insert one character */
|
|
||||||
if (len < l - 1)
|
|
||||||
{
|
|
||||||
if (newpos >= len)
|
|
||||||
{
|
|
||||||
str = orig + newpos;
|
|
||||||
*str++ = ch;
|
|
||||||
}
|
|
||||||
else // char is to be inserted inside string
|
|
||||||
str = add_char (newpos, ch, orig);
|
|
||||||
++len;
|
|
||||||
++newpos;
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
||||||
showstring (win, y, x, orig, len, newpos);
|
|
||||||
wins_doupdate ();
|
|
||||||
}
|
|
||||||
*str = 0;
|
|
||||||
custom_remove_attr (win, ATTR_HIGHEST);
|
custom_remove_attr (win, ATTR_HIGHEST);
|
||||||
|
|
||||||
return (len == 0 ? GETSTRING_RET : GETSTRING_VALID);
|
return (len == 0 ? GETSTRING_RET : GETSTRING_VALID);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Loading…
x
Reference in New Issue
Block a user