diff mbox

[V2,4/6] scripts/kconfig/nconf: fix editing long strings

Message ID 1314776773-9560-5-git-send-email-crquan@gmail.com (mailing list archive)
State New, archived
Headers show

Commit Message

Cheng Renquan Aug. 31, 2011, 7:46 a.m. UTC
The original dialog_inputbox doesn't work with longer than prompt_width
strings, here fixed it in this way:

1) add variable cursor_form_win to record cursor of form_win,
   keep its value always between [0, prompt_width-1];
   keep the original cursor_position as cursor of the string result,
   for short strings, cursor_form_win is identical to cursor_position;
   for long strings, use (cursor_position-cursor_form_win) as begin offset
   to show part of the string in form_win;

2) whenever cursor of form_win is near (by 3 chars) to left or right edge
   of form_win, make a auto scroll by half prompt_width, to make this one
   line string editor more fun to use;

3) update len for later cursor_form_win correct calculation;

Signed-off-by: Cheng Renquan <crquan@gmail.com>
---
 scripts/kconfig/nconf.gui.c |   43 +++++++++++++++++++++++++++++++++++++------
 1 files changed, 37 insertions(+), 6 deletions(-)
diff mbox

Patch

diff --git a/scripts/kconfig/nconf.gui.c b/scripts/kconfig/nconf.gui.c
index d64bc1c..a236ae7 100644
--- a/scripts/kconfig/nconf.gui.c
+++ b/scripts/kconfig/nconf.gui.c
@@ -367,6 +367,7 @@  int dialog_inputbox(WINDOW *main_window,
 	int i, x, y;
 	int res = -1;
 	int cursor_position = strlen(init);
+	int cursor_form_win;
 	char *result = *resultp;
 
 	if (strlen(init)+1 > *result_len) {
@@ -410,7 +411,9 @@  int dialog_inputbox(WINDOW *main_window,
 	fill_window(prompt_win, prompt);
 
 	mvwprintw(form_win, 0, 0, "%*s", prompt_width, " ");
-	mvwprintw(form_win, 0, 0, "%s", result);
+	cursor_form_win = min(cursor_position, prompt_width-1);
+	mvwprintw(form_win, 0, 0, "%s",
+		  result + cursor_position-cursor_form_win);
 
 	/* create panels */
 	panel = new_panel(win);
@@ -436,6 +439,8 @@  int dialog_inputbox(WINDOW *main_window,
 						&result[cursor_position],
 						len-cursor_position+1);
 				cursor_position--;
+				cursor_form_win--;
+				len--;
 			}
 			break;
 		case KEY_DC:
@@ -443,18 +448,22 @@  int dialog_inputbox(WINDOW *main_window,
 				memmove(&result[cursor_position],
 						&result[cursor_position+1],
 						len-cursor_position+1);
+				len--;
 			}
 			break;
 		case KEY_UP:
 		case KEY_RIGHT:
-			if (cursor_position < len &&
-			    cursor_position < min(*result_len, prompt_width))
+			if (cursor_position < len) {
 				cursor_position++;
+				cursor_form_win++;
+			}
 			break;
 		case KEY_DOWN:
 		case KEY_LEFT:
-			if (cursor_position > 0)
+			if (cursor_position > 0) {
 				cursor_position--;
+				cursor_form_win--;
+			}
 			break;
 		default:
 			if ((isgraph(res) || isspace(res))) {
@@ -470,16 +479,38 @@  int dialog_inputbox(WINDOW *main_window,
 						len-cursor_position+1);
 				result[cursor_position] = res;
 				cursor_position++;
+				cursor_form_win++;
+				len++;
 			} else {
 				mvprintw(0, 0, "unknown key: %d\n", res);
 			}
 			break;
 		}
+		if (len <= prompt_width-1)
+			cursor_form_win = cursor_position;
+		else {
+			if (cursor_form_win <= 3)
+				cursor_form_win += prompt_width/2;
+			else if (cursor_form_win >= prompt_width-3)
+				cursor_form_win -= prompt_width/2;
+
+			if (cursor_form_win < 0)
+				cursor_form_win = 0;
+			else if (cursor_form_win >= prompt_width-1)
+				cursor_form_win = prompt_width-1;
+
+			if (cursor_form_win > cursor_position)
+				cursor_form_win = cursor_position;
+			if (cursor_form_win < (prompt_width-1) - (len-cursor_position))
+				cursor_form_win = (prompt_width-1) - (len-cursor_position);
+		}
+
 		wmove(form_win, 0, 0);
 		wclrtoeol(form_win);
 		mvwprintw(form_win, 0, 0, "%*s", prompt_width, " ");
-		mvwprintw(form_win, 0, 0, "%s", result);
-		wmove(form_win, 0, cursor_position);
+		mvwprintw(form_win, 0, 0, "%s",
+			result + cursor_position-cursor_form_win);
+		wmove(form_win, 0, cursor_form_win);
 		touchwin(win);
 		refresh_all_windows(main_window);