class Zashoku::Viewer
Main class for the zashoku application
Constants
- CMD_HISTORY
- COMMANDS
- SRCH_HISTORY
Public Class Methods
new(host:, port:)
click to toggle source
# File lib/viewer.rb, line 57 def initialize(host:, port:) @host, @port = host, port @semaphore = Mutex.new Zashoku.logger = Logger.new( File.join(Zashoku::CConf[:app][:root], "#{Zashoku::CConf[:app][:name]}.log") ) Zashoku.logger.level = Zashoku::CConf[:app][:log_level][:viewer] Zashoku.conf = ViewConfig.new Zashoku.modules = Zashoku::Module.load(Zashoku::CConf[:app][:modules][:viewer]) Zashoku.modules.merge!('conf' => Conf) Zashoku.conf.reload # note: start daemon if not running Zashoku.client = Net::Client.new(host, port) Zashoku.client.callbacks << method(:handle_event) @server_modules = Zashoku.client.command('modules') @views = Zashoku.modules.keys.zip(Zashoku.modules.map do |_k, m| m.view end).to_h @view = @views.keys.first @statusline = Statusline.new @statusline.add_observer(self, :draw_statusline) @cmdline = Util::Readline.new( ':', ac_tree: @views.map { |k, v| [k, v.methods - Object.methods] }.to_h .merge(COMMANDS.map { |k, _v| [k, nil] }.to_h) .merge({'conf' => Zashoku.conf.methods - Object.methods }) .merge(@server_modules.map { |m| ['remote::' + m, nil] }.to_h), history: Util.get_yaml(CMD_HISTORY, []) ) @searchline = Util::Readline.new('/', history: Util.get_yaml(SRCH_HISTORY, [])) init_screen lay_traps! Thread.abort_on_exception = true Thread.new { scan_keyboard! } init_view(@view) if @view @statusline.draw sleep end
Public Instance Methods
builtin_command(cmd, *args)
click to toggle source
# File lib/viewer.rb, line 217 def builtin_command(cmd, *args) Zashoku.logger.debug("executing builtin #{cmd}(#{args})") send(COMMANDS[cmd], *args) end
change_view(new_view)
click to toggle source
# File lib/viewer.rb, line 119 def change_view(new_view) Zashoku.logger.debug("Changing view to #{new_view}") @views[@view].delete_observers #@views[new_view].change_screen_size(redraw: false) #@views[new_view].expand(-1) @view = new_view init_view(@view) end
cleanup()
click to toggle source
# File lib/viewer.rb, line 151 def cleanup Zashoku.client.disconnect @views.each do |m, v| Zashoku.logger.debug("sending cleanup to #{m} #{v}") v&.send(:cleanup) end @key_thread&.exit Curses.close_screen unless Zashoku::CConf[:app][:persistent_daemon] Zashoku.command_server('stop') end if Zashoku::Conf.save? Util.put_yaml(CMD_HISTORY, @cmdline.history) Util.put_yaml(SRCH_HISTORY, @searchline.history) end ensure Term.show_cursor exit! end
command(mod, meth, *args)
click to toggle source
# File lib/viewer.rb, line 180 def command(mod, meth, *args) if /^remote::.*/.match?(mod) Zashoku.command(mod: mod, meth: meth, args: args) elsif @views.key?(mod) && @views[mod].respond_to?(meth) @views[mod].send(meth, *args) elsif @views.key?(mod) raise "#{mod} has no method '#{meth}'" else raise "module '#{mod}' not loaded" end end
draw_statusline()
click to toggle source
# File lib/viewer.rb, line 273 def draw_statusline @statusline.draw end
draw_view()
click to toggle source
# File lib/viewer.rb, line 269 def draw_view @views[@view].draw end
get_user_command()
click to toggle source
# File lib/viewer.rb, line 192 def get_user_command cmd = @cmdline.read return unless cmd return builtin_command(*cmd.split) if COMMANDS.key?(cmd.split.first) raise "no such command" if cmd.split.length == 1 command(*cmd.split) unless cmd.empty? rescue StandardError => e Zashoku.logger.error("#{cmd.split} raised an error '#{e}'") Util.alert("Error: #{e}") end
handle_event(event)
click to toggle source
# File lib/viewer.rb, line 208 def handle_event(event) return @statusline.event(event) if event['statusline'] case event['event'] when 'items' command(event['sender'], :refresh) end end
init_screen()
click to toggle source
# File lib/viewer.rb, line 173 def init_screen Curses.noecho Curses.init_screen Term.hide_cursor Curses.stdscr.keypad(true) end
init_view(view)
click to toggle source
# File lib/viewer.rb, line 128 def init_view(view) @views[view].add_observer(self, :draw_view) @views[view].refresh @views[view].dirty_all_lines draw_view end
lay_traps!()
click to toggle source
# File lib/viewer.rb, line 135 def lay_traps! Signal.trap('WINCH') do Thread.new do @semaphore.synchronize do @views[@view].change_screen_size @statusline.change_screen_size end end end Signal.trap('INT') do Thread.new do @semaphore.synchronize { Util.alert(Zashoku::CConf[:app][:msg][:quit]) } end end end
map_key(key, mod, *command)
click to toggle source
# File lib/viewer.rb, line 222 def map_key(key, mod, *command) Zashoku.conf.set(['keymaps', mod, key], command.join(' ')) end
print_version()
click to toggle source
# File lib/viewer.rb, line 226 def print_version Util.alert("zashoku v#{Zashoku::Version.join('.')}") end
reconnect_client()
click to toggle source
# File lib/viewer.rb, line 107 def reconnect_client loop do @socket = connect(@host, @port, loud_fail: false) break if @socket sleep 1 end @alive = true start_threads Util.alert('regained connection!') end
scan_keyboard!()
click to toggle source
# File lib/viewer.rb, line 230 def scan_keyboard! loop do key = Curses.getch maps = Zashoku.conf.get(%w[keymaps]) cmd = if maps['global'].key?(key) maps['global'][key] elsif maps[@view]&.key?(key) maps[@view][key] else '' end if COMMANDS.key?(cmd.split.first) builtin_command(*cmd.split) next end mod, meth, *args = cmd.split mod = mod == '$current_view' ? @view : mod args.map! do |arg| if arg.chr == '$' arg = arg[1..-1] chain = arg.split('.') chain[1..-1].reduce(@views[@view].send(chain.first)) do |m, a| m.send(a) end else arg end end begin command(mod, meth, *args) rescue Exception => e Zashoku.logger.error("#{[mod, meth, args].join(', ')} raised #{e}") end end end
search(*)
click to toggle source
# File lib/viewer.rb, line 203 def search(*) srchterm = @searchline.read command(@view, :search, srchterm) end