Class: Ruber::FilesRunner::Plugin

Inherits:
RubyRunner::RubyRunnerPlugin show all
Defined in:
plugins/ruby_development/ruby_development.rb

Overview

Plugin object for the Files runner plugn

Defined Under Namespace

Classes: FakeFileInfo

Constant Summary

Constants inherited from Plugin

LICENSES

Instance Attribute Summary

Attributes inherited from ExternalProgramPlugin

process

Attributes included from PluginLike

plugin_description

Instance Method Summary (collapse)

Methods inherited from RubyRunner::RubyRunnerPlugin

#interpreter_for, #option_for, #ruby_command_for

Methods inherited from ExternalProgramPlugin

#display_exit_message, #do_stderr, #do_stdout, #failed_to_start, #run_process, #shutdown, #slot_process_finished, #stop_process

Methods inherited from GuiPlugin

#action_collection, #execute_action, #register_action_handler, #setup_actions, #unload

Methods inherited from Plugin

#about_data

Methods included from PluginLike

#add_extensions_to_project, #add_options_to_project, #add_widgets_to_project, #create_tool_widget, #delayed_initialize, #initialize_plugin, #load_settings, #plugin_name, #query_close, #register_options, #remove_extensions_from_project, #remove_from_project, #remove_options_from_project, #remove_widgets_from_project, #restore_session, #save_settings, #session_data, #setup_action, #setup_actions, #shutdown, #unload, #update_project

Methods API

Constructor Details

- (Plugin) initialize(psf)

A new instance of Plugin

Parameters:



56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
# File 'plugins/ruby_development/ruby_development.rb', line 56

def initialize psf
  super psf, :ruby, :scope => [:document, :global], :file_extension => %w[*.rb Rakefile rakefile], 
      :mimetype => ['application/x-ruby'], :place => [:local, :remote]
  process.next_open_mode = Qt::IODevice::ReadOnly | Qt::IODevice::Unbuffered
  Ruber[:autosave].register_plugin self, true
  connect self, SIGNAL('process_finished(int, QString)'), self, SLOT('ruby_exited(int, QString)')
  self.connect(SIGNAL(:process_failed_to_start)){@gui.action_collection.action('ruby_runner-stop').enabled = false}
  Ruber[:main_window].change_state 'ruby_running', false
  register_action_handler('ruby_runner-run') do |states| 
    (states['current_document'] or states['active_project_exists']) and
        !states['ruby_running']
  end
  register_action_handler('ruby_runner-run_current_file') do |states|
    states['current_document'] and ! states['ruby_running']
  end
  Ruber[:components].connect(SIGNAL('feature_loaded(QString, QObject*)')) do |f, o|
    o.register_plugin self, true if f == 'autosave'
  end
  @output_widget = @widget
  @fake_file = nil
end

Instance Method Details

- (nil) process_standard_error(lines) (private)

Override of ExternalProgramPlugin#process_standard_error

It processes the lines using #replace_fake_file before passing it to the base class’s method

Parameters:

  • lines (Array<String>)

    the lines on standard error

Returns:

  • (nil)


467
468
469
# File 'plugins/ruby_development/ruby_development.rb', line 467

def process_standard_error lines
  super replace_fake_file(lines)
end

- (nil) process_standard_output(lines) (private)

Override of ExternalProgramPlugin#process_standard_output

It processes the lines using #replace_fake_file before passing it to the base class’s method

Parameters:

Returns:

  • (nil)


455
456
457
# File 'plugins/ruby_development/ruby_development.rb', line 455

def process_standard_output lines
  super replace_fake_file(lines)
end

- (nil) register_with_project(prj)

Override of Ruber::Plugin#register_with_project

This mehtods sets the ruby/main_program project option to bin/project_name if it’s empty and sets up a connection with the option_changed signal of the project to do the same whenever this option changes.

It works as Ruber::Plugin#register_with_project if the project has document scope

Parameters:

Returns:

  • (nil)


296
297
298
299
300
301
302
303
304
305
306
307
308
# File 'plugins/ruby_development/ruby_development.rb', line 296

def register_with_project prj
  super
  return unless prj.scope == :global
  if prj[:ruby, :main_program].empty?
    prj[:ruby, :main_program] = File.join('bin',prj.project_name.gsub(/\W/,'_').downcase)
  end
  prj.connect(SIGNAL('option_changed(QString, QString)')) do |g, n|
    if g == 'ruby' and n == 'main_program' && prj[:ruby, :main_program].empty?
      prj[:ruby, :main_program] = File.join 'bin',prj.project_name.gsub(/\W/,'_').downcase
    end
  end
  nil
