1% Public functions:
2%  rline_up_hist_search
3%  rline_down_hist_search
4%
5% These functions search up/down the history list displaying history
6% lines that match the starting line.  The idea behind this was inspired
7% by the zsh up/down-line-or-search functions.
8%
9
10define rline_up_hist_search();
11define rline_down_hist_search ();
12private variable History_Search = struct
13{
14   history,
15   prefix,
16   current_index,
17   point,
18};
19
20private define get_unique_history (prefix)
21{
22   variable h = rline_get_history ();
23
24   if (prefix == "")
25     return [h, prefix];
26
27   variable i = strncmp (h, prefix, strlen(prefix));
28   h = h[wherenot(i)];
29
30   variable new_h = String_Type[0];
31
32   %  build the list using most recent history first
33   array_reverse (h);
34   foreach (h)
35     {
36	variable name = ();
37	if (any (name == new_h))
38	  continue;
39	new_h = [new_h, name];
40     }
41   array_reverse (new_h);
42   return [new_h, prefix];
43}
44
45private define get_history_search (dir)
46{
47   variable func = rline_get_last_key_function();
48
49   if ((History_Search.history == NULL)
50       || (typeof (func) != Ref_Type)
51       || ((func != &rline_up_hist_search) && (func != &rline_down_hist_search)))
52     {
53	variable point = rline_get_point ();
54	History_Search.point = point;
55	variable prefix = rline_get_line()[[0:point-1]];
56	History_Search.history = get_unique_history (prefix);
57	History_Search.current_index = 0;
58	if (dir < 0)
59	  History_Search.current_index = length(History_Search.history)-1;
60	History_Search.prefix = prefix;
61     }
62   return History_Search;
63}
64
65private define up_down_hist_search (dir)
66{
67   variable h = get_history_search (dir);
68   variable num = length (h.history);
69   if (num == 0)
70     return;
71
72   variable index = h.current_index + dir;
73
74   ifnot (0 <= index < num)
75     return;
76
77   rline_delete_line ();
78   rline_ins (h.history[index]);
79   h.current_index = index;
80}
81
82define rline_up_hist_search ()
83{
84   up_down_hist_search (-1);
85}
86
87define rline_down_hist_search ()
88{
89   up_down_hist_search (1);
90}
91