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:
Lukas Fleischer 2011-03-05 17:13:37 +01:00
parent 355687b644
commit 6f425dc1fa

View File

@ -228,77 +228,51 @@ print_in_middle (WINDOW *win, int starty, int startx, int width, char *string)
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. */
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;
const int max_col = col - border, max_len = max_col - rec;
int page, max_page, offset, c = 0;
char *orig;
char c = 0;
orig = str;
max_page = (len - rec) / max_len;
page = (pos - rec) / max_len;
offset = page * max_len;
str += offset;
mvwaddnstr (win, y, x, str, MIN (len, max_col));
/* print string */
mvwaddnstr (win, y, x, &str[scroff], -1);
wclrtoeol (win);
if (page > 0 && page < max_page)
{
c = '*';
}
else if (page > 0)
{
c = '<';
}
else if (page < max_page)
{
c = '>';
}
else
c = 0;
/* print scrolling indicator */
if (scroff > 0 && scroff < len - col) c = '*';
else if (scroff > 0) c = '<';
else if (scroff < len - col) 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. */
static void
del_char (int pos, char *str)
{
int len;
str += pos;
len = strlen (str) + 1;
memmove (str, str + 1, len);
memmove (str, str + 1, strlen (str) + 1);
}
/* Add a character at the given position in string. */
static char *
add_char (int pos, int ch, char *str)
static void
ins_char (int pos, int ch, char *str)
{
int len;
str += pos;
len = strlen (str) + 1;
memmove (str + 1, str, len);
memmove (str + 1, str, strlen (str) + 1);
*str = ch;
return (str += len);
}
void
bell (void)
{
printf ("\a");
}
/*
@ -312,117 +286,85 @@ add_char (int pos, int ch, char *str)
enum getstr
getstring (WINDOW *win, char *str, int l, int x, int y)
{
int ch, newpos, len = 0;
char *orig;
const int pgsize = col / 3;
int len = strlen (str);
int curpos = len;
int scroff = 0;
int ch;
orig = str;
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')
{
switch (ch)
{
for (;;) {
while (curpos < scroff) scroff -= pgsize;
while (curpos >= scroff + col - 1) scroff += pgsize;
showstring (win, x, y, str, len, scroff, curpos);
wins_doupdate ();
if ((ch = wgetch (win)) == '\n') break;
switch (ch) {
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);
if (curpos > 0) {
del_char ((--curpos), str);
len--;
}
else bell ();
break;
case CTRL ('D'): /* delete next character */
if (newpos != (x + len))
{
--len;
if (newpos >= x + len)
--str;
else
del_char (newpos, orig);
if (curpos < len) {
del_char (curpos, str);
len--;
}
else
printf ("\a");
else bell ();
break;
case CTRL ('W'): /* delete a word */
while (len > 0 && newpos > x && *(orig + newpos - 1) == ' ') {
--newpos;
--len;
if (newpos >= x + len)
--str;
else
del_char (newpos, orig);
if (curpos > 0) {
while (curpos && str[curpos - 1] == ' ') {
del_char ((--curpos), str);
len--;
}
while (len > 0 && newpos > x && *(orig + newpos - 1) != ' ') {
--newpos;
--len;
if (newpos >= x + len)
--str;
else
del_char (newpos, orig);
while (curpos && str[curpos - 1] != ' ') {
del_char ((--curpos), str);
len--;
}
}
else bell ();
break;
case CTRL ('K'): /* delete to end-of-line */
str = orig + newpos;
*str = 0;
len -= (len - newpos);
str[curpos] = 0;
len = curpos;
break;
case CTRL ('A'): /* go to begginning of string */
newpos = x;
curpos = 0;
break;
case CTRL ('E'): /* go to end of string */
newpos = x + len;
curpos = len;
break;
case KEY_LEFT: /* move one char backward */
case CTRL ('B'):
if (newpos > x)
newpos--;
if (curpos > 0) curpos--;
break;
case KEY_RIGHT: /* move one char forward */
case CTRL ('F'):
if (newpos < len)
newpos++;
if (curpos < len) curpos++;
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;
if (len < l - 1) {
ins_char ((curpos++), ch, str);
len++;
}
}
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);
return (len == 0 ? GETSTRING_RET : GETSTRING_VALID);
}