From: Paulius Zaleckas <paulius.zaleckas@gmail.com>
To: mmarek@suse.cz, linux-kbuild@vger.kernel.org,
linux-kernel@vger.kernel.org
Subject: [PATCH v2 1/2] menuconfig: basic string editing in inputbox support
Date: Mon, 09 Jan 2012 13:36:33 +0200 [thread overview]
Message-ID: <20120109113633.24486.69758.stgit@localhost6.localdomain6> (raw)
For me the most irritating thing in linux kernel was absence
of string editing in menuconfig's inputbox. If you wanted to
change first symbol you had to delete all string and then type
it all again.
New implementation handles right/left cursor, backspace and
delete keys. It does a little bit more terminal manipulations
as string area is fully redrawn on each event.
Signed-off-by: Paulius Zaleckas <paulius.zaleckas@gmail.com>
---
scripts/kconfig/lxdialog/inputbox.c | 87 +++++++++++++++++++++--------------
1 files changed, 53 insertions(+), 34 deletions(-)
diff --git a/scripts/kconfig/lxdialog/inputbox.c b/scripts/kconfig/lxdialog/inputbox.c
index dd8e587..834eee9 100644
--- a/scripts/kconfig/lxdialog/inputbox.c
+++ b/scripts/kconfig/lxdialog/inputbox.c
@@ -44,7 +44,7 @@ static void print_buttons(WINDOW * dialog, int height, int width, int selected)
int dialog_inputbox(const char *title, const char *prompt, int height, int width,
const char *init)
{
- int i, x, y, box_y, box_x, box_width;
+ int i, len, x, y, box_y, box_x, box_width;
int input_x = 0, scroll = 0, key = 0, button = -1;
char *instr = dialog_input_result;
WINDOW *dialog;
@@ -54,6 +54,8 @@ int dialog_inputbox(const char *title, const char *prompt, int height, int width
else
strcpy(instr, init);
+ len = strlen(instr);
+
do_resize:
if (getmaxy(stdscr) <= (height - 2))
return -ERRDISPLAYTOOSMALL;
@@ -97,14 +99,13 @@ do_resize:
wmove(dialog, box_y, box_x);
wattrset(dialog, dlg.inputbox.atr);
- input_x = strlen(instr);
-
- if (input_x >= box_width) {
- scroll = input_x - box_width + 1;
+ if (len >= box_width) {
+ scroll = len - box_width + 1;
input_x = box_width - 1;
for (i = 0; i < box_width - 1; i++)
waddch(dialog, instr[scroll + i]);
} else {
+ input_x = len;
waddstr(dialog, instr);
}
@@ -121,50 +122,68 @@ do_resize:
case KEY_UP:
case KEY_DOWN:
break;
- case KEY_LEFT:
- continue;
case KEY_RIGHT:
+ if (scroll + input_x < len) {
+ if (input_x == box_width - 1)
+ scroll++;
+ else
+ input_x++;
+ goto redraw;
+ }
continue;
+ case KEY_LEFT:
case KEY_BACKSPACE:
case 127:
if (input_x || scroll) {
- wattrset(dialog, dlg.inputbox.atr);
- if (!input_x) {
- scroll = scroll < box_width - 1 ? 0 : scroll - (box_width - 1);
- wmove(dialog, box_y, box_x);
- for (i = 0; i < box_width; i++)
- waddch(dialog,
- instr[scroll + input_x + i] ?
- instr[scroll + input_x + i] : ' ');
- input_x = strlen(instr) - scroll;
- } else
+ /*
+ * Some fancy scrolling, so you can see what
+ * you will be deleting with backspace
+ */
+ if (!input_x || (input_x < box_width / 4 && scroll))
+ scroll--;
+ else
input_x--;
- instr[scroll + input_x] = '\0';
- mvwaddch(dialog, box_y, input_x + box_x, ' ');
- wmove(dialog, box_y, input_x + box_x);
- wrefresh(dialog);
+
+ if (key != KEY_LEFT) {
+ int pos = scroll + input_x;
+ memmove(&instr[pos], &instr[pos + 1], len-- - pos + 1);
+ }
+ goto redraw;
+ }
+ continue;
+ case KEY_DC:
+ if (scroll + input_x < len) {
+ int pos = scroll + input_x;
+ memmove(&instr[pos], &instr[pos + 1], len-- - pos + 1);
+ goto redraw;
}
continue;
default:
if (key < 0x100 && isprint(key)) {
- if (scroll + input_x < MAX_LEN) {
- wattrset(dialog, dlg.inputbox.atr);
- instr[scroll + input_x] = key;
- instr[scroll + input_x + 1] = '\0';
- if (input_x == box_width - 1) {
+ if (len < MAX_LEN) {
+ int pos = scroll + input_x;
+ memmove(&instr[pos + 1], &instr[pos], len++ - pos + 1);
+ instr[pos] = key;
+ if (input_x == box_width - 1)
scroll++;
- wmove(dialog, box_y, box_x);
- for (i = 0; i < box_width - 1; i++)
- waddch(dialog, instr [scroll + i]);
- } else {
- wmove(dialog, box_y, input_x++ + box_x);
- waddch(dialog, key);
- }
- wrefresh(dialog);
+ else
+ input_x++;
+ goto redraw;
} else
flash(); /* Alarm user about overflow */
continue;
}
+ break;
+ redraw:
+ wattrset(dialog, dlg.inputbox.atr);
+ wmove(dialog, box_y, box_x);
+ for (i = 0; i < box_width - 1; i++)
+ waddch(dialog,
+ scroll + i < len ?
+ instr[scroll + i] : ' ');
+ wmove(dialog, box_y, input_x + box_x);
+ wrefresh(dialog);
+ continue;
}
}
switch (key) {
next reply other threads:[~2012-01-09 11:36 UTC|newest]
Thread overview: 11+ messages / expand[flat|nested] mbox.gz Atom feed top
2012-01-09 11:36 Paulius Zaleckas [this message]
2012-01-09 11:36 ` [PATCH v2 2/2] menuconfig: add Home and End keys support for inputbox Paulius Zaleckas
2012-01-09 22:20 ` Randy Dunlap
2012-01-10 11:50 ` Paulius Zaleckas
2012-01-10 17:30 ` Randy Dunlap
2012-01-11 9:21 ` Paulius Zaleckas
2012-01-11 19:12 ` Randy Dunlap
2012-01-12 14:24 ` Paulius Zaleckas
2012-01-12 17:40 ` Randy Dunlap
2012-01-13 15:35 ` Paulius Zaleckas
2012-01-13 17:48 ` Randy Dunlap
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=20120109113633.24486.69758.stgit@localhost6.localdomain6 \
--to=paulius.zaleckas@gmail.com \
--cc=linux-kbuild@vger.kernel.org \
--cc=linux-kernel@vger.kernel.org \
--cc=mmarek@suse.cz \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).