From 0dc26dcd0910cd12eaf038b4783e3c3d7979f1e3 Mon Sep 17 00:00:00 2001
From: Chris Allegretta <chrisa@asty.org>
Date: Sat, 24 Jan 2009 22:40:41 +0000
Subject: [PATCH] 2009-01-24 Chris Allegretta <chrisa@asty.org>         * Add
 interruptability to search functions.  New functions enable_nodelay and      
     disable_nodelay and changes to the routines to handle checking for
 pending           searches.  Fixes Savnnah bug 24946: Need interrrupt for
 search.

git-svn-id: svn://svn.savannah.gnu.org/nano/trunk/nano@4350 35c25a1d-7b9e-4130-9fde-d3aeb78583b8
---
 ChangeLog    |  7 ++++-
 src/global.c |  3 +++
 src/proto.h  |  5 +++-
 src/search.c | 16 ++++++++++++
 src/winio.c  | 73 ++++++++++++++++++++++++++++++++++++++++++----------
 5 files changed, 89 insertions(+), 15 deletions(-)

diff --git a/ChangeLog b/ChangeLog
index 9252d402..3af262b0 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,5 +1,10 @@
+2009-01-24 Chris Allegretta <chrisa@asty.org>
+	* Add interruptability to search functions.  New functions enable_nodelay and
+	  disable_nodelay and changes to the routines to handle checking for pending
+	  searches.  Fixes Savnnah bug 24946: Need interrrupt for search.
+
 2009-01-19 Chris Allegretta <chrisa@asty.org>
-	* Change funcion definitions to shorts instead of (void *)s.  New mapping function
+	* Change function definitions to shorts instead of (void *)s.  New mapping function
           iso_me_harder_funcmap().  Fixes compilation complaints with -pedantic, 
 	  reported by Eitan Adler <eitanadlerlist@gmail.com>.
 
diff --git a/src/global.c b/src/global.c
index fabd494e..95883b6d 100644
--- a/src/global.c
+++ b/src/global.c
@@ -115,6 +115,9 @@ size_t quotelen;
 #endif
 #endif
 
+bool nodelay_mode = FALSE;
+	/* Are we in nodelay mode (checking for a cancel wile doing something */
+
 char *answer = NULL;
 	/* The answer string used by the statusbar prompt. */
 
diff --git a/src/proto.h b/src/proto.h
index 5a8d611d..ec9b5f4b 100644
--- a/src/proto.h
+++ b/src/proto.h
@@ -76,7 +76,7 @@ extern char *quoteerr;
 extern size_t quotelen;
 #endif
 #endif
-
+bool nodelay_mode;
 extern char *answer;
 
 extern ssize_t tabsize;
@@ -776,6 +776,7 @@ void do_cursorpos_void(void);
 void do_replace_highlight(bool highlight, const char *word);
 char *flagtostr(int flag);
 const subnfunc *sctofunc(sc *s);
+const subnfunc *getfuncfromkey(WINDOW *win);
 void print_sclist(void);
 sc *strtosc(int menu, char *input);
 function_type strtokeytype(char *str);
@@ -815,6 +816,8 @@ const char *backup_file_msg;
 const char *gototext_msg;
 const char *new_buffer_msg;
 void iso_me_harder_funcmap(short func);
+void enable_nodelay(void);
+void disable_nodelay(void);
 
 #ifdef HAVE_REGEX_H
 const char *regexp_msg;
diff --git a/src/search.c b/src/search.c
index e00af02e..7aa87279 100644
--- a/src/search.c
+++ b/src/search.c
@@ -28,6 +28,7 @@
 #include <unistd.h>
 #include <ctype.h>
 #include <errno.h>
+#include <time.h>
 
 static bool search_last_line = FALSE;
 	/* Have we gone past the last line while searching? */
