lib/sxmrb.rb in sxmrb-0.1.0 vs lib/sxmrb.rb in sxmrb-0.1.1

- old
+ new

@@ -3,38 +3,114 @@ require_relative 'sxmrb/version' require 'shell' require 'shellwords' +require 'singleton' +require 'forwardable' + # SXMO user scripts in ruby. -module Sxmrb - class <<self - class Error < StandardError; end +class Sxmrb + include Singleton - def sh(...) - (@_sh ||= Shell.new).system(...) - rescue StandardError => e - raise Error, e - end + # Normally when using Singleton there is no way to pass arguments + # when instantiating. The renew hack below allows the singleton + # instance to be re-instantiated and can pass arguments at that time; + # this was added as an experiment to assist with testing. + def initialize(shell: ::Shell.new) # :nodoc: + @_sh = shell + end - def menu(prompt: nil) - sh String.new.tap { |cmd| - if ENV['SSH_CLIENT'] || ENV['SSH_TTY'] - cmd << 'vis-menu -i -l 18' - else - cmd << 'dmenu -c -i -l 18' - sh 'sxmo_keyboard.sh open' - end + # Run a system shell command. + # + # @example + # sh('ls -tr').to_s.lines.last + def sh(...) + @_sh.system(...) + rescue ::StandardError => e + raise Error, e + end - cmd << " -p #{prompt.inspect}" if prompt - } - end + # Display a menu using dmenu [X11] or vis-menu [ssh]. + # A newline-separated list of items is read from standard input. + # The selected item is printed to standard output. + # + # @example + # file = (sh('ls') | menu(prompt: 'File?')).to_s.chomp + def menu(prompt: nil) + sh String.new.tap { |cmd| + if ENV['SSH_CLIENT'] || ENV['SSH_TTY'] + cmd << 'vis-menu -i -l 18' + else + cmd << 'dmenu -c -i -l 18' + sh 'sxmo_keyboard.sh open' + end - def echo(arg = '') - sh("echo #{Shellwords.escape arg.chomp}") - end + cmd << " -p #{prompt.inspect}" if prompt + } + end - def input(prompt:) - (echo | menu(prompt: prompt)).to_s.chomp + # Run the awk command. + # + # @example + # print(sh('ls -l') | awk('{print $1}').to_s) + def awk(arg = '') + sh("awk -e #{Shellwords.escape arg.chomp}") + end + + # Run the cat command. + # + # @example + # print cat('/etc/passwd').to_s + def cat(arg = '') + sh("cat #{arg.chomp}") + end + + # Run the column command. + # + # @example + # print(sh('ls -l') | column('-t').to_s) + def column(arg = '') + sh("column #{arg.chomp}") + end + + # Run the shell echo command. + # + # @example + # print echo('Hello World').to_s + def echo(arg = '') + sh("echo #{Shellwords.escape arg.chomp}") + end + + # Run the tac command. + # + # @example + # print tac('/etc/passwd').to_s + def tac(arg = '') + sh("tac #{arg.chomp}") + end + + # Use a blank #menu to prompt for a value. + # + # @example + # value = input(prompt: 'Amount?').to_i + def input(prompt:) + (echo | menu(prompt: prompt)).to_s.chomp + end + + class <<self + # This evil hack experiment is intended to allow swapping out the + # Shell instance when testing. + def renew_instance(...) # :nodoc: + @singleton__mutex__.synchronize { + @singleton__instance__ = new(...) + } end + + # Forward instance methods to the Singleton instance; false here + # excludes ancestor methods. + extend Forwardable + def_delegators :instance, *Sxmrb.instance_methods(false) end + + class Error < ::StandardError; end end