texinfo-commits
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

[5728] option to highlight search results


From: Gavin D. Smith
Subject: [5728] option to highlight search results
Date: Sun, 03 Aug 2014 12:50:29 +0000

Revision: 5728
          http://svn.sv.gnu.org/viewvc/?view=rev&root=texinfo&revision=5728
Author:   gavin
Date:     2014-08-03 12:50:28 +0000 (Sun, 03 Aug 2014)
Log Message:
-----------
option to highlight search results

Modified Paths:
--------------
    trunk/ChangeLog
    trunk/info/display.c
    trunk/info/info-utils.c
    trunk/info/nodes.h
    trunk/info/search.c
    trunk/info/search.h
    trunk/info/session.c
    trunk/info/terminal.c
    trunk/info/terminal.h
    trunk/info/variables.c
    trunk/info/variables.h
    trunk/info/window.h

Modified: trunk/ChangeLog
===================================================================
--- trunk/ChangeLog     2014-07-28 19:39:37 UTC (rev 5727)
+++ trunk/ChangeLog     2014-08-03 12:50:28 UTC (rev 5728)
@@ -1,3 +1,26 @@
+2014-08-03  Gavin Smith  <address@hidden>
+
+       * info/search.c (regexp_search): Take WINDOW argument to save results
+       of a search.  All callers updated.
+       * info/window.h (WINDOW): New fields 'matches', 'match_count'.
+       * info/session.c (info_search_in_node_internal): Use of regexp_search
+       updated.
+
+       * info/variables.c (info_variables): New user variable
+       'highlight-searches'.
+       * info/display.c (highlight_searches_p): New variable.
+       (display_update_window_1): New function, based on
+       process_node_text in window.c.  Highlight search results if this is
+       turned on.  Use struct text_buffer functions to build printed screen
+       line.
+       (display_update_one_window): Call display_update_window_1 instead of
+       process_node_text.
+       * info/terminal.c (term_so, term_se): New variables.
+       (terminal_initialize_terminal): Initialize them.
+
+       * info/session.c (info_set_node_of_window): Clear displayed
+       search matches.
+
 2014-07-28  Gavin Smith  <address@hidden>
 
        * info/nodes.c (info_get_node_of_file_buffer): Set body_start to 0

Modified: trunk/info/display.c
===================================================================
--- trunk/info/display.c        2014-07-28 19:39:37 UTC (rev 5727)
+++ trunk/info/display.c        2014-08-03 12:50:28 UTC (rev 5728)
@@ -114,11 +114,10 @@
   return i;
 }
 
-/* Called by process_node_text. */
+/* Update a single line of the screen. */
 int
-display_node_text (WINDOW *win, size_t pl_num, size_t ll_num,
-                   size_t pl_start, char *printed_line,
-                   size_t pl_bytes, size_t pl_chars)
+display_node_text (WINDOW *win, long pl_num, char *printed_line,
+                   long pl_bytes, long pl_chars)
 {
   DISPLAY_LINE **display = the_display;
   DISPLAY_LINE *entry;
@@ -209,6 +208,152 @@
   return 0;
 }
 
