Skip to content

Latest commit

 

History

History
145 lines (112 loc) · 4.67 KB

evemu.org

File metadata and controls

145 lines (112 loc) · 4.67 KB

Elvish completions for evtest and evemu

Completions for =evtest= and the =evemu= set of tools, which assist in debugging and emulating the Linux input subsystem.

Implementation

Completions for all commands

All of these commands operate on evdev nodes, contained in /dev/input/. Each represents an input device (or part of one), with a name. We can retrieve that name from sysfs and show it next to the completion.

use ./comp
use str

var -complete-dev = {
  var evdev-dir = '/dev/input/'
  ls $evdev-dir | each {|item|
    if (str:has-prefix $item 'event') {
      var path = $evdev-dir$item
      var name = (cat /sys/class/input/$item/device/name)
      edit:complex-candidate &display=$path" ("$name")" $path
    }
  }
}

Some commands take axis or key constants defined in the Kernel’s input-event-codes.h, each prefixed with a type (e.g. KEY_A, BTN_LEFT, or REL_X). We can list them with some simple matching against the header file.

var ev-code-header = /usr/include/linux/input-event-codes.h

fn -defs-with-prefix {|prefix|
  grep "#define "$prefix"_" $ev-code-header |
      eawk {|line @fields| put $fields[1] }
}

Next we’ll need a method to list all the constants corresponding to a particular event type, the name of which is prefixed by EV_. (The KEY type also includes the BTN constants.)

fn -ev-codes-for-type {|type|
  if (eq $type 'EV_KEY') {
    -defs-with-prefix 'KEY'
    -defs-with-prefix 'BTN'
  } else {
    -defs-with-prefix (str:trim-prefix $type 'EV_')
  }
}

evtest

evtest only has two options.

var -evtest-opts = [
  [&long="grab"  &desc="grab the device for exclusive access"]
  [&long="query" &desc="query a specific single-bit event code"]
]

…but --query is a little tricky, as it takes two arguments: an event type (one with binary states), and a code of that type. We have to use completer functions that look at the other arguments by index.

var -complete-evtest-type = {|@cmd|
  if (eq $cmd[1] '--query') {
    all [EV_KEY EV_SW EV_SND EV_LED]
  }
}

var -complete-evtest-code = {|@cmd|
  if (eq $cmd[1] '--query') {
    -ev-codes-for-type $cmd[3]
  }
}

set edit:completion:arg-completer[evtest] = (
    comp:sequence &opts=$-evtest-opts [$-complete-dev $-complete-evtest-type $-complete-evtest-code])

evemu-record and evemu-describe

These commands both take the same simple set of arguments.

var -autorestart-opt = [
  &long="autorestart"
  &desc="Terminate the current recording after <s> seconds of inactivity and restart a new recording"
  &arg-required=$true
]

var -record-and-describe-comp = (comp:sequence &opts=[$-autorestart-opt] [$-complete-dev $comp:files~])
set edit:completion:arg-completer[evemu-describe] = $-record-and-describe-comp
set edit:completion:arg-completer[evemu-record] = $-record-and-describe-comp

evemu-device

set edit:completion:arg-completer[evemu-device] = $edit:complete-filename~

evemu-play

This command takes either an evdev device or a recording file.

set edit:completion:arg-completer[evemu-play] = (comp:sequence [{|arg|
  $-complete-dev
  comp:files $arg
}])

evemu-event

This command, for generating single events, has an argument that could take any event code, so we put all the possible event types (as well as BTN_, an additional prefix for the EV_KEY type) into a regex with which to retrieve the constants.

var -all-ev-codes = {
  var prefix-pattern = (-defs-with-prefix 'EV' | each {|s| str:trim-prefix $s 'EV_' } | str:join '\|')
  -defs-with-prefix '\('$prefix-pattern'\|BTN\)'
}

var -event-opts = [
  [&long="sync" &desc="generate an EV_SYN event after the event"]
  [&long="type"
   &desc="the type of event to generate"
   &arg-required=$true
   &arg-completer={ -defs-with-prefix 'EV' }]
  [&long="code"
   &desc="the event code"
   &arg-required=$true
   &arg-completer=$-all-ev-codes]
  [&long="value"
   &desc="the event value"
   &arg-required=$true]
]

set edit:completion:arg-completer[evemu-event] = (comp:sequence &opts=$-event-opts [$-complete-dev])