class Mrubyc::Debugger::Console
Constants
- COL_A
- ESCDELAY
Public Class Methods
new(loops)
click to toggle source
# File lib/mrubyc/debugger/console.rb, line 24 def initialize(loops) @srcs = [] loops.each do |loop| src = [] File.open(loop, 'r') do |f| f.each_line do |line| src << line end end @srcs << src end cbreak # raw? noecho # stop echo back set_escdelay ESCDELAY # response speed. default 1000 @cursor_pos = { x: 0, y: 1} @sleepers = Array.new(@srcs.size) @events = Array.new(@srcs.size) end
Public Instance Methods
col_sample()
click to toggle source
# File lib/mrubyc/debugger/console.rb, line 59 def col_sample max = COL_A.size no = 0 max.times do |y| max.times do |x| setpos(y, x * 6) s = " %03d "%no attron(color_pair(no)) addstr(s) attroff(color_pair(no)) no += 1 end end s = "colors: %d"%(colors) setpos(12, 0) addstr(s) s = "color_pairs: %d"%(color_pairs) setpos(13, 0) addstr(s) end
color_num_by(level)
click to toggle source
# File lib/mrubyc/debugger/console.rb, line 86 def color_num_by(level) case level when :info 24 when :debug 32 when :warn 56 when :error 40 end end
make_pair()
click to toggle source
# File lib/mrubyc/debugger/console.rb, line 48 def make_pair # 0 can't be changed no = 0 COL_A.each do |c0| COL_A.each do |c1| init_pair(no, c0, c1) no += 1 end end end
run(show_colors_at_start = false)
click to toggle source
# File lib/mrubyc/debugger/console.rb, line 99 def run(show_colors_at_start = false) mainwin = init_screen mainwin.keypad true mainwin.timeout = 0 curs_set(0) start_color make_pair show_colors if show_colors_at_start begin wins = [] num = @srcs.size num.times do |i| win = {} win[:src] = mainwin.subwin(lines - 6, cols / num, 0, i * cols / num) win[:out] = mainwin.subwin(1, cols / num, lines - 6, i * cols / num) win[:var] = mainwin.subwin(5, cols / num, lines - 5, i * cols / num) wins << win end while true @key = mainwin.getch handle_key num.times do |i| wins[i][:src].resize(lines - 6, cols / num) wins[i][:out].resize(1, cols / num) wins[i][:var].resize(5, cols / num) unless $sleep_queues[i].empty? @sleepers[i] = $sleep_queues[i].pop end if @sleepers[i] && @sleepers[i] < Process.clock_gettime(Process::CLOCK_MONOTONIC_RAW, :millisecond) @sleepers[i] = nil $threads[i].run end unless $debug_queues[i].empty? message = $debug_queues[i].pop wins[i][:out].setpos(0, 0) color_num = color_num_by(message[:level]) wins[i][:out].addstr '|' wins[i][:out].attron(color_pair color_num) wins[i][:out].addstr " #{message[:level].to_s[0].upcase}) " + message[:body].ljust(wins[i][:out].maxx-6) wins[i][:out].attroff(color_pair color_num) wins[i][:out].addstr '|' wins[i][:out].refresh end unless $event_queues[i].empty? @events[i] = $event_queues[i].pop end # needs this condition in spite of being used at the first time # TODO refactor if @events[i] threads_debug_print(i) (1..(wins[i][:src].maxy - 2)).each do |y| wins[i][:src].setpos(y, 1) if !@srcs[i][y] wins[i][:src].addstr ' ' * wins[i][:src].maxx else lineno = @events[i][:lineno] - 1 # hide `using DebugQueue` line wins[i][:src].attron(A_UNDERLINE) if y == @cursor_pos[:y] && i == @cursor_pos[:x] wins[i][:src].attron(A_REVERSE) if y == lineno lineno_color = if $breakpoints.any? {|bp| bp == [i, y] } 21 else 16 end wins[i][:src].attron(color_pair lineno_color) wins[i][:src].attron(A_BOLD) wins[i][:src].addstr y.to_s.rjust(2).to_s wins[i][:src].attroff(A_BOLD) wins[i][:src].attroff(color_pair lineno_color) wins[i][:src].addstr ' ' + @srcs[i][y] wins[i][:src].attroff(A_REVERSE) if y == lineno wins[i][:src].attroff(A_UNDERLINE) if y == @cursor_pos[:y] && i == @cursor_pos[:x] end end wins[i][:src].box(?|,?-,?+) wins[i][:src].refresh if @events[i][:breakpoint] command_line(i, wins[i][:var], @events[i][:tp_binding]) @events[i][:breakpoint] = nil # to avoid #sleep line remains Thread.stop else vars = {} @events[i][:tp_binding].local_variables.each do |var| vars[var] = @events[i][:tp_binding].local_variable_get(var).inspect end vars.each_with_index do |(k,v),j| wins[i][:var].setpos(j+1, 2) wins[i][:var].addstr (k.to_s + ' => ' + v).ljust(wins[i][:var].maxx) end box_var_win(wins[i][:var], 16) end end end refresh end rescue => e sleep 5 ensure finish end end
set_escdelay(ms)
click to toggle source
# File lib/mrubyc/debugger/console.rb, line 43 def set_escdelay(ms) Curses.ESCDELAY = ms rescue NotImplementedError end
show_colors()
click to toggle source
# File lib/mrubyc/debugger/console.rb, line 80 def show_colors col_sample refresh getch end
Private Instance Methods
box_var_win(win, color)
click to toggle source
# File lib/mrubyc/debugger/console.rb, line 209 def box_var_win(win, color) win.attron(color_pair color) win.box(?|,?-,?+) win.attroff(color_pair color) win.refresh end
breakpoint()
click to toggle source
# File lib/mrubyc/debugger/console.rb, line 317 def breakpoint unless $breakpoints.delete([@cursor_pos[:x], @cursor_pos[:y]]) $breakpoints << [@cursor_pos[:x], @cursor_pos[:y]] end end
clear_var_win(win)
click to toggle source
# File lib/mrubyc/debugger/console.rb, line 202 def clear_var_win(win) (1..3).each do |l| win.setpos(l, 1) win << " " * (win.maxx - 2) end end
command_line(i, win, tp_binding)
click to toggle source
# File lib/mrubyc/debugger/console.rb, line 216 def command_line(i, win, tp_binding) box_var_win(win, 21) loop do clear_var_win(win) win.setpos(1, 1) win << " > " win.refresh str = getstr_with_echo(win) case str when "exit" clear_var_win(win) win.refresh resume(i) return when "" # do nothing else win.setpos(2, 2) win << " => " index = str.index("=") args = if index [ str[0, index - 1].strip, str[index + 1, str.size - index].strip ] else str.strip end begin result = if args.is_a?(Array) tp_binding.local_variable_set(args[0], eval(args[1])) else if tp_binding.local_variables.map(&:to_s).include?(args) tp_binding.local_variable_get(args) else eval(args) end end win << result.to_s[0, win.maxx - 7] rescue => e win << e.to_s[0, win.maxx - 7] end win.setpos(3, 2) win << "Enter to continue" box_var_win(win, 21) loop do case getch when nil sleep ESCDELAY / 1000.0 when KEY_CTRL_J # Enter break end end end end end
finish()
click to toggle source
# File lib/mrubyc/debugger/console.rb, line 359 def finish close_screen system "stty sane" puts "finished" end
getstr_with_echo(win)
click to toggle source
# File lib/mrubyc/debugger/console.rb, line 271 def getstr_with_echo(win) str = "".dup loop do case (c = Curses.getch) when nil # ignore when KEY_CTRL_J # Enter break if str.size > 0 when String win << c win.refresh str << c when KEY_BACKSPACE if str.size > 0 win.setpos(1, str.size + 3) win << " " win.setpos(1, str.size + 3) win.refresh str.chop! end end end str end
go_down()
click to toggle source
# File lib/mrubyc/debugger/console.rb, line 345 def go_down @cursor_pos[:y] += 1 if @cursor_pos[:y] >= @srcs[@cursor_pos[:x]].size @cursor_pos[:y] = 1 end end
go_left()
click to toggle source
# File lib/mrubyc/debugger/console.rb, line 323 def go_left @cursor_pos[:x] -= 1 if @cursor_pos[:x] < 0 @cursor_pos[:x] = @srcs.size - 1 end rescue_overflow end
go_right()
click to toggle source
# File lib/mrubyc/debugger/console.rb, line 331 def go_right @cursor_pos[:x] += 1 if @cursor_pos[:x] >= @srcs.size @cursor_pos[:x] = 0 end rescue_overflow end
go_up()
click to toggle source
# File lib/mrubyc/debugger/console.rb, line 352 def go_up @cursor_pos[:y] -= 1 if @cursor_pos[:y] == 0 @cursor_pos[:y] = @srcs[@cursor_pos[:x]].size - 1 end end
handle_key()
click to toggle source
# File lib/mrubyc/debugger/console.rb, line 296 def handle_key case @key when 27 # ESC exit(0) when "h" go_left when "j" go_down when "k" go_up when "l" go_right when " " breakpoint end end
rescue_overflow()
click to toggle source
# File lib/mrubyc/debugger/console.rb, line 339 def rescue_overflow if @cursor_pos[:y] >= @srcs[@cursor_pos[:x]].size @cursor_pos[:y] = @srcs[@cursor_pos[:x]].size - 1 end end
resume(i)
click to toggle source
# File lib/mrubyc/debugger/console.rb, line 313 def resume(i) $threads[i].run if $threads[i].stop? end
threads_debug_print(i)
click to toggle source
# File lib/mrubyc/debugger/console.rb, line 365 def threads_debug_print(i) $logger.debug @events[i].to_s if @events[i] $logger.debug $breakpoints.to_s $threads.each_with_index do |thread, index| $logger.debug "thread #{index}: stop? => #{thread.stop?}" end end