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); 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;
{
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 KEY_BACKSPACE: /* delete one character */
case 330: case 330:
case 127: case 127:
case CTRL ('H'): case CTRL ('H'):
if (len > 0 && newpos > x) if (curpos > 0) {
{ del_char ((--curpos), str);
--newpos; len--;
--len;
if (newpos >= x + len)
--str;
else /* to be deleted inside string */
del_char (newpos, orig);
} }
else bell ();
break; break;
case CTRL ('D'): /* delete next character */ case CTRL ('D'): /* delete next character */
if (newpos != (x + len)) if (curpos < len) {
{ del_char (curpos, str);
--len; len--;
if (newpos >= x + len)
--str;
else
del_char (newpos, orig);
} }
else else bell ();
printf ("\a");
break; break;
case CTRL ('W'): /* delete a word */ case CTRL ('W'): /* delete a word */
while (len > 0 && newpos > x && *(orig + newpos - 1) == ' ') { if (curpos > 0) {
--newpos; while (curpos && str[curpos - 1] == ' ') {
--len; del_char ((--curpos), str);
if (newpos >= x + len) len--;
--str;
else
del_char (newpos, orig);
} }
while (len > 0 && newpos > x && *(orig + newpos - 1) != ' ') { while (curpos && str[curpos - 1] != ' ') {
--newpos; del_char ((--curpos), str);
--len; len--;
if (newpos >= x + len)
--str;
else
del_char (newpos, orig);
} }
}
else bell ();
break; break;
case CTRL ('K'): /* delete to end-of-line */ case CTRL ('K'): /* delete to end-of-line */
str = orig + newpos; str[curpos] = 0;
*str = 0; len = curpos;
len -= (len - newpos);
break; break;
case CTRL ('A'): /* go to begginning of string */ case CTRL ('A'): /* go to begginning of string */
newpos = x; curpos = 0;
break; break;
case CTRL ('E'): /* go to end of string */ case CTRL ('E'): /* go to end of string */
newpos = x + len; curpos = len;
break; break;
case KEY_LEFT: /* move one char backward */ case KEY_LEFT: /* move one char backward */
case CTRL ('B'): case CTRL ('B'):
if (newpos > x) if (curpos > 0) curpos--;
newpos--;
break; break;
case KEY_RIGHT: /* move one char forward */ case KEY_RIGHT: /* move one char forward */
case CTRL ('F'): case CTRL ('F'):
if (newpos < len) if (curpos < len) curpos++;
newpos++;
break; break;
case ESCAPE: /* cancel editing */ case ESCAPE: /* cancel editing */
return (GETSTRING_ESC); return (GETSTRING_ESC);
break; break;
default: /* insert one character */ default: /* insert one character */
if (len < l - 1) if (len < l - 1) {
{ ins_char ((curpos++), ch, str);
if (newpos >= len) 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);
} }