module Lowline

Public Instance Methods

ask(q, opts={}) click to toggle source
# File lib/lowline.rb, line 69
def ask q, opts={}
  default_s = case opts[:default]
    when nil; nil
    when ""; " (enter for none)"
    else; " (enter for #{opts[:default].inspect})"
  end

  tail = case q
    when /[:?]$/; " "
    when /[:?]\s+$/; ""
    else; ": "
  end

  while true
    prompt = [q, default_s, tail].compact.join
    if Ditz::has_readline?
      ans = Readline::readline(prompt)
    else
      print prompt
      ans = STDIN.gets.strip
    end
    if opts[:default]
      ans = opts[:default] if ans.blank?
    else
      next if ans.blank? && !opts[:empty_ok]
    end
    break ans unless (opts[:restrict] && ans !~ opts[:restrict])
  end
end
ask_for_many(plural_name, name=nil) click to toggle source
# File lib/lowline.rb, line 149
def ask_for_many plural_name, name=nil
  name ||= plural_name.gsub(/s$/, "")
  stuff = []

  while true
    puts
    puts "Current #{plural_name}:"
    if stuff.empty?
      puts "None!"
    else
      stuff.each_with_index { |c, i| puts "  #{i + 1}) #{c}" }
    end
    puts
    ans = ask "(A)dd #{name}, (r)emove #{name}, or (d)one"
    case ans
    when "a", "A"
      ans = ask "#{name.capitalize} name", ""
      stuff << ans unless ans =~ /^\s*$/
    when "r", "R"
      ans = ask "Remove which #{name}? (1--#{stuff.size})"
      stuff.delete_at(ans.to_i - 1) if ans
    when "d", "D"
      break
    end
  end
  stuff
end
ask_for_selection(stuff, name, to_string=:to_s) { |c| ... } click to toggle source
# File lib/lowline.rb, line 177
def ask_for_selection stuff, name, to_string=:to_s
  puts "Choose a #{name}:"
  stuff.each_with_index do |c, i|
    pretty = case to_string
    when block_given? && to_string # heh
      yield c
    when Symbol
      c.send to_string
    when Proc
      to_string.call c
    else
      raise ArgumentError, "unknown to_string argument type; expecting Proc or Symbol"
    end
    puts "  #{i + 1}) #{pretty}"
  end

  j = while true
    i = ask "#{name.capitalize} (1--#{stuff.size})"
    break i.to_i if i && (1 .. stuff.size).member?(i.to_i)
  end

  stuff[j - 1]
end
ask_multiline(q) click to toggle source
# File lib/lowline.rb, line 110
def ask_multiline q
  puts "#{q} (ctrl-d, ., or /stop to stop, /edit to edit, /reset to reset):"
  ans = ""
  while true
    if Ditz::has_readline?
      line = Readline::readline('> ')
    else
      (line = STDIN.gets) && line.strip!
    end
    if line
      if Ditz::has_readline?
        Readline::HISTORY.push(line)
      end
      case line
      when /^\.$/, "/stop"
        break
      when "/reset"
        return ask_multiline(q)
      when "/edit"
        return ask_via_editor(q, ans)
      else
        ans << line + "\n"
      end
    else
      puts
      break
    end
  end
  ans.multistrip
end
ask_via_editor(q, default=nil) click to toggle source
# File lib/lowline.rb, line 99
def ask_via_editor q, default=nil
  fn = run_editor do |f|
    f.puts(default || "")
    f.puts q.gsub(/^/, "## ")
    f.puts "##"
    f.puts "## Enter your text above. Lines starting with a '#' will be ignored."
  end
  return unless fn
  IO.read(fn).gsub(/^#.*$/, "").multistrip
end
ask_yon(q) click to toggle source
# File lib/lowline.rb, line 141
def ask_yon q
  while true
    print "#{q} (y/n): "
    a = STDIN.gets.strip
    break a if a =~ /^[yn]$/
  end =~ /y/
end
run_editor() { |f| ... } click to toggle source
# File lib/lowline.rb, line 55
def run_editor
  f = Tempfile.new "ditz"
  yield f
  f.close

  editor = ENV["EDITOR"] || "/usr/bin/vi"
  cmd = "#{editor} #{f.path.inspect}"

  mtime = File.mtime f.path
  system cmd or raise Error, "cannot execute command: #{cmd.inspect}"

  File.mtime(f.path) == mtime ? nil : f.path
end