From e19449ec50ac7e91cd5f1b11e5d53960308ecf8b Mon Sep 17 00:00:00 2001
From: David Lawrence Ramsey <pooka109@gmail.com>
Date: Mon, 7 Nov 2005 21:45:44 +0000
Subject: [PATCH] actually use statusbar_pww in the statusbar prompt code to
 cut down on redundant updates, add related functions to do that, and rename a
 few of the statusbar prompt functions for consistency

git-svn-id: svn://svn.savannah.gnu.org/nano/trunk/nano@3099 35c25a1d-7b9e-4130-9fde-d3aeb78583b8
---
 ChangeLog     |  19 +++++----
 src/browser.c |   2 +-
 src/files.c   |  13 +++---
 src/nano.c    |   5 ++-
 src/prompt.c  | 114 +++++++++++++++++++++++++++++++++++---------------
 src/proto.h   |  13 +++---
 src/search.c  |   8 ++--
 src/text.c    |   2 +-
 8 files changed, 117 insertions(+), 59 deletions(-)

diff --git a/ChangeLog b/ChangeLog
index 8f7d6922..7ccd9613 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -61,13 +61,18 @@ CVS code -
 	  do_browser(), and do_browse_from() (all moved to browser.c).
 	  (DLR)
 	- Add the statusbar prompt's equivalent of placewewant,
-	  statusbar_pww, to prompt.c, and convert (most of) its
-	  functions to use it.  Changes to do_statusbar_mouse(),
-	  do_statusbar_output(), do_statusbar_home(),
-	  do_statusbar_end(), do_statusbar_right(), do_statusbar_left(),
-	  do_statusbar_delete(), do_statusbar_cut_text(),
-	  do_statusbar_next_word(), do_statusbar_prev_word(),
-	  do_statusbar_verbatim_input(), and nanogetstr(). (DLR)
+	  statusbar_pww, to prompt.c, and convert its functions to use
+	  it.  New functions reset_statusbar_cursor() and
+	  need_statusbar_horizontal_update(); changes to
+	  do_statusbar_mouse(), do_statusbar_output(),
+	  do_statusbar_home(), do_statusbar_end(), do_statusbar_right(),
+	  do_statusbar_left(), do_statusbar_delete(),
+	  do_statusbar_cut_text(), do_statusbar_next_word(),
+	  do_statusbar_prev_word(), do_statusbar_verbatim_input(),
+	  nanoget_repaint() (renamed update_statusbar_line()),
+	  nanogetstr() (renamed get_prompt_string()), statusq() (renamed
+	  do_prompt()), statusq_abort() (renamed do_prompt_abort()), and
+	  do_yesno() (renamed do_yesno_prompt()). (DLR)
 - files.c:
   read_file()
 	- Remove apparently unneeded logic to handle a case where
diff --git a/src/browser.c b/src/browser.c
index 0fce1a59..df997194 100644
--- a/src/browser.c
+++ b/src/browser.c
@@ -246,7 +246,7 @@ char *do_browser(char *path, DIR *dir)
 	    case 'g':
 		curs_set(1);
 