end

- (Array<String>) replace_fake_file(lines) (private)

Replaces the path of the fake file used for running remote documents with the URL of the document

It does nothing if there’s no fake file (that is, if we’re not executing the document associated with a remote file).

Note: for efficency reasons the replacement is performed in place, so create a duplicate of the array before calling this method if you need to preserve it.

with the url of the remote file. If no fake file is in use, lines will be returned unchanged

Parameters:

  • the (Array<String>)

    lines of text to perform the replacement into

Returns:

  • (Array<String>)

    the lines with all occurrences of the fake file path replaced



440
441
442
443
444
445
# File 'plugins/ruby_development/ruby_development.rb', line 440

def replace_fake_file lines
  if @fake_file
    lines.map!{|l| l.gsub(@fake_file.file.path, @fake_file.url.pretty_url)}
  end
  lines
end

- (nil) ruby_exited(code, reason) (private)

Slot called when the ruby process exited

Resets the UI, scrolls the tool widget at the end and gives focus to the editor

Returns:

  • (nil)


413
414
415
416
417
418
419
420
421
422
# File 'plugins/ruby_development/ruby_development.rb', line 413

def ruby_exited code, reason
  Ruber[:main_window].change_state 'ruby_running', false
  @widget.scroll_to -1
  Ruber[:main_window].focus_on_editor
  if @fake_file
    @fake_file.file.close true
    @fake_file = nil
  end
  nil
end

Slot Signature:

ruby_exited(int, QString)

- (Boolean) run

Runs either the project main program or the file in the current view in ruby, displaying the output in the output tool widget

This method calls #run_project or #run_document (with the current document) if theere’s a global project or an active document. If there isn’t either a global project nor a document, then #run_file is used.

started correctly or not.

Returns:

  • (Boolean)

    true or false depending on whether the ruby process was

See Also:



158
159
160
161
162
163
# File 'plugins/ruby_development/ruby_development.rb', line 158

def run
  if Ruber[:world].active_project then run_project
  elsif (doc = Ruber[:main_window].current_document) then run_document doc
  else run_file
  end
end

Slot Signature:

run()

- (Boolean?) run_current_document (private)

Runs the current document in ruby

If there’s an open document, it works like #run_document, otherwise it does nothing was started correctly and nil if no document exists

Returns:

  • (Boolean, nil)

    true or false depending on whether the ruby process

