1cae5999f412753c4b861edf69b544cc5f60c5c8
[dragonfly.git] / lib / libedit / hist.c
1 /*-
2  * Copyright (c) 1992, 1993
3  *      The Regents of the University of California.  All rights reserved.
4  *
5  * This code is derived from software contributed to Berkeley by
6  * Christos Zoulas of Cornell University.
7  *
8  * Redistribution and use in source and binary forms, with or without
9  * modification, are permitted provided that the following conditions
10  * are met:
11  * 1. Redistributions of source code must retain the above copyright
12  *    notice, this list of conditions and the following disclaimer.
13  * 2. Redistributions in binary form must reproduce the above copyright
14  *    notice, this list of conditions and the following disclaimer in the
15  *    documentation and/or other materials provided with the distribution.
16  * 3. All advertising materials mentioning features or use of this software
17  *    must display the following acknowledgement:
18  *      This product includes software developed by the University of
19  *      California, Berkeley and its contributors.
20  * 4. Neither the name of the University nor the names of its contributors
21  *    may be used to endorse or promote products derived from this software
22  *    without specific prior written permission.
23  *
24  * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
25  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
26  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
27  * ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
28  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
29  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
30  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
31  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
32  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
33  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
34  * SUCH DAMAGE.
35  *
36  * @(#)hist.c   8.1 (Berkeley) 6/4/93
37  */
38
39 /*
40  * hist.c: History access functions
41  */
42 #include "sys.h"
43 #include <stdlib.h>
44 #include "el.h"
45
46 /* hist_init():
47  *      Initialization function.
48  */
49 protected int
50 hist_init(el)
51     EditLine *el;
52 {
53     el->el_history.fun  = NULL;
54     el->el_history.ref  = NULL;
55     el->el_history.buf   = (char *) el_malloc(EL_BUFSIZ);
56     el->el_history.last  = el->el_history.buf;
57     return 0;
58 }
59
60
61 /* hist_end():
62  *      clean up history;
63  */
64 protected void
65 hist_end(el)
66     EditLine *el;
67 {
68     el_free((ptr_t) el->el_history.buf);
69     el->el_history.buf   = NULL;
70 }
71
72
73 /* hist_set():
74  *      Set new history interface
75  */
76 protected int
77 hist_set(el, fun, ptr)
78     EditLine *el;
79     hist_fun_t fun;
80     ptr_t ptr;
81
82 {
83     el->el_history.ref = ptr;
84     el->el_history.fun = fun;
85     return 0;
86 }
87
88
89 /* hist_get():
90  *      Get a history line and update it in the buffer.
91  *      eventno tells us the event to get.
92  */
93 protected el_action_t
94 hist_get(el)
95     EditLine *el;
96 {
97     const char    *hp;
98     int     h;
99
100     if (el->el_history.eventno == 0) {  /* if really the current line */
101         (void) strncpy(el->el_line.buffer, el->el_history.buf, EL_BUFSIZ);
102         el->el_line.lastchar = el->el_line.buffer +
103                 (el->el_history.last - el->el_history.buf);
104
105 #ifdef KSHVI
106     if (el->el_map.type == MAP_VI)
107         el->el_line.cursor = el->el_line.buffer;
108     else
109 #endif /* KSHVI */
110         el->el_line.cursor = el->el_line.lastchar;
111
112         return CC_REFRESH;
113     }
114
115     if (el->el_history.ref == NULL)
116         return CC_ERROR;
117
118     hp = HIST_FIRST(el);
119
120     if (hp == NULL)
121         return CC_ERROR;
122
123     for (h = 1; h < el->el_history.eventno; h++)
124         if ((hp = HIST_NEXT(el)) == NULL) {
125             el->el_history.eventno = h;
126             return CC_ERROR;
127         }
128
129     (void) strncpy(el->el_line.buffer, hp, EL_BUFSIZ);
130     el->el_line.lastchar = el->el_line.buffer + strlen(el->el_line.buffer);
131
132     if (el->el_line.lastchar > el->el_line.buffer) {
133         if (el->el_line.lastchar[-1] == '\n')
134             el->el_line.lastchar--;
135         if (el->el_line.lastchar[-1] == ' ')
136             el->el_line.lastchar--;
137         if (el->el_line.lastchar < el->el_line.buffer)
138             el->el_line.lastchar = el->el_line.buffer;
139     }
140
141 #ifdef KSHVI
142     if (el->el_map.type == MAP_VI)
143         el->el_line.cursor = el->el_line.buffer;
144     else
145 #endif /* KSHVI */
146         el->el_line.cursor = el->el_line.lastchar;
147
148     return CC_REFRESH;
149 }
150
151 /* hist_list()
152  *      List history entries
153  */
154 protected int
155 /*ARGSUSED*/
156 hist_list(el, argc, argv)
157     EditLine *el;
158     int argc;
159     char **argv;
160 {
161     const char *str;
162
163     if (el->el_history.ref == NULL)
164         return -1;
165     for (str = HIST_LAST(el); str != NULL; str = HIST_PREV(el))
166         (void) fprintf(el->el_outfile, "%d %s", el->el_history.ev->num, str);
167     return 0;
168 }