Class: Yap::World

Inherits:
Object
  • Object
show all
Extended by:
Forwardable
Includes:
Term::ANSIColor
Defined in:
lib/yap/world.rb

Defined Under Namespace

Classes: AddonHash

Constant Summary collapse

DEFAULTS =
{
  primary_prompt_text: "yap> ",
  secondary_prompt_text: "> "
}

Instance Attribute Summary collapse

Class Method Summary collapse

Instance Method Summary collapse

Constructor Details

#initialize(addons:) ⇒ World

Returns a new instance of World.



30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
# File 'lib/yap/world.rb', line 30

def initialize(addons:)
  @env = ENV.to_h.dup
  dom = build_editor_dom

  # ensure yap directory exists
  if !File.exists?(configuration.yap_path)
    if configuration.skip_first_time?
      # skipping first time
    else
      puts
      puts yellow("Yap directory not found: #{configuration.yap_path}")
      puts
      puts "Initializing yap for the first time:"
      puts

      print "    Creating #{configuration.yap_path} "
      FileUtils.mkdir_p configuration.yap_path
      puts green("done")

      print "    Creating default #{configuration.preferred_yaprc_path} "
      FileUtils.cp configuration.yaprc_template_path, configuration.yap_path
      puts green("done")
      puts
      puts "To tweak yap take a look at #{configuration.preferred_yaprc_path}."
      puts
      puts "Reloading shell"
      reload!
    end
  end

  @editor = RawLine::Editor.create(dom: dom)

  self.prompt = Yap::Shell::Prompt.new(text: DEFAULTS[:primary_prompt_text])
  self.secondary_prompt = Yap::Shell::Prompt.new(text: DEFAULTS[:secondary_prompt_text])

  @repl = Yap::Shell::Repl.new(world:self)

  @addons_initialized = []
  @addons = AddonHash.new(
    self
  )

  addons.each do |addon|
    if addon.yap_enabled?
      @addons[addon.export_as] = addon
    end
  end

  @addons.values.select(&:yap_enabled?).each do |addon|
    initialize_addon(addon) unless addon_initialized?(addon)
    addon
  end
end

Instance Attribute Details

#addonsObject (readonly)

Returns the value of attribute addons.



22
23
24
# File 'lib/yap/world.rb', line 22

def addons
  @addons
end

#contentsObject

Returns the value of attribute contents.



21
22
23
# File 'lib/yap/world.rb', line 21

def contents
  @contents
end

#editorObject

Returns the value of attribute editor.



21
22
23
# File 'lib/yap/world.rb', line 21

def editor
  @editor
end

#envObject

Returns the value of attribute env.



21
22
23
# File 'lib/yap/world.rb', line 21

def env
  @env
end

#last_resultObject

Returns the value of attribute last_result.



24
25
26
# File 'lib/yap/world.rb', line 24

def last_result
  @last_result
end

#promptObject

Returns the value of attribute prompt.



21
22
23
# File 'lib/yap/world.rb', line 21

def prompt
  @prompt
end

#replObject

Returns the value of attribute repl.



21
22
23
# File 'lib/yap/world.rb', line 21

def repl
  @repl
end

#secondary_promptObject

Returns the value of attribute secondary_prompt.



21
22
23
# File 'lib/yap/world.rb', line 21

def secondary_prompt
  @secondary_prompt
end

Class Method Details

.instance(*args) ⇒ Object



26
27
28
# File 'lib/yap/world.rb', line 26

def self.instance(*args)
  @instance ||= new(*args)
end

Instance Method Details

#[](addon_name) ⇒ Object



118
119
120
# File 'lib/yap/world.rb', line 118

def [](addon_name)
  @addons.fetch(addon_name){ raise(ArgumentError, "No addon loaded registered as #{addon_name}") }
end

#addon_initialized?(addon) ⇒ Boolean

Returns:

  • (Boolean)


84
85
86
# File 'lib/yap/world.rb', line 84

def addon_initialized?(addon)
  (@addons_initialized ||= []).include?(addon)
end

#aliasesObject



122
123
124
# File 'lib/yap/world.rb', line 122

def aliases
  Yap::Shell::Aliases.instance
end

#bind(key, &blk) ⇒ Object



138
139
140
141
142
# File 'lib/yap/world.rb', line 138

def bind(key, &blk)
  @editor.bind(key) do
    blk.call self
  end
end

#build_editor_domObject



242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
# File 'lib/yap/world.rb', line 242

