Class: DenCli::Interactive

Inherits:
Object
  • Object
show all
Defined in:
lib/dencli/interactive.rb

Instance Attribute Summary collapse

Instance Method Summary collapse

Constructor Details

#initialize(cl, prompt, histfile: nil) ⇒ Interactive

Returns a new instance of Interactive.



6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
# 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

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

  prepare_sub cl.subs
  cl.cmd :exit, "exit", min: cl.has?(:ex) ? cl.has?(:exi) ? 4 : 3 : 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

Instance Attribute Details

#clObject (readonly)

Returns the value of attribute cl.



4
5
6
# File 'lib/dencli/interactive.rb', line 4

def cl
  @cl
end

#curObject (readonly)

Returns the value of attribute cur.



4
5
6
# File 'lib/dencli/interactive.rb', line 4

def cur
  @cur
end

#histfileObject (readonly)

Returns the value of attribute histfile.



4
5
6
# File 'lib/dencli/interactive.rb', line 4

def histfile
  @histfile
end

#promptObject

Returns the value of attribute prompt.



4
5
6
# File 'lib/dencli/interactive.rb', line 4

def prompt
  @prompt
end

Instance Method Details

#complete(s) ⇒ Object



72
73
74
75
# File 'lib/dencli/interactive.rb', line 72

def complete s
  ws = words Readline.line_buffer
  @cur.complete *ws[0...-1], s
end

#history_file(file = nil) ⇒ Object



41
42
43
44
45
46
47
48
# File 'lib/dencli/interactive.rb', line 41

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) ⇒ Object



92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
# File 'lib/dencli/interactive.rb', line 92

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: n.has?(:ex) ? n.has?( :exi) ? 4 : 3 : 2,
          &lambda {|| @cur = n.parent }
      n.aliases.delete nil
      n.subs.delete nil
      n.cmd '', "", min: 2, aliases: [nil] do
        @cur = n
      end
      n.aliases['?'] = n[:help]  if n.has? :help and not n.has? '?'
      prepare_sub n
    when DenCli::CMD
    else raise "Unsupported sub-type: #{x}"
    end
  end
end

#readObject



113
114
115
116
117
118
119
120
121
# File 'lib/dencli/interactive.rb', line 113

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) ⇒ Object



50
51
52
53
54
55
56
# File 'lib/dencli/interactive.rb', line 50

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

#runObject



134
135
136
137
# File 'lib/dencli/interactive.rb', line 134

def run
  while step
  end
end

#stepObject



123
124
125
126
127
128
129
130
131
132
# File 'lib/dencli/interactive.rb', line 123

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) ⇒ Object



58
59
60
61
62
63
64
65
66
# File 'lib/dencli/interactive.rb', line 58

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