1
/* readline.c -- wrap some readline functions when available
2
Copyright (C) 1999 John Harper <john@dcs.warwick.ac.uk>
3
$Id: readline.c,v 1.13 2001/10/20 06:00:40 jsh Exp $
5
This file is part of librep.
7
librep is free software; you can redistribute it and/or modify it
8
under the terms of the GNU General Public License as published by
9
the Free Software Foundation; either version 2, or (at your option)
12
librep is distributed in the hope that it will be useful, but
13
WITHOUT ANY WARRANTY; without even the implied warranty of
14
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15
GNU General Public License for more details.
17
You should have received a copy of the GNU General Public License
18
along with librep; see the file COPYING. If not, write to
19
the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA. */
27
#ifdef HAVE_LIBREADLINE
28
# include <readline/readline.h>
29
# include <readline/history.h>
32
DEFSYM(rl_completion_generator, "rl-completion-generator");
33
DEFSYM(boundp, "boundp");
35
static repv completion_fun;
36
static repv completions;
38
#ifdef HAVE_LIBREADLINE
40
completion_generator (char *word, int state)
44
repv fun = completion_fun;
46
/* backwards compatibility, ugh */
47
fun = Fsymbol_value (Qrl_completion_generator, Qt);
48
if (Ffunctionp (fun) != Qnil)
50
completions = (rep_call_with_barrier
51
(Ffuncall, rep_list_2 (fun, rep_string_dup (word)),
56
repv re = Fquote_regexp (rep_string_dup (word));
57
repv boundp = Fsymbol_value (Qboundp, Qt);
58
completions = Fapropos (rep_concat2("^", rep_STR(re)),
61
if (completions == rep_NULL)
65
if (completions != Qnil && rep_CONSP(completions)
66
&& (rep_SYMBOLP(rep_CAR(completions))
67
|| rep_STRINGP(rep_CAR(completions))))
69
repv string = rep_CAR(completions);
70
if (rep_SYMBOLP(string))
71
string = rep_SYM(string)->name;
72
completions = rep_CDR(completions);
73
return strdup (rep_STR(string));
79
/* gratuitously stolen from guile, guile-readline/readline.c */
80
static int match_paren(int x, int k);
81
static int find_matching_paren(int k);
82
static void init_bouncing_parens();
85
init_bouncing_parens()
87
if(strncmp(rl_get_keymap_name(rl_get_keymap()), "vi", 2)) {
88
rl_bind_key(')', match_paren);
89
rl_bind_key(']', match_paren);
90
rl_bind_key('}', match_paren);
95
find_matching_paren(int k)
99
int end_parens_found = 0;
101
/* Choose the corresponding opening bracket. */
102
if (k == ')') c = '(';
103
else if (k == ']') c = '[';
104
else if (k == '}') c = '{';
106
for (i=rl_point-2; i>=0; i--)
108
/* Is the current character part of a character literal? */
110
&& rl_line_buffer[i - 1] == '\\'
111
&& rl_line_buffer[i - 2] == '#')
113
else if (rl_line_buffer[i] == k)
115
else if (rl_line_buffer[i] == '"')
117
/* Skip over a string literal. */
118
for (i--; i >= 0; i--)
119
if (rl_line_buffer[i] == '"'
121
&& rl_line_buffer[i - 1] == '\\'))
124
else if (rl_line_buffer[i] == c)
126
if (end_parens_found==0) return i;
127
else --end_parens_found;
134
match_paren(int x, int k)
138
struct timeval timeout;
142
/* Did we just insert a quoted paren? If so, then don't bounce. */
143
if (rl_point - 1 >= 1
144
&& rl_line_buffer[rl_point - 2] == '\\')
148
timeout.tv_sec = 0 /* tmp / 1000000 */ ;
149
timeout.tv_usec = 200000 /* tmp % 1000000 */ ;
151
FD_SET(fileno(rl_instream), &readset);
155
rl_point = find_matching_paren(k);
158
select(1, &readset, NULL, NULL, &timeout);
168
DEFUN("readline", Freadline, Sreadline,
169
(repv prompt_, repv completer), rep_Subr2)
171
char *prompt = rep_STRINGP(prompt_) ? ((char *) rep_STR(prompt_)) : "> ";
172
#ifdef HAVE_LIBREADLINE
174
repv ret = Qnil, saved;
175
rep_GC_root gc_saved;
177
saved = completion_fun;
178
completion_fun = completer;
179
rep_PUSHGC (gc_saved, saved);
180
input = readline (prompt);
182
completion_fun = saved;
186
int len = strlen (input);
189
ret = rep_make_string (len + 2);
190
memcpy (rep_STR(ret), input, len);
191
rep_STR(ret)[len] = '\n';
192
rep_STR(ret)[len+1] = 0;
200
fputs (prompt, stderr);
203
return Fread_line (Fstdin_file ());
215
rep_INTERN(rl_completion_generator);
218
completion_fun = Qnil;
219
rep_mark_static (&completions);
220
rep_mark_static (&completion_fun);
222
#ifdef HAVE_LIBREADLINE
223
rl_completion_entry_function = (void *) completion_generator;
224
rl_basic_quote_characters = "\"";
225
init_bouncing_parens();
227
tem = rep_push_structure ("rep.io.readline");
228
/* ::alias:readline rep.io.readline:: */
229
rep_alias_structure ("readline");
230
rep_ADD_SUBR(Sreadline);
231
return rep_pop_structure (tem);