def build_editor_dom
  @left_status_box = TerminalLayout::Box.new(content: "", style: {display: :inline})
  @right_status_box = TerminalLayout::Box.new(content: "", style: {display: :inline})
  @prompt_box = TerminalLayout::Box.new(content: "yap>", style: {display: :inline})
  @input_box = TerminalLayout::InputBox.new(content: "", style: {display: :inline})

  @content_box = TerminalLayout::Box.new(content: "", style: {display: :block})
  @bottom_left_status_box = TerminalLayout::Box.new(content: "", style: {display: :inline})
  @bottom_right_status_box = TerminalLayout::Box.new(content: "", style: {display: :inline})

  @right_status_float = TerminalLayout::Box.new(style: {display: :float, float: :right, width: @right_status_box.content.length},
    children: [
      @right_status_box
    ]
  )

  RawLine::DomTree.new(
    children:[
      @right_status_float,
      @left_status_box,
      @prompt_box,
      @input_box,
      @content_box,
      TerminalLayout::Box.new(style: {display: :float, float: :left, width: @bottom_left_status_box.content.length},
        children: [
          @bottom_left_status_box
        ]
      ),
      TerminalLayout::Box.new(style: {display: :float, float: :right, width: @bottom_right_status_box.content.length},
        children: [
          @bottom_right_status_box
        ]
      )
    ]
  ).tap do |dom|
    dom.prompt_box = @prompt_box
    dom.input_box = @input_box
    dom.content_box = @content_box
    @prompt_box.name = "prompt-box"
    @input_box.name = "input-box"
    @content_box.name = "content-box"
  end
end

#builtinsObject



126
127
128
# File 'lib/yap/world.rb', line 126

def builtins
  Yap::Shell::BuiltinCommand.builtins.keys.map(&:to_s)
end

#configurationObject



114
115
116
# File 'lib/yap/world.rb', line 114

def configuration
  ::Yap.configuration
end

#eventsObject



134
135
136
# File 'lib/yap/world.rb', line 134

def events
  @editor.events
end

#foreground?Boolean

Returns:

  • (Boolean)


191
192
193
194
# File 'lib/yap/world.rb', line 191

def foreground?
  return unless STDIN.isatty
  Process.getpgrp == Termios.tcgetpgrp($stdout)
end

#func(name, &blk) ⇒ Object



152
153
154
# File 'lib/yap/world.rb', line 152

def func(name, &blk)
  Yap::Shell::ShellCommand.define_shell_function(name, &blk)
end

#historyObject



196
197
198
# File 'lib/yap/world.rb', line 196

def history
  @editor.history
end

#initialize_addon(addon) ⇒ Object



88
89
90
91
92
93
94
95
96
97
98
# File 'lib/yap/world.rb', line 88

def initialize_addon(addon)
  return unless addon
  begin
    addon.initialize_world(self)
    (@addons_initialized ||= []) << addon
  rescue Exception => ex
    puts Term::ANSIColor.red(("The #{addon.addon_name} addon failed to initialize due to error:"))
    puts ex.message
    puts ex.backtrace[0..5]
  end
end

#interactive!Object



200
201
202
203
# File 'lib/yap/world.rb', line 200

def interactive!
  refresh_prompt
  @editor.start
end

#refresh_promptObject



229
230
231
# File 'lib/yap/world.rb', line 229

def refresh_prompt
  @editor.prompt = @prompt.update.text
end

#reload!Object



148
149
150
# File 'lib/yap/world.rb', line 148

def reload!
  exec configuration.yap_binpath
end

#right_prompt_text=(str) ⇒ Object



233
234
235
236
# File 'lib/yap/world.rb', line 233

def right_prompt_text=(str)
  @right_status_float.width = str.length
  @right_status_box.content = str
end

#shell(statement) ⇒ Object



156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
# File 'lib/yap/world.rb', line 156

def shell(statement)
  context = Yap::Shell::Execution::Context.new(
    stdin:  $stdin,
    stdout: $stdout,
    stderr: $stderr
  )
  if statement.nil?
    @last_result = Yap::Shell::Execution::Result.new(
      status_code: 1,
      directory: Dir.pwd,
      n: 1,
      of: 1
    )
  else
    evaluation = Yap::Shell::Evaluation.new(stdin:$stdin, stdout:$stdout, stderr:$stderr, world:self)
    evaluation.evaluate(statement) do |command, stdin, stdout, stderr, wait|
      context.clear_commands
      context.add_command_to_run command, stdin:stdin, stdout:stdout, stderr:stderr, wait:wait
      @last_result = context.execute(world:self) || 0
      if @last_result.is_a?(Integer)
        Yap::Shell::Execution::Result.new(
          status_code: @last_result,
          directory: Dir.pwd,
          n: 1,
          of: 1
        )
      else
        @last_result
      end
    end
  end

  @last_result
end

#shell_commandsObject



130
131
132
# File 'lib/yap/world.rb', line 130

def shell_commands
  Yap::Shell::ShellCommand.registered_functions.keys.map(&:to_s)
end

#subscribe(*args, &blk) ⇒ Object



238
239
240
# File 'lib/yap/world.rb', line 238

def subscribe(*args, &blk)
  @editor.subscribe(*args, &blk)
end

#unbind(key) ⇒ Object



144
145
146
# File 'lib/yap/world.rb', line 144

def unbind(key)
  @editor.unbind(key)
end