平衡点


2023/02/17

_ ruby 3.1 の irb がシンドかったのでなんとかする.

次期リリース候補の Debian 12 (Bookworm) の Ruby は ruby 3.1 です. これに同梱されている irb を叩いた所, 補完が効くようになっていてちょっと感動したんですが…

これは irb → reline ときて

で修正されています.

あたりを見ると, そのうち直りそうですが, まぁ.

といわけで, reline にハードコードされている色を まるっと上書きすることに.

cat ~/.irbrc

#-*- mode:ruby; coding:utf-8 -*-
IRB.conf[:SAVE_HISTORY] = 1000

## monkey patch for bgcolor
class Reline::LineEditor

  alias_method :_orig_render_each_dialog, :render_each_dialog

  private def render_each_dialog(dialog, cursor_column)
    if @in_pasting
      clear_each_dialog(dialog)
      dialog.contents = nil
      dialog.trap_key = nil
      return
    end
    dialog.set_cursor_pos(cursor_column, @first_line_started_from + @started_from)
    dialog_render_info = dialog.call(@last_key)
    if dialog_render_info.nil? or dialog_render_info.contents.nil? or dialog_render_info.contents.empty?
      dialog.lines_backup = {
        lines: modify_lines(whole_lines),
        line_index: @line_index,
        first_line_started_from: @first_line_started_from,
        started_from: @started_from,
        byte_pointer: @byte_pointer
      }
      clear_each_dialog(dialog)
      dialog.contents = nil
      dialog.trap_key = nil
      return
    end
    old_dialog = dialog.clone
    dialog.contents = dialog_render_info.contents
    pointer = dialog.pointer
    if dialog_render_info.width
      dialog.width = dialog_render_info.width
    else
      dialog.width = dialog.contents.map { |l| calculate_width(l, true) }.max
    end
    height = dialog_render_info.height || DIALOG_DEFAULT_HEIGHT
    height = dialog.contents.size if dialog.contents.size < height
    if dialog.contents.size > height
      if dialog.pointer
        if dialog.pointer < 0
          dialog.scroll_top = 0
        elsif (dialog.pointer - dialog.scroll_top) >= (height - 1)
          dialog.scroll_top = dialog.pointer - (height - 1)
        elsif (dialog.pointer - dialog.scroll_top) < 0
          dialog.scroll_top = dialog.pointer
        end
        pointer = dialog.pointer - dialog.scroll_top
      end
      dialog.contents = dialog.contents[dialog.scroll_top, height]
    end
    if dialog.contents and dialog.scroll_top >= dialog.contents.size
      dialog.scroll_top = dialog.contents.size - height
    end
    if dialog_render_info.scrollbar and dialog_render_info.contents.size > height
      bar_max_height = height * 2
      moving_distance = (dialog_render_info.contents.size - height) * 2
      position_ratio = dialog.scroll_top.zero? ? 0.0 : ((dialog.scroll_top * 2).to_f / moving_distance)
      bar_height = (bar_max_height * ((dialog.contents.size * 2).to_f / (dialog_render_info.contents.size * 2))).floor.to_i
      dialog.scrollbar_pos = ((bar_max_height - bar_height) * position_ratio).floor.to_i
    else
      dialog.scrollbar_pos = nil
    end
    upper_space = @first_line_started_from - @started_from
    dialog.column = dialog_render_info.pos.x
    dialog.width += @block_elem_width if dialog.scrollbar_pos
    diff = (dialog.column + dialog.width) - (@screen_size.last)
    if diff > 0
      dialog.column -= diff
    end
    if (@rest_height - dialog_render_info.pos.y) >= height
      dialog.vertical_offset = dialog_render_info.pos.y + 1
    elsif upper_space >= height
      dialog.vertical_offset = dialog_render_info.pos.y - height
    else
      if (@rest_height - dialog_render_info.pos.y) < height
        scroll_down(height + dialog_render_info.pos.y)
        move_cursor_up(height + dialog_render_info.pos.y)
      end
      dialog.vertical_offset = dialog_render_info.pos.y + 1
    end
    Reline::IOGate.hide_cursor
    if dialog.column < 0
      dialog.column = 0
      dialog.width = @screen_size.last
    end
    reset_dialog(dialog, old_dialog)
    move_cursor_down(dialog.vertical_offset)
    Reline::IOGate.move_cursor_column(dialog.column)
    dialog.contents.each_with_index do |item, i|
      if i == pointer
        # bg_color = '45'
        bg_color = '44'
      else
        if dialog_render_info.bg_color
          bg_color = dialog_render_info.bg_color
        else
          # bg_color = '46'
          bg_color = '100'
        end
      end
      str_width = dialog.width - (dialog.scrollbar_pos.nil? ? 0 : @block_elem_width)
      str = padding_space_with_escape_sequences(Reline::Unicode.take_range(item, 0, str_width), str_width)
      @output.write "\e[#{bg_color}m#{str}"
      if dialog.scrollbar_pos and (dialog.scrollbar_pos != old_dialog.scrollbar_pos or dialog.column != old_dialog.column)
        @output.write "\e[37m"
        if dialog.scrollbar_pos <= (i * 2) and (i * 2 + 1) < (dialog.scrollbar_pos + bar_height)
          @output.write @full_block
        elsif dialog.scrollbar_pos <= (i * 2) and (i * 2) < (dialog.scrollbar_pos + bar_height)
          @output.write @upper_half_block
          str += ''
        elsif dialog.scrollbar_pos <= (i * 2 + 1) and (i * 2) < (dialog.scrollbar_pos + bar_height)
          @output.write @lower_half_block
        else
          @output.write ' ' * @block_elem_width
        end
      end
      @output.write "\e[0m"
      Reline::IOGate.move_cursor_column(dialog.column)
      move_cursor_down(1) if i < (dialog.contents.size - 1)
    end
    Reline::IOGate.move_cursor_column(cursor_column)
    move_cursor_up(dialog.vertical_offset + dialog.contents.size - 1)
    Reline::IOGate.show_cursor
    dialog.lines_backup = {
      lines: modify_lines(whole_lines),
      line_index: @line_index,
      first_line_started_from: @first_line_started_from,
      started_from: @started_from,
      byte_pointer: @byte_pointer
    }
  end
end

というわけで.


連絡先など
最近の日記
一覧
2006|03|04|05|06|07|08|09|10|11|12|
2007|01|02|03|04|05|06|07|08|09|10|11|12|
2008|01|02|03|04|05|06|07|08|09|10|11|12|
2009|01|02|03|04|05|06|07|08|09|10|11|12|
2010|01|02|03|04|05|06|07|08|09|10|11|12|
2011|01|02|03|04|05|06|07|08|09|10|11|12|
2012|02|03|04|08|09|10|11|12|
2013|01|02|03|04|05|06|08|09|10|11|12|
2014|01|02|04|05|06|07|08|09|10|11|12|
2015|01|02|03|04|05|06|07|09|10|
2016|02|03|
2017|01|02|03|05|06|07|09|11|12|
2018|03|06|07|10|11|12|
2019|01|02|03|04|05|07|10|12|
2020|01|02|03|04|05|08|09|10|11|12|
2021|01|02|03|05|06|07|08|09|11|12|
2022|01|02|03|04|05|06|08|10|11|12|
2023|02|03|04|06|08|09|11|12|
2024|01|02|03|
Back to Top ▲