Skip to content

Commit

Permalink
REPL: transpose words with Alt-t
Browse files Browse the repository at this point in the history
Fixes part of #8447.
  • Loading branch information
rfourquet committed Aug 21, 2017
1 parent eae45d6 commit 588e01b
Show file tree
Hide file tree
Showing 2 changed files with 78 additions and 14 deletions.
34 changes: 31 additions & 3 deletions base/repl/LineEdit.jl
Original file line number Diff line number Diff line change
Expand Up @@ -587,8 +587,9 @@ function edit_kill_line(s::MIState)
refresh_line(s)
end

edit_transpose(s) = edit_transpose(buffer(s)) && refresh_line(s)
function edit_transpose(buf::IOBuffer)
edit_transpose_chars(s) = edit_transpose_chars(buffer(s)) && refresh_line(s)

function edit_transpose_chars(buf::IOBuffer)
position(buf) == 0 && return false
eof(buf) && char_move_left(buf)
char_move_left(buf)
Expand All @@ -599,6 +600,32 @@ function edit_transpose(buf::IOBuffer)
return true
end

edit_transpose_words(s) = edit_transpose_words(buffer(s)) && refresh_line(s)

function edit_transpose_words(buf::IOBuffer, mode=:readline)
mode in [:readline, :emacs] ||
throw(ArgumentError("`mode` must be `:readline` or `:emacs`"))
pos = position(buf)
if mode == :emacs
char_move_word_left(buf)
char_move_word_right(buf)
end
char_move_word_right(buf)
e2 = position(buf)
char_move_word_left(buf)
b2 = position(buf)
char_move_word_left(buf)
b1 = position(buf)
char_move_word_right(buf)
e1 = position(buf)
e1 >= b2 && (seek(buf, pos); return false)
word2 = splice!(buf.data, b2+1:e2, buf.data[b1+1:e1])
splice!(buf.data, b1+1:e1, word2)
seek(buf, e2)
true
end


edit_clear(buf::IOBuffer) = truncate(buf, 0)

function edit_clear(s::MIState)
Expand Down Expand Up @@ -1492,7 +1519,8 @@ AnyDict(
input = bracketed_paste(s)
edit_insert(s, input)
end,
"^T" => (s,o...)->edit_transpose(s)
"^T" => (s,o...)->edit_transpose_chars(s),
"\et" => (s,o...)->edit_transpose_words(s),
)

const history_keymap = AnyDict(
Expand Down
58 changes: 47 additions & 11 deletions test/lineedit.jl
Original file line number Diff line number Diff line change
Expand Up @@ -308,41 +308,77 @@ let buf = IOBuffer()
@test String(buf.data[1:buf.size]) == "a"
end

## edit_transpose ##
## edit_transpose_chars ##
let buf = IOBuffer()
LineEdit.edit_insert(buf, "abcde")
seek(buf,0)
LineEdit.edit_transpose(buf)
LineEdit.edit_transpose_chars(buf)
@test String(buf.data[1:buf.size]) == "abcde"
LineEdit.char_move_right(buf)
LineEdit.edit_transpose(buf)
LineEdit.edit_transpose_chars(buf)
@test String(buf.data[1:buf.size]) == "bacde"
LineEdit.edit_transpose(buf)
LineEdit.edit_transpose_chars(buf)
@test String(buf.data[1:buf.size]) == "bcade"
seekend(buf)
LineEdit.edit_transpose(buf)
LineEdit.edit_transpose_chars(buf)
@test String(buf.data[1:buf.size]) == "bcaed"
LineEdit.edit_transpose(buf)
LineEdit.edit_transpose_chars(buf)
@test String(buf.data[1:buf.size]) == "bcade"

seek(buf, 0)
LineEdit.edit_clear(buf)
LineEdit.edit_insert(buf, "αβγδε")
seek(buf,0)
LineEdit.edit_transpose(buf)
LineEdit.edit_transpose_chars(buf)
@test String(buf.data[1:buf.size]) == "αβγδε"
LineEdit.char_move_right(buf)
LineEdit.edit_transpose(buf)
LineEdit.edit_transpose_chars(buf)
@test String(buf.data[1:buf.size]) == "βαγδε"
LineEdit.edit_transpose(buf)
LineEdit.edit_transpose_chars(buf)
@test String(buf.data[1:buf.size]) == "βγαδε"
seekend(buf)
LineEdit.edit_transpose(buf)
LineEdit.edit_transpose_chars(buf)
@test String(buf.data[1:buf.size]) == "βγαεδ"
LineEdit.edit_transpose(buf)
LineEdit.edit_transpose_chars(buf)
@test String(buf.data[1:buf.size]) == "βγαδε"
end

@testset "edit_word_transpose" begin
buf = IOBuffer()
mode = Ref{Symbol}
function transpose!(i) # i: char indice
seek(buf, Base.unsafe_chr2ind(String(take!(copy(buf))), i+1)-1)
LineEdit.edit_transpose_words(buf, mode[])
str = String(take!(copy(buf)))
str, Base.unsafe_ind2chr(str, position(buf)+1)-1
end

mode[] = :readline
LineEdit.edit_insert(buf, "àbç def gh ")
@test transpose!(0) == ("àbç def gh ", 0)
@test transpose!(1) == ("àbç def gh ", 1)
@test transpose!(2) == ("àbç def gh ", 2)
@test transpose!(3) == ("def àbç gh ", 7)
@test transpose!(4) == ("àbç def gh ", 7)
@test transpose!(5) == ("def àbç gh ", 7)
@test transpose!(6) == ("àbç def gh ", 7)
@test transpose!(7) == ("àbç gh def ", 11)
@test transpose!(10) == ("àbç def gh ", 11)
@test transpose!(11) == ("àbç gh def", 12)
LineEdit.edit_insert(buf, " ")
@test transpose!(13) == ("àbç def gh", 13)

take!(buf)
mode[] = :emacs
LineEdit.edit_insert(buf, "àbç def gh ")
@test transpose!(0) == ("def àbç gh ", 7)
@test transpose!(4) == ("àbç def gh ", 7)
@test transpose!(5) == ("àbç gh def ", 11)
@test transpose!(10) == ("àbç def gh", 12)
LineEdit.edit_insert(buf, " ")
@test transpose!(13) == ("àbç gh def", 13)
end

let
term = TestHelpers.FakeTerminal(IOBuffer(), IOBuffer(), IOBuffer())
s = LineEdit.init_state(term, ModalInterface([Prompt("test> ")]))
Expand Down

0 comments on commit 588e01b

Please sign in to comment.