Skip to content
Merged
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
2 changes: 1 addition & 1 deletion stdlib/REPL/src/LineEdit.jl
Original file line number Diff line number Diff line change
Expand Up @@ -1101,7 +1101,7 @@ end

function edit_transpose_chars(buf::IOBuffer)
# Moving left but not transpoing anything is intentional, and matches Emacs's behavior
eof(buf) && char_move_left(buf)
eof(buf) && position(buf) !== 0 && char_move_left(buf)
position(buf) == 0 && return false
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Just swap this and the line above rather than duplicating the condition?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

That was the original logic that led to #45417 being filed—what will happen is if the buffer's position is at 1, with a length of 1, then we'll try to read past the end of the buffer.

Since I figured that it'd be best to be as close to Emacs as possible, I went with just flipping those two lines (hence the comment).

In this PR, I'm not sure there's a good way to get around the duplication of the position(buf) stuff unless I'm missing something obvious (which isn't unlikely)—we ultimately need to check it twice, first time to make sure we can move left, and then again to make sure we aren't at the start of the buffer. One other idea could be something like this though, but I'm not sure which I prefer (probably this version, but I'm curious what you think):

function edit_transpose_chars(buf::IOBuffer)
    content(buf) == "" && return false

    # Moving left but not transpoing anything is intentional, and matches Emacs's behavior
    eof(buf) && char_move_left(buf)
    position(buf) == 0 && return false 
    # ...

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Ah, I see char_move_left might update the buf position. Alright, seems reasonable I suppose

char_move_left(buf)
pos = position(buf)
Expand Down
9 changes: 9 additions & 0 deletions stdlib/REPL/test/lineedit.jl
Original file line number Diff line number Diff line change
Expand Up @@ -376,6 +376,8 @@ let buf = IOBuffer()
LineEdit.edit_transpose_chars(buf)
@test content(buf) == "βγαδε"


# Transposing a one-char buffer should behave like Emacs
seek(buf, 0)
@inferred(LineEdit.edit_clear(buf))
edit_insert(buf, "a")
Expand All @@ -385,6 +387,13 @@ let buf = IOBuffer()
LineEdit.edit_transpose_chars(buf)
@test content(buf) == "a"
@test position(buf) == 0

# Transposing an empty buffer shouldn't implode
seek(buf, 0)
LineEdit.edit_clear(buf)
LineEdit.edit_transpose_chars(buf)
@test content(buf) == ""
@test position(buf) == 0
end

@testset "edit_word_transpose" begin
Expand Down