class Reline::Unicode

def self.ed_transpose_words(line, byte_pointer)

def self.ed_transpose_words(line, byte_pointer)
  right_word_start = nil
  size = get_next_mbchar_size(line, byte_pointer)
  mbchar = line.byteslice(byte_pointer, size)
  if size.zero?
    # ' aaa bbb [cursor]'
    byte_size = 0
    while 0 < (byte_pointer + byte_size)
      size = get_prev_mbchar_size(line, byte_pointer + byte_size)
      mbchar = line.byteslice(byte_pointer + byte_size - size, size)
      break if mbchar.encode(Encoding::UTF_8) =~ /\p{Word}/
      byte_size -= size
    end
    while 0 < (byte_pointer + byte_size)
      size = get_prev_mbchar_size(line, byte_pointer + byte_size)
      mbchar = line.byteslice(byte_pointer + byte_size - size, size)
      break if mbchar.encode(Encoding::UTF_8) =~ /\P{Word}/
      byte_size -= size
    end
    right_word_start = byte_pointer + byte_size
    byte_size = 0
    while line.bytesize > (byte_pointer + byte_size)
      size = get_next_mbchar_size(line, byte_pointer + byte_size)
      mbchar = line.byteslice(byte_pointer + byte_size, size)
      break if mbchar.encode(Encoding::UTF_8) =~ /\P{Word}/
      byte_size += size
    end
    after_start = byte_pointer + byte_size
  elsif mbchar.encode(Encoding::UTF_8) =~ /\p{Word}/
    # ' aaa bb[cursor]b'
    byte_size = 0
    while 0 < (byte_pointer + byte_size)
      size = get_prev_mbchar_size(line, byte_pointer + byte_size)
      mbchar = line.byteslice(byte_pointer + byte_size - size, size)
      break if mbchar.encode(Encoding::UTF_8) =~ /\P{Word}/
      byte_size -= size
    end
    right_word_start = byte_pointer + byte_size
    byte_size = 0
    while line.bytesize > (byte_pointer + byte_size)
      size = get_next_mbchar_size(line, byte_pointer + byte_size)
      mbchar = line.byteslice(byte_pointer + byte_size, size)
      break if mbchar.encode(Encoding::UTF_8) =~ /\P{Word}/
      byte_size += size
    end
    after_start = byte_pointer + byte_size
  else
    byte_size = 0
    while (line.bytesize - 1) > (byte_pointer + byte_size)
      size = get_next_mbchar_size(line, byte_pointer + byte_size)
      mbchar = line.byteslice(byte_pointer + byte_size, size)
      break if mbchar.encode(Encoding::UTF_8) =~ /\p{Word}/
      byte_size += size
    end
    if (byte_pointer + byte_size) == (line.bytesize - 1)
      # ' aaa bbb [cursor] '
      after_start = line.bytesize
      while 0 < (byte_pointer + byte_size)
        size = get_prev_mbchar_size(line, byte_pointer + byte_size)
        mbchar = line.byteslice(byte_pointer + byte_size - size, size)
        break if mbchar.encode(Encoding::UTF_8) =~ /\p{Word}/
        byte_size -= size
      end
      while 0 < (byte_pointer + byte_size)
        size = get_prev_mbchar_size(line, byte_pointer + byte_size)
        mbchar = line.byteslice(byte_pointer + byte_size - size, size)
        break if mbchar.encode(Encoding::UTF_8) =~ /\P{Word}/
        byte_size -= size
      end
      right_word_start = byte_pointer + byte_size
    else
      # ' aaa [cursor] bbb '
      right_word_start = byte_pointer + byte_size
      while line.bytesize > (byte_pointer + byte_size)
        size = get_next_mbchar_size(line, byte_pointer + byte_size)
        mbchar = line.byteslice(byte_pointer + byte_size, size)
        break if mbchar.encode(Encoding::UTF_8) =~ /\P{Word}/
        byte_size += size
      end
      after_start = byte_pointer + byte_size
    end
  end
  byte_size = right_word_start - byte_pointer
  while 0 < (byte_pointer + byte_size)
    size = get_prev_mbchar_size(line, byte_pointer + byte_size)
    mbchar = line.byteslice(byte_pointer + byte_size - size, size)
    break if mbchar.encode(Encoding::UTF_8) =~ /\p{Word}/
    byte_size -= size
  end
  middle_start = byte_pointer + byte_size
  byte_size = middle_start - byte_pointer
  while 0 < (byte_pointer + byte_size)
    size = get_prev_mbchar_size(line, byte_pointer + byte_size)
    mbchar = line.byteslice(byte_pointer + byte_size - size, size)
    break if mbchar.encode(Encoding::UTF_8) =~ /\P{Word}/
    byte_size -= size
  end
  left_word_start = byte_pointer + byte_size
  [left_word_start, middle_start, right_word_start, after_start]
end