# frozen_string_literal: true require "set" module Fusuma module Plugin module Detectors # Detect KeypressEvent from KeypressBuffer class KeypressDetector < Detector SOURCES = %w[keypress].freeze BUFFER_TYPE = "keypress" MODIFIER_KEYS = Set.new(%w[ CAPSLOCK LEFTALT LEFTCTRL LEFTMETA LEFTSHIFT RIGHTALT RIGHTCTRL RIGHTSHIFT RIGHTMETA ]) # Always watch buffers and detect them. def watch? true end # @param buffers [Array] # @return [Event] if event is detected # @return [NilClass] if event is NOT detected def detect(buffers) keypress_buffer = find_buffer(buffers) return if keypress_buffer.empty? codes = pressed_codes(keypress_buffer.events.map(&:record)) return unless codes.any? { |code| MODIFIER_KEYS.include?(code) } record = Events::Records::IndexRecord.new( index: create_index(codes: codes), position: :surfix ) create_event(record: record) end private def find_buffer(buffers) buffers.find { |b| b.type == BUFFER_TYPE } end def pressed_codes(records) codes = [] records.each do |r| if r.status == "pressed" codes << r.code else codes.delete_if { |code| code == r.code } end end codes end # @param code [String] # @return [Config::Index] def create_index(codes:) Config::Index.new( [ Config::Index::Key.new("keypress", skippable: true), Config::Index::Key.new(codes.join("+"), skippable: true) ] ) end end end end end