Skip to content

Readline.delete text #132

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Closed
wants to merge 3 commits into from
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions ext/readline/extconf.rb
Original file line number Diff line number Diff line change
Expand Up @@ -97,6 +97,7 @@ def readline.have_macro(macro)
readline.have_func("clear_history")
readline.have_func("rl_redisplay")
readline.have_func("rl_insert_text")
readline.have_func("rl_delete_text")
readline.have_macro("RL_PROMPT_START_IGNORE")
readline.have_macro("RL_PROMPT_END_IGNORE")
create_makefile("readline")
54 changes: 54 additions & 0 deletions ext/readline/readline.c
Original file line number Diff line number Diff line change
Expand Up @@ -564,6 +564,58 @@ readline_s_insert_text(VALUE self, VALUE str)
#define readline_s_insert_text rb_f_notimplement
#endif

#if defined(HAVE_RL_DELETE_TEXT)
/*
* call-seq:
* Readline.delete_text([start[, length]]) -> self
* Readline.delete_text(start..end) -> self
* Readline.delete_text() -> self
*
* Delete text between start and end in the current line.
*
* See GNU Readline's rl_delete_text function.
*
* Raises SecurityError if $SAFE is 4.
*/
static VALUE
readline_s_delete_text(int argc, VALUE *argv, VALUE self)
{
rb_secure(4);
rb_check_arity(argc, 0, 2);
if (rl_line_buffer) {
char *p, *ptr = rl_line_buffer;
long beg = 0, len = strlen(rl_line_buffer);
struct RString fakestr;
VALUE str = (VALUE)&fakestr;

fakestr.basic.flags = T_STRING | RSTRING_NOEMBED;
fakestr.as.heap.ptr = ptr;
fakestr.as.heap.len = len;
rb_enc_associate(str, rb_locale_encoding());
OBJ_FREEZE(str);
if (argc == 2) {
beg = NUM2LONG(argv[0]);
len = NUM2LONG(argv[1]);
num_pos:
p = rb_str_subpos(str, beg, &len);
if (!p) rb_raise(rb_eArgError, "invalid index");
beg = p - ptr;
}
else if (argc == 1) {
len = rb_str_strlen(str);
if (!rb_range_beg_len(argv[0], &beg, &len, len, 1)) {
beg = NUM2LONG(argv[0]);
goto num_pos;
}
}
rl_delete_text(rb_long2int(beg), rb_long2int(beg + len));
}
return self;
}
#else
#define readline_s_delete_text rb_f_notimplement
#endif

#if defined(HAVE_RL_REDISPLAY)
/*
* call-seq:
Expand Down Expand Up @@ -1793,6 +1845,8 @@ Init_readline()
readline_s_get_pre_input_hook, 0);
rb_define_singleton_method(mReadline, "insert_text",
readline_s_insert_text, 1);
rb_define_singleton_method(mReadline, "delete_text",
readline_s_delete_text, -1);
rb_define_singleton_method(mReadline, "redisplay",
readline_s_redisplay, 0);
rb_define_singleton_method(mReadline, "special_prefixes=",
Expand Down
1 change: 1 addition & 0 deletions include/ruby/intern.h
Original file line number Diff line number Diff line change
Expand Up @@ -704,6 +704,7 @@ VALUE rb_str_times(VALUE, VALUE);
long rb_str_sublen(VALUE, long);
VALUE rb_str_substr(VALUE, long, long);
VALUE rb_str_subseq(VALUE, long, long);
char *rb_str_subpos(VALUE, long, long*);
void rb_str_modify(VALUE);
void rb_str_modify_expand(VALUE, long);
VALUE rb_str_freeze(VALUE);
Expand Down
2 changes: 1 addition & 1 deletion string.c
Original file line number Diff line number Diff line change
Expand Up @@ -1635,7 +1635,7 @@ rb_str_subseq(VALUE str, long beg, long len)
return str2;
}

static char *
char *
rb_str_subpos(VALUE str, long beg, long *lenp)
{
long len = *lenp;
Expand Down
23 changes: 21 additions & 2 deletions test/readline/test_readline.rb
Original file line number Diff line number Diff line change
Expand Up @@ -369,6 +369,25 @@ def test_insert_text
assert_equal(str, Readline.line_buffer)
assert_equal(get_default_internal_encoding,
Readline.line_buffer.encoding)

Readline.delete_text(1, 3)
assert_equal("t_insert_text", Readline.line_buffer)
Readline.delete_text(11)
assert_equal("t_insert_te", Readline.line_buffer)
Readline.delete_text(-3...-1)
assert_equal("t_inserte", Readline.line_buffer)
Readline.delete_text(-3..-1)
assert_equal("t_inse", Readline.line_buffer)
Readline.delete_text(3..-3)
assert_equal("t_ise", Readline.line_buffer)
Readline.delete_text(3, 1)
assert_equal("t_ie", Readline.line_buffer)
Readline.delete_text(1..1)
assert_equal("tie", Readline.line_buffer)
Readline.delete_text(1...2)
assert_equal("te", Readline.line_buffer)
Readline.delete_text
assert_equal("", Readline.line_buffer)
rescue NotImplementedError
end
end if !/EditLine/n.match(Readline::VERSION)
Expand Down Expand Up @@ -410,7 +429,7 @@ def test_input_metachar
assert_equal("hello", line, bug6601)
ensure
wo.close
with_pipe {|r, w| w.write("\C-a\C-k\n")} # clear line_buffer
Readline.delete_text
Readline::HISTORY.clear
end if !/EditLine/n.match(Readline::VERSION)

Expand All @@ -433,7 +452,7 @@ def test_input_metachar_multibyte
end
end
ensure
with_pipe {|r, w| w.write("\C-a\C-k\n")} # clear line_buffer
Readline.delete_text
Readline::HISTORY.clear
end if !/EditLine/n.match(Readline::VERSION)

Expand Down