-		j = statusq(FALSE, gotodir_list, "",
+		j = do_prompt(FALSE, gotodir_list, "",
 #ifndef NANO_SMALL
 			NULL,
 #endif
diff --git a/src/files.c b/src/files.c
index 65d0b7bd..09f665b2 100644
--- a/src/files.c
+++ b/src/files.c
@@ -670,7 +670,7 @@ void do_insertfile(
 	}
 #endif
 
-	i = statusq(TRUE,
+	i = do_prompt(TRUE,
 #ifndef NANO_SMALL
 		execute ? extcmd_list :
 #endif
@@ -730,7 +730,7 @@ void do_insertfile(
 		/* We have a file now.  Indicate this and get out of the
 		 * statusbar prompt cleanly. */
 		i = 0;
-		statusq_abort();
+		do_prompt_abort();
 	    }
 #endif
 
@@ -1699,7 +1699,7 @@ int do_writeout(bool exiting)
 	/* If we're using restricted mode, the filename isn't blank,
 	 * and we're at the "Write File" prompt, disable tab
 	 * completion. */
-	i = statusq(!ISSET(RESTRICTED) ||
+	i = do_prompt(!ISSET(RESTRICTED) ||
 		openfile->filename[0] == '\0', writefile_list, ans,
 #ifndef NANO_SMALL
 		NULL, "%s%s%s", _(msg), formatstr, backupstr
@@ -1729,7 +1729,7 @@ int do_writeout(bool exiting)
 
 		/* We have a file now.  Get out of the statusbar prompt
 		 * cleanly. */
-		statusq_abort();
+		do_prompt_abort();
 	    } else
 #endif /* !DISABLE_BROWSER */
 #ifndef NANO_SMALL
@@ -1772,7 +1772,8 @@ int do_writeout(bool exiting)
 		struct stat st;
 
 		if (!stat(answer, &st)) {
-		    i = do_yesno(FALSE, _("File exists, OVERWRITE ? "));
+		    i = do_yesno_prompt(FALSE,
+			_("File exists, OVERWRITE ? "));
 		    if (i == 0 || i == -1)
 			continue;
 		/* If we're using restricted mode, we aren't allowed to
@@ -1786,7 +1787,7 @@ int do_writeout(bool exiting)
 			&& (exiting || !openfile->mark_set)
 #endif
 			) {
-		    i = do_yesno(FALSE,
+		    i = do_yesno_prompt(FALSE,
 			_("Save file under DIFFERENT NAME ? "));
 		    if (i == 0 || i == -1)
 			continue;
diff --git a/src/nano.c b/src/nano.c
index 80245d8b..d430b2ff 100644
--- a/src/nano.c
+++ b/src/nano.c
@@ -905,11 +905,12 @@ void do_exit(void)
     int i;
 
     if (!openfile->modified)
-	i = 0;		/* Pretend the user chose not to save. */
+	/* Pretend the user chose not to save. */
+	i = 0;
     else if (ISSET(TEMP_FILE))
 	i = 1;
     else
-	i = do_yesno(FALSE,
+	i = do_yesno_prompt(FALSE,
 		_("Save modified buffer (ANSWERING \"No\" WILL DESTROY CHANGES) ? "));
 
 #ifdef DEBUG
diff --git a/src/prompt.c b/src/prompt.c
index a293e4fb..c50c729e 100644
--- a/src/prompt.c
+++ b/src/prompt.c
@@ -253,12 +253,16 @@ bool do_statusbar_mouse(void)
 
 	    /* Move to where the click occurred. */
 	    if (mouse_x > start_col && mouse_y == 0) {
+		size_t pww_save = statusbar_pww;
+
 		statusbar_x = actual_x(answer,
 			get_statusbar_page_start(start_col, start_col +
 			statusbar_xplustabs()) + mouse_x - start_col -
 			1);
 		statusbar_pww = statusbar_xplustabs();
-		/*nanoget_repaint(answer, statusbar_x);*/
+
+		if (need_statusbar_horizontal_update(pww_save))
+		    update_statusbar_line(answer, statusbar_x);
 	    }
 	}
     }
@@ -328,11 +332,13 @@ void do_statusbar_output(char *output, size_t output_len, bool
 
     statusbar_pww = statusbar_xplustabs();
 
-    /*nanoget_repaint(answer, statusbar_x);*/
+    update_statusbar_line(answer, statusbar_x);
 }
 
 void do_statusbar_home(void)
 {
+    size_t pww_save = statusbar_pww;
+
 #ifndef NANO_SMALL
     if (ISSET(SMART_HOME)) {
 	size_t statusbar_x_save = statusbar_x;
@@ -352,34 +358,44 @@ void do_statusbar_home(void)
     }
 #endif
 
-    /*nanoget_repaint(answer, statusbar_x);*/
+    if (need_statusbar_horizontal_update(pww_save))
+	update_statusbar_line(answer, statusbar_x);
 }
 
 void do_statusbar_end(void)
 {
+    size_t pww_save = statusbar_pww;
+
     statusbar_x = strlen(answer);
     statusbar_pww = statusbar_xplustabs();
 
-    /*nanoget_repaint(answer, statusbar_x);*/
+    if (need_statusbar_horizontal_update(pww_save))
+	update_statusbar_line(answer, statusbar_x);
 }
 
 void do_statusbar_right(void)
 {
     if (statusbar_x < strlen(answer)) {
+	size_t pww_save = statusbar_pww;
+
 	statusbar_x = move_mbright(answer, statusbar_x);
 	statusbar_pww = statusbar_xplustabs();
 
-	/*nanoget_repaint(answer, statusbar_x);*/
+	if (need_statusbar_horizontal_update(pww_save))
+	    update_statusbar_line(answer, statusbar_x);
     }
 }
 
 void do_statusbar_left(void)
 {
     if (statusbar_x > 0) {
+	size_t pww_save = statusbar_pww;
+
 	statusbar_x = move_mbleft(answer, statusbar_x);
 	statusbar_pww = statusbar_xplustabs();
 
-	/*nanoget_repaint(answer, statusbar_x);*/
+	if (need_statusbar_horizontal_update(pww_save))
+	    update_statusbar_line(answer, statusbar_x);
     }
 }
 
@@ -407,6 +423,8 @@ void do_statusbar_delete(void)
 		char_buf_len + 1);
 
 	null_at(&answer, statusbar_x + line_len - char_buf_len);
+
+	update_statusbar_line(answer, statusbar_x);
     }
 }
 
@@ -427,7 +445,7 @@ void do_statusbar_cut_text(void)
     }
 #endif
 
-    /*nanoget_repaint(answer, statusbar_x);*/
+    update_statusbar_line(answer, statusbar_x);
 }
 
 #ifndef NANO_SMALL
