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