class Viewer

Constants

Color

Attributes

pos[RW]
text[RW]
x[RW]
y[RW]

Public Class Methods

new(text) click to toggle source
# File samples/dasmnavig.rb, line 97
def initialize(text)
        text = File.read(text) if File.exist? text rescue nil
        @text = text.gsub("\t", " "*8).to_a.map { |l| l.chomp }
        @pos = @posh = 0
        @x = @y = 0
        @mode = :navig
        @searchtext = 'x'
        @posstack = []
        @h, @w = Ansi.get_terminal_size
        @h -= 2
        @w -= 1
        if y = @text.index('entrypoint:')
                view(0, y)
        end
end

Public Instance Methods

handle_key(k) click to toggle source
# File samples/dasmnavig.rb, line 222
def handle_key(k)
        case @mode
        when :navig
                handle_key_navig(k)
        when :search
                handle_key_search(k)
        end
end
handle_key_navig(k) click to toggle source
# File samples/dasmnavig.rb, line 239
def handle_key_navig(k)
        case k
        when :f1
                if not @posstack.empty?
                        @posh, @pos, @x, @y = @posstack.pop
                end
        when \n
                return if not label = readtext
                return if label.empty? or not newy = @text.index(@text.find { |l| l[0, label.length] == label }) or newy == @pos+@y
                @posstack << [@posh, @pos, @x, @y]
                view(0, newy)
        when :up
                if @y > 0; @y -= 1
                elsif @pos > 0; @pos -= 1
                end
        when :down
                if @y < @h; @y += 1
                elsif @pos < text.length-@h; @pos += 1
                end
        when :home
                @x = @posh = 0
        when :end
                @x = @text[@pos+@y].length
                @posh, @x = @x-@w, @w if @x > @w
        when :left
                x = @text[@pos+@y].rindex(/\W\w/, [@posh+@x-2, 0].max)
                x = x ? x+1 : @posh+@x-1
                x = @posh+@x-3 if x < @posh+@x-3
                x = 0 if x < 0
                if x < @posh; @posh, @x = x, 0
                else @x = x-@posh
                end
                #if @x > 0; @x -= 1
                #elsif @posh > 0; @posh -= 1
                #end
        when :right
                x = @text[@pos+@y].index(/\W\w/, @posh+@x)
                x = x ? x+1 : @posh+@x+1
                x = @posh+@x+3 if x > @posh+@x+3
                if x > @posh+@w; @posh, @x = x-@w, @w
                else
                        @x = x-@posh
                        @posh, @x = @x-@w, @w if @x > @w
                end
                #if @x < @w; @x += 1
                #elsif @posh+@w < (@text[@pos, @h].map { |l| l.length }.max); @posh += 1
                #end
        when :pgdown
                if @y < @h/2; @y += @h/2
                elsif @pos < @text.length-3*@h/2; @pos += @h/2 ; @y = @h
                else @pos = [0, @text.length-@h].max ; @y = @h
                end
        when :pgup
                if @y > @h/2; @y -= @h/2
                elsif @pos > @h/2; @pos -= @h/2 ; @y = 0
                else @pos = @y = 0
                end
        when q; exit
        when o; @text.insert(@pos+@y+1, '')
        when O; @text.insert(@pos+@y, '') ; handle_key_navig(:down)
        when :suppr; @text.delete_at(@pos+@y) if @text[@pos+@y] == ''
        when D; @text.delete_at(@pos+@y)
        when /
                @mode = :search
                @searchtext = ''
        when *
                @searchtext = readtext || ''
                search_next
        when n; search_next
        when N; search_prev
        when :f5
                ARGV << '--reload'
                load $0
        end
end
main_loop() click to toggle source
# File samples/dasmnavig.rb, line 113
def main_loop
        Ansi.set_term_canon(true)
        $stdout.write Ansi::ClearScreen
        begin
                loop do
                        refresh if not IO.select([$stdin], nil, nil, 0)
                        handle_key(Ansi.getkey)
                end
        ensure
                Ansi.set_term_canon(false)
                $stdout.write Ansi.set_cursor_pos(@h+2, 0) + Ansi::ClearLineAfter
        end
end
outline(l, hl=nil) click to toggle source
# File samples/dasmnavig.rb, line 153
def outline(l, hl=nil)
        l = l[@posh, @w] || ''
        hlr = /\b#{Regexp.escape(hl)}\b/ if hl
        case l
        when /^\/\//; Color[:comment] + l + Color[:normal]
        when /^\S+:$/; Color[:label] + l + Color[:normal]
        when /^(.*)(;.*)$/
                str = $1
                cmt = $2
                str.gsub!(hlr, Color[:hilight]+hl+Color[:normal]) if hl
                str + Color[:comment] + cmt + Color[:normal]
        else
                l = l.gsub(hlr, Color[:hilight]+hl+Color[:normal]) if hl
                l
        end
end
readtext() click to toggle source
# File samples/dasmnavig.rb, line 215
def readtext
        return if not l = @text[@pos+@y]
        x = (l.rindex(/\W/, [@posh+@x-1, 0].max) || -1)+1
        t = l[x..-1][/^\w+/]
        t if t and @posh+@x < x+t.length
end
refresh() click to toggle source
# File samples/dasmnavig.rb, line 127
def refresh
        case @mode
        when :navig
                refresh_navig
        when :search
                refresh_search
        end
end
refresh_navig() click to toggle source
# File samples/dasmnavig.rb, line 136
def refresh_navig
        str = ''
        #str << Ansi::ClearScreen
        str << Ansi.set_cursor_pos(0, 0)
        hl = readtext
        (0..@h).each { |h|
                l = @text[@pos+h] || ''
                str << outline(l, hl) << Ansi::ClearLineAfter << "\n"
        }
        str << Ansi.set_cursor_pos(@y+1, @x+1)
        $stdout.write str
end
search_next() click to toggle source
# File samples/dasmnavig.rb, line 184
def search_next
        return if @searchtext == ''
        y = @pos+@y+1
        loop do
                y = 0 if not @text[y]
                if x = (@text[y] =~ /#@searchtext/)
                        view(x, y)
                        return
                end
                break if y == @pos+@y or (y >= @text.length and not @text[@pos+@y])
                y += 1
        end
end
search_prev() click to toggle source
# File samples/dasmnavig.rb, line 170
def search_prev
        return if @searchtext == ''
        y = @pos+@y-1
        loop do
                y = @text.length-1 if not @text[y] or y < 0
                if x = (@text[y] =~ /#@searchtext/)
                        view(x, y)
                        return
                end
                y -= 1
                break if y == @pos+@y
        end
end
view(x, y) click to toggle source
# File samples/dasmnavig.rb, line 198
def view(x, y)
        @posh, @x = 0, x
        if @x > @w
                @posh = @w-@x
                @x = @w
        end
        if @pos+@h < y
                @y = @h/2-1
                @pos = y-@y
        elsif @pos > y
                @y = 1
                @pos = y-@y
        else
                @y = y-@pos
        end
end