@@ -288,6 +289,8 @@ bool findnextstr(
     ssize_t current_y_find = openfile->current_y;
     filestruct *fileptr = openfile->current;
     const char *rev_start = fileptr->data, *found = NULL;
+    const subnfunc *f;
+    time_t lastkbcheck = time(NULL);
 
     /* rev_start might end up 1 character before the start or after the
      * end of the line.  This won't be a problem because strstrwrapper()
@@ -302,7 +305,17 @@ bool findnextstr(
 	openfile->current_x + 1;
 
     /* Look for needle in the current line we're searching. */
+    enable_nodelay();
     while (TRUE) {
+        if (time(NULL) - lastkbcheck > 1) {
+            lastkbcheck = time(NULL);
+	    f = getfuncfromkey(edit);
+            if (f && f->scfunc == CANCEL_MSG) {
+		statusbar(_("Cancelled"));
+		return FALSE;
+	    }
+	}
+
 	found = strstrwrapper(fileptr->data, needle, rev_start);
 
 	/* We've found a potential match. */
@@ -348,6 +361,7 @@ bool findnextstr(
 	/* We've finished processing the file, so get out. */
 	if (search_last_line) {
 	    not_found_msg(needle);
+            disable_nodelay();
 	    return FALSE;
 	}
 
@@ -405,9 +419,11 @@ bool findnextstr(
 #endif
 	) {
 	not_found_msg(needle);
+	disable_nodelay();
 	return FALSE;
     }
 
+    disable_nodelay();
     /* We've definitely found something. */
     openfile->current = fileptr;
     openfile->current_x = current_x_find;
diff --git a/src/winio.c b/src/winio.c
index 69a1f789..b14dbccd 100644
--- a/src/winio.c
+++ b/src/winio.c
@@ -1,4 +1,3 @@
-
 /* $Id$ */
 /**************************************************************************
  *   winio.c                                                              *
@@ -123,17 +122,21 @@ void get_key_buffer(WINDOW *win)
     doupdate();
 
     errcount = 0;
-    while ((input = wgetch(win)) == ERR) {
-	errcount++;
-
-	/* If we've failed to get a character MAX_BUF_SIZE times in a
-	 * row, assume that the input source we were using is gone and
-	 * die gracefully.  We could check if errno is set to EIO
-	 * ("Input/output error") and die gracefully in that case, but
-	 * it's not always set properly.  Argh. */
-	if (errcount == MAX_BUF_SIZE)
-	    handle_hupterm(0);
-    }
+    if (nodelay_mode) {
+	if ((input =  wgetch(win)) == ERR)
+           return;
+    } else
+	while ((input = wgetch(win)) == ERR) {
+	    errcount++;
+
+	    /* If we've failed to get a character MAX_BUF_SIZE times in a
+	     * row, assume that the input source we were using is gone and
+	     * die gracefully.  We could check if errno is set to EIO
+	     * ("Input/output error") and die gracefully in that case, but
+	     * it's not always set properly.  Argh. */
+	    if (errcount == MAX_BUF_SIZE)
+		handle_hupterm(0);
+	}
 
 #ifndef NANO_TINY
     allow_pending_sigwinch(FALSE);
@@ -331,7 +334,12 @@ int parse_kbinput(WINDOW *win, bool *meta_key, bool *func_key)
     *func_key = FALSE;
 
     /* Read in a character. */
-    while ((kbinput = get_input(win, 1)) == NULL);
+    if (nodelay_mode) {
+	kbinput = get_input(win, 1);
+	if (kbinput == 0)
+	    return 0;
+    } else
+	while ((kbinput = get_input(win, 1)) == NULL);
 
     switch (*kbinput) {
 	case ERR:
@@ -1790,6 +1798,32 @@ const sc *get_shortcut(int menu, int *kbinput, bool
     return NULL;
 }
 
+
+/* Try to get a function back from a window.  Just a wrapper so
+   functions to need to create function_key meta_key blah blah 
+    mmenu - what menu name to look through for valid funcs */
+const subnfunc *getfuncfromkey(WINDOW *win)
+{
+    int kbinput;
+    bool func_key = FALSE, meta_key = FALSE;
+    const sc *s;
+    const subnfunc *f;
+
+    kbinput = parse_kbinput(win, &meta_key, &func_key);
+    if (kbinput == 0)
+	return NULL;
+
+    s = get_shortcut(currmenu, &kbinput, &meta_key, &func_key);
+    if (!s)
+	return NULL;
+
+    f = sctofunc((sc *) s);
+    return f;
+
+}
+
+
+
 /* Move to (x, y) in win, and display a line of n spaces with the
  * current attributes. */
 void blank_line(WINDOW *win, int y, int x, int n)
@@ -3183,6 +3217,19 @@ void do_cursorpos_void(void)
     do_cursorpos(FALSE);
 }
 
+void enable_nodelay(void)
+{
+   nodelay_mode = TRUE;
+   nodelay(edit, TRUE);
+}
+
+void disable_nodelay(void)
+{
+   nodelay_mode = FALSE;
+   nodelay(edit, FALSE);
+}
+
+
 /* Highlight the current word being replaced or spell checked.  We
  * expect word to have tabs and control characters expanded. */
 void do_replace_highlight(bool highlight, const char *word)
-- 
GitLab