class DenCli::Interactive

Attributes

cl[R]
cur[R]
histfile[R]
prompt[R]

Public Class Methods

new(cl, prompt, histfile: nil) click to toggle source
# File lib/dencli/interactive.rb, line 6
def initialize cl, prompt, histfile: nil
        require 'readline'
        @cl, self.prompt = cl, prompt
        @cur = cl.subs
        cur.instance_variable_set :@name, ''

        @histfile =
                case histfile
                when nil then nil
                when Pathname then histfile
                else Pathname.new histfile.to_s
                end
        read_history  if @histfile

        Readline.vi_editing_mode  rescue NotImplementedError
        Readline.completion_append_character = " "
        Readline.completion_proc = method :complete

        prepare_sub cl.subs
        cl.cmd :exit, "exit", min: 2 do
                exit 0
        end
        cl.subs.aliases['?'] = cl.subs.subs['help']
        cl.subs.subs.delete 'cli'

        stty_save = %x`stty -g`.chomp
        trap "INT" do
                system "stty", stty_save
                Readline.refresh_line
        end
end

Public Instance Methods

complete(s) click to toggle source
# File lib/dencli/interactive.rb, line 69
def complete s
        ws = words Readline.line_buffer
        @cur.complete *ws[0...-1], s
end
history_file(file = nil) click to toggle source
# File lib/dencli/interactive.rb, line 38
def history_file file = nil
        file =
                case file
                when Pathname then file
                when nil then @histfile
                else Pathname.new file.to_s
                end
end
prepare_sub(c) click to toggle source
# File lib/dencli/interactive.rb, line 89
def prepare_sub c
        c.subs.values.each do |n|
                case n
                when DenCli::Sub
                        n.cmd :exit, "<- #{n.parent.full_cmd.join ' '} - #{n.parent.description[3..-1]}", min: 2 do
                                @cur = n.parent
                        end
                        n.cmd '', "", min: 2, aliases: [nil] do
                                @cur = n
                        end
                        n.subs.delete ''
                        n.aliases['?'] = n.subs['help']
                        prepare_sub n
                when DenCli::CMD
                else raise "Unsupported sub-type: #{x}"
                end
        end
end
prompt=(s) click to toggle source
# File lib/dencli/interactive.rb, line 65
def prompt= s
        @prompt = s.to_s
end
read() click to toggle source
# File lib/dencli/interactive.rb, line 108
def read
        line = Readline.readline( "#{prompt}#{cur.full_cmd.join ' '}> ", true)
        return nil  if line.nil?
        Readline::HISTORY.pop  if /^\s*$/ =~ line
        if 0 < Readline::HISTORY.length-2 and Readline::HISTORY[Readline::HISTORY.length-2] == line
                Readline::HISTORY.pop
        end
        line.split " "
end
read_history(file = nil) click to toggle source
# File lib/dencli/interactive.rb, line 47
def read_history file = nil
        file = history_file file
        return  unless file and file.exist?
        file.each_line do |line|
                Readline::HISTORY.push line.chomp
        end
end
run() click to toggle source
# File lib/dencli/interactive.rb, line 129
def run
        while step
        end
end
step() click to toggle source
# File lib/dencli/interactive.rb, line 118
def step
        line = read
        return nil  if line.nil?
        begin
                cur.call *line
        rescue ::DenCli::UsageError
                STDERR.puts "! #$!"
        end
        true
end
write_history(file = nil) click to toggle source
# File lib/dencli/interactive.rb, line 55
def write_history file = nil
        file = history_file file
        return  unless file
        file.open 'w+' do |f|
                Readline::HISTORY.each do |line|
                        f.puts line
                end
        end
end

Private Instance Methods

sub(*args, cur: nil) click to toggle source
# File lib/dencli/interactive.rb, line 74
def sub *args, cur: nil
        args.inject( cur || @cur) do |r, a|
                return nil  unless r.is_a? DenCli::Sub
                r[a]
        end
end
words(line = nil) click to toggle source
# File lib/dencli/interactive.rb, line 82
def words line = nil
        r = line.split " "
        r.push ''  if ' ' == line[-1]
        r
end