See Also:

  • Ruber::FilesRunner::Plugin.{{#run_document}


378
379
380
381
382
# File 'plugins/ruby_development/ruby_development.rb', line 378

def run_current_document
  doc =  Ruber[:main_window].current_document
  return unless doc        
  run_document doc
end

Slot Signature:

run_current_document()

- (Boolean) run_document(doc)

Runs the file associated with the given document in ruby

If the user has enabled autosave for this plugin, the document will be saved before ruby is run.

Ruby will be executed from the directory where the file is, while the interpreter to use, the options to pass to ruby and those to pass to the program are read from the DocumentProject associated with the document itself.

The #run_in_terminal? method is used to decide whether the program should be run in a terminal window or not.

This method uses #run_ruby_for.

successfully or not

Parameters:

Returns:

  • (Boolean)

    true or false depending on whether the ruby process was started

See Also:



211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
# File 'plugins/ruby_development/ruby_development.rb', line 211

def run_document doc
  return unless doc.save if !doc.has_file?
  prj = doc.project
  file = File.basename(doc.path)
  dir = File.dirname(doc.path)
  url = doc.url
  if url.remote_file?
    @fake_file = FakeFileInfo.new Tempfile.new('ruby_development'), url
    @fake_file.file.write doc.text
    @fake_file.file.flush
    file = @fake_file.file.path
    dir = ENV['HOME']
  end
  unless prj.has_setting?(:ruby, :options)
    KDE::MessageBox.sorry nil, "The document #{url.pretty_url} doesn't seem to be a ruby file, so it can't be run"
    return
  end
  run_ruby_for prj, file, dir, prj[:ruby, :options], run_in_terminal?(doc.project),
      :files => [doc], :on_failure => :ask
end

- (Boolean?) run_file(file = nil)

Runs a file in ruby.

If the file is associated with a document, this method will work like #run_document.

The file can be local or remote.

Ruby will be executed from the directory where the file is or from the user’s home directory if the file is remote.

The program will be run in a terminal if the corresponding action is checked.

This method uses #run_ruby_for

Note: it is not possible to specify command line options to be passed to file. dialog is shown to the user was started. If the user pressed the Cancel button of the dialog, nil is returned.

Parameters:

  • file (String, nil) (defaults to: nil)

    the path or url of the file to run. If nil, an “Open file”

Returns:

  • (Boolean, nil)

    true or false depending on whether the ruby process

See Also:



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
# File 'plugins/ruby_development/ruby_development.rb', line 253

def run_file file = nil
  if file then url = KDE::Url.new file
  else
    url = KDE::FileDialog.get_open_url KDE::Url.new(Ruber[:config][:general, :default_script_directory]),
        "*.rb|Ruby files (*.rb)", nil, "Choose file to run"
    return unless url
    file = url.to_encoded.to_s
  end
  
  if doc = Ruber[:world].documents.document_for_url(url)
   return run_document doc 
  end
  
  if url.local_file?
    dir = File.dirname(file)
    file = File.basename(file)
  else
    @fake_file = FakeFileInfo.new Tempfile.new('ruby_development'), url
    downloaded = KIO::NetAccess.download url, @fake_file.file.path, Ruber[:main_window]
    unless downloaded
      KDE::MessageBox.sorry Ruber[:main_window], KIO::NetAccess.last_error_string
      return
    end
    file = @fake_file.file.path
    dir = ENV['HOME']
  end
  run_ruby_for nil, file, dir, [], run_in_terminal?
end

Slot Signature:

run_file()

- (Boolean) run_in_terminal?(prj = nil) (private)

Whether a given ruby program should be run in terminal or not

This method takes into account the ruby/run_in_terminal option stored in the given project (if any) and the state of the ruby_runner-run_in_terminal action (which, if checked, overrides the option).

Note: while the user can, by checking the action, force a program to be run in terminal even if the project doesn’t say so, there’s no way in which he can force a program to be run without a terminal if the project says it should be run in a terminal (because if the action is unchecked, only the project option is taken into account).

settings. If nil, only the action will be taken into account otherwise.

Parameters:

Returns:

  • (Boolean)

    true if the program should be run in terminal and false



402
403
404
405
# File 'plugins/ruby_development/ruby_development.rb', line 402

def run_in_terminal? prj = nil
  action_collection.action('ruby_runner-run_in_terminal').checked? ||
      (prj and prj[:ruby, :run_in_terminal])
end

- (Booelan) run_project

Runs the main program of the project.

It uses the project settings for options, working directory and so on.

If the appropriate option is set, it will attempt to save all the documents corresponding to files in the project before executing. If it fails, then ruby won’t be run.

This method calls #run_ruby_for internally. started successfully.

Returns:

  • (Booelan)

    true or false depending on whether the ruby process was

See Also:



180
181
182
183
184
185
186
187
188
# File 'plugins/ruby_development/ruby_development.rb', line 180

def run_project
  prj = Ruber[:world].active_project
  data = prj[:ruby]
  prog = Pathname.new(data[:main_program, :abs])
  wdir = Pathname.new(data[:working_dir, :abs]||prj.project_dir)
  prog = (prog.relative_path_from(wdir)).to_s
  run_ruby_for prj, prog, wdir.to_s, data[:options], run_in_terminal?(prj),
      :files => :project_files, :on_failure => :ask
end

- (Boolean) run_ruby(script, opts, autosave_opts = {}, &blk)

Runs ruby the given script in ruby

The output of ruby is displayed in the associated output widget. If desired, files are autosaved before running it.

If ruby is already running, or if autosaving fails, noting is done.

passed to autosave

to use an array with the options to pass to the ruby interpreter to the script It can be anything which can be passed as second parameter to Autosave::AutosavePlugin#autosave. If it’s nil, autosave won’t be used as first argument to Autosave::AutosavePlugin#autosave (including the case when the process was already running or autosaving failed)

Parameters:

  • script (String)

    the ruby script to execute (either absolute path or relative to the :dir entry of opts)

  • opts (Hash)

    options to fine-tune the behaviour of ruby

  • autosave_opts (Hash) (defaults to: {})

    options telling whether and how autosave files

  • blk (Proc)

    a block to pass to autosave. If not given, no block will be

Options Hash (opts):

  • :ruby (String) — default: Ruber[:config][:ruby, :ruby]

    the ruby interpreter

  • :ruby_options (Array<String>) — default: Ruber[:config][:ruby, :ruby_options]
  • :options (Array<String>) — default: []

    an array with the options to pass

  • :dir (String) — default: Dir.pwd

    the directory to run ruby from

Options Hash (autosave_opts):

Returns:

  • (Boolean)

    true if the process is started and false otherwise

See Also:



115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
# File 'plugins/ruby_development/ruby_development.rb', line 115

def run_ruby script, opts, autosave_opts = {}, &blk
  default = {
    :ruby => Ruber[:config][:ruby, :ruby],
    :ruby_options => Ruber[:config][:ruby, :ruby_options],
    :dir => Dir.pwd,
    :options => []
    }
  opts = default.merge opts
  return false unless process.state == Qt::Process::NotRunning
  if autosave_opts[:files]
    plug = autosave_opts[:plugin] || self
    what = autosave_opts[:files]
    return false unless Ruber[:autosave].autosave plug, 
        what, autosave_opts, &blk
  end
  @widget.working_directory = opts[:dir]
  @widget.clear_output
  cmd = opts[:ruby_options] + [script] + opts[:options]
  Ruber[:main_window].show_tool @widget
  Ruber[:main_window].change_state 'ruby_running', true
  if opts[:run_in_terminal]
    terminal, *term_opts = terminal_command opts[:dir], ([opts[:ruby]] + cmd)
    run_process terminal, opts[:dir], term_opts
  else run_process opts[:ruby], opts[:dir], cmd
  end
  true
end

- (Boolean) run_ruby_for(what, file, dir, prog_options, run_in_terminal, autosave_opts = {}, &blk) (private)

Starts executing a given ruby program and displays the tool widget

This method uses RubyRunner::RubyRunnerPlugin#ruby_command_for to retrieve the first part of the command line to use and #run_ruby to actually start the ruby process.

meaning as in RubyRunner::RubyRunnerPlugin#ruby_command_for program (not to ruby itself) or not started correctly

Parameters:

  • what (Ruber::AbstractProject, Ruber::Document, String, nil)

    has the same

  • file (String)

    the filename of the script to run

  • dir (String)

    has the same meaning as in RubyRunner::RubyRunnerPlugin#ruby_command_for

  • prog_options (<String>)

    a list of the command line options to pass to the

  • run_in_terminal (Boolean)

    whether to run the program in a terminal window

  • autosave_opts (Hash) (defaults to: {})

    has the same meaning as in #run_ruby

  • blk (Proc)

    has the same meaning as in #run_ruby

Returns:

  • (Boolean)

    true or false depending on whether the ruby process was

See Also:

  • #run_ruby
  • RubyRunner::RubyRunnerPluginInternal#ruby_command_for


357
358
359
360
361
362
363
364
365
366
367
# File 'plugins/ruby_development/ruby_development.rb', line 357

def run_ruby_for what, file, dir, prog_options, run_in_terminal, autosave_opts={}, &blk
  ruby, *ruby_opts = ruby_command_for what, dir
  opts = {
    :dir => dir,
    :options => prog_options,
    :run_in_terminal => run_in_terminal,
    :ruby => ruby,
    :ruby_options => ruby_opts
    }
  run_ruby file, opts, autosave_opts, &blk
end

- (Array<String>) terminal_command(dir, ruby_command) (private)

The command line to use to run the given ruby command in a terminal

This method replaces every instance of %d in the ruby/run_in_terminal_cmd setting with the working directory and every instance of %r with the ruby command. If %r is sourrounded by spaces, it’ll be replaced by ruby_command as it is; it %r is part of a string, it’ll be replaced by the elements of ruby_command joined with spaces.

Parameters:

  • dir (String)

    the working directory

  • ruby_command (Array<String>)

    the ruby command to execute in the terminal

Returns:



326
327
328
329
330
331
332
333
334
# File 'plugins/ruby_development/ruby_development.rb', line 326

def terminal_command dir, ruby_command
  cmd = Ruber[:config][:ruby, :run_in_terminal_cmd].split(/\s+/)
  cmd.each do |c|
    c.gsub!('%d', dir)
    c.gsub!('%r', ruby_command.join(' ')) unless c == '%r'
  end
  cmd.each_with_index.find{|e, i| e == '%r'}.each_index{|i| cmd[i] = ruby_command}
  cmd.flatten
end