@@ -436,6 +454,7 @@ void do_statusbar_cut_text(void)
  * on a word, and FALSE otherwise. */
 bool do_statusbar_next_word(bool allow_punct)
 {
+    size_t pww_save = statusbar_pww;
     char *char_mb;
     int char_mb_len;
     bool end_line = FALSE, started_on_word = FALSE;
@@ -488,7 +507,8 @@ bool do_statusbar_next_word(bool allow_punct)
 
     statusbar_pww = statusbar_xplustabs();
 
-    /*nanoget_repaint(answer, statusbar_x);*/
+    if (need_statusbar_horizontal_update(pww_save))
+	update_statusbar_line(answer, statusbar_x);
 
     /* Return whether we started on a word. */
     return started_on_word;
@@ -499,6 +519,7 @@ bool do_statusbar_next_word(bool allow_punct)
  * on a word, and FALSE otherwise. */
 bool do_statusbar_prev_word(bool allow_punct)
 {
+    size_t pww_save = statusbar_pww;
     char *char_mb;
     int char_mb_len;
     bool begin_line = FALSE, started_on_word = FALSE;
@@ -581,7 +602,8 @@ bool do_statusbar_prev_word(bool allow_punct)
 
     statusbar_pww = statusbar_xplustabs();
 
-    /*nanoget_repaint(answer, statusbar_x);*/
+    if (need_statusbar_horizontal_update(pww_save))
+	update_statusbar_line(answer, statusbar_x);
 
     /* Return whether we started on a word. */
     return started_on_word;
@@ -634,18 +656,20 @@ size_t get_statusbar_page_start(size_t start_col, size_t column)
 		start_col - 1);
 }
 
-/* Repaint the statusbar when getting a character in nanogetstr().  Note
- * that we must turn on A_REVERSE here, since do_help() turns it off! */
-void nanoget_repaint(const char *buf, size_t x)
+/* Repaint the statusbar when getting a character in
+ * get_prompt_string().  The statusbar text line will be displayed
+ * starting with curranswer[index].  Assume the A_REVERSE attribute is
+ * turned off. */
+void update_statusbar_line(const char *curranswer, size_t index)
 {
-    size_t start_col, xpt, page_start;
+    size_t start_col, page_start;
     char *expanded;
 
-    assert(prompt != NULL && x <= strlen(buf));
+    assert(prompt != NULL && index <= strlen(buf));
 
     start_col = strlenpt(prompt) + 1;
-    xpt = strnlenpt(buf, x);
-    page_start = get_statusbar_page_start(start_col, start_col + xpt);
+    index = strnlenpt(curranswer, index);
+    page_start = get_statusbar_page_start(start_col, start_col + index);
 
     wattron(bottomwin, A_REVERSE);
 
@@ -655,19 +679,40 @@ void nanoget_repaint(const char *buf, size_t x)
     waddch(bottomwin, ':');
     waddch(bottomwin, (page_start == 0) ? ' ' : '$');
 
-    expanded = display_string(buf, page_start, COLS - start_col - 1,
-	FALSE);
+    expanded = display_string(curranswer, page_start, COLS - start_col -
+	1, FALSE);
     waddstr(bottomwin, expanded);
     free(expanded);
 
-    wmove(bottomwin, 0, start_col + xpt + 1 - page_start);
+    reset_statusbar_cursor();
 
     wattroff(bottomwin, A_REVERSE);
 }
 