+
+int highlight_searches_p = 0;
+
+/* Print each line in the window into our local buffer, and then
+   check the contents of that buffer against the display.  If they
+   differ, update the display.
+   Return value: number of lines processed.  */
+long
+display_update_window_1 (WINDOW *win, long pagetop)
+{
+  char *start = win->node->contents + win->line_starts[win->pagetop];
+
+  struct text_buffer tb_printed_line;     /* Buffer for a printed line. */
+  long pl_chars = 0;     /* Number of characters written to printed_line */
+  long pl_bytes = 0;     /* Number of bytes written to printed_line */
+  long pl_num = 0;       /* Number of physical lines done so far. */
+  mbi_iterator_t iter;
+
+  regmatch_t *matches = 0;
+  size_t match_index = 0;
+  int in_match = 0; /* If we have highlighting on for a match. */
+
+  if (highlight_searches_p)
+    matches = win->matches;
+
+  /* Find first search match after the start of the page, and check whether
+     we start inside a match. */
+  if (matches)
+    {
+      for (match_index = 0; match_index < win->match_count; match_index++)
+        {
+          if (matches[match_index].rm_so > win->line_starts[win->pagetop])
+            {
+              in_match = 0;
+              break;
+            }
+
+          if (matches[match_index].rm_eo > win->line_starts[win->pagetop])
+            {
+              in_match = 1;
+              break;
+            }
+        }
+    }
+
+  text_buffer_init (&tb_printed_line);
+
+  if (in_match)
+    text_buffer_add_string (&tb_printed_line, term_so, strlen(term_so));
+
+  for (mbi_init (iter, start, 
+                 win->node->contents + win->node->nodelen - start);
+       mbi_avail (iter);
+       mbi_advance (iter))
+    {
+      const char *cur_ptr;
+      char *rep;
+
+      size_t pchars = 0; /* Printed chars */
+      size_t pbytes = 0; /* Bytes to output. */
+      int delim = 0;
+      int finish;
+
+      rep = printed_representation (&iter, &delim, pl_chars, &pchars, &pbytes);
+
+      cur_ptr = mbi_cur_ptr (iter);
+
+      if (delim || pl_chars + pchars >= win->width)
+        {
+          /* If this character cannot be printed in this line, we have
+             found the end of this line as it would appear on the screen. */
+
+          if (!delim)
+            {
+              if (!(win->flags & W_NoWrap))
+                text_buffer_add_char (&tb_printed_line, '\\');
+              else
+                {
+                  text_buffer_add_char (&tb_printed_line, '$');
+                  /* If this window has chosen not to wrap lines, skip to the
+                     end of the logical line in the buffer, and start a new
+                     line here. */
+                  for (; mbi_avail (iter); mbi_advance (iter))
+                    if (mb_len (mbi_cur (iter)) == 1
+                        && *mbi_cur_ptr (iter) == '\n')
+                      break;
+                }
+            }
+
+          text_buffer_add_char (&tb_printed_line, '\0');
+
+          finish = display_node_text (win, pl_num,
+                      text_buffer_base (&tb_printed_line), pl_bytes, pl_chars);
+
+          ++pl_num;
+
+          pl_bytes = 0;
+          pl_chars = 0;
+          text_buffer_reset (&tb_printed_line);
+
+          if (finish)
+            break;
+        }
+
+      if (matches && match_index != win->match_count)
+        {
+          if (!in_match && cur_ptr >= win->node->contents
+                             + matches[match_index].rm_so)
+            {
+              text_buffer_add_string (&tb_printed_line, term_so, 
strlen(term_so));
+              in_match = 1;
+            } 
+          else if (in_match && cur_ptr >= win->node->contents
+                             + matches[match_index].rm_eo)
+            {
+              text_buffer_add_string (&tb_printed_line, term_se, 
strlen(term_se));
+              in_match = 0;
+              match_index++;
+            } 
+        }
+
+      if (*cur_ptr != '\n') 
+        {
+          int i;
+          
+          text_buffer_add_string (&tb_printed_line, rep, pbytes);
+          pl_chars += pchars;
+          continue;
+        }
+    }
+
+  /* This would be the very last line of the node. */
+  if (pl_chars)
+    {
+      text_buffer_add_char (&tb_printed_line, '\0');
+      display_node_text (win, pl_num,
+                         text_buffer_base (&tb_printed_line),
+                         pl_bytes, pl_chars);
+      pl_num++;
+    }
+
+  text_buffer_free (&tb_printed_line);
+  return pl_num;
+}
+
+/* Update one window on the screen. */
 void
 display_update_one_window (WINDOW *win)
 {
@@ -241,10 +386,8 @@
 
   if (win->node && win->line_starts)
     {
-      line_index = process_node_text (win,
-                                     win->node->contents
-                                        + win->line_starts[win->pagetop],
-                                     display_node_text);
+      line_index = display_update_window_1 (win, win->pagetop);
+
       if (display_was_interrupted_p)
        goto funexit;
     }

Modified: trunk/info/info-utils.c
===================================================================
--- trunk/info/info-utils.c     2014-07-28 19:39:37 UTC (rev 5727)
+++ trunk/info/info-utils.c     2014-08-03 12:50:28 UTC (rev 5728)
@@ -1606,7 +1606,7 @@
   s.flags = S_FoldCase;
 
 search_again:
-  while (regexp_search (search_string, &s, &position, 0) == search_success)
+  while (regexp_search (search_string, &s, &position, 0, 0) == search_success)
     {
       int in_parentheses = 0;
       REFERENCE *entry;

Modified: trunk/info/nodes.h
===================================================================
--- trunk/info/nodes.h  2014-07-28 19:39:37 UTC (rev 5727)
+++ trunk/info/nodes.h  2014-08-03 12:50:28 UTC (rev 5728)
@@ -23,7 +23,6 @@
 #define NODES_H
 
 #include "info.h"
-#include "search.h"
 
 /* Structure which describes a node reference, such as a menu entry or
    cross reference. */

Modified: trunk/info/search.c
===================================================================
--- trunk/info/search.c 2014-07-28 19:39:37 UTC (rev 5727)
+++ trunk/info/search.c 2014-08-03 12:50:28 UTC (rev 5728)
@@ -90,11 +90,13 @@
 
    If PEND is specified, it receives a copy of BINDING at the end of a
    succeded search.  Its START and END fields contain bounds of the found
-   string instance. 
+   string instance.
+
+   If WINDOW is specified, pass back the list of matches in WINDOW->matches.
 */
 enum search_result
 regexp_search (char *regexp, SEARCH_BINDING *binding, 
-              long *poff, SEARCH_BINDING *pend)
+              long *poff, SEARCH_BINDING *pend, WINDOW *window)
 {
   static regex_t preg; /* Compiled pattern buffer for regexp. */
 
@@ -239,6 +241,13 @@
       previous_content[end] = saved_char;
     }
 
+  /* Pass back the full list of results. */
+  if (window)
+    {
+      window->matches = matches;
+      window->match_count = match_count;
+    }
+
   if (binding->start > binding->end)
     {
       /* searching backward */

Modified: trunk/info/search.h
===================================================================
--- trunk/info/search.h 2014-07-28 19:39:37 UTC (rev 5727)
+++ trunk/info/search.h 2014-08-03 12:50:28 UTC (rev 5728)
@@ -32,6 +32,8 @@
 #ifndef INFO_SEARCH_H
 #define INFO_SEARCH_H
 
+#include "window.h"
+
 typedef struct {
   char *buffer;                 /* The buffer of text to search. */
   long start;                   /* Offset of the start of the search. */
@@ -61,7 +63,7 @@
 extern enum search_result regexp_search (char *regexp,
                                         SEARCH_BINDING *binding,
                                         long *poff,
-                                        SEARCH_BINDING *pret);
+                                        SEARCH_BINDING *pret, WINDOW *window);
 extern int looking_at (char *string, SEARCH_BINDING *binding);
 
 /* Note that STRING_IN_LINE () always returns the offset of the 1st character

Modified: trunk/info/session.c
===================================================================
--- trunk/info/session.c        2014-07-28 19:39:37 UTC (rev 5727)
+++ trunk/info/session.c        2014-08-03 12:50:28 UTC (rev 5728)
@@ -802,6 +802,10 @@
       win->hist[win->hist_index - 1]->point = win->point;
     }
 
+  /* Clear displayed search matches if any.  TODO: do search again in new
+     node? */
+  win->matches = 0;
+
   /* Put this node into the window. */
   window_set_node_of_window (win, node);
 
@@ -3483,10 +3487,10 @@
          binding.end = strlen (node->nodename);
          
          result = (match_regexp ? 
-                   regexp_search (string, &binding, poff, resbnd):
+                   regexp_search (string, &binding, poff, resbnd, window):
                    search (string, &binding, poff));
          if (result == search_success)
-           *poff += start_off;
+            *poff += start_off;
        }
     }
 
