rubysl-readline 0.0.1 → 1.0.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +7 -0
- data/.gitignore +0 -1
- data/.travis.yml +8 -0
- data/README.md +2 -2
- data/Rakefile +0 -1
- data/ext/rubysl/readline/extconf.rb +64 -0
- data/ext/rubysl/readline/readline.c +537 -0
- data/lib/readline.rb +1 -0
- data/lib/rubysl/readline.rb +2 -0
- data/lib/{rubysl-readline → rubysl/readline}/version.rb +1 -1
- data/rubysl-readline.gemspec +20 -18
- data/spec/basic_quote_characters_spec.rb +18 -0
- data/spec/basic_word_break_characters_spec.rb +18 -0
- data/spec/completer_quote_characters_spec.rb +18 -0
- data/spec/completer_word_break_characters_spec.rb +18 -0
- data/spec/completion_append_character_spec.rb +18 -0
- data/spec/completion_case_fold_spec.rb +20 -0
- data/spec/completion_proc_spec.rb +24 -0
- data/spec/constants_spec.rb +20 -0
- data/spec/emacs_editing_mode_spec.rb +11 -0
- data/spec/filename_quote_characters_spec.rb +18 -0
- data/spec/history/append_spec.rb +30 -0
- data/spec/history/delete_at_spec.rb +47 -0
- data/spec/history/each_spec.rb +31 -0
- data/spec/history/element_reference_spec.rb +42 -0
- data/spec/history/element_set_spec.rb +37 -0
- data/spec/history/empty_spec.rb +15 -0
- data/spec/history/history_spec.rb +11 -0
- data/spec/history/length_spec.rb +10 -0
- data/spec/history/pop_spec.rb +32 -0
- data/spec/history/push_spec.rb +28 -0
- data/spec/history/shared/size.rb +14 -0
- data/spec/history/shift_spec.rb +32 -0
- data/spec/history/size_spec.rb +10 -0
- data/spec/history/to_s_spec.rb +11 -0
- data/spec/readline_spec.rb +32 -0
- data/spec/vi_editing_mode_spec.rb +11 -0
- metadata +135 -87
- data/lib/rubysl-readline.rb +0 -7
checksums.yaml
ADDED
@@ -0,0 +1,7 @@
|
|
1
|
+
---
|
2
|
+
SHA1:
|
3
|
+
metadata.gz: 926cb4be63fac4d727b0dcc528219483beb8962f
|
4
|
+
data.tar.gz: 697e6f288c806657af0eff194296d181af74ee75
|
5
|
+
SHA512:
|
6
|
+
metadata.gz: df8bd90663d5ba8362be5aecfe5a3b03b50282f08e6a29b78c10f9fb623adf21370e27bff31cd04a491148a441086c68a37ea071ac3b6a4e40a6db6172a375bb
|
7
|
+
data.tar.gz: 551083b1dbdc4e52c6530353ffcbbc3b0749c870174f22ca223b0679f66ad29e9847ba8ce40abccf3c2bf18ed96165f8cb3ee70cb9a1229478965a0fd1c5bfc5
|
data/.gitignore
CHANGED
data/.travis.yml
ADDED
data/README.md
CHANGED
@@ -1,4 +1,4 @@
|
|
1
|
-
#
|
1
|
+
# Rubysl::Readline
|
2
2
|
|
3
3
|
TODO: Write a gem description
|
4
4
|
|
@@ -24,6 +24,6 @@ TODO: Write usage instructions here
|
|
24
24
|
|
25
25
|
1. Fork it
|
26
26
|
2. Create your feature branch (`git checkout -b my-new-feature`)
|
27
|
-
3. Commit your changes (`git commit -am '
|
27
|
+
3. Commit your changes (`git commit -am 'Add some feature'`)
|
28
28
|
4. Push to the branch (`git push origin my-new-feature`)
|
29
29
|
5. Create new Pull Request
|
data/Rakefile
CHANGED
@@ -0,0 +1,64 @@
|
|
1
|
+
require "mkmf"
|
2
|
+
|
3
|
+
$readline_headers = ["stdio.h"]
|
4
|
+
|
5
|
+
def have_readline_header(header)
|
6
|
+
if have_header(header)
|
7
|
+
$readline_headers.push(header)
|
8
|
+
return true
|
9
|
+
else
|
10
|
+
return false
|
11
|
+
end
|
12
|
+
end
|
13
|
+
|
14
|
+
def have_readline_var(var)
|
15
|
+
return have_var(var, $readline_headers)
|
16
|
+
end
|
17
|
+
|
18
|
+
dir_config('curses')
|
19
|
+
dir_config('ncurses')
|
20
|
+
dir_config('termcap')
|
21
|
+
dir_config("readline")
|
22
|
+
enable_libedit = enable_config("libedit")
|
23
|
+
have_library("user32", nil) if /cygwin/ === RUBY_PLATFORM
|
24
|
+
have_library("ncurses", "tgetnum") ||
|
25
|
+
have_library("termcap", "tgetnum") ||
|
26
|
+
have_library("curses", "tgetnum")
|
27
|
+
|
28
|
+
if enable_libedit
|
29
|
+
unless (have_readline_header("editline/readline.h") ||
|
30
|
+
have_readline_header("readline/readline.h")) &&
|
31
|
+
have_library("edit", "readline")
|
32
|
+
exit
|
33
|
+
end
|
34
|
+
else
|
35
|
+
unless ((have_readline_header("readline/readline.h") &&
|
36
|
+
have_readline_header("readline/history.h")) &&
|
37
|
+
(have_library("readline", "readline") ||
|
38
|
+
have_library("edit", "readline"))) ||
|
39
|
+
(have_readline_header("editline/readline.h") &&
|
40
|
+
have_library("edit", "readline"))
|
41
|
+
exit
|
42
|
+
end
|
43
|
+
end
|
44
|
+
|
45
|
+
have_func("rl_filename_completion_function")
|
46
|
+
have_func("rl_username_completion_function")
|
47
|
+
have_func("rl_completion_matches")
|
48
|
+
have_readline_var("rl_deprep_term_function")
|
49
|
+
have_readline_var("rl_completion_append_character")
|
50
|
+
have_readline_var("rl_basic_word_break_characters")
|
51
|
+
have_readline_var("rl_completer_word_break_characters")
|
52
|
+
have_readline_var("rl_basic_quote_characters")
|
53
|
+
have_readline_var("rl_completer_quote_characters")
|
54
|
+
have_readline_var("rl_filename_quote_characters")
|
55
|
+
have_readline_var("rl_attempted_completion_over")
|
56
|
+
have_readline_var("rl_library_version")
|
57
|
+
have_readline_var("rl_event_hook")
|
58
|
+
have_func("rl_cleanup_after_signal")
|
59
|
+
have_func("rl_clear_signals")
|
60
|
+
have_func("rl_vi_editing_mode")
|
61
|
+
have_func("rl_emacs_editing_mode")
|
62
|
+
have_func("replace_history_entry")
|
63
|
+
have_func("remove_history")
|
64
|
+
create_makefile("readline/readline")
|
@@ -0,0 +1,537 @@
|
|
1
|
+
/* readline.c -- GNU Readline module
|
2
|
+
Copyright (C) 1997-2001 Shugo Maeda
|
3
|
+
|
4
|
+
Modified for Rubinius by Evan Phoenix and others
|
5
|
+
*/
|
6
|
+
|
7
|
+
#include <errno.h>
|
8
|
+
#include <stdio.h>
|
9
|
+
#include <stdlib.h>
|
10
|
+
#include <ctype.h>
|
11
|
+
#include <string.h>
|
12
|
+
#include <readline/readline.h>
|
13
|
+
#include <readline/history.h>
|
14
|
+
|
15
|
+
#include "ruby.h"
|
16
|
+
|
17
|
+
#include <unistd.h>
|
18
|
+
|
19
|
+
static VALUE mReadline;
|
20
|
+
|
21
|
+
#define TOLOWER(c) (isupper(c) ? tolower(c) : c)
|
22
|
+
|
23
|
+
#define COMPLETION_PROC "completion_proc"
|
24
|
+
#define COMPLETION_CASE_FOLD "completion_case_fold"
|
25
|
+
static ID completion_proc, completion_case_fold;
|
26
|
+
|
27
|
+
static char **readline_attempted_completion_function(const char *text,
|
28
|
+
int start, int end);
|
29
|
+
|
30
|
+
static VALUE readline_unlocked(void* prompt) {
|
31
|
+
return (VALUE)readline((char*)prompt);
|
32
|
+
}
|
33
|
+
|
34
|
+
static VALUE
|
35
|
+
readline_readline(VALUE self, VALUE tmp, VALUE add_hist)
|
36
|
+
{
|
37
|
+
VALUE result;
|
38
|
+
char *prompt = NULL;
|
39
|
+
char *buff;
|
40
|
+
|
41
|
+
rb_secure(4);
|
42
|
+
SafeStringValue(tmp);
|
43
|
+
prompt = RSTRING_PTR(tmp);
|
44
|
+
|
45
|
+
if(!isatty(0) && errno == EBADF) rb_raise(rb_eIOError, "stdin closed");
|
46
|
+
|
47
|
+
buff = (char*)rb_thread_blocking_region(readline_unlocked, prompt, 0, 0);
|
48
|
+
|
49
|
+
if(RTEST(add_hist) && buff) {
|
50
|
+
add_history(buff);
|
51
|
+
}
|
52
|
+
|
53
|
+
if(buff) {
|
54
|
+
result = rb_tainted_str_new2(buff);
|
55
|
+
free(buff);
|
56
|
+
} else {
|
57
|
+
result = Qnil;
|
58
|
+
}
|
59
|
+
|
60
|
+
return result;
|
61
|
+
}
|
62
|
+
|
63
|
+
static VALUE
|
64
|
+
readline_s_set_completion_proc(self, proc)
|
65
|
+
VALUE self;
|
66
|
+
VALUE proc;
|
67
|
+
{
|
68
|
+
rb_secure(4);
|
69
|
+
if (!rb_respond_to(proc, rb_intern("call")))
|
70
|
+
rb_raise(rb_eArgError, "argument must respond to `call'");
|
71
|
+
return rb_ivar_set(mReadline, completion_proc, proc);
|
72
|
+
}
|
73
|
+
|
74
|
+
static VALUE
|
75
|
+
readline_s_get_completion_proc(self)
|
76
|
+
VALUE self;
|
77
|
+
{
|
78
|
+
rb_secure(4);
|
79
|
+
return rb_attr_get(mReadline, completion_proc);
|
80
|
+
}
|
81
|
+
|
82
|
+
static VALUE
|
83
|
+
readline_s_set_completion_case_fold(self, val)
|
84
|
+
VALUE self;
|
85
|
+
VALUE val;
|
86
|
+
{
|
87
|
+
rb_secure(4);
|
88
|
+
return rb_ivar_set(mReadline, completion_case_fold, val);
|
89
|
+
}
|
90
|
+
|
91
|
+
static VALUE
|
92
|
+
readline_s_get_completion_case_fold(self)
|
93
|
+
VALUE self;
|
94
|
+
{
|
95
|
+
rb_secure(4);
|
96
|
+
return rb_attr_get(mReadline, completion_case_fold);
|
97
|
+
}
|
98
|
+
|
99
|
+
struct complete_args {
|
100
|
+
const char* text;
|
101
|
+
int start;
|
102
|
+
int end;
|
103
|
+
};
|
104
|
+
|
105
|
+
static void*
|
106
|
+
readline_complete_locked(struct complete_args* args) {
|
107
|
+
const char *text = args->text;
|
108
|
+
int start = args->start;
|
109
|
+
int end = args->end;
|
110
|
+
|
111
|
+
VALUE proc, ary, temp;
|
112
|
+
char **result;
|
113
|
+
int case_fold;
|
114
|
+
int i, matches;
|
115
|
+
|
116
|
+
proc = rb_attr_get(mReadline, completion_proc);
|
117
|
+
if (NIL_P(proc))
|
118
|
+
return NULL;
|
119
|
+
#ifdef HAVE_RL_ATTEMPTED_COMPLETION_OVER
|
120
|
+
rl_attempted_completion_over = 1;
|
121
|
+
#endif
|
122
|
+
case_fold = RTEST(rb_attr_get(mReadline, completion_case_fold));
|
123
|
+
ary = rb_funcall(proc, rb_intern("call"), 1, rb_tainted_str_new2(text));
|
124
|
+
ary = rb_Array(ary);
|
125
|
+
|
126
|
+
matches = rb_ary_size(ary);
|
127
|
+
if (matches == 0) return NULL;
|
128
|
+
result = ALLOC_N(char *, matches + 2);
|
129
|
+
for (i = 0; i < matches; i++) {
|
130
|
+
temp = rb_obj_as_string(rb_ary_entry(ary, i));
|
131
|
+
result[i + 1] = ALLOC_N(char, RSTRING_LEN(temp) + 1);
|
132
|
+
strcpy(result[i + 1], RSTRING_PTR(temp));
|
133
|
+
}
|
134
|
+
result[matches + 1] = NULL;
|
135
|
+
|
136
|
+
if (matches == 1) {
|
137
|
+
result[0] = strdup(result[1]);
|
138
|
+
}
|
139
|
+
else {
|
140
|
+
register int i = 1;
|
141
|
+
int low = 100000;
|
142
|
+
|
143
|
+
while (i < matches) {
|
144
|
+
register int c1, c2, si;
|
145
|
+
|
146
|
+
if (case_fold) {
|
147
|
+
for (si = 0;
|
148
|
+
(c1 = TOLOWER(result[i][si])) &&
|
149
|
+
(c2 = TOLOWER(result[i + 1][si]));
|
150
|
+
si++)
|
151
|
+
if (c1 != c2) break;
|
152
|
+
} else {
|
153
|
+
for (si = 0;
|
154
|
+
(c1 = result[i][si]) &&
|
155
|
+
(c2 = result[i + 1][si]);
|
156
|
+
si++)
|
157
|
+
if (c1 != c2) break;
|
158
|
+
}
|
159
|
+
|
160
|
+
if (low > si) low = si;
|
161
|
+
i++;
|
162
|
+
}
|
163
|
+
result[0] = ALLOC_N(char, low + 1);
|
164
|
+
strncpy(result[0], result[1], low);
|
165
|
+
result[0][low] = '\0';
|
166
|
+
}
|
167
|
+
|
168
|
+
return (void*)result;
|
169
|
+
}
|
170
|
+
|
171
|
+
static char **
|
172
|
+
readline_attempted_completion_function(text, start, end)
|
173
|
+
const char *text;
|
174
|
+
int start;
|
175
|
+
int end;
|
176
|
+
{
|
177
|
+
struct complete_args args = {text, start, end};
|
178
|
+
void* ret = rb_thread_call_with_gvl((rb_thread_call_func)readline_complete_locked, &args);
|
179
|
+
return (char**)ret;
|
180
|
+
}
|
181
|
+
|
182
|
+
static VALUE
|
183
|
+
readline_s_set_completion_append_character(self, str)
|
184
|
+
VALUE self, str;
|
185
|
+
{
|
186
|
+
rb_secure(4);
|
187
|
+
if (NIL_P(str)) {
|
188
|
+
rl_completion_append_character = '\0';
|
189
|
+
}
|
190
|
+
else {
|
191
|
+
SafeStringValue(str);
|
192
|
+
if (RSTRING_LEN(str) == 0) {
|
193
|
+
rl_completion_append_character = '\0';
|
194
|
+
} else {
|
195
|
+
rl_completion_append_character = RSTRING_PTR(str)[0];
|
196
|
+
}
|
197
|
+
}
|
198
|
+
return self;
|
199
|
+
}
|
200
|
+
|
201
|
+
static VALUE
|
202
|
+
readline_s_get_completion_append_character(self)
|
203
|
+
VALUE self;
|
204
|
+
{
|
205
|
+
rb_secure(4);
|
206
|
+
if (rl_completion_append_character == '\0')
|
207
|
+
return Qnil;
|
208
|
+
|
209
|
+
return rb_str_new((char*)&rl_completion_append_character, 1);
|
210
|
+
}
|
211
|
+
|
212
|
+
static VALUE
|
213
|
+
readline_s_set_basic_word_break_characters(self, str)
|
214
|
+
VALUE self, str;
|
215
|
+
{
|
216
|
+
static char *basic_word_break_characters = NULL;
|
217
|
+
|
218
|
+
rb_secure(4);
|
219
|
+
SafeStringValue(str);
|
220
|
+
if (basic_word_break_characters == NULL) {
|
221
|
+
basic_word_break_characters =
|
222
|
+
ALLOC_N(char, RSTRING_LEN(str) + 1);
|
223
|
+
}
|
224
|
+
else {
|
225
|
+
REALLOC_N(basic_word_break_characters, char, RSTRING_LEN(str) + 1);
|
226
|
+
}
|
227
|
+
strncpy(basic_word_break_characters,
|
228
|
+
RSTRING_PTR(str), RSTRING_LEN(str));
|
229
|
+
basic_word_break_characters[RSTRING_LEN(str)] = '\0';
|
230
|
+
rl_basic_word_break_characters = basic_word_break_characters;
|
231
|
+
return self;
|
232
|
+
}
|
233
|
+
|
234
|
+
static VALUE
|
235
|
+
readline_s_get_basic_word_break_characters(self, str)
|
236
|
+
VALUE self, str;
|
237
|
+
{
|
238
|
+
rb_secure(4);
|
239
|
+
if (rl_basic_word_break_characters == NULL)
|
240
|
+
return Qnil;
|
241
|
+
return rb_tainted_str_new2(rl_basic_word_break_characters);
|
242
|
+
}
|
243
|
+
|
244
|
+
static VALUE
|
245
|
+
readline_s_set_completer_word_break_characters(self, str)
|
246
|
+
VALUE self, str;
|
247
|
+
{
|
248
|
+
static char *completer_word_break_characters = NULL;
|
249
|
+
|
250
|
+
rb_secure(4);
|
251
|
+
SafeStringValue(str);
|
252
|
+
if (completer_word_break_characters == NULL) {
|
253
|
+
completer_word_break_characters =
|
254
|
+
ALLOC_N(char, RSTRING_LEN(str) + 1);
|
255
|
+
}
|
256
|
+
else {
|
257
|
+
REALLOC_N(completer_word_break_characters, char, RSTRING_LEN(str) + 1);
|
258
|
+
}
|
259
|
+
strncpy(completer_word_break_characters,
|
260
|
+
RSTRING_PTR(str), RSTRING_LEN(str));
|
261
|
+
completer_word_break_characters[RSTRING_LEN(str)] = '\0';
|
262
|
+
rl_completer_word_break_characters = completer_word_break_characters;
|
263
|
+
return self;
|
264
|
+
}
|
265
|
+
|
266
|
+
static VALUE
|
267
|
+
readline_s_get_completer_word_break_characters(self, str)
|
268
|
+
VALUE self, str;
|
269
|
+
{
|
270
|
+
rb_secure(4);
|
271
|
+
if (rl_completer_word_break_characters == NULL)
|
272
|
+
return Qnil;
|
273
|
+
return rb_tainted_str_new2(rl_completer_word_break_characters);
|
274
|
+
}
|
275
|
+
|
276
|
+
static VALUE
|
277
|
+
readline_s_set_completer_quote_characters(self, str)
|
278
|
+
VALUE self, str;
|
279
|
+
{
|
280
|
+
static char *completer_quote_characters = NULL;
|
281
|
+
|
282
|
+
rb_secure(4);
|
283
|
+
SafeStringValue(str);
|
284
|
+
if (completer_quote_characters == NULL) {
|
285
|
+
completer_quote_characters =
|
286
|
+
ALLOC_N(char, RSTRING_LEN(str) + 1);
|
287
|
+
}
|
288
|
+
else {
|
289
|
+
REALLOC_N(completer_quote_characters, char, RSTRING_LEN(str) + 1);
|
290
|
+
}
|
291
|
+
strncpy(completer_quote_characters,
|
292
|
+
RSTRING_PTR(str), RSTRING_LEN(str));
|
293
|
+
completer_quote_characters[RSTRING_LEN(str)] = '\0';
|
294
|
+
rl_completer_quote_characters = completer_quote_characters;
|
295
|
+
|
296
|
+
return self;
|
297
|
+
}
|
298
|
+
|
299
|
+
static VALUE
|
300
|
+
readline_s_get_completer_quote_characters(self, str)
|
301
|
+
VALUE self, str;
|
302
|
+
{
|
303
|
+
rb_secure(4);
|
304
|
+
if (rl_completer_quote_characters == NULL)
|
305
|
+
return Qnil;
|
306
|
+
return rb_tainted_str_new2(rl_completer_quote_characters);
|
307
|
+
}
|
308
|
+
|
309
|
+
static VALUE
|
310
|
+
hist_to_s(self)
|
311
|
+
VALUE self;
|
312
|
+
{
|
313
|
+
return rb_str_new2("HISTORY");
|
314
|
+
}
|
315
|
+
|
316
|
+
static VALUE
|
317
|
+
hist_get(self, index)
|
318
|
+
VALUE self;
|
319
|
+
VALUE index;
|
320
|
+
{
|
321
|
+
HIST_ENTRY *entry;
|
322
|
+
int i;
|
323
|
+
|
324
|
+
rb_secure(4);
|
325
|
+
i = NUM2INT(index);
|
326
|
+
if (i < 0) {
|
327
|
+
i += history_length;
|
328
|
+
}
|
329
|
+
entry = history_get(history_base + i);
|
330
|
+
if (entry == NULL) {
|
331
|
+
rb_raise(rb_eIndexError, "invalid index");
|
332
|
+
}
|
333
|
+
return rb_tainted_str_new2(entry->line);
|
334
|
+
}
|
335
|
+
|
336
|
+
static VALUE
|
337
|
+
hist_set(self, index, str)
|
338
|
+
VALUE self;
|
339
|
+
VALUE index;
|
340
|
+
VALUE str;
|
341
|
+
{
|
342
|
+
HIST_ENTRY *entry;
|
343
|
+
int i;
|
344
|
+
|
345
|
+
rb_secure(4);
|
346
|
+
i = NUM2INT(index);
|
347
|
+
SafeStringValue(str);
|
348
|
+
if (i < 0) {
|
349
|
+
i += history_length;
|
350
|
+
}
|
351
|
+
entry = replace_history_entry(i, RSTRING_PTR(str), NULL);
|
352
|
+
if (entry == NULL) {
|
353
|
+
rb_raise(rb_eIndexError, "invalid index");
|
354
|
+
}
|
355
|
+
return str;
|
356
|
+
}
|
357
|
+
|
358
|
+
static VALUE
|
359
|
+
hist_push(self, str)
|
360
|
+
VALUE self;
|
361
|
+
VALUE str;
|
362
|
+
{
|
363
|
+
rb_secure(4);
|
364
|
+
SafeStringValue(str);
|
365
|
+
add_history(RSTRING_PTR(str));
|
366
|
+
return self;
|
367
|
+
}
|
368
|
+
|
369
|
+
static VALUE
|
370
|
+
hist_push_method(argc, argv, self)
|
371
|
+
int argc;
|
372
|
+
VALUE *argv;
|
373
|
+
VALUE self;
|
374
|
+
{
|
375
|
+
VALUE str;
|
376
|
+
|
377
|
+
rb_secure(4);
|
378
|
+
while (argc--) {
|
379
|
+
str = *argv++;
|
380
|
+
SafeStringValue(str);
|
381
|
+
add_history(RSTRING_PTR(str));
|
382
|
+
}
|
383
|
+
return self;
|
384
|
+
}
|
385
|
+
|
386
|
+
static VALUE
|
387
|
+
rb_remove_history(index)
|
388
|
+
int index;
|
389
|
+
{
|
390
|
+
HIST_ENTRY *entry;
|
391
|
+
VALUE val;
|
392
|
+
|
393
|
+
rb_secure(4);
|
394
|
+
entry = remove_history(index);
|
395
|
+
if (entry) {
|
396
|
+
val = rb_tainted_str_new2(entry->line);
|
397
|
+
free((char*)entry->line);
|
398
|
+
free(entry);
|
399
|
+
return val;
|
400
|
+
}
|
401
|
+
return Qnil;
|
402
|
+
}
|
403
|
+
|
404
|
+
static VALUE
|
405
|
+
hist_pop(self)
|
406
|
+
VALUE self;
|
407
|
+
{
|
408
|
+
rb_secure(4);
|
409
|
+
if (history_length > 0) {
|
410
|
+
return rb_remove_history(history_length - 1);
|
411
|
+
} else {
|
412
|
+
return Qnil;
|
413
|
+
}
|
414
|
+
}
|
415
|
+
|
416
|
+
static VALUE
|
417
|
+
hist_shift(self)
|
418
|
+
VALUE self;
|
419
|
+
{
|
420
|
+
rb_secure(4);
|
421
|
+
if (history_length > 0) {
|
422
|
+
return rb_remove_history(0);
|
423
|
+
} else {
|
424
|
+
return Qnil;
|
425
|
+
}
|
426
|
+
}
|
427
|
+
|
428
|
+
static VALUE
|
429
|
+
hist_each(self)
|
430
|
+
VALUE self;
|
431
|
+
{
|
432
|
+
HIST_ENTRY *entry;
|
433
|
+
int i;
|
434
|
+
|
435
|
+
rb_secure(4);
|
436
|
+
for (i = 0; i < history_length; i++) {
|
437
|
+
entry = history_get(history_base + i);
|
438
|
+
if (entry == NULL)
|
439
|
+
break;
|
440
|
+
rb_yield(rb_tainted_str_new2(entry->line));
|
441
|
+
}
|
442
|
+
return self;
|
443
|
+
}
|
444
|
+
|
445
|
+
static VALUE
|
446
|
+
hist_length(self)
|
447
|
+
VALUE self;
|
448
|
+
{
|
449
|
+
rb_secure(4);
|
450
|
+
return INT2NUM(history_length);
|
451
|
+
}
|
452
|
+
|
453
|
+
static VALUE
|
454
|
+
hist_empty_p(self)
|
455
|
+
VALUE self;
|
456
|
+
{
|
457
|
+
rb_secure(4);
|
458
|
+
return history_length == 0 ? Qtrue : Qfalse;
|
459
|
+
}
|
460
|
+
|
461
|
+
static VALUE
|
462
|
+
hist_delete_at(self, index)
|
463
|
+
VALUE self;
|
464
|
+
VALUE index;
|
465
|
+
{
|
466
|
+
int i;
|
467
|
+
|
468
|
+
rb_secure(4);
|
469
|
+
i = NUM2INT(index);
|
470
|
+
if (i < 0)
|
471
|
+
i += history_length;
|
472
|
+
if (i < 0 || i > history_length - 1) {
|
473
|
+
rb_raise(rb_eIndexError, "invalid index");
|
474
|
+
}
|
475
|
+
return rb_remove_history(i);
|
476
|
+
}
|
477
|
+
|
478
|
+
void
|
479
|
+
Init_readline()
|
480
|
+
{
|
481
|
+
VALUE history;
|
482
|
+
|
483
|
+
/* Allow conditional parsing of the ~/.inputrc file. */
|
484
|
+
rl_readline_name = "Ruby";
|
485
|
+
|
486
|
+
using_history();
|
487
|
+
|
488
|
+
completion_proc = rb_intern(COMPLETION_PROC);
|
489
|
+
completion_case_fold = rb_intern(COMPLETION_CASE_FOLD);
|
490
|
+
|
491
|
+
mReadline = rb_define_module("Readline");
|
492
|
+
rb_define_singleton_method(mReadline, "perform_readline",
|
493
|
+
readline_readline, 2);
|
494
|
+
rb_define_singleton_method(mReadline, "completion_proc=",
|
495
|
+
readline_s_set_completion_proc, 1);
|
496
|
+
rb_define_singleton_method(mReadline, "completion_proc",
|
497
|
+
readline_s_get_completion_proc, 0);
|
498
|
+
rb_define_singleton_method(mReadline, "completion_case_fold=",
|
499
|
+
readline_s_set_completion_case_fold, 1);
|
500
|
+
rb_define_singleton_method(mReadline, "completion_case_fold",
|
501
|
+
readline_s_get_completion_case_fold, 0);
|
502
|
+
rb_define_singleton_method(mReadline, "completion_append_character=",
|
503
|
+
readline_s_set_completion_append_character, 1);
|
504
|
+
rb_define_singleton_method(mReadline, "completion_append_character",
|
505
|
+
readline_s_get_completion_append_character, 0);
|
506
|
+
rb_define_singleton_method(mReadline, "basic_word_break_characters=",
|
507
|
+
readline_s_set_basic_word_break_characters, 1);
|
508
|
+
rb_define_singleton_method(mReadline, "basic_word_break_characters",
|
509
|
+
readline_s_get_basic_word_break_characters, 0);
|
510
|
+
rb_define_singleton_method(mReadline, "completer_word_break_characters=",
|
511
|
+
readline_s_set_completer_word_break_characters, 1);
|
512
|
+
rb_define_singleton_method(mReadline, "completer_word_break_characters",
|
513
|
+
readline_s_get_completer_word_break_characters, 0);
|
514
|
+
rb_define_singleton_method(mReadline, "completer_quote_characters=",
|
515
|
+
readline_s_set_completer_quote_characters, 1);
|
516
|
+
rb_define_singleton_method(mReadline, "completer_quote_characters",
|
517
|
+
readline_s_get_completer_quote_characters, 0);
|
518
|
+
|
519
|
+
history = rb_obj_alloc(rb_cObject);
|
520
|
+
rb_define_singleton_method(history,"to_s", hist_to_s, 0);
|
521
|
+
rb_define_singleton_method(history,"[]", hist_get, 1);
|
522
|
+
rb_define_singleton_method(history,"[]=", hist_set, 2);
|
523
|
+
rb_define_singleton_method(history,"<<", hist_push, 1);
|
524
|
+
rb_define_singleton_method(history,"push", hist_push_method, -1);
|
525
|
+
rb_define_singleton_method(history,"pop", hist_pop, 0);
|
526
|
+
rb_define_singleton_method(history,"shift", hist_shift, 0);
|
527
|
+
rb_define_singleton_method(history,"each", hist_each, 0);
|
528
|
+
rb_define_singleton_method(history,"length", hist_length, 0);
|
529
|
+
rb_define_singleton_method(history,"size", hist_length, 0);
|
530
|
+
rb_define_singleton_method(history,"empty?", hist_empty_p, 0);
|
531
|
+
rb_define_singleton_method(history,"delete_at", hist_delete_at, 1);
|
532
|
+
rb_define_const(mReadline, "HISTORY", history);
|
533
|
+
|
534
|
+
rb_define_const(mReadline, "VERSION", rb_str_new2(rl_library_version));
|
535
|
+
|
536
|
+
rl_attempted_completion_function = readline_attempted_completion_function;
|
537
|
+
}
|