-/* Get the input from the keyboard.  This should only be called from
- * statusq(). */
-int nanogetstr(bool allow_tabs, const char *curranswer,
+/* Put the cursor in the statusbar prompt at statusbar_x. */
+void reset_statusbar_cursor(void)
+{
+    size_t start_col = strlenpt(prompt) + 1;
+    size_t page_start = get_statusbar_page_start(start_col,
+	start_col + statusbar_x);
+
+    wmove(bottomwin, 0, start_col + statusbar_x + 1 - page_start);
+}
+
+/* Return TRUE if we need an update after moving horizontally, and FALSE
+ * otherwise.  We need one if old_pww and statusbar_pww are on different
+ * pages. */
+bool need_statusbar_horizontal_update(size_t old_pww)
+{
+    size_t start_col = strlenpt(prompt) + 1;
+
+    return get_statusbar_page_start(start_col, start_col + old_pww) !=
+	get_statusbar_page_start(start_col, start_col + statusbar_pww);
+}
+
+/* Get a string of input at the statusbar prompt.  This should only be
+ * called from do_prompt(). */
+int get_prompt_string(bool allow_tabs, const char *curranswer,
 #ifndef NANO_SMALL
 	filestruct **history_list,
 #endif
@@ -715,7 +760,7 @@ int nanogetstr(bool allow_tabs, const char *curranswer,
 
     currshortcut = s;
 
-    nanoget_repaint(answer, statusbar_x);
+    update_statusbar_line(answer, statusbar_x);
 
     /* Refresh the edit window and the statusbar before getting
      * input. */
@@ -824,8 +869,7 @@ int nanogetstr(bool allow_tabs, const char *curranswer,
 	last_kbinput = kbinput;
 #endif
 
-	nanoget_repaint(answer, statusbar_x);
-	wnoutrefresh(bottomwin);
+	reset_statusbar_cursor();
     }
 
 #ifndef NANO_SMALL
@@ -850,15 +894,16 @@ int nanogetstr(bool allow_tabs, const char *curranswer,
     return kbinput;
 }
 
-/* Ask a question on the statusbar.  The prompt will be stored in
- * the static prompt, which should be NULL initially, and the answer
- * will be stored in the answer global.  Returns -1 on aborted enter, -2
- * on a blank string, and 0 otherwise, the valid shortcut key caught.
+/* Ask a question on the statusbar.  The prompt will be stored in the
+ * static prompt, which should be NULL initially, and the answer will be
+ * stored in the answer global.  Returns -1 on aborted enter, -2 on a
+ * blank string, and 0 otherwise, the valid shortcut key caught.
  * curranswer is any editable text that we want to put up by default.
  *
  * The allow_tabs parameter indicates whether we should allow tabs to be
  * interpreted. */
-int statusq(bool allow_tabs, const shortcut *s, const char *curranswer,
+int do_prompt(bool allow_tabs, const shortcut *s, const char
+	*curranswer,
 #ifndef NANO_SMALL
 	filestruct **history_list,
 #endif
@@ -884,7 +929,7 @@ int statusq(bool allow_tabs, const shortcut *s, const char *curranswer,
     va_end(ap);
     null_at(&prompt, actual_x(prompt, COLS - 4));
 
-    retval = nanogetstr(allow_tabs, curranswer,
+    retval = get_prompt_string(allow_tabs, curranswer,
 #ifndef NANO_SMALL
 		history_list,
 #endif
@@ -928,7 +973,10 @@ int statusq(bool allow_tabs, const shortcut *s, const char *curranswer,
     return retval;
 }
 
-void statusq_abort(void)
+/* This function forces a reset of the statusbar cursor position.  It
+ * should only be called after do_prompt(), and is only needed if the
+ * user leaves the prompt via something other than Enter or Cancel. */
+void do_prompt_abort(void)
 {
     reset_statusbar_x = TRUE;
 }
@@ -936,7 +984,7 @@ void statusq_abort(void)
 /* Ask a simple Yes/No (and optionally All) question, specified in msg,
  * on the statusbar.  Return 1 for Yes, 0 for No, 2 for All (if all is
  * TRUE when passed in), and -1 for Cancel. */
-int do_yesno(bool all, const char *msg)
+int do_yesno_prompt(bool all, const char *msg)
 {
     int ok = -2, width = 16;
     const char *yesstr;		/* String of Yes characters accepted. */
diff --git a/src/proto.h b/src/proto.h
index 2b2b20ab..7a4ff7db 100644
--- a/src/proto.h
+++ b/src/proto.h
@@ -440,8 +440,10 @@ bool do_statusbar_prev_word(bool allow_punct);
 void do_statusbar_verbatim_input(bool *got_enter);
 size_t statusbar_xplustabs(void);
 size_t get_statusbar_page_start(size_t start_col, size_t column);
-void nanoget_repaint(const char *buf, size_t x);
-int nanogetstr(bool allow_tabs, const char *curranswer,
+void update_statusbar_line(const char *curranswer, size_t index);
+void reset_statusbar_cursor(void);
+bool need_statusbar_horizontal_update(size_t old_pww);
+int get_prompt_string(bool allow_tabs, const char *curranswer,
 #ifndef NANO_SMALL
 	filestruct **history_list,
 #endif
@@ -450,13 +452,14 @@ int nanogetstr(bool allow_tabs, const char *curranswer,
 	, bool *list
 #endif
 	);
-int statusq(bool allow_tabs, const shortcut *s, const char *curranswer,
+int do_prompt(bool allow_tabs, const shortcut *s, const char
+	*curranswer,
 #ifndef NANO_SMALL
 	filestruct **history_list,
 #endif
 	const char *msg, ...);
-void statusq_abort(void);
-int do_yesno(bool all, const char *msg);
+void do_prompt_abort(void);
+int do_yesno_prompt(bool all, const char *msg);
 
 /* Public functions in rcfile.c. */
 #ifdef ENABLE_NANORC
diff --git a/src/search.c b/src/search.c
index a772b76a..aa77f741 100644
--- a/src/search.c
+++ b/src/search.c
@@ -161,7 +161,7 @@ int search_init(bool replacing, bool use_answer)
 	buf = mallocstrcpy(NULL, "");
 
     /* This is now one simple call.  It just does a lot. */
-    i = statusq(FALSE, replacing ? replace_list : whereis_list,
+    i = do_prompt(FALSE, replacing ? replace_list : whereis_list,
 	backupstring,
 #ifndef NANO_SMALL
 	&search_history,
@@ -734,7 +734,7 @@ ssize_t do_replace_loop(const char *needle, const filestruct
 
 	    do_replace_highlight(TRUE, exp_word);
 
-	    i = do_yesno(TRUE, _("Replace this instance?"));
+	    i = do_yesno_prompt(TRUE, _("Replace this instance?"));
 
 	    do_replace_highlight(FALSE, exp_word);
 
@@ -892,7 +892,7 @@ void do_replace(void)
 
     last_replace = mallocstrcpy(last_replace, "");
 
-    i = statusq(FALSE, replace_list_2, last_replace,
+    i = do_prompt(FALSE, replace_list_2, last_replace,
 #ifndef NANO_SMALL
 	&replace_history,
 #endif
@@ -953,7 +953,7 @@ void do_gotolinecolumn(ssize_t line, ssize_t column, bool use_answer,
 	char *ans = mallocstrcpy(NULL, answer);
 
 	/* Ask for it. */
-	int i = statusq(FALSE, gotoline_list, use_answer ? ans : "",
+	int i = do_prompt(FALSE, gotoline_list, use_answer ? ans : "",
 #ifndef NANO_SMALL
 		NULL,
 #endif
diff --git a/src/text.c b/src/text.c
index 41c61994..642ce1e1 100644
--- a/src/text.c
+++ b/src/text.c
@@ -1564,7 +1564,7 @@ bool do_int_spell_fix(const char *word)
 	    do_replace_highlight(TRUE, exp_word);
 
 	    /* Allow all instances of the word to be corrected. */
-	    canceled = (statusq(FALSE, spell_list, word,
+	    canceled = (do_prompt(FALSE, spell_list, word,
 #ifndef NANO_SMALL
 			NULL,
 #endif
-- 
GitLab