#!/usr/bin/env ruby # encoding: UTF-8 require 'curses' require 'optparse' $LOAD_PATH.unshift File.expand_path('../../lib', __FILE__) def parse_options options = {} parser = OptionParser.new do |opts| opts.banner = < we can use timeouts Curses.init_screen begin yield ensure Curses.close_screen end end def display(lines, style_mask) columns = Curses.stdscr.maxx @screen ||= [] # current screen is used as cache style_mask = style_mask.flatten lines.each_with_index do |content, line| styles = style_mask[line] # expand line with whitespace to overwrite previous content missing = columns - content.size content += " " * missing # display tabs as single-space -> nothing breaks content.gsub!("\t",' ') # cache !? next if @screen[line] == [content, styles] @screen[line] = [content, styles] # position at start of line and draw Curses.setpos(line,0) Ruco::StyleMap.styled(content, styles).each do |style, part| Curses.attrset Ruco::StyleMap.curses_style(style) Curses.addstr part end if @options[:debug_cache] write(line, 0, (rand(899)+100).to_s) end end end def show_app(app) lines = app.view.naive_split("\n") style_map = app.style_map # TODO move this logic into application display(lines, style_map) Curses.setpos(app.cursor.line, app.cursor.column) end def debug_key(key) @key_line ||= -1 @key_line = (@key_line + 1) % Curses.stdscr.maxy write(@key_line, 0, "#{key.inspect}---") end def log(stuff) File.open('ruco.log','a'){|f| f.puts stuff } end @options = parse_options require 'ruco' app = Ruco::Application.new(ARGV[0], :convert_tabs => @options[:convert_tabs], :lines => Curses.stdscr.maxy, :columns => Curses.stdscr.maxx ) init_screen do show_app app Keyboard.input do Curses.getch end Keyboard.output do |key| debug_key(key) if @options[:debug_keys] if key == :resize app.resize(Curses.stdscr.maxy, Curses.stdscr.maxx) @screen.clear # clear cache else result = app.key key end break if result == :quit show_app app end end