class Rooibos::Command::Open
Opens a file or URL with the systemโs default application.
Terminal applications often need to hand off to external programs. Opening a PDF, launching a URL, or viewing an image requires platform-specific commands.
This command detects the platform and runs the appropriate opener: open on macOS, xdg-open on Linux, start on Windows.
On success (exit 0), sends Message::Open. On failure (non-zero), sends Message::Error.
Prefer the Command.open factory method for convenience.
Example
# Using the factory method (recommended) Command.open(model.selected_file) Command.open("https://rooibos.run") # Using the class directly Open.new(path: model.selected_file, envelope: model.selected_file) # Pattern-match on the response def update(msg, model) case msg in { type: :open, envelope: path } model.with(status: "Opened #{path}") in { type: :error, envelope: path } model.with(error: "Could not open #{path}") end end
Public Instance Methods
Source
# File lib/rooibos/command/open.rb, line 51 def call(out, token) return if token.canceled? require "open3" cmd = self.class.__send__(:system_command, path) _stdout, stderr, status = Open3.capture3(cmd) message = if status.exitstatus == 0 Message::Open.new(envelope:) else error_msg = stderr.empty? ? "Failed to open: #{path}" : stderr.strip Message::Error.new( command: envelope, exception: RuntimeError.new(error_msg.freeze).freeze ) end out.put(Ractor.make_shareable(message)) rescue => e out.put(Ractor.make_shareable(Message::Error.new( command: envelope, exception: RuntimeError.new(e.message.freeze).freeze ))) end
Executes the open command and sends the result message.
Source
# File lib/rooibos/command/open.rb, line 48 def rooibos_cancellation_grace_period = 0 # Executes the open command and sends the result message. def call(out, token) return if token.canceled? require "open3" cmd = self.class.__send__(:system_command, path) _stdout, stderr, status = Open3.capture3(cmd) message = if status.exitstatus == 0 Message::Open.new(envelope:) else error_msg = stderr.empty? ? "Failed to open: #{path}" : stderr.strip Message::Error.new( command: envelope, exception: RuntimeError.new(error_msg.freeze).freeze ) end out.put(Ractor.make_shareable(message)) rescue => e out.put(Ractor.make_shareable(Message::Error.new( command: envelope, exception: RuntimeError.new(e.message.freeze).freeze ))) end # Builds the platform-specific open command. def self.system_command(path, platform = RUBY_PLATFORM) # :nodoc: escaped = path.shellescape case platform when /darwin/ "open #{escaped}" when /linux/ "xdg-open #{escaped}" when /mingw|mswin|cygwin/ "start #{path}" else "xdg-open #{escaped}" end end private_class_method :system_command end
System commands are generally fast; no grace period needed.