sup

A curses threads-with-tags style email client

sup.git

git clone https://supmua.dev/git/sup/

lib/sup/modes/console_mode.rb (2793B) - raw

      1 require 'pp'
      2 
      3 require "sup/service/label_service"
      4 
      5 module Redwood
      6 
      7 class Console
      8   def initialize mode
      9     @mode = mode
     10     @label_service = LabelService.new
     11   end
     12 
     13   def query(query)
     14     Index.instance.enum_for :each_message, Index.parse_query(query)
     15   end
     16 
     17   def add_labels(query, *labels)
     18     count = @label_service.add_labels(query, *labels)
     19     print_buffer_dirty_msg count
     20   end
     21 
     22   def remove_labels(query, *labels)
     23     count = @label_service.remove_labels(query, *labels)
     24     print_buffer_dirty_msg count
     25   end
     26 
     27   def print_buffer_dirty_msg msg_count
     28     puts "Scanned #{msg_count} messages."
     29     puts "You might want to refresh open buffers with `@` key."
     30   end
     31   private :print_buffer_dirty_msg
     32 
     33   def xapian; Index.instance.instance_variable_get :@xapian; end
     34 
     35   def loglevel; Redwood::Logger.level; end
     36   def set_loglevel(level); Redwood::Logger.level = level; end
     37 
     38   def special_methods; public_methods - Object.methods end
     39 
     40   def puts x; @mode << "#{x.to_s.rstrip}\n" end
     41   def p x; puts x.inspect end
     42 
     43   ## files that won't cause problems when reloaded
     44   ## TODO expand this list / convert to blacklist
     45   RELOAD_WHITELIST = %w(sup/index.rb sup/modes/console-mode.rb)
     46 
     47   def reload
     48     old_verbose = $VERBOSE
     49     $VERBOSE = nil
     50     old_features = $".dup
     51     begin
     52       fs = $".grep(/^sup\//)
     53       fs.reject! { |f| not RELOAD_WHITELIST.member? f }
     54       fs.each { |f| $".delete f }
     55       fs.each do |f|
     56         @mode << "reloading #{f}\n"
     57         begin
     58           require f
     59         rescue LoadError => e
     60           raise unless e.message =~ /no such file to load/
     61         end
     62       end
     63     rescue Exception
     64       $".clear
     65       $".concat old_features
     66       raise
     67     ensure
     68       $VERBOSE = old_verbose
     69     end
     70     true
     71   end
     72 
     73   def clear_hooks
     74     HookManager.clear
     75     nil
     76   end
     77 end
     78 
     79 class ConsoleMode < LogMode
     80   register_keymap do |k|
     81     k.add :run, "Restart evaluation", 'e'
     82   end
     83 
     84   def initialize
     85     super "console"
     86     @console = Console.new self
     87     @binding = @console.instance_eval { binding }
     88   end
     89 
     90   def execute cmd
     91     begin
     92       self << ">> #{cmd}\n"
     93       ret = eval cmd, @binding
     94       self << "=> #{ret.pretty_inspect}\n"
     95     rescue Exception
     96       self << "#{$!.class}: #{$!.message}\n"
     97       clean_backtrace = []
     98       $!.backtrace.each { |l| break if l =~ /console-mode/; clean_backtrace << l }
     99       clean_backtrace.each { |l| self << "#{l}\n" }
    100     end
    101   end
    102 
    103   def prompt
    104     BufferManager.ask :console, ">> "
    105   end
    106 
    107   def run
    108     self << <<EOS
    109 Sup v#{VERSION} console session started.
    110 Available extra commands: #{(@console.special_methods) * ", "}
    111 Ctrl-G stops evaluation; 'e' restarts it.
    112 
    113 EOS
    114     while true
    115       if(cmd = prompt)
    116         execute cmd
    117       else
    118         self << "Console session ended."
    119         break
    120       end
    121     end
    122   end
    123 end
    124 
    125 end