Skip to content

Commit

Permalink
Add delays-characters package (#152)
Browse files Browse the repository at this point in the history
* delays-characters package

An Espanso trigger that uses the Python `pynput` library to inject text, *instead* of Espanso. This enables the addition of pauses (sleep), \<Tab> etc, and other key combinations not supported by Espanso.

* Update README.md

Added pynput installation instructions.

* Update README.md

* Added testing for 'pynput'

and generating an error message to Espanso log if not present.

README.md updated to mention Python version.

* Update README.md
  • Loading branch information
smeech authored Jan 15, 2025
1 parent f170b11 commit 706ac64
Show file tree
Hide file tree
Showing 4 changed files with 131 additions and 0 deletions.
15 changes: 15 additions & 0 deletions packages/delays-characters/0.1.0/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
# Delays-characters

An Espanso trigger that uses the Python `pynput` library to inject text, *instead* of Espanso. This enables the addition of pauses (sleep), \<Tab> etc, and other key combinations not supported by Espanso. It can include use of Espanso {{variables}}.

See https://pynput.readthedocs.io/en/latest/keyboard.html#controlling-the-keyboard for details of the keywords, and https://pynput.readthedocs.io/en/latest/keyboard.html#pynput.keyboard.Key for the key names.

If necessary, use `python -m pip install pynput` to add pynput to your Python installation. Tested here with Python 3.10 but may work from Python 2.7 or earlier.

Supports keywords "type", "tap", "press", "release", and "sleep".

The package includes a sample script which demonstrates a delay and the effect of simulating pressing the \<Shift> key. For different scripts, copy, and rename, the `package.yml` file into the `espanso/match/` directory. Edit the trigger value and Input list to suit your purpose.

NB. *The variable {{Trig}} **must** match the trigger in length at least, so that `parse_pynput.py` removes the trigger text cleanly.*

A possible future enhancement could be the addition of mouse control.
7 changes: 7 additions & 0 deletions packages/delays-characters/0.1.0/_manifest.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
name: delays-characters
title: Delays and characters
description: A package to allow delays, and characters not supported by Espanso, to be injected using the Python pynput library.
homepage: https://github.com/smeech
version: 0.1.0
author: Stephen Meech
tags: [delays, characters, keyboard, control, python]
41 changes: 41 additions & 0 deletions packages/delays-characters/0.1.0/package.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,41 @@
# yaml-language-server: $schema=https://raw.githubusercontent.com/espanso/espanso/dev/schemas/match.schema.json

# Supports type, tap, press, release, and sleep.

# For new scripts this file may be copied to the espanso/match directory and edited.

matches:
- trigger: :delay # Remember to include this value in Trig, below.
replace: "{{Output}}"
vars:
- name: Trig
type: echo
params:
echo: :delay # This MUST match the trigger text.
- name: Input
type: echo
params:
echo: | # Amend the contents below to suit, adding variables etc.
type Hello, World!
tap enter
type Pausing for one second
tap enter
sleep 1
type How are you?
tap space
press shift
type I am a bot
release shift
tap enter
type The trigger was "{{Trig}}"
tap enter
tap tab
type The End.
- name: Output
type: script
params:
args:
- python
- '%CONFIG%/match/packages/delays-characters/parse_pynput.py'
- '{{Trig}}'
- '{{Input}}'
68 changes: 68 additions & 0 deletions packages/delays-characters/0.1.0/parse_pynput.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,68 @@
# Intended for use with the delays-characters package.yml file.
# Uses the Python pynput library to inject text, instead of Espanso. Enables the
# addition of pauses (sleep) and <Tab> etc. keys and can include Espanso {{variables}}
# See https://pynput.readthedocs.io/en/latest/keyboard.html#controlling-the-keyboard
# Supports type, tap, press, release, and sleep

import argparse, time
try:
from pynput.keyboard import Controller, Key
except ImportError:
import sys
print("Error: The 'pynput' library is not installed.", file=sys.stderr)
print("Install it using: pip install pynput", file=sys.stderr)
sys.exit(1) # Exit with a non-zero status code to indicate failure


# Initialize the keyboard controller
keyboard = Controller()

def parse_and_execute_commands(commands):
lines = commands.strip().splitlines()

for line in lines:
line = line.strip()
if line.startswith('type'):
text = line[len('type '):].strip()
keyboard.type(text)

elif line.startswith('tap'):
key_name = line[len('tap '):].strip().lower()
key = getattr(Key, key_name, key_name)
keyboard.tap(key)

elif line.startswith('press'):
key_name = line[len('press '):].strip().lower()
key = getattr(Key, key_name, key_name)
keyboard.press(key)

elif line.startswith('release'):
key_name = line[len('release '):].strip().lower()
key = getattr(Key, key_name, key_name)
keyboard.release(key)

elif line.startswith('sleep'):
time_to_sleep = float(line[len('sleep '):].strip())
time.sleep(time_to_sleep)

def main():
# Set up argument parsing
parser = argparse.ArgumentParser(description="Execute keyboard automation commands.")
parser.add_argument('trig', type=str, help='The trigger key to simulate.')
parser.add_argument('input', type=str, help='The input commands to execute.')
args = parser.parse_args()

# Press backspace key as many times as the length of the trigger
for _ in args.trig: keyboard.tap(Key.backspace)

# Parse and execute the input commands
if args.input:
parse_and_execute_commands(args.input)
else:
print("No input provided.")

# Replace trigger for Espanso to remove after the script
keyboard.type(args.trig)

if __name__ == "__main__":
main()

0 comments on commit 706ac64

Please sign in to comment.