Ruby 2.7.7p221 (2022-11-24 revision 168ec2b1e5ad0e4688e963d9de019557c78feed9)
readline.c
Go to the documentation of this file.
1/************************************************
2
3 readline.c - GNU Readline module
4
5 $Author$
6 created at: Wed Jan 20 13:59:32 JST 1999
7
8 Copyright (C) 1997-2008 Shugo Maeda
9 Copyright (C) 2008-2013 Kouji Takao
10
11 $Id$
12
13 Contact:
14 - Kouji Takao <kouji dot takao at gmail dot com> (current maintainer)
15
16************************************************/
17
18#ifdef RUBY_EXTCONF_H
19#include RUBY_EXTCONF_H
20#endif
21
22#include "ruby/config.h"
23#include <errno.h>
24#include <stdio.h>
25#include <string.h>
26#ifdef HAVE_READLINE_READLINE_H
27#include <readline/readline.h>
28#endif
29#ifdef HAVE_READLINE_HISTORY_H
30#include <readline/history.h>
31#endif
32#ifdef HAVE_EDITLINE_READLINE_H
33#include <editline/readline.h>
34#endif
35
36#include "ruby/io.h"
37#include "ruby/thread.h"
38
39#ifdef HAVE_UNISTD_H
40#include <unistd.h>
41#endif
42
43#ifdef HAVE_SYS_STAT_H
44#include <sys/stat.h>
45#endif
46
47static VALUE mReadline;
48
49#define EDIT_LINE_LIBRARY_VERSION "EditLine wrapper"
50#ifndef USE_INSERT_IGNORE_ESCAPE
51# if !defined(HAVE_EDITLINE_READLINE_H) && defined(RL_PROMPT_START_IGNORE) && defined(RL_PROMPT_END_IGNORE)
52# define USE_INSERT_IGNORE_ESCAPE 1
53# else
54# define USE_INSERT_IGNORE_ESCAPE 0
55# endif
56#endif
57
58#define COMPLETION_PROC "completion_proc"
59#define COMPLETION_CASE_FOLD "completion_case_fold"
60static ID id_call, completion_proc, completion_case_fold;
61#if defined HAVE_RL_CHAR_IS_QUOTED_P
62#define QUOTING_DETECTION_PROC "quoting_detection_proc"
63static ID quoting_detection_proc;
64#endif
65#if USE_INSERT_IGNORE_ESCAPE
66static ID id_orig_prompt, id_last_prompt;
67#endif
68#if defined(HAVE_RL_PRE_INPUT_HOOK)
69static ID id_pre_input_hook;
70#endif
71#if defined(HAVE_RL_SPECIAL_PREFIXES)
72static ID id_special_prefixes;
73#endif
74
75#ifndef HAVE_RL_FILENAME_COMPLETION_FUNCTION
76# define rl_filename_completion_function filename_completion_function
77#endif
78#ifndef HAVE_RL_USERNAME_COMPLETION_FUNCTION
79# define rl_username_completion_function username_completion_function
80#else
81char *rl_username_completion_function(const char *, int);
82#endif
83#ifndef HAVE_RL_COMPLETION_MATCHES
84# define rl_completion_matches completion_matches
85#endif
86
87static int (*history_get_offset_func)(int);
88static int (*history_replace_offset_func)(int);
89#ifdef HAVE_RL_COMPLETION_APPEND_CHARACTER
90static int readline_completion_append_character;
91#endif
92
93static char **readline_attempted_completion_function(const char *text,
94 int start, int end);
95
96#define OutputStringValue(str) do {\
97 StringValueCStr(str);\
98 (str) = rb_str_conv_enc((str), rb_enc_get(str), rb_locale_encoding());\
99} while (0)\
100
101
102/*
103 * Document-class: Readline
104 *
105 * The Readline module provides interface for GNU Readline.
106 * This module defines a number of methods to facilitate completion
107 * and accesses input history from the Ruby interpreter.
108 * This module supported Edit Line(libedit) too.
109 * libedit is compatible with GNU Readline.
110 *
111 * GNU Readline:: http://www.gnu.org/directory/readline.html
112 * libedit:: http://www.thrysoee.dk/editline/
113 *
114 * Reads one inputted line with line edit by Readline.readline method.
115 * At this time, the facilitatation completion and the key
116 * bind like Emacs can be operated like GNU Readline.
117 *
118 * require "readline"
119 * while buf = Readline.readline("> ", true)
120 * p buf
121 * end
122 *
123 * The content that the user input can be recorded to the history.
124 * The history can be accessed by Readline::HISTORY constant.
125 *
126 * require "readline"
127 * while buf = Readline.readline("> ", true)
128 * p Readline::HISTORY.to_a
129 * print("-> ", buf, "\n")
130 * end
131 *
132 * Documented by Kouji Takao <kouji dot takao at gmail dot com>.
133 */
134
135static VALUE readline_instream;
136static VALUE readline_outstream;
137static FILE *readline_rl_instream;
138static FILE *readline_rl_outstream;
139
140static void
141mustbe_callable(VALUE proc)
142{
143 if (!NIL_P(proc) && !rb_respond_to(proc, id_call))
144 rb_raise(rb_eArgError, "argument must respond to `call'");
145}
146
147#if defined HAVE_RL_GETC_FUNCTION
148
149#ifndef HAVE_RL_GETC
150#define rl_getc(f) EOF
151#endif
152
153struct getc_struct {
154 FILE *input;
155 int fd;
156 int ret;
157 int err;
158};
159
160static int
161getc_body(struct getc_struct *p)
162{
163 char ch;
164 ssize_t ss;
165
166#if defined(_WIN32)
167 {
168 INPUT_RECORD ir;
169 DWORD n;
170 static int prior_key = '0';
171 for (;;) {
172 HANDLE h;
173 if (prior_key > 0xff) {
174 prior_key = rl_getc(p->input);
175 return prior_key;
176 }
177 h = (HANDLE)_get_osfhandle(p->fd);
178 if (PeekConsoleInput(h, &ir, 1, &n)) {
179 if (n == 1) {
180 if (ir.EventType == KEY_EVENT && ir.Event.KeyEvent.bKeyDown) {
181 prior_key = rl_getc(p->input);
182 return prior_key;
183 } else {
184 ReadConsoleInput(h, &ir, 1, &n);
185 }
186 } else {
187 rb_w32_wait_events_blocking(&h, 1, INFINITE);
188 }
189 } else {
190 break;
191 }
192 }
193 }
194#endif
195
196 ss = read(p->fd, &ch, 1);
197 if (ss == 0) {
198 errno = 0;
199 return EOF;
200 }
201 if (ss != 1)
202 return EOF;
203 return (unsigned char)ch;
204}
205
206static void *
207getc_func(void *data1)
208{
209 struct getc_struct *p = data1;
210 errno = 0;
211 p->ret = getc_body(p);
212 p->err = errno;
213 return NULL;
214}
215
216static int
217readline_getc(FILE *input)
218{
219 struct getc_struct data;
220 if (input == NULL) /* editline may give NULL as input. */
221 input = stdin;
222 data.input = input;
223 data.fd = fileno(input);
224 again:
225 data.ret = EOF;
226 data.err = EINTR; /* getc_func is not called if already interrupted. */
227 rb_thread_call_without_gvl2(getc_func, &data, RUBY_UBF_IO, NULL);
228 if (data.ret == EOF) {
229 if (data.err == 0) {
230 return EOF;
231 }
232 if (data.err == EINTR) {
234 goto again;
235 }
236 if (data.err == EWOULDBLOCK || data.err == EAGAIN) {
237 int ret;
238 if (fileno(input) != data.fd)
239 rb_bug("readline_getc: input closed unexpectedly or memory corrupted");
240 ret = rb_wait_for_single_fd(data.fd, RB_WAITFD_IN, NULL);
241 if (ret != -1 || errno == EINTR)
242 goto again;
243 rb_sys_fail("rb_wait_for_single_fd");
244 }
245 rb_syserr_fail(data.err, "read");
246 }
247 return data.ret;
248}
249
250#elif defined HAVE_RL_EVENT_HOOK
251#define BUSY_WAIT 0
252
253static int readline_event(void);
254static int
255readline_event(void)
256{
257#if BUSY_WAIT
259#else
261 return 0;
262#endif
263}
264#endif
265
266#if USE_INSERT_IGNORE_ESCAPE
267static VALUE
268insert_ignore_escape(VALUE self, VALUE prompt)
269{
270 VALUE last_prompt, orig_prompt = rb_attr_get(self, id_orig_prompt);
271 int ignoring = 0;
272 const char *s0, *s, *e;
273 long len;
274 static const char ignore_code[2] = {RL_PROMPT_START_IGNORE, RL_PROMPT_END_IGNORE};
275
276 prompt = rb_str_new_shared(prompt);
277 last_prompt = rb_attr_get(self, id_last_prompt);
278 if (orig_prompt == prompt) return last_prompt;
279 len = RSTRING_LEN(prompt);
280 if (NIL_P(last_prompt)) {
281 last_prompt = rb_str_tmp_new(len);
282 }
283
284 s = s0 = RSTRING_PTR(prompt);
285 e = s0 + len;
286 rb_str_set_len(last_prompt, 0);
287 while (s < e && *s) {
288 switch (*s) {
289 case RL_PROMPT_START_IGNORE:
290 ignoring = -1;
291 rb_str_cat(last_prompt, s0, ++s - s0);
292 s0 = s;
293 break;
294 case RL_PROMPT_END_IGNORE:
295 ignoring = 0;
296 rb_str_cat(last_prompt, s0, ++s - s0);
297 s0 = s;
298 break;
299 case '\033':
300 if (++s < e && *s == '[') {
301 rb_str_cat(last_prompt, s0, s - s0 - 1);
302 s0 = s - 1;
303 while (++s < e && *s) {
304 if (ISALPHA(*(unsigned char *)s)) {
305 if (!ignoring) {
306 ignoring = 1;
307 rb_str_cat(last_prompt, ignore_code+0, 1);
308 }
309 rb_str_cat(last_prompt, s0, ++s - s0);
310 s0 = s;
311 break;
312 }
313 else if (!(('0' <= *s && *s <= '9') || *s == ';')) {
314 break;
315 }
316 }
317 }
318 break;
319 default:
320 if (ignoring > 0) {
321 ignoring = 0;
322 rb_str_cat(last_prompt, ignore_code+1, 1);
323 }
324 s++;
325 break;
326 }
327 }
328 if (ignoring > 0) {
329 ignoring = 0;
330 rb_str_cat(last_prompt, ignore_code+1, 1);
331 }
332 rb_str_cat(last_prompt, s0, s - s0);
333
334 rb_ivar_set(self, id_orig_prompt, prompt);
335 rb_ivar_set(self, id_last_prompt, last_prompt);
336
337 return last_prompt;
338}
339#endif
340
341static VALUE
342readline_get(VALUE prompt)
343{
344#ifdef HAVE_RL_COMPLETION_APPEND_CHARACTER
345 readline_completion_append_character = rl_completion_append_character;
346#endif
347 return (VALUE)readline((char *)prompt);
348}
349
350static void
351clear_rl_instream(void)
352{
353 if (readline_rl_instream) {
354 fclose(readline_rl_instream);
355 if (rl_instream == readline_rl_instream)
356 rl_instream = NULL;
357 readline_rl_instream = NULL;
358 }
359 readline_instream = Qfalse;
360}
361
362static void
363clear_rl_outstream(void)
364{
365 if (readline_rl_outstream) {
366 fclose(readline_rl_outstream);
367 if (rl_outstream == readline_rl_outstream)
368 rl_outstream = NULL;
369 readline_rl_outstream = NULL;
370 }
371 readline_outstream = Qfalse;
372}
373
374static void
375prepare_readline(void)
376{
377 static int initialized = 0;
378 if (!initialized) {
379 rl_initialize();
380 initialized = 1;
381 }
382
383 if (readline_instream) {
384 rb_io_t *ifp;
385 rb_io_check_initialized(ifp = RFILE(rb_io_taint_check(readline_instream))->fptr);
386 if (ifp->fd < 0) {
387 clear_rl_instream();
388 rb_raise(rb_eIOError, "closed readline input");
389 }
390 }
391
392 if (readline_outstream) {
393 rb_io_t *ofp;
394 rb_io_check_initialized(ofp = RFILE(rb_io_taint_check(readline_outstream))->fptr);
395 if (ofp->fd < 0) {
396 clear_rl_outstream();
397 rb_raise(rb_eIOError, "closed readline output");
398 }
399 }
400}
401
402/*
403 * call-seq:
404 * Readline.readline(prompt = "", add_hist = false) -> string or nil
405 *
406 * Shows the +prompt+ and reads the inputted line with line editing.
407 * The inputted line is added to the history if +add_hist+ is true.
408 *
409 * Returns nil when the inputted line is empty and user inputs EOF
410 * (Presses ^D on UNIX).
411 *
412 * Raises IOError exception if one of below conditions are satisfied.
413 * 1. stdin was closed.
414 * 2. stdout was closed.
415 *
416 * This method supports thread. Switches the thread context when waits
417 * inputting line.
418 *
419 * Supports line edit when inputs line. Provides VI and Emacs editing mode.
420 * Default is Emacs editing mode.
421 *
422 * NOTE: Terminates ruby interpreter and does not return the terminal
423 * status after user pressed '^C' when wait inputting line.
424 * Give 3 examples that avoid it.
425 *
426 * * Catches the Interrupt exception by pressed ^C after returns
427 * terminal status:
428 *
429 * require "readline"
430 *
431 * stty_save = `stty -g`.chomp
432 * begin
433 * while buf = Readline.readline
434 * p buf
435 * end
436 * rescue Interrupt
437 * system("stty", stty_save)
438 * exit
439 * end
440 * end
441 * end
442 *
443 * * Catches the INT signal by pressed ^C after returns terminal
444 * status:
445 *
446 * require "readline"
447 *
448 * stty_save = `stty -g`.chomp
449 * trap("INT") { system "stty", stty_save; exit }
450 *
451 * while buf = Readline.readline
452 * p buf
453 * end
454 *
455 * * Ignores pressing ^C:
456 *
457 * require "readline"
458 *
459 * trap("INT", "SIG_IGN")
460 *
461 * while buf = Readline.readline
462 * p buf
463 * end
464 *
465 * Can make as follows with Readline::HISTORY constant.
466 * It does not record to the history if the inputted line is empty or
467 * the same it as last one.
468 *
469 * require "readline"
470 *
471 * while buf = Readline.readline("> ", true)
472 * # p Readline::HISTORY.to_a
473 * Readline::HISTORY.pop if /^\s*$/ =~ buf
474 *
475 * begin
476 * if Readline::HISTORY[Readline::HISTORY.length-2] == buf
477 * Readline::HISTORY.pop
478 * end
479 * rescue IndexError
480 * end
481 *
482 * # p Readline::HISTORY.to_a
483 * print "-> ", buf, "\n"
484 * end
485 */
486static VALUE
487readline_readline(int argc, VALUE *argv, VALUE self)
488{
489 VALUE tmp, add_hist, result;
490 char *prompt = NULL;
491 char *buff;
492 int status;
493
494 if (rb_scan_args(argc, argv, "02", &tmp, &add_hist) > 0) {
496#if USE_INSERT_IGNORE_ESCAPE
497 tmp = insert_ignore_escape(self, tmp);
498 rb_str_locktmp(tmp);
499#endif
500 prompt = RSTRING_PTR(tmp);
501 }
502
503 prepare_readline();
504
505#ifdef _WIN32
506 rl_prep_terminal(1);
507#endif
508 buff = (char*)rb_protect(readline_get, (VALUE)prompt, &status);
509#if USE_INSERT_IGNORE_ESCAPE
510 if (prompt) {
511 rb_str_unlocktmp(tmp);
512 }
513#endif
514 if (status) {
515#if defined HAVE_RL_CLEANUP_AFTER_SIGNAL
516 /* restore terminal mode and signal handler*/
517#if defined HAVE_RL_FREE_LINE_STATE
518 rl_free_line_state();
519#endif
520 rl_cleanup_after_signal();
521#elif defined HAVE_RL_DEPREP_TERM_FUNCTION
522 /* restore terminal mode */
523 if (rl_deprep_term_function != NULL) /* NULL in libedit. [ruby-dev:29116] */
524 (*rl_deprep_term_function)();
525 else
526#else
527 rl_deprep_terminal();
528#endif
529 rb_jump_tag(status);
530 }
531
532 if (RTEST(add_hist) && buff) {
533 add_history(buff);
534 }
535 if (buff) {
536 result = rb_locale_str_new_cstr(buff);
537 }
538 else
539 result = Qnil;
540 if (buff) free(buff);
541 return result;
542}
543
544/*
545 * call-seq:
546 * Readline.input = input
547 *
548 * Specifies a File object +input+ that is input stream for
549 * Readline.readline method.
550 */
551static VALUE
552readline_s_set_input(VALUE self, VALUE input)
553{
554 rb_io_t *ifp;
555 int fd;
556 FILE *f;
557
558 if (NIL_P(input)) {
559 clear_rl_instream();
560 }
561 else {
563 GetOpenFile(input, ifp);
564 clear_rl_instream();
565 fd = rb_cloexec_dup(ifp->fd);
566 if (fd == -1)
567 rb_sys_fail("dup");
568 f = fdopen(fd, "r");
569 if (f == NULL) {
570 int save_errno = errno;
571 close(fd);
572 rb_syserr_fail(save_errno, "fdopen");
573 }
574 rl_instream = readline_rl_instream = f;
575 readline_instream = input;
576 }
577 return input;
578}
579
580/*
581 * call-seq:
582 * Readline.output = output
583 *
584 * Specifies a File object +output+ that is output stream for
585 * Readline.readline method.
586 */
587static VALUE
588readline_s_set_output(VALUE self, VALUE output)
589{
590 rb_io_t *ofp;
591 int fd;
592 FILE *f;
593
594 if (NIL_P(output)) {
595 clear_rl_outstream();
596 }
597 else {
598 Check_Type(output, T_FILE);
599 GetOpenFile(output, ofp);
600 clear_rl_outstream();
601 fd = rb_cloexec_dup(ofp->fd);
602 if (fd == -1)
603 rb_sys_fail("dup");
604 f = fdopen(fd, "w");
605 if (f == NULL) {
606 int save_errno = errno;
607 close(fd);
608 rb_syserr_fail(save_errno, "fdopen");
609 }
610 rl_outstream = readline_rl_outstream = f;
611 readline_outstream = output;
612 }
613 return output;
614}
615
616#if defined(HAVE_RL_PRE_INPUT_HOOK)
617/*
618 * call-seq:
619 * Readline.pre_input_hook = proc
620 *
621 * Specifies a Proc object +proc+ to call after the first prompt has
622 * been printed and just before readline starts reading input
623 * characters.
624 *
625 * See GNU Readline's rl_pre_input_hook variable.
626 *
627 * Raises ArgumentError if +proc+ does not respond to the call method.
628 *
629 * Raises NotImplementedError if the using readline library does not support.
630 */
631static VALUE
633{
634 mustbe_callable(proc);
635 return rb_ivar_set(mReadline, id_pre_input_hook, proc);
636}
637
638/*
639 * call-seq:
640 * Readline.pre_input_hook -> proc
641 *
642 * Returns a Proc object +proc+ to call after the first prompt has
643 * been printed and just before readline starts reading input
644 * characters. The default is nil.
645 *
646 * Raises NotImplementedError if the using readline library does not support.
647 */
648static VALUE
650{
651 return rb_attr_get(mReadline, id_pre_input_hook);
652}
653
654static int
655readline_pre_input_hook(void)
656{
657 VALUE proc;
658
659 proc = rb_attr_get(mReadline, id_pre_input_hook);
660 if (!NIL_P(proc))
661 rb_funcall(proc, id_call, 0);
662 return 0;
663}
664#else
665#define readline_s_set_pre_input_hook rb_f_notimplement
666#define readline_s_get_pre_input_hook rb_f_notimplement
667#endif
668
669#if defined(HAVE_RL_INSERT_TEXT)
670/*
671 * call-seq:
672 * Readline.insert_text(string) -> self
673 *
674 * Insert text into the line at the current cursor position.
675 *
676 * See GNU Readline's rl_insert_text function.
677 *
678 * Raises NotImplementedError if the using readline library does not support.
679 */
680static VALUE
682{
684 rl_insert_text(RSTRING_PTR(str));
685 return self;
686}
687#else
688#define readline_s_insert_text rb_f_notimplement
689#endif
690
691#if defined(HAVE_RL_DELETE_TEXT)
692int rl_delete_text(int, int);
693static const char *
694str_subpos(const char *ptr, const char *end, long beg, long *sublen, rb_encoding *enc)
695{
698 ptr = rb_str_subpos(str, beg, sublen);
700 return ptr;
701}
702
703/*
704 * call-seq:
705 * Readline.delete_text([start[, length]]) -> self
706 * Readline.delete_text(start..end) -> self
707 * Readline.delete_text() -> self
708 *
709 * Delete text between start and end in the current line.
710 *
711 * See GNU Readline's rl_delete_text function.
712 *
713 * Raises NotImplementedError if the using readline library does not support.
714 */
715static VALUE
717{
718 rb_check_arity(argc, 0, 2);
719 if (rl_line_buffer) {
720 const char *p, *ptr = rl_line_buffer;
721 long beg = 0, len = strlen(ptr);
722 const char *end = ptr + len;
724 if (argc == 2) {
725 beg = NUM2LONG(argv[0]);
726 len = NUM2LONG(argv[1]);
727 num_pos:
728 p = str_subpos(ptr, end, beg, &len, enc);
729 if (!p) rb_raise(rb_eArgError, "invalid index");
730 beg = p - ptr;
731 }
732 else if (argc == 1) {
733 len = rb_enc_strlen(ptr, ptr + len, enc);
734 if (!rb_range_beg_len(argv[0], &beg, &len, len, 1)) {
735 beg = NUM2LONG(argv[0]);
736 goto num_pos;
737 }
738 }
739 rl_delete_text(rb_long2int(beg), rb_long2int(beg + len));
740 }
741 return self;
742}
743#else
744#define readline_s_delete_text rb_f_notimplement
745#endif
746
747#if defined(HAVE_RL_REDISPLAY)
748/*
749 * call-seq:
750 * Readline.redisplay -> self
751 *
752 * Change what's displayed on the screen to reflect the current
753 * contents.
754 *
755 * See GNU Readline's rl_redisplay function.
756 *
757 * Raises NotImplementedError if the using readline library does not support.
758 */
759static VALUE
761{
762 rl_redisplay();
763 return self;
764}
765#else
766#define readline_s_redisplay rb_f_notimplement
767#endif
768
769/*
770 * call-seq:
771 * Readline.completion_proc = proc
772 *
773 * Specifies a Proc object +proc+ to determine completion behavior. It
774 * should take input string and return an array of completion candidates.
775 *
776 * The default completion is used if +proc+ is nil.
777 *
778 * The String that is passed to the Proc depends on the
779 * Readline.completer_word_break_characters property. By default the word
780 * under the cursor is passed to the Proc. For example, if the input is "foo
781 * bar" then only "bar" would be passed to the completion Proc.
782 *
783 * Upon successful completion the Readline.completion_append_character will be
784 * appended to the input so the user can start working on their next argument.
785 *
786 * = Examples
787 *
788 * == Completion for a Static List
789 *
790 * require 'readline'
791 *
792 * LIST = [
793 * 'search', 'download', 'open',
794 * 'help', 'history', 'quit',
795 * 'url', 'next', 'clear',
796 * 'prev', 'past'
797 * ].sort
798 *
799 * comp = proc { |s| LIST.grep(/^#{Regexp.escape(s)}/) }
800 *
801 * Readline.completion_append_character = " "
802 * Readline.completion_proc = comp
803 *
804 * while line = Readline.readline('> ', true)
805 * p line
806 * end
807 *
808 * == Completion For Directory Contents
809 *
810 * require 'readline'
811 *
812 * Readline.completion_append_character = " "
813 * Readline.completion_proc = Proc.new do |str|
814 * Dir[str+'*'].grep(/^#{Regexp.escape(str)}/)
815 * end
816 *
817 * while line = Readline.readline('> ', true)
818 * p line
819 * end
820 *
821 * = Autocomplete strategies
822 *
823 * When working with auto-complete there are some strategies that work well.
824 * To get some ideas you can take a look at the
825 * completion.rb[https://git.ruby-lang.org/ruby.git/tree/lib/irb/completion.rb]
826 * file for irb.
827 *
828 * The common strategy is to take a list of possible completions and filter it
829 * down to those completions that start with the user input. In the above
830 * examples Enumerator.grep is used. The input is escaped to prevent Regexp
831 * special characters from interfering with the matching.
832 *
833 * It may also be helpful to use the Abbrev library to generate completions.
834 *
835 * Raises ArgumentError if +proc+ does not respond to the call method.
836 */
837static VALUE
838readline_s_set_completion_proc(VALUE self, VALUE proc)
839{
840 mustbe_callable(proc);
841 return rb_ivar_set(mReadline, completion_proc, proc);
842}
843
844/*
845 * call-seq:
846 * Readline.completion_proc -> proc
847 *
848 * Returns the completion Proc object.
849 */
850static VALUE
851readline_s_get_completion_proc(VALUE self)
852{
853 return rb_attr_get(mReadline, completion_proc);
854}
855
856#ifdef HAVE_RL_CHAR_IS_QUOTED_P
857/*
858 * call-seq:
859 * Readline.quoting_detection_proc = proc
860 *
861 * Specifies a Proc object +proc+ to determine if a character in the user's
862 * input is escaped. It should take the user's input and the index of the
863 * character in question as input, and return a boolean (true if the specified
864 * character is escaped).
865 *
866 * Readline will only call this proc with characters specified in
867 * +completer_quote_characters+, to discover if they indicate the end of a
868 * quoted argument, or characters specified in
869 * +completer_word_break_characters+, to discover if they indicate a break
870 * between arguments.
871 *
872 * If +completer_quote_characters+ is not set, or if the user input doesn't
873 * contain one of the +completer_quote_characters+ or a +\+ character,
874 * Readline will not attempt to use this proc at all.
875 *
876 * Raises ArgumentError if +proc+ does not respond to the call method.
877 */
878static VALUE
880{
881 mustbe_callable(proc);
882 return rb_ivar_set(mReadline, quoting_detection_proc, proc);
883}
884
885/*
886 * call-seq:
887 * Readline.quoting_detection_proc -> proc
888 *
889 * Returns the quoting detection Proc object.
890 */
891static VALUE
893{
894 return rb_attr_get(mReadline, quoting_detection_proc);
895}
896#else
897#define readline_s_set_quoting_detection_proc rb_f_notimplement
898#define readline_s_get_quoting_detection_proc rb_f_notimplement
899#endif
900
901/*
902 * call-seq:
903 * Readline.completion_case_fold = bool
904 *
905 * Sets whether or not to ignore case on completion.
906 */
907static VALUE
908readline_s_set_completion_case_fold(VALUE self, VALUE val)
909{
910 return rb_ivar_set(mReadline, completion_case_fold, val);
911}
912
913/*
914 * call-seq:
915 * Readline.completion_case_fold -> bool
916 *
917 * Returns true if completion ignores case. If no, returns false.
918 *
919 * NOTE: Returns the same object that is specified by
920 * Readline.completion_case_fold= method.
921 *
922 * require "readline"
923 *
924 * Readline.completion_case_fold = "This is a String."
925 * p Readline.completion_case_fold # => "This is a String."
926 */
927static VALUE
928readline_s_get_completion_case_fold(VALUE self)
929{
930 return rb_attr_get(mReadline, completion_case_fold);
931}
932
933#ifdef HAVE_RL_LINE_BUFFER
934/*
935 * call-seq:
936 * Readline.line_buffer -> string
937 *
938 * Returns the full line that is being edited. This is useful from
939 * within the complete_proc for determining the context of the
940 * completion request.
941 *
942 * The length of +Readline.line_buffer+ and GNU Readline's rl_end are
943 * same.
944 *
945 * Raises NotImplementedError if the using readline library does not support.
946 */
947static VALUE
949{
950 if (rl_line_buffer == NULL)
951 return Qnil;
952 return rb_locale_str_new_cstr(rl_line_buffer);
953}
954#else
955#define readline_s_get_line_buffer rb_f_notimplement
956#endif
957
958#ifdef HAVE_RL_POINT
959/*
960 * call-seq:
961 * Readline.point -> int
962 *
963 * Returns the index of the current cursor position in
964 * +Readline.line_buffer+.
965 *
966 * The index in +Readline.line_buffer+ which matches the start of
967 * input-string passed to completion_proc is computed by subtracting
968 * the length of input-string from +Readline.point+.
969 *
970 * start = (the length of input-string) - Readline.point
971 *
972 * Raises NotImplementedError if the using readline library does not support.
973 */
974static VALUE
976{
977 return INT2NUM(rl_point);
978}
979
980/*
981 * call-seq:
982 * Readline.point = int
983 *
984 * Set the index of the current cursor position in
985 * +Readline.line_buffer+.
986 *
987 * Raises NotImplementedError if the using readline library does not support.
988 *
989 * See +Readline.point+.
990 */
991static VALUE
993{
994 rl_point = NUM2INT(pos);
995 return pos;
996}
997#else
998#define readline_s_get_point rb_f_notimplement
999#define readline_s_set_point rb_f_notimplement
1000#endif
1001
1002static char **
1003readline_attempted_completion_function(const char *text, int start, int end)
1004{
1005 VALUE proc, ary, temp;
1006 char **result;
1007 int case_fold;
1008 long i, matches;
1009 rb_encoding *enc;
1010 VALUE encobj;
1011
1012 proc = rb_attr_get(mReadline, completion_proc);
1013 if (NIL_P(proc))
1014 return NULL;
1015#ifdef HAVE_RL_COMPLETION_APPEND_CHARACTER
1016 rl_completion_append_character = readline_completion_append_character;
1017#endif
1018#ifdef HAVE_RL_ATTEMPTED_COMPLETION_OVER
1019 rl_attempted_completion_over = 1;
1020#endif
1021 case_fold = RTEST(rb_attr_get(mReadline, completion_case_fold));
1022 ary = rb_funcall(proc, id_call, 1, rb_locale_str_new_cstr(text));
1023 if (!RB_TYPE_P(ary, T_ARRAY))
1024 ary = rb_Array(ary);
1025 matches = RARRAY_LEN(ary);
1026 if (matches == 0) return NULL;
1027 result = (char**)malloc((matches + 2)*sizeof(char*));
1028 if (result == NULL) rb_memerror();
1029 enc = rb_locale_encoding();
1030 encobj = rb_enc_from_encoding(enc);
1031 for (i = 0; i < matches; i++) {
1032 temp = rb_obj_as_string(RARRAY_AREF(ary, i));
1033 StringValueCStr(temp); /* must be NUL-terminated */
1034 rb_enc_check(encobj, temp);
1035 result[i + 1] = (char*)malloc(RSTRING_LEN(temp) + 1);
1036 if (result[i + 1] == NULL) rb_memerror();
1037 strcpy(result[i + 1], RSTRING_PTR(temp));
1038 }
1039 result[matches + 1] = NULL;
1040
1041 if (matches == 1) {
1042 result[0] = strdup(result[1]);
1043 }
1044 else {
1045 const char *result1 = result[1];
1046 long low = strlen(result1);
1047
1048 for (i = 1; i < matches; ++i) {
1049 register int c1, c2;
1050 long i1, i2, l2;
1051 int n1, n2;
1052 const char *p2 = result[i + 1];
1053
1054 l2 = strlen(p2);
1055 for (i1 = i2 = 0; i1 < low && i2 < l2; i1 += n1, i2 += n2) {
1056 c1 = rb_enc_codepoint_len(result1 + i1, result1 + low, &n1, enc);
1057 c2 = rb_enc_codepoint_len(p2 + i2, p2 + l2, &n2, enc);
1058 if (case_fold) {
1059 c1 = rb_tolower(c1);
1060 c2 = rb_tolower(c2);
1061 }
1062 if (c1 != c2) break;
1063 }
1064
1065 low = i1;
1066 }
1067 result[0] = (char*)malloc(low + 1);
1068 if (result[0] == NULL) rb_memerror();
1069 strncpy(result[0], result[1], low);
1070 result[0][low] = '\0';
1071 }
1072
1073 return result;
1074}
1075
1076#ifdef HAVE_RL_CHAR_IS_QUOTED_P
1077static int
1078readline_char_is_quoted(char *text, int byte_index)
1079{
1080 VALUE proc, result, str;
1081 long char_index;
1082 size_t len;
1083
1084 proc = rb_attr_get(mReadline, quoting_detection_proc);
1085 if (NIL_P(proc)) {
1086 return 0;
1087 }
1088
1089 len = strlen(text);
1090 if (byte_index < 0 || len < (size_t)byte_index) {
1091 rb_raise(rb_eIndexError, "invalid byte index (%d in %"PRIdSIZE")",
1092 byte_index, len);
1093 }
1094
1095 str = rb_locale_str_new(text, len);
1096 char_index = rb_str_sublen(str, byte_index);
1097 result = rb_funcall(proc, id_call, 2, str, LONG2FIX(char_index));
1098 return RTEST(result);
1099}
1100#endif
1101
1102#ifdef HAVE_RL_SET_SCREEN_SIZE
1103/*
1104 * call-seq:
1105 * Readline.set_screen_size(rows, columns) -> self
1106 *
1107 * Set terminal size to +rows+ and +columns+.
1108 *
1109 * See GNU Readline's rl_set_screen_size function.
1110 *
1111 * Raises NotImplementedError if the using readline library does not support.
1112 */
1113static VALUE
1114readline_s_set_screen_size(VALUE self, VALUE rows, VALUE columns)
1115{
1116 rl_set_screen_size(NUM2INT(rows), NUM2INT(columns));
1117 return self;
1118}
1119#else
1120#define readline_s_set_screen_size rb_f_notimplement
1121#endif
1122
1123#ifdef HAVE_RL_GET_SCREEN_SIZE
1124/*
1125 * call-seq:
1126 * Readline.get_screen_size -> [rows, columns]
1127 *
1128 * Returns the terminal's rows and columns.
1129 *
1130 * See GNU Readline's rl_get_screen_size function.
1131 *
1132 * Raises NotImplementedError if the using readline library does not support.
1133 */
1134static VALUE
1136{
1137 int rows, columns;
1138 VALUE res;
1139
1140 rl_get_screen_size(&rows, &columns);
1141 res = rb_ary_new();
1142 rb_ary_push(res, INT2NUM(rows));
1143 rb_ary_push(res, INT2NUM(columns));
1144 return res;
1145}
1146#else
1147#define readline_s_get_screen_size rb_f_notimplement
1148#endif
1149
1150#ifdef HAVE_RL_VI_EDITING_MODE
1151int rl_vi_editing_mode(int, int);
1152/*
1153 * call-seq:
1154 * Readline.vi_editing_mode -> nil
1155 *
1156 * Specifies VI editing mode. See the manual of GNU Readline for
1157 * details of VI editing mode.
1158 *
1159 * Raises NotImplementedError if the using readline library does not support.
1160 */
1161static VALUE
1163{
1164 rl_vi_editing_mode(1,0);
1165 return Qnil;
1166}
1167#else
1168#define readline_s_vi_editing_mode rb_f_notimplement
1169#endif
1170
1171#ifdef HAVE_RL_EDITING_MODE
1172/*
1173 * call-seq:
1174 * Readline.vi_editing_mode? -> bool
1175 *
1176 * Returns true if vi mode is active. Returns false if not.
1177 *
1178 * Raises NotImplementedError if the using readline library does not support.
1179 */
1180static VALUE
1182{
1183 return rl_editing_mode == 0 ? Qtrue : Qfalse;
1184}
1185#else
1186#define readline_s_vi_editing_mode_p rb_f_notimplement
1187#endif
1188
1189#ifdef HAVE_RL_EMACS_EDITING_MODE
1190int rl_emacs_editing_mode(int, int);
1191/*
1192 * call-seq:
1193 * Readline.emacs_editing_mode -> nil
1194 *
1195 * Specifies Emacs editing mode. The default is this mode. See the
1196 * manual of GNU Readline for details of Emacs editing mode.
1197 *
1198 * Raises NotImplementedError if the using readline library does not support.
1199 */
1200static VALUE
1202{
1203 rl_emacs_editing_mode(1,0);
1204 return Qnil;
1205}
1206#else
1207#define readline_s_emacs_editing_mode rb_f_notimplement
1208#endif
1209
1210#ifdef HAVE_RL_EDITING_MODE
1211/*
1212 * call-seq:
1213 * Readline.emacs_editing_mode? -> bool
1214 *
1215 * Returns true if emacs mode is active. Returns false if not.
1216 *
1217 * Raises NotImplementedError if the using readline library does not support.
1218 */
1219static VALUE
1221{
1222 return rl_editing_mode == 1 ? Qtrue : Qfalse;
1223}
1224#else
1225#define readline_s_emacs_editing_mode_p rb_f_notimplement
1226#endif
1227
1228#ifdef HAVE_RL_COMPLETION_APPEND_CHARACTER
1229/*
1230 * call-seq:
1231 * Readline.completion_append_character = char
1232 *
1233 * Specifies a character to be appended on completion.
1234 * Nothing will be appended if an empty string ("") or nil is
1235 * specified.
1236 *
1237 * For example:
1238 * require "readline"
1239 *
1240 * Readline.readline("> ", true)
1241 * Readline.completion_append_character = " "
1242 *
1243 * Result:
1244 * >
1245 * Input "/var/li".
1246 *
1247 * > /var/li
1248 * Press TAB key.
1249 *
1250 * > /var/lib
1251 * Completes "b" and appends " ". So, you can continuously input "/usr".
1252 *
1253 * > /var/lib /usr
1254 *
1255 * NOTE: Only one character can be specified. When "string" is
1256 * specified, sets only "s" that is the first.
1257 *
1258 * require "readline"
1259 *
1260 * Readline.completion_append_character = "string"
1261 * p Readline.completion_append_character # => "s"
1262 *
1263 * Raises NotImplementedError if the using readline library does not support.
1264 */
1265static VALUE
1267{
1268 if (NIL_P(str)) {
1269 rl_completion_append_character = '\0';
1270 }
1271 else {
1273 if (RSTRING_LEN(str) == 0) {
1274 rl_completion_append_character = '\0';
1275 } else {
1276 rl_completion_append_character = RSTRING_PTR(str)[0];
1277 }
1278 }
1279 return self;
1280}
1281#else
1282#define readline_s_set_completion_append_character rb_f_notimplement
1283#endif
1284
1285#ifdef HAVE_RL_COMPLETION_APPEND_CHARACTER
1286/*
1287 * call-seq:
1288 * Readline.completion_append_character -> char
1289 *
1290 * Returns a string containing a character to be appended on
1291 * completion. The default is a space (" ").
1292 *
1293 * Raises NotImplementedError if the using readline library does not support.
1294 */
1295static VALUE
1297{
1298 char buf[1];
1299
1300 if (rl_completion_append_character == '\0')
1301 return Qnil;
1302
1303 buf[0] = (char) rl_completion_append_character;
1304 return rb_locale_str_new(buf, 1);
1305}
1306#else
1307#define readline_s_get_completion_append_character rb_f_notimplement
1308#endif
1309
1310#ifdef HAVE_RL_COMPLETION_QUOTE_CHARACTER
1311/*
1312 * call-seq:
1313 * Readline.completion_quote_character -> char
1314 *
1315 * When called during a completion (e.g. from within your completion_proc),
1316 * it will return a string containing the character used to quote the
1317 * argument being completed, or nil if the argument is unquoted.
1318 *
1319 * When called at other times, it will always return nil.
1320 *
1321 * Note that Readline.completer_quote_characters must be set,
1322 * or this method will always return nil.
1323 */
1324static VALUE
1326{
1327 char buf[1];
1328
1329 if (rl_completion_quote_character == '\0')
1330 return Qnil;
1331
1332 buf[0] = (char) rl_completion_quote_character;
1333 return rb_locale_str_new(buf, 1);
1334}
1335#else
1336#define readline_s_get_completion_quote_character rb_f_notimplement
1337#endif
1338
1339#ifdef HAVE_RL_BASIC_WORD_BREAK_CHARACTERS
1340/*
1341 * call-seq:
1342 * Readline.basic_word_break_characters = string
1343 *
1344 * Sets the basic list of characters that signal a break between words
1345 * for the completer routine. The default is the characters which
1346 * break words for completion in Bash: " \t\n\"\\'`@$><=;|&{(".
1347 *
1348 * Raises NotImplementedError if the using readline library does not support.
1349 */
1350static VALUE
1352{
1353 static char *basic_word_break_characters = NULL;
1354
1356 if (basic_word_break_characters == NULL) {
1357 basic_word_break_characters =
1358 ALLOC_N(char, RSTRING_LEN(str) + 1);
1359 }
1360 else {
1361 REALLOC_N(basic_word_break_characters, char, RSTRING_LEN(str) + 1);
1362 }
1363 strncpy(basic_word_break_characters,
1365 basic_word_break_characters[RSTRING_LEN(str)] = '\0';
1366 rl_basic_word_break_characters = basic_word_break_characters;
1367 return self;
1368}
1369#else
1370#define readline_s_set_basic_word_break_characters rb_f_notimplement
1371#endif
1372
1373#ifdef HAVE_RL_BASIC_WORD_BREAK_CHARACTERS
1374/*
1375 * call-seq:
1376 * Readline.basic_word_break_characters -> string
1377 *
1378 * Gets the basic list of characters that signal a break between words
1379 * for the completer routine.
1380 *
1381 * Raises NotImplementedError if the using readline library does not support.
1382 */
1383static VALUE
1385{
1386 if (rl_basic_word_break_characters == NULL)
1387 return Qnil;
1388 return rb_locale_str_new_cstr(rl_basic_word_break_characters);
1389}
1390#else
1391#define readline_s_get_basic_word_break_characters rb_f_notimplement
1392#endif
1393
1394#ifdef HAVE_RL_COMPLETER_WORD_BREAK_CHARACTERS
1395/*
1396 * call-seq:
1397 * Readline.completer_word_break_characters = string
1398 *
1399 * Sets the basic list of characters that signal a break between words
1400 * for rl_complete_internal(). The default is the value of
1401 * Readline.basic_word_break_characters.
1402 *
1403 * Raises NotImplementedError if the using readline library does not support.
1404 */
1405static VALUE
1407{
1408 static char *completer_word_break_characters = NULL;
1409
1411 if (completer_word_break_characters == NULL) {
1412 completer_word_break_characters =
1413 ALLOC_N(char, RSTRING_LEN(str) + 1);
1414 }
1415 else {
1416 REALLOC_N(completer_word_break_characters, char, RSTRING_LEN(str) + 1);
1417 }
1418 strncpy(completer_word_break_characters,
1420 completer_word_break_characters[RSTRING_LEN(str)] = '\0';
1421 rl_completer_word_break_characters = completer_word_break_characters;
1422 return self;
1423}
1424#else
1425#define readline_s_set_completer_word_break_characters rb_f_notimplement
1426#endif
1427
1428#ifdef HAVE_RL_COMPLETER_WORD_BREAK_CHARACTERS
1429/*
1430 * call-seq:
1431 * Readline.completer_word_break_characters -> string
1432 *
1433 * Gets the basic list of characters that signal a break between words
1434 * for rl_complete_internal().
1435 *
1436 * Raises NotImplementedError if the using readline library does not support.
1437 */
1438static VALUE
1440{
1441 if (rl_completer_word_break_characters == NULL)
1442 return Qnil;
1443 return rb_locale_str_new_cstr(rl_completer_word_break_characters);
1444}
1445#else
1446#define readline_s_get_completer_word_break_characters rb_f_notimplement
1447#endif
1448
1449#if defined(HAVE_RL_SPECIAL_PREFIXES)
1450/*
1451 * call-seq:
1452 * Readline.special_prefixes = string
1453 *
1454 * Sets the list of characters that are word break characters, but
1455 * should be left in text when it is passed to the completion
1456 * function. Programs can use this to help determine what kind of
1457 * completing to do. For instance, Bash sets this variable to "$@" so
1458 * that it can complete shell variables and hostnames.
1459 *
1460 * See GNU Readline's rl_special_prefixes variable.
1461 *
1462 * Raises NotImplementedError if the using readline library does not support.
1463 */
1464static VALUE
1466{
1467 if (!NIL_P(str)) {
1471 }
1472 rb_ivar_set(mReadline, id_special_prefixes, str);
1473 if (NIL_P(str)) {
1474 rl_special_prefixes = NULL;
1475 }
1476 else {
1477 rl_special_prefixes = RSTRING_PTR(str);
1478 }
1479 return self;
1480}
1481
1482/*
1483 * call-seq:
1484 * Readline.special_prefixes -> string
1485 *
1486 * Gets the list of characters that are word break characters, but
1487 * should be left in text when it is passed to the completion
1488 * function.
1489 *
1490 * See GNU Readline's rl_special_prefixes variable.
1491 *
1492 * Raises NotImplementedError if the using readline library does not support.
1493 */
1494static VALUE
1496{
1497 VALUE str;
1498 if (rl_special_prefixes == NULL) return Qnil;
1499 str = rb_ivar_get(mReadline, id_special_prefixes);
1500 if (!NIL_P(str)) {
1503 }
1504 return str;
1505}
1506#else
1507#define readline_s_set_special_prefixes rb_f_notimplement
1508#define readline_s_get_special_prefixes rb_f_notimplement
1509#endif
1510
1511#ifdef HAVE_RL_BASIC_QUOTE_CHARACTERS
1512/*
1513 * call-seq:
1514 * Readline.basic_quote_characters = string
1515 *
1516 * Sets a list of quote characters which can cause a word break.
1517 *
1518 * Raises NotImplementedError if the using readline library does not support.
1519 */
1520static VALUE
1522{
1523 static char *basic_quote_characters = NULL;
1524
1526 if (basic_quote_characters == NULL) {
1527 basic_quote_characters =
1528 ALLOC_N(char, RSTRING_LEN(str) + 1);
1529 }
1530 else {
1531 REALLOC_N(basic_quote_characters, char, RSTRING_LEN(str) + 1);
1532 }
1533 strncpy(basic_quote_characters,
1535 basic_quote_characters[RSTRING_LEN(str)] = '\0';
1536 rl_basic_quote_characters = basic_quote_characters;
1537
1538 return self;
1539}
1540#else
1541#define readline_s_set_basic_quote_characters rb_f_notimplement
1542#endif
1543
1544#ifdef HAVE_RL_BASIC_QUOTE_CHARACTERS
1545/*
1546 * call-seq:
1547 * Readline.basic_quote_characters -> string
1548 *
1549 * Gets a list of quote characters which can cause a word break.
1550 *
1551 * Raises NotImplementedError if the using readline library does not support.
1552 */
1553static VALUE
1555{
1556 if (rl_basic_quote_characters == NULL)
1557 return Qnil;
1558 return rb_locale_str_new_cstr(rl_basic_quote_characters);
1559}
1560#else
1561#define readline_s_get_basic_quote_characters rb_f_notimplement
1562#endif
1563
1564#ifdef HAVE_RL_COMPLETER_QUOTE_CHARACTERS
1565/*
1566 * call-seq:
1567 * Readline.completer_quote_characters = string
1568 *
1569 * Sets a list of characters which can be used to quote a substring of
1570 * the line. Completion occurs on the entire substring, and within
1571 * the substring Readline.completer_word_break_characters are treated
1572 * as any other character, unless they also appear within this list.
1573 *
1574 * Raises NotImplementedError if the using readline library does not support.
1575 */
1576static VALUE
1578{
1579 static char *completer_quote_characters = NULL;
1580
1582 if (completer_quote_characters == NULL) {
1583 completer_quote_characters =
1584 ALLOC_N(char, RSTRING_LEN(str) + 1);
1585 }
1586 else {
1587 REALLOC_N(completer_quote_characters, char, RSTRING_LEN(str) + 1);
1588 }
1589 strncpy(completer_quote_characters, RSTRING_PTR(str), RSTRING_LEN(str));
1590 completer_quote_characters[RSTRING_LEN(str)] = '\0';
1591 rl_completer_quote_characters = completer_quote_characters;
1592
1593 return self;
1594}
1595#else
1596#define readline_s_set_completer_quote_characters rb_f_notimplement
1597#endif
1598
1599#ifdef HAVE_RL_COMPLETER_QUOTE_CHARACTERS
1600/*
1601 * call-seq:
1602 * Readline.completer_quote_characters -> string
1603 *
1604 * Gets a list of characters which can be used to quote a substring of
1605 * the line.
1606 *
1607 * Raises NotImplementedError if the using readline library does not support.
1608 */
1609static VALUE
1611{
1612 if (rl_completer_quote_characters == NULL)
1613 return Qnil;
1614 return rb_locale_str_new_cstr(rl_completer_quote_characters);
1615}
1616#else
1617#define readline_s_get_completer_quote_characters rb_f_notimplement
1618#endif
1619
1620#ifdef HAVE_RL_FILENAME_QUOTE_CHARACTERS
1621/*
1622 * call-seq:
1623 * Readline.filename_quote_characters = string
1624 *
1625 * Sets a list of characters that cause a filename to be quoted by the completer
1626 * when they appear in a completed filename. The default is nil.
1627 *
1628 * Raises NotImplementedError if the using readline library does not support.
1629 */
1630static VALUE
1632{
1633 static char *filename_quote_characters = NULL;
1634
1636 if (filename_quote_characters == NULL) {
1637 filename_quote_characters =
1638 ALLOC_N(char, RSTRING_LEN(str) + 1);
1639 }
1640 else {
1641 REALLOC_N(filename_quote_characters, char, RSTRING_LEN(str) + 1);
1642 }
1643 strncpy(filename_quote_characters, RSTRING_PTR(str), RSTRING_LEN(str));
1644 filename_quote_characters[RSTRING_LEN(str)] = '\0';
1645 rl_filename_quote_characters = filename_quote_characters;
1646
1647 return self;
1648}
1649#else
1650#define readline_s_set_filename_quote_characters rb_f_notimplement
1651#endif
1652
1653#ifdef HAVE_RL_FILENAME_QUOTE_CHARACTERS
1654/*
1655 * call-seq:
1656 * Readline.filename_quote_characters -> string
1657 *
1658 * Gets a list of characters that cause a filename to be quoted by the completer
1659 * when they appear in a completed filename.
1660 *
1661 * Raises NotImplementedError if the using readline library does not support.
1662 */
1663static VALUE
1665{
1666 if (rl_filename_quote_characters == NULL)
1667 return Qnil;
1668 return rb_locale_str_new_cstr(rl_filename_quote_characters);
1669}
1670#else
1671#define readline_s_get_filename_quote_characters rb_f_notimplement
1672#endif
1673
1674#ifdef HAVE_RL_REFRESH_LINE
1675int rl_refresh_line(int, int);
1676/*
1677 * call-seq:
1678 * Readline.refresh_line -> nil
1679 *
1680 * Clear the current input line.
1681 */
1682static VALUE
1684{
1685 prepare_readline();
1686 rl_refresh_line(0, 0);
1687 return Qnil;
1688}
1689#else
1690#define readline_s_refresh_line rb_f_notimplement
1691#endif
1692
1693static VALUE
1694hist_to_s(VALUE self)
1695{
1696 return rb_str_new_cstr("HISTORY");
1697}
1698
1699static int
1700history_get_offset_history_base(int offset)
1701{
1702 return history_base + offset;
1703}
1704
1705static int
1706history_get_offset_0(int offset)
1707{
1708 return offset;
1709}
1710
1711static VALUE
1712hist_get(VALUE self, VALUE index)
1713{
1714 HIST_ENTRY *entry = NULL;
1715 int i;
1716
1717 i = NUM2INT(index);
1718 if (i < 0) {
1719 i += history_length;
1720 }
1721 if (i >= 0) {
1722 entry = history_get(history_get_offset_func(i));
1723 }
1724 if (entry == NULL) {
1725 rb_raise(rb_eIndexError, "invalid index");
1726 }
1727 return rb_locale_str_new_cstr(entry->line);
1728}
1729
1730#ifdef HAVE_REPLACE_HISTORY_ENTRY
1731static VALUE
1733{
1734 HIST_ENTRY *entry = NULL;
1735 int i;
1736
1737 i = NUM2INT(index);
1739 if (i < 0) {
1740 i += history_length;
1741 }
1742 if (i >= 0) {
1743 entry = replace_history_entry(history_replace_offset_func(i), RSTRING_PTR(str), NULL);
1744 }
1745 if (entry == NULL) {
1746 rb_raise(rb_eIndexError, "invalid index");
1747 }
1748 return str;
1749}
1750#else
1751#define hist_set rb_f_notimplement
1752#endif
1753
1754static VALUE
1755hist_push(VALUE self, VALUE str)
1756{
1758 add_history(RSTRING_PTR(str));
1759 return self;
1760}
1761
1762static VALUE
1763hist_push_method(int argc, VALUE *argv, VALUE self)
1764{
1765 VALUE str;
1766
1767 while (argc--) {
1768 str = *argv++;
1770 add_history(RSTRING_PTR(str));
1771 }
1772 return self;
1773}
1774
1775static VALUE
1776rb_remove_history(int index)
1777{
1778#ifdef HAVE_REMOVE_HISTORY
1779 HIST_ENTRY *entry;
1780 VALUE val;
1781
1782 entry = remove_history(index);
1783 if (entry) {
1784 val = rb_locale_str_new_cstr(entry->line);
1785 free((void *) entry->line);
1786 free(entry);
1787 return val;
1788 }
1789 return Qnil;
1790#else
1792
1794#endif
1795}
1796
1797static VALUE
1798hist_pop(VALUE self)
1799{
1800 if (history_length > 0) {
1801 return rb_remove_history(history_length - 1);
1802 } else {
1803 return Qnil;
1804 }
1805}
1806
1807static VALUE
1808hist_shift(VALUE self)
1809{
1810 if (history_length > 0) {
1811 return rb_remove_history(0);
1812 } else {
1813 return Qnil;
1814 }
1815}
1816
1817static VALUE
1818hist_each(VALUE self)
1819{
1820 HIST_ENTRY *entry;
1821 int i;
1822
1823 RETURN_ENUMERATOR(self, 0, 0);
1824
1825 for (i = 0; i < history_length; i++) {
1826 entry = history_get(history_get_offset_func(i));
1827 if (entry == NULL)
1828 break;
1829 rb_yield(rb_locale_str_new_cstr(entry->line));
1830 }
1831 return self;
1832}
1833
1834static VALUE
1835hist_length(VALUE self)
1836{
1837 return INT2NUM(history_length);
1838}
1839
1840static VALUE
1841hist_empty_p(VALUE self)
1842{
1843 return history_length == 0 ? Qtrue : Qfalse;
1844}
1845
1846static VALUE
1847hist_delete_at(VALUE self, VALUE index)
1848{
1849 int i;
1850
1851 i = NUM2INT(index);
1852 if (i < 0)
1853 i += history_length;
1854 if (i < 0 || i > history_length - 1) {
1855 rb_raise(rb_eIndexError, "invalid index");
1856 }
1857 return rb_remove_history(i);
1858}
1859
1860#ifdef HAVE_CLEAR_HISTORY
1861static VALUE
1862hist_clear(VALUE self)
1863{
1864 clear_history();
1865 return self;
1866}
1867#else
1868#define hist_clear rb_f_notimplement
1869#endif
1870
1871static VALUE
1872filename_completion_proc_call(VALUE self, VALUE str)
1873{
1874 VALUE result;
1875 char **matches;
1876 int i;
1877
1880 if (matches) {
1881 result = rb_ary_new();
1882 for (i = 0; matches[i]; i++) {
1883 rb_ary_push(result, rb_locale_str_new_cstr(matches[i]));
1884 free(matches[i]);
1885 }
1886 free(matches);
1887 if (RARRAY_LEN(result) >= 2)
1888 rb_ary_shift(result);
1889 }
1890 else {
1891 result = Qnil;
1892 }
1893 return result;
1894}
1895
1896static VALUE
1897username_completion_proc_call(VALUE self, VALUE str)
1898{
1899 VALUE result;
1900 char **matches;
1901 int i;
1902
1905 if (matches) {
1906 result = rb_ary_new();
1907 for (i = 0; matches[i]; i++) {
1908 rb_ary_push(result, rb_locale_str_new_cstr(matches[i]));
1909 free(matches[i]);
1910 }
1911 free(matches);
1912 if (RARRAY_LEN(result) >= 2)
1913 rb_ary_shift(result);
1914 }
1915 else {
1916 result = Qnil;
1917 }
1918 return result;
1919}
1920
1921#ifdef HAVE_RL_CLEAR_SIGNALS
1922int rl_clear_signals(void);
1923#endif
1924
1925#undef rb_intern
1926void
1928{
1929 VALUE history, fcomp, ucomp, version;
1930
1931 /* Allow conditional parsing of the ~/.inputrc file. */
1932 rl_readline_name = (char *)"Ruby";
1933
1934#if defined HAVE_RL_GETC_FUNCTION
1935 /* libedit check rl_getc_function only when rl_initialize() is called, */
1936 /* and using_history() call rl_initialize(). */
1937 /* This assignment should be placed before using_history() */
1938 rl_getc_function = readline_getc;
1939#elif defined HAVE_RL_EVENT_HOOK
1940 rl_event_hook = readline_event;
1941#endif
1942
1943 using_history();
1944
1945 id_call = rb_intern("call");
1946 completion_proc = rb_intern(COMPLETION_PROC);
1947 completion_case_fold = rb_intern(COMPLETION_CASE_FOLD);
1948#if defined(HAVE_RL_PRE_INPUT_HOOK)
1949 id_pre_input_hook = rb_intern("pre_input_hook");
1950#endif
1951#if defined(HAVE_RL_SPECIAL_PREFIXES)
1952 id_special_prefixes = rb_intern("special_prefixes");
1953#endif
1954#if defined HAVE_RL_CHAR_IS_QUOTED_P
1955 quoting_detection_proc = rb_intern(QUOTING_DETECTION_PROC);
1956#endif
1957
1958 mReadline = rb_define_module("Readline");
1959 rb_define_module_function(mReadline, "readline",
1960 readline_readline, -1);
1961 rb_define_singleton_method(mReadline, "input=",
1962 readline_s_set_input, 1);
1963 rb_define_singleton_method(mReadline, "output=",
1964 readline_s_set_output, 1);
1965 rb_define_singleton_method(mReadline, "completion_proc=",
1966 readline_s_set_completion_proc, 1);
1967 rb_define_singleton_method(mReadline, "completion_proc",
1968 readline_s_get_completion_proc, 0);
1969 rb_define_singleton_method(mReadline, "quoting_detection_proc=",
1971 rb_define_singleton_method(mReadline, "quoting_detection_proc",
1973 rb_define_singleton_method(mReadline, "completion_case_fold=",
1974 readline_s_set_completion_case_fold, 1);
1975 rb_define_singleton_method(mReadline, "completion_case_fold",
1976 readline_s_get_completion_case_fold, 0);
1977 rb_define_singleton_method(mReadline, "line_buffer",
1979 rb_define_singleton_method(mReadline, "point",
1981 rb_define_singleton_method(mReadline, "point=",
1983 rb_define_singleton_method(mReadline, "set_screen_size",
1985 rb_define_singleton_method(mReadline, "get_screen_size",
1987 rb_define_singleton_method(mReadline, "vi_editing_mode",
1989 rb_define_singleton_method(mReadline, "vi_editing_mode?",
1991 rb_define_singleton_method(mReadline, "emacs_editing_mode",
1993 rb_define_singleton_method(mReadline, "emacs_editing_mode?",
1995 rb_define_singleton_method(mReadline, "completion_append_character=",
1997 rb_define_singleton_method(mReadline, "completion_append_character",
1999 rb_define_singleton_method(mReadline, "completion_quote_character",
2001 rb_define_singleton_method(mReadline, "basic_word_break_characters=",
2003 rb_define_singleton_method(mReadline, "basic_word_break_characters",
2005 rb_define_singleton_method(mReadline, "completer_word_break_characters=",
2007 rb_define_singleton_method(mReadline, "completer_word_break_characters",
2009 rb_define_singleton_method(mReadline, "basic_quote_characters=",
2011 rb_define_singleton_method(mReadline, "basic_quote_characters",
2013 rb_define_singleton_method(mReadline, "completer_quote_characters=",
2015 rb_define_singleton_method(mReadline, "completer_quote_characters",
2017 rb_define_singleton_method(mReadline, "filename_quote_characters=",
2019 rb_define_singleton_method(mReadline, "filename_quote_characters",
2021 rb_define_singleton_method(mReadline, "refresh_line",
2023 rb_define_singleton_method(mReadline, "pre_input_hook=",
2025 rb_define_singleton_method(mReadline, "pre_input_hook",
2027 rb_define_singleton_method(mReadline, "insert_text",
2029 rb_define_singleton_method(mReadline, "delete_text",
2031 rb_define_singleton_method(mReadline, "redisplay",
2033 rb_define_singleton_method(mReadline, "special_prefixes=",
2035 rb_define_singleton_method(mReadline, "special_prefixes",
2037
2038#if USE_INSERT_IGNORE_ESCAPE
2039 id_orig_prompt = rb_intern("orig_prompt");
2040 id_last_prompt = rb_intern("last_prompt");
2041#endif
2042
2043 history = rb_obj_alloc(rb_cObject);
2045 rb_define_singleton_method(history,"to_s", hist_to_s, 0);
2046 rb_define_singleton_method(history,"[]", hist_get, 1);
2047 rb_define_singleton_method(history,"[]=", hist_set, 2);
2048 rb_define_singleton_method(history,"<<", hist_push, 1);
2049 rb_define_singleton_method(history,"push", hist_push_method, -1);
2050 rb_define_singleton_method(history,"pop", hist_pop, 0);
2051 rb_define_singleton_method(history,"shift", hist_shift, 0);
2052 rb_define_singleton_method(history,"each", hist_each, 0);
2053 rb_define_singleton_method(history,"length", hist_length, 0);
2054 rb_define_singleton_method(history,"size", hist_length, 0);
2055 rb_define_singleton_method(history,"empty?", hist_empty_p, 0);
2056 rb_define_singleton_method(history,"delete_at", hist_delete_at, 1);
2057 rb_define_singleton_method(history,"clear", hist_clear, 0);
2058
2059 /*
2060 * The history buffer. It extends Enumerable module, so it behaves
2061 * just like an array.
2062 * For example, gets the fifth content that the user input by
2063 * HISTORY[4].
2064 */
2065 rb_define_const(mReadline, "HISTORY", history);
2066
2067 fcomp = rb_obj_alloc(rb_cObject);
2068 rb_define_singleton_method(fcomp, "call",
2069 filename_completion_proc_call, 1);
2070 /*
2071 * The Object with the call method that is a completion for filename.
2072 * This is sets by Readline.completion_proc= method.
2073 */
2074 rb_define_const(mReadline, "FILENAME_COMPLETION_PROC", fcomp);
2075
2076 ucomp = rb_obj_alloc(rb_cObject);
2077 rb_define_singleton_method(ucomp, "call",
2078 username_completion_proc_call, 1);
2079 /*
2080 * The Object with the call method that is a completion for usernames.
2081 * This is sets by Readline.completion_proc= method.
2082 */
2083 rb_define_const(mReadline, "USERNAME_COMPLETION_PROC", ucomp);
2084 history_get_offset_func = history_get_offset_history_base;
2085 history_replace_offset_func = history_get_offset_0;
2086#if defined HAVE_RL_LIBRARY_VERSION
2087 version = rb_str_new_cstr(rl_library_version);
2088#if defined HAVE_CLEAR_HISTORY || defined HAVE_REMOVE_HISTORY
2089 if (strncmp(rl_library_version, EDIT_LINE_LIBRARY_VERSION,
2091 add_history("1");
2092 if (history_get(history_get_offset_func(0)) == NULL) {
2093 history_get_offset_func = history_get_offset_0;
2094 }
2095#ifdef HAVE_REPLACE_HISTORY_ENTRY
2096 if (replace_history_entry(0, "a", NULL) == NULL) {
2097 history_replace_offset_func = history_get_offset_history_base;
2098 }
2099#endif
2100#ifdef HAVE_CLEAR_HISTORY
2101 clear_history();
2102#else
2103 {
2104 HIST_ENTRY *entry = remove_history(0);
2105 if (entry) {
2106 free((char *)entry->line);
2107 free(entry);
2108 }
2109 }
2110#endif
2111 }
2112#endif
2113#else
2114 version = rb_str_new_cstr("2.0 or prior version");
2115#endif
2116 /* Version string of GNU Readline or libedit. */
2117 rb_define_const(mReadline, "VERSION", version);
2118
2119 rl_attempted_completion_function = readline_attempted_completion_function;
2120#if defined(HAVE_RL_PRE_INPUT_HOOK)
2121 rl_pre_input_hook = (rl_hook_func_t *)readline_pre_input_hook;
2122#endif
2123#if defined HAVE_RL_CHAR_IS_QUOTED_P
2124 rl_char_is_quoted_p = &readline_char_is_quoted;
2125#endif
2126#ifdef HAVE_RL_CATCH_SIGNALS
2127 rl_catch_signals = 0;
2128#endif
2129#ifdef HAVE_RL_CLEAR_SIGNALS
2130 rl_clear_signals();
2131#endif
2132
2133 rb_gc_register_address(&readline_instream);
2134 rb_gc_register_address(&readline_outstream);
2135}
2136
2137/*
2138 * Local variables:
2139 * indent-tabs-mode: nil
2140 * end:
2141 */
int errno
struct RIMemo * ptr
Definition: debug.c:65
#define free(x)
Definition: dln.c:52
unsigned int rb_enc_codepoint_len(const char *p, const char *e, int *len_p, rb_encoding *enc)
Definition: encoding.c:1068
rb_encoding * rb_enc_check(VALUE str1, VALUE str2)
Definition: encoding.c:891
rb_encoding * rb_locale_encoding(void)
Definition: encoding.c:1372
VALUE rb_enc_from_encoding(rb_encoding *encoding)
Definition: encoding.c:116
VALUE rb_enc_str_new_static(const char *, long, rb_encoding *)
Definition: string.c:890
long rb_enc_strlen(const char *, const char *, rb_encoding *)
Definition: string.c:1740
char str[HTML_ESCAPE_MAX_LEN+1]
Definition: escape.c:18
ID id_call
Definition: eventids1.c:30
void rb_memerror(void)
Definition: gc.c:9611
void rb_extend_object(VALUE, VALUE)
Extend the object with the module.
Definition: eval.c:1701
VALUE rb_define_module(const char *)
Definition: class.c:785
VALUE rb_cObject
Object class.
Definition: ruby.h:2012
VALUE rb_eIOError
Definition: ruby.h:2066
VALUE rb_cString
Definition: ruby.h:2046
VALUE rb_mEnumerable
Definition: enum.c:20
void rb_notimplement(void)
Definition: error.c:2714
void rb_syserr_fail(int e, const char *mesg)
Definition: error.c:2783
void rb_raise(VALUE exc, const char *fmt,...)
Definition: error.c:2671
void rb_bug(const char *fmt,...)
Definition: error.c:636
VALUE rb_protect(VALUE(*)(VALUE), VALUE, int *)
Protects a function call from potential global escapes from the function.
Definition: eval.c:1072
VALUE rb_eArgError
Definition: error.c:925
VALUE rb_eIndexError
Definition: error.c:926
void rb_jump_tag(int tag)
Continues the exception caught by rb_protect() and rb_eval_string_protect().
Definition: eval.c:884
void rb_sys_fail(const char *mesg)
Definition: error.c:2795
VALUE rb_obj_reveal(VALUE obj, VALUE klass)
Make a hidden object visible again.
Definition: object.c:95
VALUE rb_obj_alloc(VALUE)
Allocates an instance of klass.
Definition: object.c:1895
VALUE rb_obj_hide(VALUE obj)
Make the object invisible from Ruby code.
Definition: object.c:78
VALUE rb_Array(VALUE)
Equivalent to Kernel#Array in Ruby.
Definition: object.c:3684
int rb_wait_for_single_fd(int fd, int events, struct timeval *tv)
Definition: thread.c:4275
VALUE rb_io_taint_check(VALUE)
Definition: io.c:703
#define RB_WAITFD_IN
Definition: io.h:51
#define GetOpenFile(obj, fp)
Definition: io.h:127
void rb_io_check_initialized(rb_io_t *)
Definition: io.c:710
unsigned int input
Definition: nkf.c:4325
unsigned char buf[MIME_BUF_SIZE]
Definition: nkf.c:4322
#define RARRAY_LEN(a)
VALUE rb_str_unlocktmp(VALUE)
Definition: string.c:2675
#define NULL
#define T_FILE
#define RSTRING_LEN(str)
#define RTEST(v)
size_t strlen(const char *)
void * malloc(size_t) __attribute__((__malloc__)) __attribute__((__warn_unused_result__)) __attribute__((__alloc_size__(1)))
#define StringValuePtr(v)
VALUE rb_str_new_shared(VALUE)
Definition: string.c:1197
int close(int __fildes)
char * rb_str_subpos(VALUE, long, long *)
Definition: string.c:2497
#define LONG2FIX(i)
VALUE rb_range_beg_len(VALUE, long *, long *, long, int)
Definition: range.c:1278
VALUE rb_ivar_get(VALUE, ID)
Definition: variable.c:1070
int fileno(FILE *)
#define RSTRING_PTR(str)
#define RUBY_UBF_IO
char * strncpy(char *__restrict__, const char *__restrict__, size_t)
#define EINTR
#define NIL_P(v)
#define EWOULDBLOCK
VALUE rb_str_cat(VALUE, const char *, long)
Definition: string.c:2812
VALUE rb_locale_str_new(const char *, long)
Definition: string.c:1099
#define REALLOC_N(var, type, n)
char * strcpy(char *__restrict__, const char *__restrict__)
const char size_t n
void rb_str_set_len(VALUE, long)
Definition: string.c:2692
int rb_respond_to(VALUE, ID)
Definition: vm_method.c:2207
VALUE rb_ary_push(VALUE, VALUE)
Definition: array.c:1195
int fclose(FILE *)
uint32_t i
#define char
int strncmp(const char *, const char *, size_t)
__inline__ const void *__restrict__ size_t len
#define ALLOC_N(type, n)
#define OBJ_FREEZE(x)
#define INT2NUM(x)
void rb_define_module_function(VALUE, const char *, VALUE(*)(), int)
void rb_define_const(VALUE, const char *, VALUE)
Definition: variable.c:2891
#define NUM2INT(x)
void rb_define_singleton_method(VALUE, const char *, VALUE(*)(), int)
#define rb_long2int(n)
#define rb_funcall(recv, mid, argc,...)
VALUE rb_ary_new(void)
Definition: array.c:723
#define rb_scan_args(argc, argvp, fmt,...)
void rb_gc_register_address(VALUE *)
Definition: gc.c:7093
int int int int int int int int char char int int int int int int int int int char char int int int int int int int int FILE * fdopen(int, const char *)
VALUE rb_str_tmp_new(long)
Definition: string.c:1343
void rb_thread_check_ints(void)
Definition: thread.c:1361
#define rb_intern(str)
#define UNREACHABLE_RETURN(val)
#define stdin
#define Qtrue
char * strdup(const char *) __attribute__((__malloc__)) __attribute__((__warn_unused_result__))
VALUE rb_attr_get(VALUE, ID)
Definition: variable.c:1084
#define Qnil
#define Qfalse
#define T_ARRAY
#define rb_locale_str_new_cstr(str)
#define RB_TYPE_P(obj, type)
#define rb_str_dup_frozen
VALUE rb_str_locktmp(VALUE)
void rb_gc_force_recycle(VALUE)
Definition: gc.c:7027
#define RFILE(obj)
VALUE rb_obj_as_string(VALUE)
Definition: string.c:1440
const VALUE * argv
_ssize_t ssize_t
__inline__ int
VALUE rb_ary_shift(VALUE)
Definition: array.c:1294
VALUE rb_ivar_set(VALUE, ID, VALUE)
Definition: variable.c:1300
#define RETURN_ENUMERATOR(obj, argc, argv)
void rb_thread_schedule(void)
Definition: thread.c:1407
#define Check_Type(v, t)
#define rb_check_arity
long rb_str_sublen(VALUE, long)
Definition: string.c:2463
#define PRIdSIZE
int rb_cloexec_dup(int oldfd)
Definition: io.c:318
unsigned long ID
VALUE rb_yield(VALUE)
Definition: vm_eval.c:1237
size_t st_index_t h
#define NUM2LONG(x)
#define RARRAY_AREF(a, i)
#define EAGAIN
#define rb_str_new_cstr(str)
_ssize_t read(int __fd, void *__buf, size_t __nbyte)
#define StringValueCStr(v)
#define ISALPHA(c)
#define hist_clear
Definition: readline.c:1868
void Init_readline(void)
Definition: readline.c:1927
#define readline_s_get_completion_quote_character
Definition: readline.c:1336
#define readline_s_refresh_line
Definition: readline.c:1690
#define readline_s_vi_editing_mode_p
Definition: readline.c:1186
#define OutputStringValue(str)
Definition: readline.c:96
#define readline_s_set_screen_size
Definition: readline.c:1120
#define readline_s_vi_editing_mode
Definition: readline.c:1168
#define readline_s_set_basic_word_break_characters
Definition: readline.c:1370
#define readline_s_get_screen_size
Definition: readline.c:1147
#define readline_s_get_special_prefixes
Definition: readline.c:1508
#define readline_s_set_point
Definition: readline.c:999
#define readline_s_delete_text
Definition: readline.c:744
#define readline_s_set_pre_input_hook
Definition: readline.c:665
#define readline_s_set_completion_append_character
Definition: readline.c:1282
#define readline_s_set_basic_quote_characters
Definition: readline.c:1541
#define readline_s_set_completer_word_break_characters
Definition: readline.c:1425
#define readline_s_set_filename_quote_characters
Definition: readline.c:1650
#define readline_s_get_quoting_detection_proc
Definition: readline.c:898
#define readline_s_set_quoting_detection_proc
Definition: readline.c:897
#define readline_s_emacs_editing_mode
Definition: readline.c:1207
#define rl_completion_matches
Definition: readline.c:84
#define readline_s_get_basic_quote_characters
Definition: readline.c:1561
#define readline_s_get_pre_input_hook
Definition: readline.c:666
#define hist_set
Definition: readline.c:1751
#define rl_filename_completion_function
Definition: readline.c:76
#define readline_s_get_filename_quote_characters
Definition: readline.c:1671
#define readline_s_set_special_prefixes
Definition: readline.c:1507
#define COMPLETION_CASE_FOLD
Definition: readline.c:59
#define readline_s_redisplay
Definition: readline.c:766
#define readline_s_get_line_buffer
Definition: readline.c:955
#define readline_s_get_completer_quote_characters
Definition: readline.c:1617
#define readline_s_get_point
Definition: readline.c:998
#define rl_username_completion_function
Definition: readline.c:79
#define readline_s_insert_text
Definition: readline.c:688
#define readline_s_get_completer_word_break_characters
Definition: readline.c:1446
#define readline_s_set_completer_quote_characters
Definition: readline.c:1596
#define EDIT_LINE_LIBRARY_VERSION
Definition: readline.c:49
#define readline_s_get_completion_append_character
Definition: readline.c:1307
#define readline_s_emacs_editing_mode_p
Definition: readline.c:1225
#define readline_s_get_basic_word_break_characters
Definition: readline.c:1391
#define COMPLETION_PROC
Definition: readline.c:58
unsigned long VALUE
Definition: ruby.h:102
#define f
Definition: io.h:66
int fd
Definition: io.h:68
void * rb_thread_call_without_gvl2(void *(*func)(void *), void *data1, rb_unblock_function_t *ubf, void *data2)
Definition: thread.c:1580
int rb_w32_wait_events_blocking(HANDLE *events, int num, DWORD timeout)
IUnknown DWORD
Definition: win32ole.c:33