class Reline::Unicode

def self.split_by_width(str, max_width, encoding = str.encoding)

def self.split_by_width(str, max_width, encoding = str.encoding)
  lines = [String.new(encoding: encoding)]
  height = 1
  width = 0
  rest = str.encode(Encoding::UTF_8)
  in_zero_width = false
  seq = String.new(encoding: encoding)
  rest.scan(WIDTH_SCANNER) do |gc|
    case
    when gc[NON_PRINTING_START_INDEX]
      in_zero_width = true
      lines.last << NON_PRINTING_START
    when gc[NON_PRINTING_END_INDEX]
      in_zero_width = false
      lines.last << NON_PRINTING_END
    when gc[CSI_REGEXP_INDEX]
      lines.last << gc[CSI_REGEXP_INDEX]
      seq << gc[CSI_REGEXP_INDEX]
    when gc[OSC_REGEXP_INDEX]
      lines.last << gc[OSC_REGEXP_INDEX]
      seq << gc[OSC_REGEXP_INDEX]
    when gc[GRAPHEME_CLUSTER_INDEX]
      gc = gc[GRAPHEME_CLUSTER_INDEX]
      unless in_zero_width
        mbchar_width = get_mbchar_width(gc)
        if (width += mbchar_width) > max_width
          width = mbchar_width
          lines << nil
          lines << seq.dup
          height += 1
        end
      end
      lines.last << gc
    end
  end
  # The cursor moves to next line in first
  if width == max_width
    lines << nil
    lines << String.new(encoding: encoding)
    height += 1
  end
  [lines, height]
end