@@ -3508,14 +3512,20 @@
        binding.start = node->body_start;
       
       result = (match_regexp ? 
-               regexp_search (string, &binding, poff, resbnd):
+               regexp_search (string, &binding, poff, resbnd, window):
                search (string, &binding, poff));
     }
   
   if (result == search_success && window)
     {
+      window->flags |= W_UpdateWindow;
       if (window->node != node)
-        info_set_node_of_window (window, node);
+        {
+          regmatch_t *saved_matches = window->matches;
+          info_set_node_of_window (window, node);
+          window->matches = saved_matches;
+        }
+
       window->point = *poff;
       window_adjust_pagetop (window);
     }

Modified: trunk/info/terminal.c
===================================================================
--- trunk/info/terminal.c       2014-07-28 19:39:37 UTC (rev 5727)
+++ trunk/info/terminal.c       2014-08-03 12:50:28 UTC (rev 5728)
@@ -113,6 +113,9 @@
 /* String introducing a mouse event. */
 static char *term_Km;
 
+/* Strings entering and leaving standout mode. */
+char *term_so, *term_se;
+
 /* Although I can't find any documentation that says this is supposed to
    return its argument, all the code I've looked at (termutils, less)
    does so, so fine.  */
@@ -701,6 +704,12 @@
   else
     term_invend = NULL;
 
+  term_so = tgetstr ("so", &buffer);
+  if (term_so)
+    term_se = tgetstr ("se", &buffer);
+  else
+    term_se = NULL;
+
   if (!term_cr)
     term_cr =  "\r";
 

Modified: trunk/info/terminal.h
===================================================================
--- trunk/info/terminal.h       2014-07-28 19:39:37 UTC (rev 5727)
+++ trunk/info/terminal.h       2014-08-03 12:50:28 UTC (rev 5728)
@@ -126,4 +126,6 @@
 extern char *term_kD, *term_ki;
 extern char *term_bt;
 
+extern char *term_so, *term_se;
+
 #endif /* !TERMINAL_H */

Modified: trunk/info/variables.c
===================================================================
--- trunk/info/variables.c      2014-07-28 19:39:37 UTC (rev 5727)
+++ trunk/info/variables.c      2014-08-03 12:50:28 UTC (rev 5728)
@@ -104,6 +104,10 @@
       N_("Length of time in milliseconds to wait for the next byte in a 
sequence indicating that a key has been pressed"),
     &key_time, NULL },
 
+  { "highlight-searches",
+      N_("Highlight search matches"),
+    &highlight_searches_p, (char **)on_off_choices },
+
   { NULL }
 };
 

Modified: trunk/info/variables.h
===================================================================
--- trunk/info/variables.h      2014-07-28 19:39:37 UTC (rev 5727)
+++ trunk/info/variables.h      2014-08-03 12:50:28 UTC (rev 5728)
@@ -77,5 +77,6 @@
 extern int infopath_no_defaults_p;
 extern int preprocess_nodes_p;
 extern int key_time;
+extern int highlight_searches_p;
 
 #endif /* not INFO_VARIABLES_H */

Modified: trunk/info/window.h
===================================================================
--- trunk/info/window.h 2014-07-28 19:39:37 UTC (rev 5727)
+++ trunk/info/window.h 2014-08-03 12:50:28 UTC (rev 5728)
@@ -24,6 +24,7 @@
 
 #include "infomap.h"
 #include "nodes.h"
+#include <regex.h>
 
 /* Smallest number of visible lines in a window.  The actual height is
    always one more than this number because each window has a modeline. */
@@ -87,6 +88,10 @@
 
   int flags;            /* See below for details. */
 
+  /* Used for highlighting search matches. */
+  regmatch_t *matches;
+  size_t match_count;
+
   /* History of nodes visited in this window. */
   WINDOW_STATE **hist;       /* Nodes visited in this window. */
   size_t hist_index;            /* Index where to add the next node. */




reply via email to

[Prev in Thread] Current Thread [Next in Thread]