Compare commits
35 Commits
b9abf02b12
...
testing
Author | SHA1 | Date | |
---|---|---|---|
|
96cdda99c4 | ||
|
0658d37ae8 | ||
|
a6bb3e1301 | ||
|
5ff653bd00 | ||
|
356f4b01c1 | ||
|
c7ad4d9200 | ||
|
d274fe78f3 | ||
|
f5344a7227 | ||
|
90ffc2fc08 | ||
|
b635f7538b | ||
|
7f473b72a7 | ||
|
e255651c28 | ||
|
b3d73102fc | ||
|
78c1cbbb6b | ||
|
8c26d93001 | ||
|
98b9c56af7 | ||
|
8bada48a09 | ||
|
0a2c8472c0 | ||
|
e9a0101fe7 | ||
|
69eade3327 | ||
|
73f67c2a04 | ||
|
9ef9d762f4 | ||
|
84293db6dc | ||
|
914535d12b | ||
|
94a1acbaca | ||
|
8c233e0385 | ||
|
b6a9e1a692 | ||
|
d41ea8388f | ||
|
2dd732dc9d | ||
|
b68a28e857 | ||
|
8c668cc0cc | ||
|
579bf0f0f0 | ||
|
d1bad818cd | ||
|
e177c7f486 | ||
|
ae4c418323 |
77
README.md
77
README.md
@@ -134,6 +134,58 @@ By default Fenrir uses:
|
||||
- **Input driver**: evdevDriver (Linux) or ptyDriver (other platforms)
|
||||
- **Screen driver**: vcsaDriver (Linux TTY) or ptyDriver (terminal emulation)
|
||||
|
||||
## Audio Configuration
|
||||
|
||||
Both PulseAudio and PipeWire require special configuration to allow console applications running as root (like Fenrir) to route audio to your regular user session. This is normal audio system behavior, not a Fenrir issue.
|
||||
|
||||
### Quick Setup - Direct Script Download
|
||||
|
||||
For non-Fenrir users or quick setup, download and run these scripts directly:
|
||||
|
||||
#### PulseAudio Configuration
|
||||
```bash
|
||||
# Download the script
|
||||
wget https://git.stormux.org/storm/fenrir/raw/branch/master/tools/configure_pulse.sh
|
||||
chmod +x configure_pulse.sh
|
||||
|
||||
# Run twice: once as user, once as root
|
||||
./configure_pulse.sh
|
||||
sudo ./configure_pulse.sh
|
||||
```
|
||||
|
||||
#### PipeWire Configuration
|
||||
```bash
|
||||
# Download the script
|
||||
wget https://git.stormux.org/storm/fenrir/raw/branch/master/tools/configure_pipewire.sh
|
||||
chmod +x configure_pipewire.sh
|
||||
|
||||
# Run twice: once as user, once as root
|
||||
./configure_pipewire.sh
|
||||
sudo ./configure_pipewire.sh
|
||||
```
|
||||
|
||||
**Direct links:**
|
||||
- [configure_pulse.sh](https://git.stormux.org/storm/fenrir/raw/branch/master/tools/configure_pulse.sh)
|
||||
- [configure_pipewire.sh](https://git.stormux.org/storm/fenrir/raw/branch/master/tools/configure_pipewire.sh)
|
||||
|
||||
### Using Installed Scripts
|
||||
|
||||
If you have Fenrir installed, the scripts are available at:
|
||||
|
||||
**PulseAudio:**
|
||||
```bash
|
||||
/usr/share/fenrirscreenreader/tools/configure_pulse.sh
|
||||
sudo /usr/share/fenrirscreenreader/tools/configure_pulse.sh
|
||||
```
|
||||
|
||||
**PipeWire:**
|
||||
```bash
|
||||
/usr/share/fenrirscreenreader/tools/configure_pipewire.sh
|
||||
sudo /usr/share/fenrirscreenreader/tools/configure_pipewire.sh
|
||||
```
|
||||
|
||||
**Note:** These scripts work for any console application that needs root audio access, not just Fenrir.
|
||||
|
||||
## Getting Started
|
||||
|
||||
### Basic Usage
|
||||
@@ -640,31 +692,6 @@ send_fenrir_command("setting set speech#rate=0.9")
|
||||
- Check Fenrir debug logs: `/var/log/fenrir.log`
|
||||
- Test with simple command: `echo "command interrupt" | socat - UNIX-CLIENT:/tmp/fenrirscreenreader-deamon.sock`
|
||||
|
||||
## Configure pulseaudio
|
||||
|
||||
Pulseaudio by default only plays sound for the user its currently running for. As fenrir is running as root, your local user does not hear the sound and speech produced by fenrir.
|
||||
for this fenrir provides a script to configure pulseaudio to stream the sound played as root to your local user. This is not a issue of fenrir but this is how pulseaudio works.
|
||||
|
||||
just run the configuration script twice (once as user, once as root):
|
||||
|
||||
/usr/share/fenrirscreenreader/tools/configure_pulse.sh
|
||||
sudo /usr/share/fenrirscreenreader/tools/configure_pulse.sh
|
||||
|
||||
The script is also located in the tools directory in git
|
||||
|
||||
|
||||
## Configure pipewire
|
||||
|
||||
Pipewire by default only plays sound for the user its currently running for. As fenrir is running as root, your local user does not hear the sound and speech produced by fenrir.
|
||||
for this fenrir provides a script to configure pipewire to stream the sound played as root to your local user. This is not a issue of fenrir but this is how pipewire works.
|
||||
|
||||
just run the configuration script twice (once as user, once as root):
|
||||
|
||||
/usr/share/fenrirscreenreader/tools/configure_pipewire.sh
|
||||
sudo /usr/share/fenrirscreenreader/tools/configure_pipewire.sh
|
||||
|
||||
The script is also located in the tools directory in git
|
||||
|
||||
## Command Line Options
|
||||
|
||||
Fenrir supports several command-line options for different use cases:
|
||||
|
192
RELEASE_CHECKLIST.md
Normal file
192
RELEASE_CHECKLIST.md
Normal file
@@ -0,0 +1,192 @@
|
||||
# Fenrir Release Validation Checklist
|
||||
|
||||
This checklist ensures thorough validation before releasing Fenrir packages.
|
||||
|
||||
## 🔧 Setup Tools (One-time setup)
|
||||
|
||||
### Install Pre-commit Hook
|
||||
```bash
|
||||
# Safely install composite hook (preserves existing version management)
|
||||
./tools/install_validation_hook.sh
|
||||
|
||||
# Test the hook
|
||||
./.git/hooks/pre-commit
|
||||
```
|
||||
|
||||
### Validation Scripts
|
||||
- `tools/validate_syntax.py` - Python syntax validation
|
||||
- `tools/validate_pep8.py` - PEP8 compliance checking with safe auto-fix
|
||||
- `tools/validate_release.py` - Comprehensive release validation
|
||||
- `tools/cleanup_cache.py` - Remove Python cache files and directories
|
||||
- `tools/pre-commit-hook` - Git pre-commit validation
|
||||
|
||||
## 📋 Pre-Release Checklist
|
||||
|
||||
### 1. Code Quality Validation ✅
|
||||
```bash
|
||||
# Comprehensive release validation (includes syntax, imports, structure)
|
||||
python3 tools/validate_release.py
|
||||
|
||||
# If issues found, try auto-fix
|
||||
python3 tools/validate_release.py --fix
|
||||
|
||||
# Quick validation (skips slow dependency checks)
|
||||
python3 tools/validate_release.py --quick
|
||||
```
|
||||
|
||||
**Expected Result**: All tests pass, no syntax errors
|
||||
|
||||
### 2. Dependency Validation ✅
|
||||
```bash
|
||||
# Validate all dependencies are available
|
||||
python3 check-dependencies.py
|
||||
```
|
||||
|
||||
**Expected Result**: All required dependencies reported as available
|
||||
|
||||
### 3. Core Functionality Test ✅
|
||||
```bash
|
||||
# Test core imports (safe to run without sudo)
|
||||
cd src
|
||||
python3 -c "
|
||||
import fenrirscreenreader.core.fenrirManager
|
||||
import fenrirscreenreader.core.commandManager
|
||||
import fenrirscreenreader.core.eventManager
|
||||
print('Core imports successful')
|
||||
"
|
||||
cd ..
|
||||
```
|
||||
|
||||
**Expected Result**: No import errors
|
||||
|
||||
### 4. Installation Script Validation ✅
|
||||
```bash
|
||||
# Validate setup.py syntax
|
||||
python3 -m py_compile setup.py
|
||||
|
||||
# Check setup.py can be parsed
|
||||
python3 setup.py --help-commands >/dev/null
|
||||
```
|
||||
|
||||
**Expected Result**: No syntax errors, setup.py functional
|
||||
|
||||
### 5. Configuration Validation ✅
|
||||
```bash
|
||||
# Verify config files exist and are parseable
|
||||
ls -la config/settings/settings.conf
|
||||
ls -la config/keyboard/desktop.conf
|
||||
ls -la config/punctuation/default.conf
|
||||
```
|
||||
|
||||
**Expected Result**: All core config files present
|
||||
|
||||
### 6. Manual Testing (User/Package Maintainer) ⚠️
|
||||
|
||||
**Important**: These require user interaction as they need sudo access or specific hardware.
|
||||
|
||||
```bash
|
||||
# Test basic functionality (ask user to run)
|
||||
sudo ./src/fenrir --help
|
||||
|
||||
# Test in emulation mode (safer for desktop environments)
|
||||
sudo ./src/fenrir -e --version
|
||||
|
||||
# Quick functionality test (3-5 seconds)
|
||||
sudo timeout 5 ./src/fenrir -e -f || echo "Timeout reached (expected)"
|
||||
```
|
||||
|
||||
**Expected Result**: No immediate crashes, basic help/version output works
|
||||
|
||||
### 7. Package-Specific Validation ✅
|
||||
```bash
|
||||
# Test the same compilation process used by package managers
|
||||
python3 -m compileall src/fenrirscreenreader/ -q
|
||||
|
||||
# Verify no __pycache__ permission issues
|
||||
find src/ -name "*.pyc" -delete
|
||||
find src/ -name "__pycache__" -delete
|
||||
```
|
||||
|
||||
**Expected Result**: Clean compilation, no permission errors
|
||||
|
||||
## 🚨 Known Issue Categories
|
||||
|
||||
### Critical Issues (Block Release)
|
||||
- **Python syntax errors** (SyntaxError, unterminated strings)
|
||||
- **Missing core dependencies** (dbus-python, evdev, etc.)
|
||||
- **Import failures in core modules** (fenrirManager, commandManager)
|
||||
- **Missing critical config files** (settings.conf, desktop.conf)
|
||||
|
||||
### Warning Issues (Address if Possible)
|
||||
- **PEP8 violations** (cosmetic, don't block release)
|
||||
- **Missing optional dependencies** (for specific features)
|
||||
- **Command structure issues** (missing methods in command files)
|
||||
- **Very long lines** (>120 characters)
|
||||
|
||||
## 🔍 Root Cause Analysis
|
||||
|
||||
### Why These Errors Weren't Caught Previously
|
||||
|
||||
1. **No automated syntax validation** - The codebase relied on manual testing
|
||||
2. **No pre-commit hooks** - Syntax errors could be committed
|
||||
3. **No CI/CD pipeline** - Package compilation happens only during release
|
||||
4. **Manual PEP8 cleanup** - F-string refactoring introduced syntax errors during batch cleanup
|
||||
|
||||
## 📖 Usage Instructions
|
||||
|
||||
### For Developers
|
||||
```bash
|
||||
# Before committing changes
|
||||
git add .
|
||||
git commit # Pre-commit hook will run automatically
|
||||
|
||||
# Before creating tags/releases
|
||||
python3 tools/validate_release.py
|
||||
```
|
||||
|
||||
### For Package Maintainers
|
||||
```bash
|
||||
# Before packaging
|
||||
python3 tools/validate_release.py
|
||||
|
||||
# If validation fails
|
||||
python3 tools/validate_release.py --fix
|
||||
|
||||
# Quick check (if dependencies are known good)
|
||||
python3 tools/validate_release.py --quick
|
||||
```
|
||||
|
||||
### For Release Managers
|
||||
```bash
|
||||
# Complete validation before tagging
|
||||
python3 tools/validate_release.py
|
||||
|
||||
# Manual verification (requires sudo)
|
||||
sudo ./src/fenrir --version
|
||||
|
||||
# Tag release only after all validations pass
|
||||
git tag -a v2.x.x -m "Release v2.x.x"
|
||||
```
|
||||
|
||||
## 🎯 Future Improvements
|
||||
|
||||
### Recommended Additions
|
||||
1. **GitHub Actions CI/CD** - Automated validation on every push
|
||||
2. **Automated testing** - Unit tests for core functionality
|
||||
3. **Integration testing** - Test driver interactions
|
||||
4. **Package testing** - Validate actual package installation
|
||||
|
||||
### Modern Python Packaging
|
||||
- Consider migrating to `pyproject.toml` (PEP 621)
|
||||
- Use `build` instead of `setup.py` directly
|
||||
- Add `tox.ini` for multi-environment testing
|
||||
|
||||
## 📞 Support
|
||||
|
||||
If validation fails and auto-fix doesn't resolve issues:
|
||||
|
||||
1. **Check the specific error messages** in validation output
|
||||
2. **Review recent commits** that might have introduced issues
|
||||
3. **Run individual validation steps** to isolate problems
|
||||
|
||||
Remember: **Working code is better than perfect code** - especially for accessibility software where reliability is critical.
|
@@ -126,7 +126,8 @@ KEY_FENRIR,KEY_CTRL,KEY_S=save_settings
|
||||
# linux specific
|
||||
KEY_FENRIR,KEY_F7=import_clipboard_from_x
|
||||
KEY_FENRIR,KEY_F8=export_clipboard_to_x
|
||||
KEY_FENRIR,KEY_CTRL,KEY_UP=inc_alsa_volume
|
||||
KEY_FENRIR,KEY_CTRL,KEY_DOWN=dec_alsa_volume
|
||||
# Read-all functionality
|
||||
KEY_FENRIR,KEY_CTRL,KEY_DOWN=read_all_by_line
|
||||
KEY_FENRIR,KEY_CTRL,KEY_PAGEDOWN=read_all_by_page
|
||||
KEY_FENRIR,KEY_SHIFT,KEY_V=announce_fenrir_version
|
||||
KEY_F4=cycle_keyboard_layout
|
||||
KEY_FENRIR,KEY_LEFTCTRL,KEY_F4=cycle_keyboard_layout
|
||||
|
@@ -126,7 +126,8 @@ KEY_FENRIR,KEY_CTRL,KEY_S=save_settings
|
||||
# linux specific
|
||||
KEY_FENRIR,KEY_F7=import_clipboard_from_x
|
||||
KEY_FENRIR,KEY_F8=export_clipboard_to_x
|
||||
KEY_FENRIR,KEY_CTRL,KEY_UP=inc_alsa_volume
|
||||
KEY_FENRIR,KEY_CTRL,KEY_DOWN=dec_alsa_volume
|
||||
# Read-all functionality
|
||||
KEY_FENRIR,KEY_CTRL,KEY_DOWN=read_all_by_line
|
||||
KEY_FENRIR,KEY_CTRL,KEY_PAGEDOWN=read_all_by_page
|
||||
KEY_FENRIR,KEY_SHIFT,KEY_V=announce_fenrir_version
|
||||
KEY_F4=cycle_keyboard_layout
|
||||
KEY_FENRIR,KEY_LEFTCTRL,KEY_F4=cycle_keyboard_layout
|
||||
|
@@ -1,130 +0,0 @@
|
||||
KEY_FENRIR,KEY_F1=toggle_tutorial_mode
|
||||
KEY_FENRIR,KEY_H=toggle_tutorial_mode
|
||||
KEY_CTRL=shut_up
|
||||
KEY_SHIFT,KEY_KP9=review_bottom
|
||||
KEY_SHIFT,KEY_KP7=review_top
|
||||
KEY_KP8=review_curr_line
|
||||
KEY_KP7=review_prev_line
|
||||
KEY_KP9=review_next_line
|
||||
KEY_SHIFT,KEY_KP1=review_line_begin
|
||||
KEY_SHIFT,KEY_KP3=review_line_end
|
||||
KEY_FENRIR,KEY_KP1=review_line_first_char
|
||||
KEY_FENRIR,KEY_KP3=review_line_last_char
|
||||
KEY_FENRIR,KEY_ALT,KEY_1=present_first_line
|
||||
KEY_FENRIR,KEY_ALT,KEY_2=present_last_line
|
||||
KEY_KP5=review_curr_word
|
||||
KEY_KP4=review_prev_word
|
||||
KEY_KP6=review_next_word
|
||||
2,KEY_KP5=review_curr_word_phonetic
|
||||
2,KEY_KP4=review_prev_word_phonetic
|
||||
2,KEY_KP6=review_next_word_phonetic
|
||||
KEY_KP2=review_curr_char
|
||||
KEY_KP1=review_prev_char
|
||||
KEY_KP3=review_next_char
|
||||
2,KEY_KP2=review_curr_char_phonetic
|
||||
2,KEY_KP1=review_prev_char_phonetic
|
||||
2,KEY_KP3=review_next_char_phonetic
|
||||
KEY_FENRIR,KEY_CTRL,KEY_KP8=review_up
|
||||
KEY_FENRIR,KEY_CTRL,KEY_KP2=review_down
|
||||
KEY_FENRIR,KEY_KPDOT=exit_review
|
||||
KEY_KPDOT=cursor_position
|
||||
KEY_FENRIR,KEY_I=indent_curr_line
|
||||
KEY_FENRIR,KEY_B=curr_screen
|
||||
KEY_FENRIR,KEY_KP8=curr_screen_before_cursor
|
||||
KEY_FENRIR,KEY_KP2=curr_screen_after_cursor
|
||||
KEY_FENRIR,KEY_SHIFT,KEY_PAGEDOWN=cursor_read_to_end_of_line
|
||||
#=cursor_column
|
||||
#=cursor_lineno
|
||||
#=braille_flush
|
||||
KEY_FENRIR,KEY_CTRL,KEY_T=braille_return_to_cursor
|
||||
#=braille_pan_left
|
||||
#=braille_pan_right
|
||||
KEY_FENRIR,KEY_CTRL,KEY_1=clear_bookmark_1
|
||||
KEY_FENRIR,KEY_SHIFT,KEY_1=set_bookmark_1
|
||||
KEY_FENRIR,KEY_1=bookmark_1
|
||||
KEY_FENRIR,KEY_K=bookmark_1
|
||||
KEY_FENRIR,KEY_CTRL,KEY_2=clear_bookmark_2
|
||||
KEY_FENRIR,KEY_SHIFT,KEY_2=set_bookmark_2
|
||||
KEY_FENRIR,KEY_2=bookmark_2
|
||||
KEY_FENRIR,KEY_CTRL,KEY_3=clear_bookmark_3
|
||||
KEY_FENRIR,KEY_SHIFT,KEY_3=set_bookmark_3
|
||||
KEY_FENRIR,KEY_3=bookmark_3
|
||||
KEY_FENRIR,KEY_CTRL,KEY_4=clear_bookmark_4
|
||||
KEY_FENRIR,KEY_SHIFT,KEY_4=set_bookmark_4
|
||||
KEY_FENRIR,KEY_4=bookmark_4
|
||||
KEY_FENRIR,KEY_CTRL,KEY_5=clear_bookmark_5
|
||||
KEY_FENRIR,KEY_SHIFT,KEY_5=set_bookmark_5
|
||||
KEY_FENRIR,KEY_5=bookmark_5
|
||||
KEY_FENRIR,KEY_CTRL,KEY_6=clear_bookmark_6
|
||||
KEY_FENRIR,KEY_SHIFT,KEY_6=set_bookmark_6
|
||||
KEY_FENRIR,KEY_6=bookmark_6
|
||||
KEY_FENRIR,KEY_CTRL,KEY_7=clear_bookmark_7
|
||||
KEY_FENRIR,KEY_SHIFT,KEY_7=set_bookmark_7
|
||||
KEY_FENRIR,KEY_7=bookmark_7
|
||||
KEY_FENRIR,KEY_CTRL,KEY_8=clear_bookmark_8
|
||||
KEY_FENRIR,KEY_SHIFT,KEY_8=set_bookmark_8
|
||||
KEY_FENRIR,KEY_8=bookmark_8
|
||||
KEY_FENRIR,KEY_CTRL,KEY_9=clear_bookmark_9
|
||||
KEY_FENRIR,KEY_SHIFT,KEY_9=set_bookmark_9
|
||||
KEY_FENRIR,KEY_9=bookmark_9
|
||||
KEY_FENRIR,KEY_CTRL,KEY_0=clear_bookmark_10
|
||||
KEY_FENRIR,KEY_SHIFT,KEY_0=set_bookmark_10
|
||||
KEY_FENRIR,KEY_0=bookmark_10
|
||||
KEY_FENRIR,KEY_KPSLASH=set_window_application
|
||||
2,KEY_FENRIR,KEY_KPSLASH=clear_window_application
|
||||
KEY_KPPLUS=progress_bar_monitor
|
||||
KEY_FENRIR,KEY_KPPLUS=silence_until_prompt
|
||||
#=toggle_braille
|
||||
KEY_FENRIR,KEY_F3=toggle_sound
|
||||
KEY_FENRIR,KEY_F4=toggle_speech
|
||||
KEY_KPENTER=temp_disable_speech
|
||||
KEY_FENRIR,KEY_P=toggle_punctuation_level
|
||||
KEY_FENRIR,KEY_RIGHTBRACE=toggle_auto_spell_check
|
||||
KEY_FENRIR,KEY_S=toggle_output
|
||||
KEY_FENRIR,KEY_CTRL,KEY_E=toggle_emoticons
|
||||
key_FENRIR,KEY_5=toggle_auto_read
|
||||
KEY_FENRIR,KEY_CTRL,KEY_T=toggle_auto_time
|
||||
KEY_FENRIR,KEY_KPASTERISK=toggle_highlight_tracking
|
||||
KEY_FENRIR,KEY_KPMINUS=toggle_barrier
|
||||
KEY_FENRIR,KEY_Q=quit_fenrir
|
||||
KEY_FENRIR,KEY_T=time
|
||||
KEY_FENRIR,KEY_F12=time
|
||||
2,KEY_FENRIR,KEY_T=date
|
||||
2,KEY_FENRIR,KEY_F12=date
|
||||
KEY_KPSLASH=toggle_auto_indent
|
||||
KEY_FENRIR,KEY_F=attribute_cursor
|
||||
#=toggle_has_attribute
|
||||
KEY_FENRIR,KEY_F7=spell_check
|
||||
2,KEY_FENRIR,KEY_S=add_word_to_spell_check
|
||||
KEY_FENRIR,KEY_SHIFT,KEY_S=remove_word_from_spell_check
|
||||
KEY_FENRIR,KEY_F2=forward_keypress
|
||||
KEY_FENRIR,KEY_ALT,KEY_UP=inc_sound_volume
|
||||
KEY_FENRIR,KEY_ALT,KEY_DOWN=dec_sound_volume
|
||||
#=clear_clipboard
|
||||
KEY_FENRIR,KEY_HOME=first_clipboard
|
||||
KEY_FENRIR,KEY_END=last_clipboard
|
||||
KEY_FENRIR,KEY_PAGEUP=prev_clipboard
|
||||
KEY_FENRIR,KEY_PAGEDOWN=next_clipboard
|
||||
KEY_FENRIR,KEY_SHIFT,KEY_C=curr_clipboard
|
||||
KEY_FENRIR,KEY_C=copy_marked_to_clipboard
|
||||
KEY_FENRIR,KEY_CTRL,KEY_SHIFT,KEY_C=copy_last_echo_to_clipboard
|
||||
KEY_FENRIR,KEY_V=paste_clipboard
|
||||
KEY_FENRIR,KEY_F5=import_clipboard_from_file
|
||||
KEY_FENRIR,KEY_F6=export_clipboard_to_file
|
||||
KEY_FENRIR,KEY_CTRL,KEY_SHIFT,KEY_X=remove_marks
|
||||
KEY_FENRIR,KEY_F9=set_mark
|
||||
KEY_FENRIR,KEY_F10=marked_text
|
||||
KEY_FENRIR,KEY_F10=toggle_vmenu_mode
|
||||
KEY_FENRIR,KEY_SPACE=current_quick_menu_entry
|
||||
KEY_FENRIR,KEY_CTRL,KEY_SPACE=current_quick_menu_value
|
||||
KEY_FENRIR,KEY_CTRL,KEY_RIGHT=next_quick_menu_entry
|
||||
KEY_FENRIR,KEY_CTRL,KEY_UP=next_quick_menu_value
|
||||
KEY_FENRIR,KEY_CTRL,KEY_LEFT=prev_quick_menu_entry
|
||||
KEY_FENRIR,KEY_CTRL,KEY_DOWN=prev_quick_menu_value
|
||||
KEY_FENRIR,KEY_CTRL,KEY_C=save_settings
|
||||
# linux specific
|
||||
#=import_clipboard_from_x
|
||||
KEY_FENRIR,KEY_F8=export_clipboard_to_x
|
||||
KEY_FENRIR,KEY_ALT,KEY_UP=inc_alsa_volume
|
||||
KEY_FENRIR,KEY_ALT,KEY_DOWN=dec_alsa_volume
|
||||
KEY_F4=cycle_keyboard_layout
|
@@ -1,129 +0,0 @@
|
||||
KEY_FENRIR,KEY_F1=toggle_tutorial_mode
|
||||
KEY_FENRIR,KEY_H=toggle_tutorial_mode
|
||||
KEY_CTRL=shut_up
|
||||
KEY_FENRIR,KEY_CTRL,KEY_END=review_bottom
|
||||
KEY_FENRIR,KEY_CTRL,KEY_HOME=review_top
|
||||
KEY_FENRIR,KEY_SHIFT,KEY_DOT=review_curr_line
|
||||
KEY_FENRIR,KEY_U=review_prev_line
|
||||
KEY_FENRIR,KEY_O=review_next_line
|
||||
KEY_FENRIR,KEY_HOME=review_line_begin
|
||||
KEY_FENRIR,KEY_END=review_line_end
|
||||
KEY_FENRIR,KEY_CTRL,KEY_J=review_line_first_char
|
||||
KEY_FENRIR,KEY_CTRL,KEY_L=review_line_last_char
|
||||
KEY_FENRIR,KEY_ALT,KEY_1=present_first_line
|
||||
KEY_FENRIR,KEY_ALT,KEY_2=present_last_line
|
||||
KEY_FENRIR,KEY_CTRL,KEY_DOT=review_curr_word
|
||||
KEY_FENRIR,KEY_J=review_prev_word
|
||||
KEY_FENRIR,KEY_L=review_next_word
|
||||
2,KEY_FENRIR,KEY_CTRL,KEY_DOT=review_curr_word_phonetic
|
||||
2,KEY_FENRIR,KEY_J=review_prev_word_phonetic
|
||||
2,KEY_FENRIR,KEY_L=review_next_word_phonetic
|
||||
KEY_FENRIR,KEY_COMMA=review_curr_char
|
||||
KEY_FENRIR,KEY_M=review_prev_char
|
||||
KEY_FENRIR,KEY_DOT=review_next_char
|
||||
2,KEY_FENRIR,KEY_COMMA=curr_char_phonetic
|
||||
2,KEY_FENRIR,KEY_M=prev_char_phonetic
|
||||
2,KEY_FENRIR,KEY_DOT=next_char_phonetic
|
||||
KEY_FENRIR,KEY_CTRL,KEY_I=review_up
|
||||
KEY_FENRIR,KEY_CTRL,KEY_COMMA=review_down
|
||||
KEY_FENRIR,KEY_SLASH=exit_review
|
||||
KEY_FENRIR,KEY_SHIFT,KEY_DOT=cursor_position
|
||||
2,KEY_FENRIR,KEY_I=indent_curr_line
|
||||
KEY_FENRIR,KEY_B=curr_screen
|
||||
KEY_FENRIR,KEY_SHIFT,KEY_I=curr_screen_before_cursor
|
||||
KEY_FENRIR,KEY_SHIFT,KEY_COMMA=curr_screen_after_cursor
|
||||
KEY_FENRIR,KEY_SHIFT,KEY_PAGEDOWN=cursor_read_to_end_of_line
|
||||
#=cursor_column
|
||||
#=cursor_lineno
|
||||
#=braille_flush
|
||||
KEY_FENRIR,KEY_CTRL,KEY_T=braille_return_to_cursor
|
||||
#=braille_pan_left
|
||||
#=braille_pan_right
|
||||
KEY_FENRIR,KEY_CTRL,KEY_1=clear_bookmark_1
|
||||
KEY_FENRIR,KEY_SHIFT,KEY_1=set_bookmark_1
|
||||
KEY_FENRIR,KEY_1=bookmark_1
|
||||
KEY_FENRIR,KEY_K=bookmark_1
|
||||
KEY_FENRIR,KEY_CTRL,KEY_2=clear_bookmark_2
|
||||
KEY_FENRIR,KEY_SHIFT,KEY_2=set_bookmark_2
|
||||
KEY_FENRIR,KEY_2=bookmark_2
|
||||
KEY_FENRIR,KEY_CTRL,KEY_3=clear_bookmark_3
|
||||
KEY_FENRIR,KEY_SHIFT,KEY_3=set_bookmark_3
|
||||
KEY_FENRIR,KEY_3=bookmark_3
|
||||
KEY_FENRIR,KEY_CTRL,KEY_4=clear_bookmark_4
|
||||
KEY_FENRIR,KEY_SHIFT,KEY_4=set_bookmark_4
|
||||
KEY_FENRIR,KEY_4=bookmark_4
|
||||
KEY_FENRIR,KEY_CTRL,KEY_5=clear_bookmark_5
|
||||
KEY_FENRIR,KEY_SHIFT,KEY_5=set_bookmark_5
|
||||
KEY_FENRIR,KEY_5=bookmark_5
|
||||
KEY_FENRIR,KEY_CTRL,KEY_6=clear_bookmark_6
|
||||
KEY_FENRIR,KEY_SHIFT,KEY_6=set_bookmark_6
|
||||
KEY_FENRIR,KEY_6=bookmark_6
|
||||
KEY_FENRIR,KEY_CTRL,KEY_7=clear_bookmark_7
|
||||
KEY_FENRIR,KEY_SHIFT,KEY_7=set_bookmark_7
|
||||
KEY_FENRIR,KEY_7=bookmark_7
|
||||
KEY_FENRIR,KEY_CTRL,KEY_8=clear_bookmark_8
|
||||
KEY_FENRIR,KEY_SHIFT,KEY_8=set_bookmark_8
|
||||
KEY_FENRIR,KEY_8=bookmark_8
|
||||
KEY_FENRIR,KEY_CTRL,KEY_9=clear_bookmark_9
|
||||
KEY_FENRIR,KEY_SHIFT,KEY_9=set_bookmark_9
|
||||
KEY_FENRIR,KEY_9=bookmark_9
|
||||
KEY_FENRIR,KEY_CTRL,KEY_0=clear_bookmark_10
|
||||
KEY_FENRIR,KEY_SHIFT,KEY_0=set_bookmark_10
|
||||
KEY_FENRIR,KEY_0=bookmark_10
|
||||
KEY_FENRIR,KEY_CTRL,KEY_8=set_window_application
|
||||
2,KEY_FENRIR,KEY_CTRL,KEY_8=clear_window_application
|
||||
KEY_FENRIR,KEY_SEMICOLON=last_incoming
|
||||
#=toggle_braille
|
||||
KEY_FENRIR,KEY_F3=toggle_sound
|
||||
KEY_FENRIR,KEY_F4=toggle_speech
|
||||
KEY_FENRIR,KEY_ENTER=temp_disable_speech
|
||||
KEY_FENRIR,KEY_P=toggle_punctuation_level
|
||||
KEY_FENRIR,KEY_RIGHTBRACE=toggle_auto_spell_check
|
||||
KEY_FENRIR,KEY_S=toggle_output
|
||||
KEY_FENRIR,KEY_SHIFT,KEY_E=toggle_emoticons
|
||||
KEY_FENRIR,KEY_5=toggle_auto_read
|
||||
KEY_FENRIR,KEY_CTRL,KEY_T=toggle_auto_time
|
||||
KEY_FENRIR,KEY_Y=toggle_highlight_tracking
|
||||
#=toggle_barrier
|
||||
KEY_FENRIR,KEY_Q=quit_fenrir
|
||||
KEY_FENRIR,KEY_T=time
|
||||
KEY_FENRIR,KEY_F12=time
|
||||
2,KEY_FENRIR,KEY_T=date
|
||||
2,KEY_FENRIR,KEY_F12=date
|
||||
KEY_FENRIR,KEY_BACKSLASH=toggle_auto_indent
|
||||
KEY_FENRIR,KEY_F=attribute_cursor
|
||||
#=toggle_has_attribute
|
||||
KEY_FENRIR,KEY_F7=spell_check
|
||||
2,KEY_FENRIR,KEY_S=add_word_to_spell_check
|
||||
KEY_FENRIR,KEY_SHIFT,KEY_S=remove_word_from_spell_check
|
||||
KEY_FENRIR,KEY_F2=forward_keypress
|
||||
KEY_FENRIR,KEY_ALT,KEY_UP=inc_sound_volume
|
||||
KEY_FENRIR,KEY_ALT,KEY_DOWN=dec_sound_volume
|
||||
#=clear_clipboard
|
||||
#=first_clipboard
|
||||
#=last_clipboard
|
||||
KEY_FENRIR,KEY_PAGEUP=prev_clipboard
|
||||
KEY_FENRIR,KEY_PAGEDOWN=next_clipboard
|
||||
KEY_FENRIR,KEY_SHIFT,KEY_C=curr_clipboard
|
||||
KEY_FENRIR,KEY_C=copy_marked_to_clipboard
|
||||
KEY_FENRIR,KEY_CTRL,KEY_SHIFT,KEY_C=copy_last_echo_to_clipboard
|
||||
KEY_FENRIR,KEY_V=paste_clipboard
|
||||
KEY_FENRIR,KEY_F5=import_clipboard_from_file
|
||||
KEY_FENRIR,KEY_F6=export_clipboard_to_file
|
||||
KEY_FENRIR,KEY_CTRL,KEY_SHIFT,KEY_X=remove_marks
|
||||
KEY_FENRIR,KEY_F9=set_mark
|
||||
KEY_FENRIR,KEY_F10=marked_text
|
||||
KEY_FENRIR,KEY_SHIFT,KEY_F10=toggle_vmenu_mode
|
||||
KEY_FENRIR,KEY_SPACE=current_quick_menu_entry
|
||||
KEY_FENRIR,KEY_CTRL,KEY_SPACE=current_quick_menu_value
|
||||
KEY_FENRIR,KEY_CTRL,KEY_RIGHT=next_quick_menu_entry
|
||||
KEY_FENRIR,KEY_CTRL,KEY_UP=next_quick_menu_value
|
||||
KEY_FENRIR,KEY_CTRL,KEY_LEFT=prev_quick_menu_entry
|
||||
KEY_FENRIR,KEY_CTRL,KEY_DOWN=prev_quick_menu_value
|
||||
KEY_FENRIR,KEY_CTRL,KEY_C=save_settings
|
||||
# linux specific
|
||||
#=import_clipboard_from_x
|
||||
KEY_FENRIR,KEY_F8=export_clipboard_to_x
|
||||
KEY_FENRIR,KEY_ALT,KEY_UP=inc_alsa_volume
|
||||
KEY_FENRIR,KEY_ALT,KEY_DOWN=dec_alsa_volume
|
||||
KEY_F4=cycle_keyboard_layout
|
@@ -24,9 +24,8 @@ class command:
|
||||
def run(self):
|
||||
try:
|
||||
self.env["runtime"]["OutputManager"].present_text(
|
||||
f"Fenrir screen reader version {
|
||||
fenrirVersion.version}-{
|
||||
fenrirVersion.code_name}",
|
||||
f"Fenrir screen reader version "
|
||||
f"{fenrirVersion.version}-{fenrirVersion.code_name}",
|
||||
interrupt=True,
|
||||
)
|
||||
except Exception as e:
|
||||
|
@@ -1,21 +0,0 @@
|
||||
#!/usr/bin/env python3
|
||||
# -*- coding: utf-8 -*-
|
||||
|
||||
# Fenrir TTY screen reader
|
||||
# By Chrys, Storm Dragon, and contributors.
|
||||
|
||||
import importlib.util
|
||||
import os
|
||||
|
||||
from fenrirscreenreader.core.i18n import _
|
||||
|
||||
_base_path = os.path.join(os.path.dirname(__file__), "adjustment_base.py")
|
||||
_spec = importlib.util.spec_from_file_location("adjustment_base", _base_path)
|
||||
_module = importlib.util.module_from_spec(_spec)
|
||||
_spec.loader.exec_module(_module)
|
||||
adjustment_command = _module.adjustment_command
|
||||
|
||||
|
||||
class command(adjustment_command):
|
||||
def __init__(self):
|
||||
super().__init__("alsa", "volume", "dec")
|
@@ -1,21 +0,0 @@
|
||||
#!/usr/bin/env python3
|
||||
# -*- coding: utf-8 -*-
|
||||
|
||||
# Fenrir TTY screen reader
|
||||
# By Chrys, Storm Dragon, and contributors.
|
||||
|
||||
import importlib.util
|
||||
import os
|
||||
|
||||
from fenrirscreenreader.core.i18n import _
|
||||
|
||||
_base_path = os.path.join(os.path.dirname(__file__), "adjustment_base.py")
|
||||
_spec = importlib.util.spec_from_file_location("adjustment_base", _base_path)
|
||||
_module = importlib.util.module_from_spec(_spec)
|
||||
_spec.loader.exec_module(_module)
|
||||
adjustment_command = _module.adjustment_command
|
||||
|
||||
|
||||
class command(adjustment_command):
|
||||
def __init__(self):
|
||||
super().__init__("alsa", "volume", "inc")
|
70
src/fenrirscreenreader/commands/commands/read_all_by_line.py
Normal file
70
src/fenrirscreenreader/commands/commands/read_all_by_line.py
Normal file
@@ -0,0 +1,70 @@
|
||||
#!/usr/bin/env python3
|
||||
# -*- coding: utf-8 -*-
|
||||
|
||||
# Fenrir TTY screen reader
|
||||
# By Chrys, Storm Dragon, and contributors.
|
||||
|
||||
from fenrirscreenreader.core.i18n import _
|
||||
from fenrirscreenreader.core import debug
|
||||
|
||||
|
||||
class command:
|
||||
def __init__(self):
|
||||
pass
|
||||
|
||||
def initialize(self, environment):
|
||||
self.env = environment
|
||||
|
||||
def shutdown(self):
|
||||
pass
|
||||
|
||||
def get_description(self):
|
||||
return _("Read all text line by line from current position")
|
||||
|
||||
def run(self):
|
||||
self.env["runtime"]["OutputManager"].present_text(
|
||||
"Read-all functionality temporarily disabled",
|
||||
interrupt=True
|
||||
)
|
||||
return
|
||||
# Check if speechd is available for callbacks
|
||||
try:
|
||||
speech_driver = self.env['runtime']['SpeechDriver']
|
||||
if not (hasattr(speech_driver, '_sd') and speech_driver._sd):
|
||||
self.env["runtime"]["OutputManager"].present_text(
|
||||
_("Read all requires speech-dispatcher - not available with current speech driver"),
|
||||
interrupt=True
|
||||
)
|
||||
return
|
||||
except Exception as e:
|
||||
self.env["runtime"]["DebugManager"].write_debug_out(
|
||||
f"ReadAllByLine run: Error checking speech driver: {e}",
|
||||
debug.DebugLevel.ERROR
|
||||
)
|
||||
return
|
||||
|
||||
# Check if ReadAllManager is available
|
||||
if "ReadAllManager" not in self.env["runtime"]:
|
||||
self.env["runtime"]["OutputManager"].present_text(
|
||||
_("Read all manager not in runtime"),
|
||||
interrupt=True
|
||||
)
|
||||
return
|
||||
elif not self.env["runtime"]["ReadAllManager"]:
|
||||
self.env["runtime"]["OutputManager"].present_text(
|
||||
_("Read all manager is None"),
|
||||
interrupt=True
|
||||
)
|
||||
return
|
||||
|
||||
# Start continuous line-by-line reading
|
||||
if self.env["runtime"]["ReadAllManager"].is_active():
|
||||
# Stop if already active
|
||||
self.env["runtime"]["ReadAllManager"].stop_read_all()
|
||||
else:
|
||||
# Start line-by-line reading
|
||||
self.env["runtime"]["ReadAllManager"].start_read_all('line')
|
||||
|
||||
|
||||
def set_callback(self, callback):
|
||||
pass
|
65
src/fenrirscreenreader/commands/commands/read_all_by_page.py
Normal file
65
src/fenrirscreenreader/commands/commands/read_all_by_page.py
Normal file
@@ -0,0 +1,65 @@
|
||||
#!/usr/bin/env python3
|
||||
# -*- coding: utf-8 -*-
|
||||
|
||||
# Fenrir TTY screen reader
|
||||
# By Chrys, Storm Dragon, and contributors.
|
||||
|
||||
from fenrirscreenreader.core.i18n import _
|
||||
from fenrirscreenreader.core import debug
|
||||
|
||||
|
||||
class command:
|
||||
def __init__(self):
|
||||
pass
|
||||
|
||||
def initialize(self, environment):
|
||||
self.env = environment
|
||||
|
||||
def shutdown(self):
|
||||
pass
|
||||
|
||||
def get_description(self):
|
||||
return _("Read all text page by page from current position")
|
||||
|
||||
def run(self):
|
||||
# Check if speechd is available for callbacks
|
||||
try:
|
||||
speech_driver = self.env['runtime']['SpeechDriver']
|
||||
if not (hasattr(speech_driver, '_sd') and speech_driver._sd):
|
||||
self.env["runtime"]["OutputManager"].present_text(
|
||||
_("Read all requires speech-dispatcher - not available with current speech driver"),
|
||||
interrupt=True
|
||||
)
|
||||
return
|
||||
except Exception as e:
|
||||
self.env["runtime"]["DebugManager"].write_debug_out(
|
||||
f"ReadAllByPage run: Error checking speech driver: {e}",
|
||||
debug.DebugLevel.ERROR
|
||||
)
|
||||
return
|
||||
|
||||
# Check if ReadAllManager is available
|
||||
if "ReadAllManager" not in self.env["runtime"]:
|
||||
self.env["runtime"]["OutputManager"].present_text(
|
||||
_("Read all manager not in runtime"),
|
||||
interrupt=True
|
||||
)
|
||||
return
|
||||
elif not self.env["runtime"]["ReadAllManager"]:
|
||||
self.env["runtime"]["OutputManager"].present_text(
|
||||
_("Read all manager is None"),
|
||||
interrupt=True
|
||||
)
|
||||
return
|
||||
|
||||
# Start continuous page-by-page reading
|
||||
if self.env["runtime"]["ReadAllManager"].is_active():
|
||||
# Stop if already active
|
||||
self.env["runtime"]["ReadAllManager"].stop_read_all()
|
||||
else:
|
||||
# Start page-by-page reading
|
||||
self.env["runtime"]["ReadAllManager"].start_read_all('page')
|
||||
|
||||
|
||||
def set_callback(self, callback):
|
||||
pass
|
@@ -4,7 +4,7 @@
|
||||
# Fenrir TTY screen reader
|
||||
# By Chrys, Storm Dragon, and contributors.
|
||||
|
||||
|
||||
import time
|
||||
from fenrirscreenreader.core.i18n import _
|
||||
|
||||
|
||||
@@ -14,55 +14,150 @@ class command:
|
||||
|
||||
def initialize(self, environment):
|
||||
self.env = environment
|
||||
# Initialize tab completion state tracking
|
||||
if "tabCompletion" not in self.env["commandBuffer"]:
|
||||
self.env["commandBuffer"]["tabCompletion"] = {
|
||||
"lastTabTime": 0,
|
||||
"pendingCompletion": None,
|
||||
"retryCount": 0
|
||||
}
|
||||
|
||||
def shutdown(self):
|
||||
pass
|
||||
|
||||
def get_description(self):
|
||||
return "No Description found"
|
||||
return _("Announces tab completions when detected")
|
||||
|
||||
def _is_recent_tab_input(self):
|
||||
"""Check if TAB was pressed recently (within 200ms window)"""
|
||||
current_time = time.time()
|
||||
tab_detected = False
|
||||
|
||||
# Check KEY mode
|
||||
if self.env["runtime"]["InputManager"].get_shortcut_type() in ["KEY"]:
|
||||
if (self.env["runtime"]["InputManager"].get_last_deepest_input()
|
||||
in [["KEY_TAB"]]):
|
||||
tab_detected = True
|
||||
self.env["commandBuffer"]["tabCompletion"]["lastTabTime"] = current_time
|
||||
|
||||
# Check BYTE mode
|
||||
elif self.env["runtime"]["InputManager"].get_shortcut_type() in ["BYTE"]:
|
||||
for currByte in self.env["runtime"]["ByteManager"].get_last_byte_key():
|
||||
if currByte == 9: # Tab character
|
||||
tab_detected = True
|
||||
self.env["commandBuffer"]["tabCompletion"]["lastTabTime"] = current_time
|
||||
|
||||
# Check if tab was pressed recently (200ms window)
|
||||
if not tab_detected:
|
||||
time_since_tab = current_time - self.env["commandBuffer"]["tabCompletion"]["lastTabTime"]
|
||||
if time_since_tab <= 0.2: # 200ms window
|
||||
tab_detected = True
|
||||
|
||||
return tab_detected
|
||||
|
||||
def _is_flexible_completion_match(self, x_move, delta_text):
|
||||
"""Use flexible matching instead of strict equality"""
|
||||
if not delta_text:
|
||||
return False
|
||||
|
||||
delta_len = len(delta_text)
|
||||
|
||||
# Exact match (preserve original behavior)
|
||||
if x_move == delta_len:
|
||||
return True
|
||||
|
||||
# Flexible range: allow ±2 characters difference
|
||||
# Handles spacing adjustments and unicode width variations
|
||||
if abs(x_move - delta_len) <= 2 and delta_len > 0:
|
||||
return True
|
||||
|
||||
# For longer completions, allow proportional variance
|
||||
if delta_len > 10 and abs(x_move - delta_len) <= (delta_len * 0.2):
|
||||
return True
|
||||
|
||||
return False
|
||||
|
||||
def _detect_completion_patterns(self, delta_text):
|
||||
"""Detect common tab completion patterns for improved accuracy"""
|
||||
if not delta_text:
|
||||
return False
|
||||
|
||||
delta_stripped = delta_text.strip()
|
||||
|
||||
# File extension completion
|
||||
if '.' in delta_stripped and delta_stripped.count('.') <= 2:
|
||||
return True
|
||||
|
||||
# Path completion (contains / or \)
|
||||
if '/' in delta_stripped or '\\' in delta_stripped:
|
||||
return True
|
||||
|
||||
# Command parameter completion (starts with -)
|
||||
if delta_stripped.startswith('-') and len(delta_stripped) > 1:
|
||||
return True
|
||||
|
||||
# Word boundary completion (alphanumeric content)
|
||||
if delta_stripped.isalnum() and len(delta_stripped) >= 2:
|
||||
return True
|
||||
|
||||
return False
|
||||
|
||||
def run(self):
|
||||
# try to detect the tab completion by cursor change
|
||||
"""Enhanced tab completion detection with improved reliability"""
|
||||
# Basic cursor movement check (preserve original logic)
|
||||
x_move = (
|
||||
self.env["screen"]["new_cursor"]["x"]
|
||||
- self.env["screen"]["old_cursor"]["x"]
|
||||
)
|
||||
if x_move <= 0:
|
||||
return
|
||||
if self.env["runtime"]["InputManager"].get_shortcut_type() in ["KEY"]:
|
||||
if not (
|
||||
self.env["runtime"]["InputManager"].get_last_deepest_input()
|
||||
in [["KEY_TAB"]]
|
||||
):
|
||||
if x_move < 5:
|
||||
return
|
||||
elif self.env["runtime"]["InputManager"].get_shortcut_type() in [
|
||||
"BYTE"
|
||||
]:
|
||||
found = False
|
||||
for currByte in self.env["runtime"][
|
||||
"ByteManager"
|
||||
].get_last_byte_key():
|
||||
if currByte == 9:
|
||||
found = True
|
||||
if not found:
|
||||
if x_move < 5:
|
||||
return
|
||||
# is there any change?
|
||||
|
||||
# Enhanced tab input detection with persistence
|
||||
tab_detected = self._is_recent_tab_input()
|
||||
|
||||
# Fallback for non-tab movements (preserve original thresholds)
|
||||
if not tab_detected:
|
||||
if x_move < 5:
|
||||
return
|
||||
|
||||
# Screen delta availability check
|
||||
if not self.env["runtime"]["ScreenManager"].is_delta():
|
||||
# If tab was detected but no delta yet, store for potential retry
|
||||
if tab_detected and self.env["commandBuffer"]["tabCompletion"]["retryCount"] < 2:
|
||||
self.env["commandBuffer"]["tabCompletion"]["pendingCompletion"] = {
|
||||
"x_move": x_move,
|
||||
"timestamp": time.time()
|
||||
}
|
||||
self.env["commandBuffer"]["tabCompletion"]["retryCount"] += 1
|
||||
return
|
||||
if not x_move == len(self.env["screen"]["new_delta"]):
|
||||
return
|
||||
# filter unneded space on word begin
|
||||
curr_delta = self.env["screen"]["new_delta"]
|
||||
if (
|
||||
len(curr_delta.strip()) != len(curr_delta)
|
||||
and curr_delta.strip() != ""
|
||||
):
|
||||
|
||||
delta_text = self.env["screen"]["new_delta"]
|
||||
|
||||
# Enhanced correlation checking with flexible matching
|
||||
if not self._is_flexible_completion_match(x_move, delta_text):
|
||||
# Additional pattern-based validation for edge cases
|
||||
if not (tab_detected and self._detect_completion_patterns(delta_text)):
|
||||
return
|
||||
|
||||
# Reset retry counter on successful detection
|
||||
self.env["commandBuffer"]["tabCompletion"]["retryCount"] = 0
|
||||
self.env["commandBuffer"]["tabCompletion"]["pendingCompletion"] = None
|
||||
|
||||
# Mark that we've handled this delta to prevent duplicate announcements
|
||||
# This prevents the incoming text handler from also announcing the same content
|
||||
self.env["commandBuffer"]["tabCompletion"]["lastProcessedDelta"] = delta_text
|
||||
self.env["commandBuffer"]["tabCompletion"]["lastProcessedTime"] = time.time()
|
||||
|
||||
# Text filtering and announcement (preserve original behavior)
|
||||
curr_delta = delta_text
|
||||
if (len(curr_delta.strip()) != len(curr_delta) and curr_delta.strip() != ""):
|
||||
curr_delta = curr_delta.strip()
|
||||
self.env["runtime"]["OutputManager"].present_text(
|
||||
curr_delta, interrupt=True, announce_capital=True, flush=False
|
||||
)
|
||||
|
||||
# Enhanced announcement with better handling of empty completions
|
||||
if curr_delta:
|
||||
self.env["runtime"]["OutputManager"].present_text(
|
||||
curr_delta, interrupt=True, announce_capital=True, flush=False
|
||||
)
|
||||
|
||||
def set_callback(self, callback):
|
||||
pass
|
||||
|
@@ -60,9 +60,10 @@ class command:
|
||||
if self.env["runtime"]["SettingsManager"].get_setting_as_int(
|
||||
"general", "autoPresentIndentMode"
|
||||
) in [0, 1]:
|
||||
self.env["runtime"]["OutputManager"].play_frequence(
|
||||
curr_ident * 50, 0.1, interrupt=do_interrupt
|
||||
)
|
||||
if self.lastIdent != curr_ident:
|
||||
self.env["runtime"]["OutputManager"].play_frequence(
|
||||
curr_ident * 50, 0.1, interrupt=do_interrupt
|
||||
)
|
||||
if self.env["runtime"]["SettingsManager"].get_setting_as_int(
|
||||
"general", "autoPresentIndentMode"
|
||||
) in [0, 2]:
|
||||
|
@@ -31,10 +31,9 @@ class command:
|
||||
self.lastIdent = 0
|
||||
return
|
||||
|
||||
# is a vertical change?
|
||||
if not self.env["runtime"][
|
||||
"CursorManager"
|
||||
].is_cursor_horizontal_move():
|
||||
# Skip if no cursor movement at all
|
||||
if (not self.env["runtime"]["CursorManager"].is_cursor_horizontal_move() and
|
||||
not self.env["runtime"]["CursorManager"].is_cursor_vertical_move()):
|
||||
return
|
||||
x, y, curr_line = line_utils.get_current_line(
|
||||
self.env["screen"]["new_cursor"]["x"],
|
||||
@@ -43,27 +42,34 @@ class command:
|
||||
)
|
||||
curr_ident = self.env["screen"]["new_cursor"]["x"]
|
||||
|
||||
if not curr_line.isspace():
|
||||
# ident
|
||||
lastIdent, lastY, last_line = line_utils.get_current_line(
|
||||
self.env["screen"]["new_cursor"]["x"],
|
||||
self.env["screen"]["new_cursor"]["y"],
|
||||
self.env["screen"]["old_content_text"],
|
||||
)
|
||||
if curr_line.strip() != last_line.strip():
|
||||
return
|
||||
if len(curr_line.lstrip()) == len(last_line.lstrip()):
|
||||
return
|
||||
if curr_line.isspace():
|
||||
# Don't beep for lines with only spaces - no meaningful indentation
|
||||
return
|
||||
|
||||
# Lines with actual content - calculate proper indentation
|
||||
lastIdent, lastY, last_line = line_utils.get_current_line(
|
||||
self.env["screen"]["new_cursor"]["x"],
|
||||
self.env["screen"]["new_cursor"]["y"],
|
||||
self.env["screen"]["old_content_text"],
|
||||
)
|
||||
if curr_line.strip() != last_line.strip():
|
||||
return
|
||||
if len(curr_line.lstrip()) == len(last_line.lstrip()):
|
||||
return
|
||||
|
||||
curr_ident = len(curr_line) - len(curr_line.lstrip())
|
||||
curr_ident = len(curr_line) - len(curr_line.lstrip())
|
||||
|
||||
if self.lastIdent == -1:
|
||||
self.lastIdent = curr_ident
|
||||
if curr_ident <= 0:
|
||||
return
|
||||
if curr_ident <= 0:
|
||||
return
|
||||
|
||||
# Initialize lastIdent if needed
|
||||
if self.lastIdent == -1:
|
||||
self.lastIdent = curr_ident
|
||||
|
||||
# Only beep/announce if indentation level has changed
|
||||
if self.env["runtime"]["SettingsManager"].get_setting_as_bool(
|
||||
"general", "autoPresentIndent"
|
||||
):
|
||||
) and self.lastIdent != curr_ident:
|
||||
if self.env["runtime"]["SettingsManager"].get_setting_as_int(
|
||||
"general", "autoPresentIndentMode"
|
||||
) in [0, 1]:
|
||||
@@ -71,14 +77,15 @@ class command:
|
||||
curr_ident * 50, 0.1, interrupt=False
|
||||
)
|
||||
if self.env["runtime"]["SettingsManager"].get_setting_as_int(
|
||||
"general", "autoPresentIndentMode"
|
||||
"general", "autePresentIndentMode"
|
||||
) in [0, 2]:
|
||||
if self.lastIdent != curr_ident:
|
||||
self.env["runtime"]["OutputManager"].present_text(
|
||||
_("indented ") + str(curr_ident) + " ",
|
||||
interrupt=False,
|
||||
flush=False,
|
||||
)
|
||||
self.env["runtime"]["OutputManager"].present_text(
|
||||
_("indented ") + str(curr_ident) + " ",
|
||||
interrupt=False,
|
||||
flush=False,
|
||||
)
|
||||
|
||||
# Always update lastIdent for next comparison
|
||||
self.lastIdent = curr_ident
|
||||
|
||||
def set_callback(self, callback):
|
||||
|
@@ -0,0 +1,128 @@
|
||||
#!/usr/bin/env python3
|
||||
# -*- coding: utf-8 -*-
|
||||
|
||||
# Fenrir TTY screen reader
|
||||
# By Chrys, Storm Dragon, and contributors.
|
||||
|
||||
import time
|
||||
from fenrirscreenreader.core.i18n import _
|
||||
|
||||
|
||||
class command:
|
||||
def __init__(self):
|
||||
pass
|
||||
|
||||
def initialize(self, environment):
|
||||
self.env = environment
|
||||
|
||||
def shutdown(self):
|
||||
pass
|
||||
|
||||
def get_description(self):
|
||||
return _("Handles delayed retry for tab completion detection")
|
||||
|
||||
def run(self):
|
||||
"""Check for and process pending tab completions with slight delay"""
|
||||
# Only process if we have tab completion state
|
||||
if "tabCompletion" not in self.env["commandBuffer"]:
|
||||
return
|
||||
|
||||
tab_state = self.env["commandBuffer"]["tabCompletion"]
|
||||
pending = tab_state.get("pendingCompletion")
|
||||
|
||||
if not pending:
|
||||
return
|
||||
|
||||
current_time = time.time()
|
||||
|
||||
# Process pending completion after 50ms delay
|
||||
if current_time - pending["timestamp"] < 0.05:
|
||||
return
|
||||
|
||||
# Check if screen delta is now available
|
||||
if not self.env["runtime"]["ScreenManager"].is_delta():
|
||||
# Give up after 200ms total
|
||||
if current_time - pending["timestamp"] > 0.2:
|
||||
tab_state["pendingCompletion"] = None
|
||||
tab_state["retryCount"] = 0
|
||||
return
|
||||
|
||||
# Process the delayed completion
|
||||
delta_text = self.env["screen"]["new_delta"]
|
||||
x_move = pending["x_move"]
|
||||
|
||||
# Use the same flexible matching logic as main tab completion
|
||||
match_found = self._is_flexible_completion_match(x_move, delta_text)
|
||||
|
||||
if not match_found:
|
||||
# Try pattern-based detection as final fallback
|
||||
match_found = self._detect_completion_patterns(delta_text)
|
||||
|
||||
if match_found and delta_text:
|
||||
# Mark that we've handled this delta to prevent duplicate announcements
|
||||
tab_state["lastProcessedDelta"] = delta_text
|
||||
tab_state["lastProcessedTime"] = current_time
|
||||
|
||||
# Filter and announce the completion
|
||||
curr_delta = delta_text
|
||||
if (len(curr_delta.strip()) != len(curr_delta) and
|
||||
curr_delta.strip() != ""):
|
||||
curr_delta = curr_delta.strip()
|
||||
|
||||
if curr_delta:
|
||||
self.env["runtime"]["OutputManager"].present_text(
|
||||
curr_delta, interrupt=True, announce_capital=True, flush=False
|
||||
)
|
||||
|
||||
# Clear pending completion
|
||||
tab_state["pendingCompletion"] = None
|
||||
tab_state["retryCount"] = 0
|
||||
|
||||
def _is_flexible_completion_match(self, x_move, delta_text):
|
||||
"""Use flexible matching (duplicated from main command for heartbeat use)"""
|
||||
if not delta_text:
|
||||
return False
|
||||
|
||||
delta_len = len(delta_text)
|
||||
|
||||
# Exact match
|
||||
if x_move == delta_len:
|
||||
return True
|
||||
|
||||
# Flexible range: allow ±2 characters difference
|
||||
if abs(x_move - delta_len) <= 2 and delta_len > 0:
|
||||
return True
|
||||
|
||||
# For longer completions, allow proportional variance
|
||||
if delta_len > 10 and abs(x_move - delta_len) <= (delta_len * 0.2):
|
||||
return True
|
||||
|
||||
return False
|
||||
|
||||
def _detect_completion_patterns(self, delta_text):
|
||||
"""Detect common tab completion patterns (duplicated from main command)"""
|
||||
if not delta_text:
|
||||
return False
|
||||
|
||||
delta_stripped = delta_text.strip()
|
||||
|
||||
# File extension completion
|
||||
if '.' in delta_stripped and delta_stripped.count('.') <= 2:
|
||||
return True
|
||||
|
||||
# Path completion
|
||||
if '/' in delta_stripped or '\\' in delta_stripped:
|
||||
return True
|
||||
|
||||
# Command parameter completion
|
||||
if delta_stripped.startswith('-') and len(delta_stripped) > 1:
|
||||
return True
|
||||
|
||||
# Word boundary completion
|
||||
if delta_stripped.isalnum() and len(delta_stripped) >= 2:
|
||||
return True
|
||||
|
||||
return False
|
||||
|
||||
def set_callback(self, callback):
|
||||
pass
|
@@ -24,14 +24,19 @@ class command:
|
||||
def run(self):
|
||||
if self.env["input"]["oldNumLock"] == self.env["input"]["newNumLock"]:
|
||||
return
|
||||
if self.env["input"]["newNumLock"]:
|
||||
self.env["runtime"]["OutputManager"].present_text(
|
||||
_("Numlock on"), interrupt=True
|
||||
)
|
||||
else:
|
||||
self.env["runtime"]["OutputManager"].present_text(
|
||||
_("Numlock off"), interrupt=True
|
||||
)
|
||||
|
||||
# Only announce numlock changes if an actual numlock key was pressed
|
||||
# This prevents spurious announcements from external numpad automatic state changes
|
||||
current_input = self.env["input"]["currInput"]
|
||||
if current_input and "KEY_NUMLOCK" in current_input:
|
||||
if self.env["input"]["newNumLock"]:
|
||||
self.env["runtime"]["OutputManager"].present_text(
|
||||
_("Numlock on"), interrupt=True
|
||||
)
|
||||
else:
|
||||
self.env["runtime"]["OutputManager"].present_text(
|
||||
_("Numlock off"), interrupt=True
|
||||
)
|
||||
|
||||
def set_callback(self, callback):
|
||||
pass
|
||||
|
@@ -99,6 +99,13 @@ class command:
|
||||
"Progress detector checking: '" + text + "'", debug.DebugLevel.INFO
|
||||
)
|
||||
|
||||
# Filter out URLs to prevent false positives
|
||||
if self.contains_url(text):
|
||||
self.env["runtime"]["DebugManager"].write_debug_out(
|
||||
"Skipping progress detection - text contains URL", debug.DebugLevel.INFO
|
||||
)
|
||||
return
|
||||
|
||||
# Note: Auto-disable on 100% completion removed to respect user
|
||||
# settings
|
||||
|
||||
@@ -137,13 +144,43 @@ class command:
|
||||
] = current_time
|
||||
return
|
||||
|
||||
# Pattern 1a2: Curl classic progress format (percentage without % symbol)
|
||||
# Extract percentage from curl's classic format
|
||||
curl_classic_match = re.search(
|
||||
r"^\s*(\d+)\s+\d+[kMGT]?\s+(\d+)\s+\d+[kMGT]?\s+\d+\s+\d+\s+\d+[kMGT]?\s+\d+\s+\d+:\d+:\d+\s+\d+:\d+:\d+\s+\d+:\d+:\d+\s+\d+[kMGT]?\s*$", text
|
||||
)
|
||||
if curl_classic_match:
|
||||
# Use the first percentage (total progress)
|
||||
percentage = float(curl_classic_match.group(1))
|
||||
if 0 <= percentage <= 100:
|
||||
self.env["runtime"]["DebugManager"].write_debug_out(
|
||||
"found curl classic percentage: " + str(percentage),
|
||||
debug.DebugLevel.INFO,
|
||||
)
|
||||
if (
|
||||
percentage
|
||||
!= self.env["commandBuffer"]["lastProgressValue"]
|
||||
):
|
||||
self.env["runtime"]["DebugManager"].write_debug_out(
|
||||
"Playing tone for curl: " + str(percentage),
|
||||
debug.DebugLevel.INFO,
|
||||
)
|
||||
self.play_progress_tone(percentage)
|
||||
self.env["commandBuffer"][
|
||||
"lastProgressValue"
|
||||
] = percentage
|
||||
self.env["commandBuffer"][
|
||||
"lastProgressTime"
|
||||
] = current_time
|
||||
return
|
||||
|
||||
# Pattern 1b: Time/token activity (not percentage-based, so use single
|
||||
# beep)
|
||||
time_match = re.search(r"(\d+)s\s", text)
|
||||
token_match = re.search(r"(\d+)\s+tokens", text)
|
||||
time_match = re.search(r"(?:(?:remaining|elapsed|left|ETA|eta)[:;\s]*(\d+)s|(\d+)s\s+(?:remaining|elapsed|left))", text, re.IGNORECASE)
|
||||
token_match = re.search(r"(?:processing|generating|used|consumed)\s+(\d+)\s+tokens", text, re.IGNORECASE)
|
||||
# Pattern 1c: dd command output (bytes copied with transfer rate)
|
||||
dd_match = re.search(r"\d+\s+bytes.*copied.*\d+\s+s.*[kMGT]?B/s", text)
|
||||
# Pattern 1d: Curl-style transfer data (bytes, speed indicators)
|
||||
# Pattern 1d: Curl-style transfer data (bytes, speed indicators - legacy)
|
||||
curl_match = re.search(
|
||||
r"(\d+\s+\d+\s+\d+\s+\d+.*?(?:k|M|G)?.*?--:--:--|Speed)", text
|
||||
)
|
||||
@@ -151,8 +188,12 @@ class command:
|
||||
transfer_match = re.search(
|
||||
r"\d+\s+\d+[kMGT]?\s+\d+\s+\d+[kMGT]?.*?\d+\.\d+[kMGT].*?\d+:\d+:\d+", text
|
||||
)
|
||||
# Pattern 1f: Pacman-style transfer progress (flexible size/speed/time)
|
||||
pacman_match = re.search(
|
||||
r"\d+(?:\.\d+)?\s+[kKmMgGtT]iB\s+\d+(?:\.\d+)?\s+[kKmMgGtT]iB/s\s+\d+:\d+", text
|
||||
)
|
||||
|
||||
if time_match or token_match or dd_match or curl_match or transfer_match:
|
||||
if time_match or token_match or dd_match or curl_match or transfer_match or pacman_match:
|
||||
# For non-percentage progress, use a single activity beep every 2
|
||||
# seconds
|
||||
if (
|
||||
@@ -172,7 +213,10 @@ class command:
|
||||
if fraction_match:
|
||||
current = int(fraction_match.group(1))
|
||||
total = int(fraction_match.group(2))
|
||||
if total > 0:
|
||||
# Filter out dates, page numbers, and other non-progress fractions
|
||||
if (total > 0 and total <= 1000 and current <= total and
|
||||
not re.search(r"\b(?:page|chapter|section|line|row|column|year|month|day)\b", text, re.IGNORECASE) and
|
||||
not re.search(r"\d{1,2}/\d{1,2}/\d{2,4}", text)): # Date pattern
|
||||
percentage = (current / total) * 100
|
||||
if (
|
||||
percentage
|
||||
@@ -224,6 +268,38 @@ class command:
|
||||
):
|
||||
self.play_activity_beep()
|
||||
self.env["commandBuffer"]["lastProgressTime"] = current_time
|
||||
return
|
||||
|
||||
# Pattern 5: Braille progress indicators
|
||||
braille_match = re.search(r'[⠋⠙⠹⠸⠼⠴⠦⠧⠇⠏⡿⣟⣯⣷⣾⣽⣻⢿]', text)
|
||||
if braille_match:
|
||||
if current_time - self.env["commandBuffer"]["lastProgressTime"] >= 1.0:
|
||||
self.play_activity_beep()
|
||||
self.env["commandBuffer"]["lastProgressTime"] = current_time
|
||||
return
|
||||
|
||||
# Pattern 6: Claude Code progress indicators
|
||||
claude_progress_match = re.search(r'^[·✶✢✻*]\s+[^(]+[…\.]*\s*\(esc to interrupt[^)]*\)\s*$', text)
|
||||
if claude_progress_match:
|
||||
if current_time - self.env["commandBuffer"]["lastProgressTime"] >= 1.0:
|
||||
self.play_activity_beep()
|
||||
self.env["commandBuffer"]["lastProgressTime"] = current_time
|
||||
return
|
||||
|
||||
# Pattern 7: Moon phase progress indicators
|
||||
moon_match = re.search(r'[🌑🌒🌓🌔🌕🌖🌗🌘]', text)
|
||||
if moon_match:
|
||||
moon_phases = {
|
||||
'🌑': 0, '🌒': 12.5, '🌓': 25, '🌔': 37.5,
|
||||
'🌕': 50, '🌖': 62.5, '🌗': 75, '🌘': 87.5
|
||||
}
|
||||
moon_char = moon_match.group(0)
|
||||
if moon_char in moon_phases:
|
||||
percentage = moon_phases[moon_char]
|
||||
if percentage != self.env["commandBuffer"]["lastProgressValue"]:
|
||||
self.play_progress_tone(percentage)
|
||||
self.env["commandBuffer"]["lastProgressValue"] = percentage
|
||||
return
|
||||
|
||||
def play_progress_tone(self, percentage):
|
||||
# Map 0-100% to 400-1200Hz frequency range
|
||||
@@ -239,9 +315,21 @@ class command:
|
||||
self.play_quiet_tone(800, 0.08)
|
||||
|
||||
def play_quiet_tone(self, frequency, duration):
|
||||
"""Play a quiet tone using Sox directly"""
|
||||
"""Play a quiet tone using Sox directly with flood protection"""
|
||||
import shlex
|
||||
import subprocess
|
||||
import time
|
||||
|
||||
# Flood protection: prevent beeps closer than 0.1 seconds apart
|
||||
current_time = time.time()
|
||||
if not hasattr(self, '_last_beep_time'):
|
||||
self._last_beep_time = 0
|
||||
|
||||
if current_time - self._last_beep_time < 0.1:
|
||||
# Skip this beep to prevent audio crackling on low-resource systems
|
||||
return
|
||||
|
||||
self._last_beep_time = current_time
|
||||
|
||||
# Build the Sox command: play -qn synth <duration> tri <frequency> gain
|
||||
# -8
|
||||
@@ -354,5 +442,20 @@ class command:
|
||||
# If anything fails, assume it's not a prompt to be safe
|
||||
return False
|
||||
|
||||
def contains_url(self, text):
|
||||
"""Check if text contains URLs that might cause false progress detection"""
|
||||
import re
|
||||
|
||||
# Specific URL patterns - only match actual URLs, not filenames
|
||||
url_patterns = [
|
||||
r"\S+://\S+\.\S{2,}", # Any protocol:// with domain.ext
|
||||
r"www\.[^\s]+\.[a-zA-Z]{2,}", # www.domain.ext patterns
|
||||
]
|
||||
|
||||
for pattern in url_patterns:
|
||||
if re.search(pattern, text, re.IGNORECASE):
|
||||
return True
|
||||
return False
|
||||
|
||||
def set_callback(self, callback):
|
||||
pass
|
||||
|
@@ -4,7 +4,7 @@
|
||||
# Fenrir TTY screen reader
|
||||
# By Chrys, Storm Dragon, and contributors.
|
||||
|
||||
|
||||
import time
|
||||
from fenrirscreenreader.core.i18n import _
|
||||
|
||||
|
||||
@@ -19,7 +19,25 @@ class command:
|
||||
pass
|
||||
|
||||
def get_description(self):
|
||||
return "No Description found"
|
||||
return _("Announces incoming text changes")
|
||||
|
||||
def _was_handled_by_tab_completion(self, delta_text):
|
||||
"""Check if this delta was already handled by tab completion to avoid duplicates"""
|
||||
if "tabCompletion" not in self.env["commandBuffer"]:
|
||||
return False
|
||||
|
||||
tab_state = self.env["commandBuffer"]["tabCompletion"]
|
||||
|
||||
# Check if this exact delta was processed recently by tab completion
|
||||
if (tab_state.get("lastProcessedDelta") == delta_text and
|
||||
tab_state.get("lastProcessedTime")):
|
||||
|
||||
# Only suppress if processed within the last 100ms to avoid stale suppression
|
||||
time_since_processed = time.time() - tab_state["lastProcessedTime"]
|
||||
if time_since_processed <= 0.1:
|
||||
return True
|
||||
|
||||
return False
|
||||
|
||||
def run(self):
|
||||
if not self.env["runtime"]["SettingsManager"].get_setting_as_bool(
|
||||
@@ -30,6 +48,12 @@ class command:
|
||||
if not self.env["runtime"]["ScreenManager"].is_delta(ignoreSpace=True):
|
||||
return
|
||||
|
||||
delta_text = self.env["screen"]["new_delta"]
|
||||
|
||||
# Skip if tab completion already handled this delta
|
||||
if self._was_handled_by_tab_completion(delta_text):
|
||||
return
|
||||
|
||||
# this must be a keyecho or something
|
||||
# if len(self.env['screen']['new_delta'].strip(' \n\t')) <= 1:
|
||||
x_move = abs(
|
||||
@@ -41,14 +65,14 @@ class command:
|
||||
- self.env["screen"]["old_cursor"]["y"]
|
||||
)
|
||||
|
||||
if (x_move >= 1) and x_move == len(self.env["screen"]["new_delta"]):
|
||||
if (x_move >= 1) and x_move == len(delta_text):
|
||||
# if len(self.env['screen']['new_delta'].strip(' \n\t0123456789'))
|
||||
# <= 2:
|
||||
if "\n" not in self.env["screen"]["new_delta"]:
|
||||
if "\n" not in delta_text:
|
||||
return
|
||||
# print(x_move, y_move, len(self.env['screen']['new_delta']), len(self.env['screen']['newNegativeDelta']))
|
||||
self.env["runtime"]["OutputManager"].present_text(
|
||||
self.env["screen"]["new_delta"], interrupt=False, flush=False
|
||||
delta_text, interrupt=False, flush=False
|
||||
)
|
||||
|
||||
def set_callback(self, callback):
|
||||
|
@@ -0,0 +1 @@
|
||||
# Emoji VMenu category
|
@@ -0,0 +1 @@
|
||||
# Flags emoji subcategory
|
@@ -0,0 +1,22 @@
|
||||
class command():
|
||||
def initialize(self, environment):
|
||||
self.env = environment
|
||||
self.emoji = "🇦🇷"
|
||||
|
||||
def shutdown(self):
|
||||
pass
|
||||
|
||||
def setCallback(self, callback):
|
||||
pass
|
||||
|
||||
def getDescription(self):
|
||||
return "Add Argentina flag emoji to clipboard"
|
||||
|
||||
def run(self):
|
||||
self.env["runtime"]["MemoryManager"].add_value_to_first_index(
|
||||
"clipboardHistory", self.emoji
|
||||
)
|
||||
self.env["runtime"]["OutputManager"].present_text(
|
||||
"Added Argentina flag to clipboard",
|
||||
interrupt=False, flush=False
|
||||
)
|
@@ -0,0 +1,22 @@
|
||||
class command():
|
||||
def initialize(self, environment):
|
||||
self.env = environment
|
||||
self.emoji = "🇦🇺"
|
||||
|
||||
def shutdown(self):
|
||||
pass
|
||||
|
||||
def setCallback(self, callback):
|
||||
pass
|
||||
|
||||
def getDescription(self):
|
||||
return "Add Australia flag emoji to clipboard"
|
||||
|
||||
def run(self):
|
||||
self.env["runtime"]["MemoryManager"].add_value_to_first_index(
|
||||
"clipboardHistory", self.emoji
|
||||
)
|
||||
self.env["runtime"]["OutputManager"].present_text(
|
||||
"Added Australia flag to clipboard",
|
||||
interrupt=False, flush=False
|
||||
)
|
@@ -0,0 +1,22 @@
|
||||
class command():
|
||||
def initialize(self, environment):
|
||||
self.env = environment
|
||||
self.emoji = "🇧🇪"
|
||||
|
||||
def shutdown(self):
|
||||
pass
|
||||
|
||||
def setCallback(self, callback):
|
||||
pass
|
||||
|
||||
def getDescription(self):
|
||||
return "Add Belgium flag emoji to clipboard"
|
||||
|
||||
def run(self):
|
||||
self.env["runtime"]["MemoryManager"].add_value_to_first_index(
|
||||
"clipboardHistory", self.emoji
|
||||
)
|
||||
self.env["runtime"]["OutputManager"].present_text(
|
||||
"Added Belgium flag to clipboard",
|
||||
interrupt=False, flush=False
|
||||
)
|
@@ -0,0 +1,22 @@
|
||||
class command():
|
||||
def initialize(self, environment):
|
||||
self.env = environment
|
||||
self.emoji = "🇧🇷"
|
||||
|
||||
def shutdown(self):
|
||||
pass
|
||||
|
||||
def setCallback(self, callback):
|
||||
pass
|
||||
|
||||
def getDescription(self):
|
||||
return "Add Brazil flag emoji to clipboard"
|
||||
|
||||
def run(self):
|
||||
self.env["runtime"]["MemoryManager"].add_value_to_first_index(
|
||||
"clipboardHistory", self.emoji
|
||||
)
|
||||
self.env["runtime"]["OutputManager"].present_text(
|
||||
"Added Brazil flag to clipboard",
|
||||
interrupt=False, flush=False
|
||||
)
|
@@ -0,0 +1,22 @@
|
||||
class command():
|
||||
def initialize(self, environment):
|
||||
self.env = environment
|
||||
self.emoji = "🇨🇦"
|
||||
|
||||
def shutdown(self):
|
||||
pass
|
||||
|
||||
def setCallback(self, callback):
|
||||
pass
|
||||
|
||||
def getDescription(self):
|
||||
return "Add Canada flag emoji to clipboard"
|
||||
|
||||
def run(self):
|
||||
self.env["runtime"]["MemoryManager"].add_value_to_first_index(
|
||||
"clipboardHistory", self.emoji
|
||||
)
|
||||
self.env["runtime"]["OutputManager"].present_text(
|
||||
"Added Canada flag to clipboard",
|
||||
interrupt=False, flush=False
|
||||
)
|
@@ -0,0 +1,22 @@
|
||||
class command():
|
||||
def initialize(self, environment):
|
||||
self.env = environment
|
||||
self.emoji = "🇨🇳"
|
||||
|
||||
def shutdown(self):
|
||||
pass
|
||||
|
||||
def setCallback(self, callback):
|
||||
pass
|
||||
|
||||
def getDescription(self):
|
||||
return "Add China flag emoji to clipboard"
|
||||
|
||||
def run(self):
|
||||
self.env["runtime"]["MemoryManager"].add_value_to_first_index(
|
||||
"clipboardHistory", self.emoji
|
||||
)
|
||||
self.env["runtime"]["OutputManager"].present_text(
|
||||
"Added China flag to clipboard",
|
||||
interrupt=False, flush=False
|
||||
)
|
@@ -0,0 +1,22 @@
|
||||
class command():
|
||||
def initialize(self, environment):
|
||||
self.env = environment
|
||||
self.emoji = "🇩🇰"
|
||||
|
||||
def shutdown(self):
|
||||
pass
|
||||
|
||||
def setCallback(self, callback):
|
||||
pass
|
||||
|
||||
def getDescription(self):
|
||||
return "Add Denmark flag emoji to clipboard"
|
||||
|
||||
def run(self):
|
||||
self.env["runtime"]["MemoryManager"].add_value_to_first_index(
|
||||
"clipboardHistory", self.emoji
|
||||
)
|
||||
self.env["runtime"]["OutputManager"].present_text(
|
||||
"Added Denmark flag to clipboard",
|
||||
interrupt=False, flush=False
|
||||
)
|
@@ -0,0 +1,22 @@
|
||||
class command():
|
||||
def initialize(self, environment):
|
||||
self.env = environment
|
||||
self.emoji = "🇫🇮"
|
||||
|
||||
def shutdown(self):
|
||||
pass
|
||||
|
||||
def setCallback(self, callback):
|
||||
pass
|
||||
|
||||
def getDescription(self):
|
||||
return "Add Finland flag emoji to clipboard"
|
||||
|
||||
def run(self):
|
||||
self.env["runtime"]["MemoryManager"].add_value_to_first_index(
|
||||
"clipboardHistory", self.emoji
|
||||
)
|
||||
self.env["runtime"]["OutputManager"].present_text(
|
||||
"Added Finland flag to clipboard",
|
||||
interrupt=False, flush=False
|
||||
)
|
@@ -0,0 +1,22 @@
|
||||
class command():
|
||||
def initialize(self, environment):
|
||||
self.env = environment
|
||||
self.emoji = "🇫🇷"
|
||||
|
||||
def shutdown(self):
|
||||
pass
|
||||
|
||||
def setCallback(self, callback):
|
||||
pass
|
||||
|
||||
def getDescription(self):
|
||||
return "Add France flag emoji to clipboard"
|
||||
|
||||
def run(self):
|
||||
self.env["runtime"]["MemoryManager"].add_value_to_first_index(
|
||||
"clipboardHistory", self.emoji
|
||||
)
|
||||
self.env["runtime"]["OutputManager"].present_text(
|
||||
"Added France flag to clipboard",
|
||||
interrupt=False, flush=False
|
||||
)
|
@@ -0,0 +1,22 @@
|
||||
class command():
|
||||
def initialize(self, environment):
|
||||
self.env = environment
|
||||
self.emoji = "🇩🇪"
|
||||
|
||||
def shutdown(self):
|
||||
pass
|
||||
|
||||
def setCallback(self, callback):
|
||||
pass
|
||||
|
||||
def getDescription(self):
|
||||
return "Add Germany flag emoji to clipboard"
|
||||
|
||||
def run(self):
|
||||
self.env["runtime"]["MemoryManager"].add_value_to_first_index(
|
||||
"clipboardHistory", self.emoji
|
||||
)
|
||||
self.env["runtime"]["OutputManager"].present_text(
|
||||
"Added Germany flag to clipboard",
|
||||
interrupt=False, flush=False
|
||||
)
|
@@ -0,0 +1,22 @@
|
||||
class command():
|
||||
def initialize(self, environment):
|
||||
self.env = environment
|
||||
self.emoji = "🇬🇷"
|
||||
|
||||
def shutdown(self):
|
||||
pass
|
||||
|
||||
def setCallback(self, callback):
|
||||
pass
|
||||
|
||||
def getDescription(self):
|
||||
return "Add Greece flag emoji to clipboard"
|
||||
|
||||
def run(self):
|
||||
self.env["runtime"]["MemoryManager"].add_value_to_first_index(
|
||||
"clipboardHistory", self.emoji
|
||||
)
|
||||
self.env["runtime"]["OutputManager"].present_text(
|
||||
"Added Greece flag to clipboard",
|
||||
interrupt=False, flush=False
|
||||
)
|
@@ -0,0 +1,22 @@
|
||||
class command():
|
||||
def initialize(self, environment):
|
||||
self.env = environment
|
||||
self.emoji = "🇮🇳"
|
||||
|
||||
def shutdown(self):
|
||||
pass
|
||||
|
||||
def setCallback(self, callback):
|
||||
pass
|
||||
|
||||
def getDescription(self):
|
||||
return "Add India flag emoji to clipboard"
|
||||
|
||||
def run(self):
|
||||
self.env["runtime"]["MemoryManager"].add_value_to_first_index(
|
||||
"clipboardHistory", self.emoji
|
||||
)
|
||||
self.env["runtime"]["OutputManager"].present_text(
|
||||
"Added India flag to clipboard",
|
||||
interrupt=False, flush=False
|
||||
)
|
@@ -0,0 +1,22 @@
|
||||
class command():
|
||||
def initialize(self, environment):
|
||||
self.env = environment
|
||||
self.emoji = "🇮🇪"
|
||||
|
||||
def shutdown(self):
|
||||
pass
|
||||
|
||||
def setCallback(self, callback):
|
||||
pass
|
||||
|
||||
def getDescription(self):
|
||||
return "Add Ireland flag emoji to clipboard"
|
||||
|
||||
def run(self):
|
||||
self.env["runtime"]["MemoryManager"].add_value_to_first_index(
|
||||
"clipboardHistory", self.emoji
|
||||
)
|
||||
self.env["runtime"]["OutputManager"].present_text(
|
||||
"Added Ireland flag to clipboard",
|
||||
interrupt=False, flush=False
|
||||
)
|
@@ -0,0 +1,22 @@
|
||||
class command():
|
||||
def initialize(self, environment):
|
||||
self.env = environment
|
||||
self.emoji = "🇮🇱"
|
||||
|
||||
def shutdown(self):
|
||||
pass
|
||||
|
||||
def setCallback(self, callback):
|
||||
pass
|
||||
|
||||
def getDescription(self):
|
||||
return "Add Israel flag emoji to clipboard"
|
||||
|
||||
def run(self):
|
||||
self.env["runtime"]["MemoryManager"].add_value_to_first_index(
|
||||
"clipboardHistory", self.emoji
|
||||
)
|
||||
self.env["runtime"]["OutputManager"].present_text(
|
||||
"Added Israel flag to clipboard",
|
||||
interrupt=False, flush=False
|
||||
)
|
@@ -0,0 +1,22 @@
|
||||
class command():
|
||||
def initialize(self, environment):
|
||||
self.env = environment
|
||||
self.emoji = "🇮🇹"
|
||||
|
||||
def shutdown(self):
|
||||
pass
|
||||
|
||||
def setCallback(self, callback):
|
||||
pass
|
||||
|
||||
def getDescription(self):
|
||||
return "Add Italy flag emoji to clipboard"
|
||||
|
||||
def run(self):
|
||||
self.env["runtime"]["MemoryManager"].add_value_to_first_index(
|
||||
"clipboardHistory", self.emoji
|
||||
)
|
||||
self.env["runtime"]["OutputManager"].present_text(
|
||||
"Added Italy flag to clipboard",
|
||||
interrupt=False, flush=False
|
||||
)
|
@@ -0,0 +1,22 @@
|
||||
class command():
|
||||
def initialize(self, environment):
|
||||
self.env = environment
|
||||
self.emoji = "🇯🇵"
|
||||
|
||||
def shutdown(self):
|
||||
pass
|
||||
|
||||
def setCallback(self, callback):
|
||||
pass
|
||||
|
||||
def getDescription(self):
|
||||
return "Add Japan flag emoji to clipboard"
|
||||
|
||||
def run(self):
|
||||
self.env["runtime"]["MemoryManager"].add_value_to_first_index(
|
||||
"clipboardHistory", self.emoji
|
||||
)
|
||||
self.env["runtime"]["OutputManager"].present_text(
|
||||
"Added Japan flag to clipboard",
|
||||
interrupt=False, flush=False
|
||||
)
|
@@ -0,0 +1,22 @@
|
||||
class command():
|
||||
def initialize(self, environment):
|
||||
self.env = environment
|
||||
self.emoji = "🇲🇽"
|
||||
|
||||
def shutdown(self):
|
||||
pass
|
||||
|
||||
def setCallback(self, callback):
|
||||
pass
|
||||
|
||||
def getDescription(self):
|
||||
return "Add Mexico flag emoji to clipboard"
|
||||
|
||||
def run(self):
|
||||
self.env["runtime"]["MemoryManager"].add_value_to_first_index(
|
||||
"clipboardHistory", self.emoji
|
||||
)
|
||||
self.env["runtime"]["OutputManager"].present_text(
|
||||
"Added Mexico flag to clipboard",
|
||||
interrupt=False, flush=False
|
||||
)
|
@@ -0,0 +1,22 @@
|
||||
class command():
|
||||
def initialize(self, environment):
|
||||
self.env = environment
|
||||
self.emoji = "🇳🇱"
|
||||
|
||||
def shutdown(self):
|
||||
pass
|
||||
|
||||
def setCallback(self, callback):
|
||||
pass
|
||||
|
||||
def getDescription(self):
|
||||
return "Add Netherlands flag emoji to clipboard"
|
||||
|
||||
def run(self):
|
||||
self.env["runtime"]["MemoryManager"].add_value_to_first_index(
|
||||
"clipboardHistory", self.emoji
|
||||
)
|
||||
self.env["runtime"]["OutputManager"].present_text(
|
||||
"Added Netherlands flag to clipboard",
|
||||
interrupt=False, flush=False
|
||||
)
|
@@ -0,0 +1,22 @@
|
||||
class command():
|
||||
def initialize(self, environment):
|
||||
self.env = environment
|
||||
self.emoji = "🇳🇴"
|
||||
|
||||
def shutdown(self):
|
||||
pass
|
||||
|
||||
def setCallback(self, callback):
|
||||
pass
|
||||
|
||||
def getDescription(self):
|
||||
return "Add Norway flag emoji to clipboard"
|
||||
|
||||
def run(self):
|
||||
self.env["runtime"]["MemoryManager"].add_value_to_first_index(
|
||||
"clipboardHistory", self.emoji
|
||||
)
|
||||
self.env["runtime"]["OutputManager"].present_text(
|
||||
"Added Norway flag to clipboard",
|
||||
interrupt=False, flush=False
|
||||
)
|
@@ -0,0 +1,22 @@
|
||||
class command():
|
||||
def initialize(self, environment):
|
||||
self.env = environment
|
||||
self.emoji = "🇵🇱"
|
||||
|
||||
def shutdown(self):
|
||||
pass
|
||||
|
||||
def setCallback(self, callback):
|
||||
pass
|
||||
|
||||
def getDescription(self):
|
||||
return "Add Poland flag emoji to clipboard"
|
||||
|
||||
def run(self):
|
||||
self.env["runtime"]["MemoryManager"].add_value_to_first_index(
|
||||
"clipboardHistory", self.emoji
|
||||
)
|
||||
self.env["runtime"]["OutputManager"].present_text(
|
||||
"Added Poland flag to clipboard",
|
||||
interrupt=False, flush=False
|
||||
)
|
@@ -0,0 +1,22 @@
|
||||
class command():
|
||||
def initialize(self, environment):
|
||||
self.env = environment
|
||||
self.emoji = "🇵🇹"
|
||||
|
||||
def shutdown(self):
|
||||
pass
|
||||
|
||||
def setCallback(self, callback):
|
||||
pass
|
||||
|
||||
def getDescription(self):
|
||||
return "Add Portugal flag emoji to clipboard"
|
||||
|
||||
def run(self):
|
||||
self.env["runtime"]["MemoryManager"].add_value_to_first_index(
|
||||
"clipboardHistory", self.emoji
|
||||
)
|
||||
self.env["runtime"]["OutputManager"].present_text(
|
||||
"Added Portugal flag to clipboard",
|
||||
interrupt=False, flush=False
|
||||
)
|
@@ -0,0 +1,22 @@
|
||||
class command():
|
||||
def initialize(self, environment):
|
||||
self.env = environment
|
||||
self.emoji = "🇷🇺"
|
||||
|
||||
def shutdown(self):
|
||||
pass
|
||||
|
||||
def setCallback(self, callback):
|
||||
pass
|
||||
|
||||
def getDescription(self):
|
||||
return "Add Russia flag emoji to clipboard"
|
||||
|
||||
def run(self):
|
||||
self.env["runtime"]["MemoryManager"].add_value_to_first_index(
|
||||
"clipboardHistory", self.emoji
|
||||
)
|
||||
self.env["runtime"]["OutputManager"].present_text(
|
||||
"Added Russia flag to clipboard",
|
||||
interrupt=False, flush=False
|
||||
)
|
@@ -0,0 +1,22 @@
|
||||
class command():
|
||||
def initialize(self, environment):
|
||||
self.env = environment
|
||||
self.emoji = "🇿🇦"
|
||||
|
||||
def shutdown(self):
|
||||
pass
|
||||
|
||||
def setCallback(self, callback):
|
||||
pass
|
||||
|
||||
def getDescription(self):
|
||||
return "Add South Africa flag emoji to clipboard"
|
||||
|
||||
def run(self):
|
||||
self.env["runtime"]["MemoryManager"].add_value_to_first_index(
|
||||
"clipboardHistory", self.emoji
|
||||
)
|
||||
self.env["runtime"]["OutputManager"].present_text(
|
||||
"Added South Africa flag to clipboard",
|
||||
interrupt=False, flush=False
|
||||
)
|
@@ -0,0 +1,22 @@
|
||||
class command():
|
||||
def initialize(self, environment):
|
||||
self.env = environment
|
||||
self.emoji = "🇰🇷"
|
||||
|
||||
def shutdown(self):
|
||||
pass
|
||||
|
||||
def setCallback(self, callback):
|
||||
pass
|
||||
|
||||
def getDescription(self):
|
||||
return "Add South Korea flag emoji to clipboard"
|
||||
|
||||
def run(self):
|
||||
self.env["runtime"]["MemoryManager"].add_value_to_first_index(
|
||||
"clipboardHistory", self.emoji
|
||||
)
|
||||
self.env["runtime"]["OutputManager"].present_text(
|
||||
"Added South Korea flag to clipboard",
|
||||
interrupt=False, flush=False
|
||||
)
|
@@ -0,0 +1,22 @@
|
||||
class command():
|
||||
def initialize(self, environment):
|
||||
self.env = environment
|
||||
self.emoji = "🇪🇸"
|
||||
|
||||
def shutdown(self):
|
||||
pass
|
||||
|
||||
def setCallback(self, callback):
|
||||
pass
|
||||
|
||||
def getDescription(self):
|
||||
return "Add Spain flag emoji to clipboard"
|
||||
|
||||
def run(self):
|
||||
self.env["runtime"]["MemoryManager"].add_value_to_first_index(
|
||||
"clipboardHistory", self.emoji
|
||||
)
|
||||
self.env["runtime"]["OutputManager"].present_text(
|
||||
"Added Spain flag to clipboard",
|
||||
interrupt=False, flush=False
|
||||
)
|
@@ -0,0 +1,22 @@
|
||||
class command():
|
||||
def initialize(self, environment):
|
||||
self.env = environment
|
||||
self.emoji = "🇸🇪"
|
||||
|
||||
def shutdown(self):
|
||||
pass
|
||||
|
||||
def setCallback(self, callback):
|
||||
pass
|
||||
|
||||
def getDescription(self):
|
||||
return "Add Sweden flag emoji to clipboard"
|
||||
|
||||
def run(self):
|
||||
self.env["runtime"]["MemoryManager"].add_value_to_first_index(
|
||||
"clipboardHistory", self.emoji
|
||||
)
|
||||
self.env["runtime"]["OutputManager"].present_text(
|
||||
"Added Sweden flag to clipboard",
|
||||
interrupt=False, flush=False
|
||||
)
|
@@ -0,0 +1,22 @@
|
||||
class command():
|
||||
def initialize(self, environment):
|
||||
self.env = environment
|
||||
self.emoji = "🇨🇭"
|
||||
|
||||
def shutdown(self):
|
||||
pass
|
||||
|
||||
def setCallback(self, callback):
|
||||
pass
|
||||
|
||||
def getDescription(self):
|
||||
return "Add Switzerland flag emoji to clipboard"
|
||||
|
||||
def run(self):
|
||||
self.env["runtime"]["MemoryManager"].add_value_to_first_index(
|
||||
"clipboardHistory", self.emoji
|
||||
)
|
||||
self.env["runtime"]["OutputManager"].present_text(
|
||||
"Added Switzerland flag to clipboard",
|
||||
interrupt=False, flush=False
|
||||
)
|
@@ -0,0 +1,22 @@
|
||||
class command():
|
||||
def initialize(self, environment):
|
||||
self.env = environment
|
||||
self.emoji = "🇹🇷"
|
||||
|
||||
def shutdown(self):
|
||||
pass
|
||||
|
||||
def setCallback(self, callback):
|
||||
pass
|
||||
|
||||
def getDescription(self):
|
||||
return "Add Turkey flag emoji to clipboard"
|
||||
|
||||
def run(self):
|
||||
self.env["runtime"]["MemoryManager"].add_value_to_first_index(
|
||||
"clipboardHistory", self.emoji
|
||||
)
|
||||
self.env["runtime"]["OutputManager"].present_text(
|
||||
"Added Turkey flag to clipboard",
|
||||
interrupt=False, flush=False
|
||||
)
|
@@ -0,0 +1,22 @@
|
||||
class command():
|
||||
def initialize(self, environment):
|
||||
self.env = environment
|
||||
self.emoji = "🇬🇧"
|
||||
|
||||
def shutdown(self):
|
||||
pass
|
||||
|
||||
def setCallback(self, callback):
|
||||
pass
|
||||
|
||||
def getDescription(self):
|
||||
return "Add UK flag emoji to clipboard"
|
||||
|
||||
def run(self):
|
||||
self.env["runtime"]["MemoryManager"].add_value_to_first_index(
|
||||
"clipboardHistory", self.emoji
|
||||
)
|
||||
self.env["runtime"]["OutputManager"].present_text(
|
||||
"Added UK flag to clipboard",
|
||||
interrupt=False, flush=False
|
||||
)
|
@@ -0,0 +1,22 @@
|
||||
class command():
|
||||
def initialize(self, environment):
|
||||
self.env = environment
|
||||
self.emoji = "🇺🇦"
|
||||
|
||||
def shutdown(self):
|
||||
pass
|
||||
|
||||
def setCallback(self, callback):
|
||||
pass
|
||||
|
||||
def getDescription(self):
|
||||
return "Add Ukraine flag emoji to clipboard"
|
||||
|
||||
def run(self):
|
||||
self.env["runtime"]["MemoryManager"].add_value_to_first_index(
|
||||
"clipboardHistory", self.emoji
|
||||
)
|
||||
self.env["runtime"]["OutputManager"].present_text(
|
||||
"Added Ukraine flag to clipboard",
|
||||
interrupt=False, flush=False
|
||||
)
|
@@ -0,0 +1,22 @@
|
||||
class command():
|
||||
def initialize(self, environment):
|
||||
self.env = environment
|
||||
self.emoji = "🇺🇸"
|
||||
|
||||
def shutdown(self):
|
||||
pass
|
||||
|
||||
def setCallback(self, callback):
|
||||
pass
|
||||
|
||||
def getDescription(self):
|
||||
return "Add USA flag emoji to clipboard"
|
||||
|
||||
def run(self):
|
||||
self.env["runtime"]["MemoryManager"].add_value_to_first_index(
|
||||
"clipboardHistory", self.emoji
|
||||
)
|
||||
self.env["runtime"]["OutputManager"].present_text(
|
||||
"Added USA flag to clipboard",
|
||||
interrupt=False, flush=False
|
||||
)
|
@@ -0,0 +1 @@
|
||||
# Food emoji subcategory
|
@@ -0,0 +1,22 @@
|
||||
class command():
|
||||
def initialize(self, environment):
|
||||
self.env = environment
|
||||
self.emoji = "🍎"
|
||||
|
||||
def shutdown(self):
|
||||
pass
|
||||
|
||||
def setCallback(self, callback):
|
||||
pass
|
||||
|
||||
def getDescription(self):
|
||||
return "Red apple emoji"
|
||||
|
||||
def run(self):
|
||||
self.env["runtime"]["MemoryManager"].add_value_to_first_index(
|
||||
"clipboardHistory", self.emoji
|
||||
)
|
||||
self.env["runtime"]["OutputManager"].present_text(
|
||||
"Added red apple to clipboard",
|
||||
interrupt=False, flush=False
|
||||
)
|
@@ -0,0 +1,22 @@
|
||||
class command():
|
||||
def initialize(self, environment):
|
||||
self.env = environment
|
||||
self.emoji = "🥑"
|
||||
|
||||
def shutdown(self):
|
||||
pass
|
||||
|
||||
def setCallback(self, callback):
|
||||
pass
|
||||
|
||||
def getDescription(self):
|
||||
return "Avocado emoji"
|
||||
|
||||
def run(self):
|
||||
self.env["runtime"]["MemoryManager"].add_value_to_first_index(
|
||||
"clipboardHistory", self.emoji
|
||||
)
|
||||
self.env["runtime"]["OutputManager"].present_text(
|
||||
"Added avocado to clipboard",
|
||||
interrupt=False, flush=False
|
||||
)
|
@@ -0,0 +1,22 @@
|
||||
class command():
|
||||
def initialize(self, environment):
|
||||
self.env = environment
|
||||
self.emoji = "🍺"
|
||||
|
||||
def shutdown(self):
|
||||
pass
|
||||
|
||||
def setCallback(self, callback):
|
||||
pass
|
||||
|
||||
def getDescription(self):
|
||||
return "Beer emoji"
|
||||
|
||||
def run(self):
|
||||
self.env["runtime"]["MemoryManager"].add_value_to_first_index(
|
||||
"clipboardHistory", self.emoji
|
||||
)
|
||||
self.env["runtime"]["OutputManager"].present_text(
|
||||
"Added beer to clipboard",
|
||||
interrupt=False, flush=False
|
||||
)
|
@@ -0,0 +1,22 @@
|
||||
class command():
|
||||
def initialize(self, environment):
|
||||
self.env = environment
|
||||
self.emoji = "🎂"
|
||||
|
||||
def shutdown(self):
|
||||
pass
|
||||
|
||||
def setCallback(self, callback):
|
||||
pass
|
||||
|
||||
def getDescription(self):
|
||||
return "Birthday cake emoji"
|
||||
|
||||
def run(self):
|
||||
self.env["runtime"]["MemoryManager"].add_value_to_first_index(
|
||||
"clipboardHistory", self.emoji
|
||||
)
|
||||
self.env["runtime"]["OutputManager"].present_text(
|
||||
"Added birthday cake to clipboard",
|
||||
interrupt=False, flush=False
|
||||
)
|
@@ -0,0 +1,22 @@
|
||||
class command():
|
||||
def initialize(self, environment):
|
||||
self.env = environment
|
||||
self.emoji = "☕"
|
||||
|
||||
def shutdown(self):
|
||||
pass
|
||||
|
||||
def setCallback(self, callback):
|
||||
pass
|
||||
|
||||
def getDescription(self):
|
||||
return "Add coffee emoji to clipboard"
|
||||
|
||||
def run(self):
|
||||
self.env["runtime"]["MemoryManager"].add_value_to_first_index(
|
||||
"clipboardHistory", self.emoji
|
||||
)
|
||||
self.env["runtime"]["OutputManager"].present_text(
|
||||
"Added coffee to clipboard",
|
||||
interrupt=False, flush=False
|
||||
)
|
@@ -0,0 +1,22 @@
|
||||
class command():
|
||||
def initialize(self, environment):
|
||||
self.env = environment
|
||||
self.emoji = "🍩"
|
||||
|
||||
def shutdown(self):
|
||||
pass
|
||||
|
||||
def setCallback(self, callback):
|
||||
pass
|
||||
|
||||
def getDescription(self):
|
||||
return "Donut emoji"
|
||||
|
||||
def run(self):
|
||||
self.env["runtime"]["MemoryManager"].add_value_to_first_index(
|
||||
"clipboardHistory", self.emoji
|
||||
)
|
||||
self.env["runtime"]["OutputManager"].present_text(
|
||||
"Added donut to clipboard",
|
||||
interrupt=False, flush=False
|
||||
)
|
@@ -0,0 +1,22 @@
|
||||
class command():
|
||||
def initialize(self, environment):
|
||||
self.env = environment
|
||||
self.emoji = "🍔"
|
||||
|
||||
def shutdown(self):
|
||||
pass
|
||||
|
||||
def setCallback(self, callback):
|
||||
pass
|
||||
|
||||
def getDescription(self):
|
||||
return "Add hamburger emoji to clipboard"
|
||||
|
||||
def run(self):
|
||||
self.env["runtime"]["MemoryManager"].add_value_to_first_index(
|
||||
"clipboardHistory", self.emoji
|
||||
)
|
||||
self.env["runtime"]["OutputManager"].present_text(
|
||||
"Added hamburger to clipboard",
|
||||
interrupt=False, flush=False
|
||||
)
|
@@ -0,0 +1,22 @@
|
||||
class command():
|
||||
def initialize(self, environment):
|
||||
self.env = environment
|
||||
self.emoji = "🍕"
|
||||
|
||||
def shutdown(self):
|
||||
pass
|
||||
|
||||
def setCallback(self, callback):
|
||||
pass
|
||||
|
||||
def getDescription(self):
|
||||
return "Add pizza emoji to clipboard"
|
||||
|
||||
def run(self):
|
||||
self.env["runtime"]["MemoryManager"].add_value_to_first_index(
|
||||
"clipboardHistory", self.emoji
|
||||
)
|
||||
self.env["runtime"]["OutputManager"].present_text(
|
||||
"Added pizza to clipboard",
|
||||
interrupt=False, flush=False
|
||||
)
|
@@ -0,0 +1,22 @@
|
||||
class command():
|
||||
def initialize(self, environment):
|
||||
self.env = environment
|
||||
self.emoji = "🍓"
|
||||
|
||||
def shutdown(self):
|
||||
pass
|
||||
|
||||
def setCallback(self, callback):
|
||||
pass
|
||||
|
||||
def getDescription(self):
|
||||
return "Strawberry emoji"
|
||||
|
||||
def run(self):
|
||||
self.env["runtime"]["MemoryManager"].add_value_to_first_index(
|
||||
"clipboardHistory", self.emoji
|
||||
)
|
||||
self.env["runtime"]["OutputManager"].present_text(
|
||||
"Added strawberry to clipboard",
|
||||
interrupt=False, flush=False
|
||||
)
|
@@ -0,0 +1,22 @@
|
||||
class command():
|
||||
def initialize(self, environment):
|
||||
self.env = environment
|
||||
self.emoji = "🌮"
|
||||
|
||||
def shutdown(self):
|
||||
pass
|
||||
|
||||
def setCallback(self, callback):
|
||||
pass
|
||||
|
||||
def getDescription(self):
|
||||
return "Taco emoji"
|
||||
|
||||
def run(self):
|
||||
self.env["runtime"]["MemoryManager"].add_value_to_first_index(
|
||||
"clipboardHistory", self.emoji
|
||||
)
|
||||
self.env["runtime"]["OutputManager"].present_text(
|
||||
"Added taco to clipboard",
|
||||
interrupt=False, flush=False
|
||||
)
|
@@ -0,0 +1 @@
|
||||
# Holidays emoji subcategory
|
@@ -0,0 +1,22 @@
|
||||
class command():
|
||||
def initialize(self, environment):
|
||||
self.env = environment
|
||||
self.emoji = "👾"
|
||||
|
||||
def shutdown(self):
|
||||
pass
|
||||
|
||||
def setCallback(self, callback):
|
||||
pass
|
||||
|
||||
def getDescription(self):
|
||||
return "Alien monster emoji"
|
||||
|
||||
def run(self):
|
||||
self.env["runtime"]["MemoryManager"].add_value_to_first_index(
|
||||
"clipboardHistory", self.emoji
|
||||
)
|
||||
self.env["runtime"]["OutputManager"].present_text(
|
||||
"Added alien monster to clipboard",
|
||||
interrupt=False, flush=False
|
||||
)
|
@@ -0,0 +1,22 @@
|
||||
class command():
|
||||
def initialize(self, environment):
|
||||
self.env = environment
|
||||
self.emoji = "🦇"
|
||||
|
||||
def shutdown(self):
|
||||
pass
|
||||
|
||||
def setCallback(self, callback):
|
||||
pass
|
||||
|
||||
def getDescription(self):
|
||||
return "Add bat emoji to clipboard"
|
||||
|
||||
def run(self):
|
||||
self.env["runtime"]["MemoryManager"].add_value_to_first_index(
|
||||
"clipboardHistory", self.emoji
|
||||
)
|
||||
self.env["runtime"]["OutputManager"].present_text(
|
||||
"Added bat to clipboard",
|
||||
interrupt=False, flush=False
|
||||
)
|
@@ -0,0 +1,22 @@
|
||||
class command():
|
||||
def initialize(self, environment):
|
||||
self.env = environment
|
||||
self.emoji = "🐈⬛"
|
||||
|
||||
def shutdown(self):
|
||||
pass
|
||||
|
||||
def setCallback(self, callback):
|
||||
pass
|
||||
|
||||
def getDescription(self):
|
||||
return "Black cat emoji"
|
||||
|
||||
def run(self):
|
||||
self.env["runtime"]["MemoryManager"].add_value_to_first_index(
|
||||
"clipboardHistory", self.emoji
|
||||
)
|
||||
self.env["runtime"]["OutputManager"].present_text(
|
||||
"Added black cat to clipboard",
|
||||
interrupt=False, flush=False
|
||||
)
|
@@ -0,0 +1,22 @@
|
||||
class command():
|
||||
def initialize(self, environment):
|
||||
self.env = environment
|
||||
self.emoji = "🐰"
|
||||
|
||||
def shutdown(self):
|
||||
pass
|
||||
|
||||
def setCallback(self, callback):
|
||||
pass
|
||||
|
||||
def getDescription(self):
|
||||
return "Add bunny emoji to clipboard"
|
||||
|
||||
def run(self):
|
||||
self.env["runtime"]["MemoryManager"].add_value_to_first_index(
|
||||
"clipboardHistory", self.emoji
|
||||
)
|
||||
self.env["runtime"]["OutputManager"].present_text(
|
||||
"Added bunny to clipboard",
|
||||
interrupt=False, flush=False
|
||||
)
|
@@ -0,0 +1,22 @@
|
||||
class command():
|
||||
def initialize(self, environment):
|
||||
self.env = environment
|
||||
self.emoji = "🧙"
|
||||
|
||||
def shutdown(self):
|
||||
pass
|
||||
|
||||
def setCallback(self, callback):
|
||||
pass
|
||||
|
||||
def getDescription(self):
|
||||
return "Mage emoji"
|
||||
|
||||
def run(self):
|
||||
self.env["runtime"]["MemoryManager"].add_value_to_first_index(
|
||||
"clipboardHistory", self.emoji
|
||||
)
|
||||
self.env["runtime"]["OutputManager"].present_text(
|
||||
"Added mage to clipboard",
|
||||
interrupt=False, flush=False
|
||||
)
|
@@ -0,0 +1,22 @@
|
||||
class command():
|
||||
def initialize(self, environment):
|
||||
self.env = environment
|
||||
self.emoji = "🎄"
|
||||
|
||||
def shutdown(self):
|
||||
pass
|
||||
|
||||
def setCallback(self, callback):
|
||||
pass
|
||||
|
||||
def getDescription(self):
|
||||
return "Add Christmas tree emoji to clipboard"
|
||||
|
||||
def run(self):
|
||||
self.env["runtime"]["MemoryManager"].add_value_to_first_index(
|
||||
"clipboardHistory", self.emoji
|
||||
)
|
||||
self.env["runtime"]["OutputManager"].present_text(
|
||||
"Added Christmas tree to clipboard",
|
||||
interrupt=False, flush=False
|
||||
)
|
@@ -0,0 +1,22 @@
|
||||
class command():
|
||||
def initialize(self, environment):
|
||||
self.env = environment
|
||||
self.emoji = "⚰️"
|
||||
|
||||
def shutdown(self):
|
||||
pass
|
||||
|
||||
def setCallback(self, callback):
|
||||
pass
|
||||
|
||||
def getDescription(self):
|
||||
return "Coffin emoji"
|
||||
|
||||
def run(self):
|
||||
self.env["runtime"]["MemoryManager"].add_value_to_first_index(
|
||||
"clipboardHistory", self.emoji
|
||||
)
|
||||
self.env["runtime"]["OutputManager"].present_text(
|
||||
"Added coffin to clipboard",
|
||||
interrupt=False, flush=False
|
||||
)
|
@@ -0,0 +1,22 @@
|
||||
class command():
|
||||
def initialize(self, environment):
|
||||
self.env = environment
|
||||
self.emoji = "🥚"
|
||||
|
||||
def shutdown(self):
|
||||
pass
|
||||
|
||||
def setCallback(self, callback):
|
||||
pass
|
||||
|
||||
def getDescription(self):
|
||||
return "Add Easter egg emoji to clipboard"
|
||||
|
||||
def run(self):
|
||||
self.env["runtime"]["MemoryManager"].add_value_to_first_index(
|
||||
"clipboardHistory", self.emoji
|
||||
)
|
||||
self.env["runtime"]["OutputManager"].present_text(
|
||||
"Added Easter egg to clipboard",
|
||||
interrupt=False, flush=False
|
||||
)
|
@@ -0,0 +1,22 @@
|
||||
class command():
|
||||
def initialize(self, environment):
|
||||
self.env = environment
|
||||
self.emoji = "🎆"
|
||||
|
||||
def shutdown(self):
|
||||
pass
|
||||
|
||||
def setCallback(self, callback):
|
||||
pass
|
||||
|
||||
def getDescription(self):
|
||||
return "Add fireworks emoji to clipboard"
|
||||
|
||||
def run(self):
|
||||
self.env["runtime"]["MemoryManager"].add_value_to_first_index(
|
||||
"clipboardHistory", self.emoji
|
||||
)
|
||||
self.env["runtime"]["OutputManager"].present_text(
|
||||
"Added fireworks to clipboard",
|
||||
interrupt=False, flush=False
|
||||
)
|
@@ -0,0 +1,22 @@
|
||||
class command():
|
||||
def initialize(self, environment):
|
||||
self.env = environment
|
||||
self.emoji = "👻"
|
||||
|
||||
def shutdown(self):
|
||||
pass
|
||||
|
||||
def setCallback(self, callback):
|
||||
pass
|
||||
|
||||
def getDescription(self):
|
||||
return "Add ghost emoji to clipboard"
|
||||
|
||||
def run(self):
|
||||
self.env["runtime"]["MemoryManager"].add_value_to_first_index(
|
||||
"clipboardHistory", self.emoji
|
||||
)
|
||||
self.env["runtime"]["OutputManager"].present_text(
|
||||
"Added ghost to clipboard",
|
||||
interrupt=False, flush=False
|
||||
)
|
@@ -0,0 +1,22 @@
|
||||
class command():
|
||||
def initialize(self, environment):
|
||||
self.env = environment
|
||||
self.emoji = "🎁"
|
||||
|
||||
def shutdown(self):
|
||||
pass
|
||||
|
||||
def setCallback(self, callback):
|
||||
pass
|
||||
|
||||
def getDescription(self):
|
||||
return "Add gift emoji to clipboard"
|
||||
|
||||
def run(self):
|
||||
self.env["runtime"]["MemoryManager"].add_value_to_first_index(
|
||||
"clipboardHistory", self.emoji
|
||||
)
|
||||
self.env["runtime"]["OutputManager"].present_text(
|
||||
"Added gift to clipboard",
|
||||
interrupt=False, flush=False
|
||||
)
|
@@ -0,0 +1,22 @@
|
||||
class command():
|
||||
def initialize(self, environment):
|
||||
self.env = environment
|
||||
self.emoji = "🎃"
|
||||
|
||||
def shutdown(self):
|
||||
pass
|
||||
|
||||
def setCallback(self, callback):
|
||||
pass
|
||||
|
||||
def getDescription(self):
|
||||
return "Add jack o'lantern emoji to clipboard"
|
||||
|
||||
def run(self):
|
||||
self.env["runtime"]["MemoryManager"].add_value_to_first_index(
|
||||
"clipboardHistory", self.emoji
|
||||
)
|
||||
self.env["runtime"]["OutputManager"].present_text(
|
||||
"Added jack o'lantern to clipboard",
|
||||
interrupt=False, flush=False
|
||||
)
|
@@ -0,0 +1,22 @@
|
||||
class command():
|
||||
def initialize(self, environment):
|
||||
self.env = environment
|
||||
self.emoji = "🧟"
|
||||
|
||||
def shutdown(self):
|
||||
pass
|
||||
|
||||
def setCallback(self, callback):
|
||||
pass
|
||||
|
||||
def getDescription(self):
|
||||
return "Mummy emoji"
|
||||
|
||||
def run(self):
|
||||
self.env["runtime"]["MemoryManager"].add_value_to_first_index(
|
||||
"clipboardHistory", self.emoji
|
||||
)
|
||||
self.env["runtime"]["OutputManager"].present_text(
|
||||
"Added mummy to clipboard",
|
||||
interrupt=False, flush=False
|
||||
)
|
@@ -0,0 +1,22 @@
|
||||
class command():
|
||||
def initialize(self, environment):
|
||||
self.env = environment
|
||||
self.emoji = "🎅"
|
||||
|
||||
def shutdown(self):
|
||||
pass
|
||||
|
||||
def setCallback(self, callback):
|
||||
pass
|
||||
|
||||
def getDescription(self):
|
||||
return "Add Santa emoji to clipboard"
|
||||
|
||||
def run(self):
|
||||
self.env["runtime"]["MemoryManager"].add_value_to_first_index(
|
||||
"clipboardHistory", self.emoji
|
||||
)
|
||||
self.env["runtime"]["OutputManager"].present_text(
|
||||
"Added Santa to clipboard",
|
||||
interrupt=False, flush=False
|
||||
)
|
@@ -0,0 +1,22 @@
|
||||
class command():
|
||||
def initialize(self, environment):
|
||||
self.env = environment
|
||||
self.emoji = "☘️"
|
||||
|
||||
def shutdown(self):
|
||||
pass
|
||||
|
||||
def setCallback(self, callback):
|
||||
pass
|
||||
|
||||
def getDescription(self):
|
||||
return "Add shamrock emoji to clipboard"
|
||||
|
||||
def run(self):
|
||||
self.env["runtime"]["MemoryManager"].add_value_to_first_index(
|
||||
"clipboardHistory", self.emoji
|
||||
)
|
||||
self.env["runtime"]["OutputManager"].present_text(
|
||||
"Added shamrock to clipboard",
|
||||
interrupt=False, flush=False
|
||||
)
|
@@ -0,0 +1,22 @@
|
||||
class command():
|
||||
def initialize(self, environment):
|
||||
self.env = environment
|
||||
self.emoji = "💀"
|
||||
|
||||
def shutdown(self):
|
||||
pass
|
||||
|
||||
def setCallback(self, callback):
|
||||
pass
|
||||
|
||||
def getDescription(self):
|
||||
return "Add skull emoji to clipboard"
|
||||
|
||||
def run(self):
|
||||
self.env["runtime"]["MemoryManager"].add_value_to_first_index(
|
||||
"clipboardHistory", self.emoji
|
||||
)
|
||||
self.env["runtime"]["OutputManager"].present_text(
|
||||
"Added skull to clipboard",
|
||||
interrupt=False, flush=False
|
||||
)
|
@@ -0,0 +1,22 @@
|
||||
class command():
|
||||
def initialize(self, environment):
|
||||
self.env = environment
|
||||
self.emoji = "⛄"
|
||||
|
||||
def shutdown(self):
|
||||
pass
|
||||
|
||||
def setCallback(self, callback):
|
||||
pass
|
||||
|
||||
def getDescription(self):
|
||||
return "Add snowman emoji to clipboard"
|
||||
|
||||
def run(self):
|
||||
self.env["runtime"]["MemoryManager"].add_value_to_first_index(
|
||||
"clipboardHistory", self.emoji
|
||||
)
|
||||
self.env["runtime"]["OutputManager"].present_text(
|
||||
"Added snowman to clipboard",
|
||||
interrupt=False, flush=False
|
||||
)
|
@@ -0,0 +1,22 @@
|
||||
class command():
|
||||
def initialize(self, environment):
|
||||
self.env = environment
|
||||
self.emoji = "🕷"
|
||||
|
||||
def shutdown(self):
|
||||
pass
|
||||
|
||||
def setCallback(self, callback):
|
||||
pass
|
||||
|
||||
def getDescription(self):
|
||||
return "Add spider emoji to clipboard"
|
||||
|
||||
def run(self):
|
||||
self.env["runtime"]["MemoryManager"].add_value_to_first_index(
|
||||
"clipboardHistory", self.emoji
|
||||
)
|
||||
self.env["runtime"]["OutputManager"].present_text(
|
||||
"Added spider to clipboard",
|
||||
interrupt=False, flush=False
|
||||
)
|
@@ -0,0 +1,22 @@
|
||||
class command():
|
||||
def initialize(self, environment):
|
||||
self.env = environment
|
||||
self.emoji = "🦃"
|
||||
|
||||
def shutdown(self):
|
||||
pass
|
||||
|
||||
def setCallback(self, callback):
|
||||
pass
|
||||
|
||||
def getDescription(self):
|
||||
return "Add turkey emoji to clipboard"
|
||||
|
||||
def run(self):
|
||||
self.env["runtime"]["MemoryManager"].add_value_to_first_index(
|
||||
"clipboardHistory", self.emoji
|
||||
)
|
||||
self.env["runtime"]["OutputManager"].present_text(
|
||||
"Added turkey to clipboard",
|
||||
interrupt=False, flush=False
|
||||
)
|
@@ -0,0 +1,22 @@
|
||||
class command():
|
||||
def initialize(self, environment):
|
||||
self.env = environment
|
||||
self.emoji = "🧛"
|
||||
|
||||
def shutdown(self):
|
||||
pass
|
||||
|
||||
def setCallback(self, callback):
|
||||
pass
|
||||
|
||||
def getDescription(self):
|
||||
return "Vampire emoji"
|
||||
|
||||
def run(self):
|
||||
self.env["runtime"]["MemoryManager"].add_value_to_first_index(
|
||||
"clipboardHistory", self.emoji
|
||||
)
|
||||
self.env["runtime"]["OutputManager"].present_text(
|
||||
"Added vampire to clipboard",
|
||||
interrupt=False, flush=False
|
||||
)
|
@@ -0,0 +1,22 @@
|
||||
class command():
|
||||
def initialize(self, environment):
|
||||
self.env = environment
|
||||
self.emoji = "🕸️"
|
||||
|
||||
def shutdown(self):
|
||||
pass
|
||||
|
||||
def setCallback(self, callback):
|
||||
pass
|
||||
|
||||
def getDescription(self):
|
||||
return "Spider web emoji"
|
||||
|
||||
def run(self):
|
||||
self.env["runtime"]["MemoryManager"].add_value_to_first_index(
|
||||
"clipboardHistory", self.emoji
|
||||
)
|
||||
self.env["runtime"]["OutputManager"].present_text(
|
||||
"Added spider web to clipboard",
|
||||
interrupt=False, flush=False
|
||||
)
|
@@ -0,0 +1,22 @@
|
||||
class command():
|
||||
def initialize(self, environment):
|
||||
self.env = environment
|
||||
self.emoji = "🧙♀️"
|
||||
|
||||
def shutdown(self):
|
||||
pass
|
||||
|
||||
def setCallback(self, callback):
|
||||
pass
|
||||
|
||||
def getDescription(self):
|
||||
return "Witch emoji"
|
||||
|
||||
def run(self):
|
||||
self.env["runtime"]["MemoryManager"].add_value_to_first_index(
|
||||
"clipboardHistory", self.emoji
|
||||
)
|
||||
self.env["runtime"]["OutputManager"].present_text(
|
||||
"Added witch to clipboard",
|
||||
interrupt=False, flush=False
|
||||
)
|
@@ -0,0 +1,22 @@
|
||||
class command():
|
||||
def initialize(self, environment):
|
||||
self.env = environment
|
||||
self.emoji = "🧟"
|
||||
|
||||
def shutdown(self):
|
||||
pass
|
||||
|
||||
def setCallback(self, callback):
|
||||
pass
|
||||
|
||||
def getDescription(self):
|
||||
return "Zombie emoji"
|
||||
|
||||
def run(self):
|
||||
self.env["runtime"]["MemoryManager"].add_value_to_first_index(
|
||||
"clipboardHistory", self.emoji
|
||||
)
|
||||
self.env["runtime"]["OutputManager"].present_text(
|
||||
"Added zombie to clipboard",
|
||||
interrupt=False, flush=False
|
||||
)
|
@@ -0,0 +1 @@
|
||||
# Nature emoji subcategory
|
@@ -0,0 +1,22 @@
|
||||
class command():
|
||||
def initialize(self, environment):
|
||||
self.env = environment
|
||||
self.emoji = "🦋"
|
||||
|
||||
def shutdown(self):
|
||||
pass
|
||||
|
||||
def setCallback(self, callback):
|
||||
pass
|
||||
|
||||
def getDescription(self):
|
||||
return "Butterfly emoji"
|
||||
|
||||
def run(self):
|
||||
self.env["runtime"]["MemoryManager"].add_value_to_first_index(
|
||||
"clipboardHistory", self.emoji
|
||||
)
|
||||
self.env["runtime"]["OutputManager"].present_text(
|
||||
"Added butterfly to clipboard",
|
||||
interrupt=False, flush=False
|
||||
)
|
@@ -0,0 +1,22 @@
|
||||
class command():
|
||||
def initialize(self, environment):
|
||||
self.env = environment
|
||||
self.emoji = "🐱"
|
||||
|
||||
def shutdown(self):
|
||||
pass
|
||||
|
||||
def setCallback(self, callback):
|
||||
pass
|
||||
|
||||
def getDescription(self):
|
||||
return "Cat emoji"
|
||||
|
||||
def run(self):
|
||||
self.env["runtime"]["MemoryManager"].add_value_to_first_index(
|
||||
"clipboardHistory", self.emoji
|
||||
)
|
||||
self.env["runtime"]["OutputManager"].present_text(
|
||||
"Added cat to clipboard",
|
||||
interrupt=False, flush=False
|
||||
)
|
@@ -0,0 +1,22 @@
|
||||
class command():
|
||||
def initialize(self, environment):
|
||||
self.env = environment
|
||||
self.emoji = "🌸"
|
||||
|
||||
def shutdown(self):
|
||||
pass
|
||||
|
||||
def setCallback(self, callback):
|
||||
pass
|
||||
|
||||
def getDescription(self):
|
||||
return "Cherry blossom emoji"
|
||||
|
||||
def run(self):
|
||||
self.env["runtime"]["MemoryManager"].add_value_to_first_index(
|
||||
"clipboardHistory", self.emoji
|
||||
)
|
||||
self.env["runtime"]["OutputManager"].present_text(
|
||||
"Added cherry blossom to clipboard",
|
||||
interrupt=False, flush=False
|
||||
)
|
@@ -0,0 +1,22 @@
|
||||
class command():
|
||||
def initialize(self, environment):
|
||||
self.env = environment
|
||||
self.emoji = "🐶"
|
||||
|
||||
def shutdown(self):
|
||||
pass
|
||||
|
||||
def setCallback(self, callback):
|
||||
pass
|
||||
|
||||
def getDescription(self):
|
||||
return "Dog emoji"
|
||||
|
||||
def run(self):
|
||||
self.env["runtime"]["MemoryManager"].add_value_to_first_index(
|
||||
"clipboardHistory", self.emoji
|
||||
)
|
||||
self.env["runtime"]["OutputManager"].present_text(
|
||||
"Added dog to clipboard",
|
||||
interrupt=False, flush=False
|
||||
)
|
@@ -0,0 +1,22 @@
|
||||
class command():
|
||||
def initialize(self, environment):
|
||||
self.env = environment
|
||||
self.emoji = "🌙"
|
||||
|
||||
def shutdown(self):
|
||||
pass
|
||||
|
||||
def setCallback(self, callback):
|
||||
pass
|
||||
|
||||
def getDescription(self):
|
||||
return "Add moon emoji to clipboard"
|
||||
|
||||
def run(self):
|
||||
self.env["runtime"]["MemoryManager"].add_value_to_first_index(
|
||||
"clipboardHistory", self.emoji
|
||||
)
|
||||
self.env["runtime"]["OutputManager"].present_text(
|
||||
"Added moon to clipboard",
|
||||
interrupt=False, flush=False
|
||||
)
|
@@ -0,0 +1,22 @@
|
||||
class command():
|
||||
def initialize(self, environment):
|
||||
self.env = environment
|
||||
self.emoji = "🌈"
|
||||
|
||||
def shutdown(self):
|
||||
pass
|
||||
|
||||
def setCallback(self, callback):
|
||||
pass
|
||||
|
||||
def getDescription(self):
|
||||
return "Rainbow emoji"
|
||||
|
||||
def run(self):
|
||||
self.env["runtime"]["MemoryManager"].add_value_to_first_index(
|
||||
"clipboardHistory", self.emoji
|
||||
)
|
||||
self.env["runtime"]["OutputManager"].present_text(
|
||||
"Added rainbow to clipboard",
|
||||
interrupt=False, flush=False
|
||||
)
|
@@ -0,0 +1,22 @@
|
||||
class command():
|
||||
def initialize(self, environment):
|
||||
self.env = environment
|
||||
self.emoji = "🌹"
|
||||
|
||||
def shutdown(self):
|
||||
pass
|
||||
|
||||
def setCallback(self, callback):
|
||||
pass
|
||||
|
||||
def getDescription(self):
|
||||
return "Rose emoji"
|
||||
|
||||
def run(self):
|
||||
self.env["runtime"]["MemoryManager"].add_value_to_first_index(
|
||||
"clipboardHistory", self.emoji
|
||||
)
|
||||
self.env["runtime"]["OutputManager"].present_text(
|
||||
"Added rose to clipboard",
|
||||
interrupt=False, flush=False
|
||||
)
|
@@ -0,0 +1,22 @@
|
||||
class command():
|
||||
def initialize(self, environment):
|
||||
self.env = environment
|
||||
self.emoji = "☀️"
|
||||
|
||||
def shutdown(self):
|
||||
pass
|
||||
|
||||
def setCallback(self, callback):
|
||||
pass
|
||||
|
||||
def getDescription(self):
|
||||
return "Add sun emoji to clipboard"
|
||||
|
||||
def run(self):
|
||||
self.env["runtime"]["MemoryManager"].add_value_to_first_index(
|
||||
"clipboardHistory", self.emoji
|
||||
)
|
||||
self.env["runtime"]["OutputManager"].present_text(
|
||||
"Added sun to clipboard",
|
||||
interrupt=False, flush=False
|
||||
)
|
@@ -0,0 +1,22 @@
|
||||
class command():
|
||||
def initialize(self, environment):
|
||||
self.env = environment
|
||||
self.emoji = "🌻"
|
||||
|
||||
def shutdown(self):
|
||||
pass
|
||||
|
||||
def setCallback(self, callback):
|
||||
pass
|
||||
|
||||
def getDescription(self):
|
||||
return "Sunflower emoji"
|
||||
|
||||
def run(self):
|
||||
self.env["runtime"]["MemoryManager"].add_value_to_first_index(
|
||||
"clipboardHistory", self.emoji
|
||||
)
|
||||
self.env["runtime"]["OutputManager"].present_text(
|
||||
"Added sunflower to clipboard",
|
||||
interrupt=False, flush=False
|
||||
)
|
@@ -0,0 +1,22 @@
|
||||
class command():
|
||||
def initialize(self, environment):
|
||||
self.env = environment
|
||||
self.emoji = "🌳"
|
||||
|
||||
def shutdown(self):
|
||||
pass
|
||||
|
||||
def setCallback(self, callback):
|
||||
pass
|
||||
|
||||
def getDescription(self):
|
||||
return "Add tree emoji to clipboard"
|
||||
|
||||
def run(self):
|
||||
self.env["runtime"]["MemoryManager"].add_value_to_first_index(
|
||||
"clipboardHistory", self.emoji
|
||||
)
|
||||
self.env["runtime"]["OutputManager"].present_text(
|
||||
"Added tree to clipboard",
|
||||
interrupt=False, flush=False
|
||||
)
|
@@ -0,0 +1,22 @@
|
||||
class command():
|
||||
def initialize(self, environment):
|
||||
self.env = environment
|
||||
self.emoji = "🐺"
|
||||
|
||||
def shutdown(self):
|
||||
pass
|
||||
|
||||
def setCallback(self, callback):
|
||||
pass
|
||||
|
||||
def getDescription(self):
|
||||
return "Wolf emoji - The mighty Fenrir!"
|
||||
|
||||
def run(self):
|
||||
self.env["runtime"]["MemoryManager"].add_value_to_first_index(
|
||||
"clipboardHistory", self.emoji
|
||||
)
|
||||
self.env["runtime"]["OutputManager"].present_text(
|
||||
"Added the mighty wolf Fenrir to clipboard",
|
||||
interrupt=False, flush=False
|
||||
)
|
@@ -0,0 +1 @@
|
||||
# People emoji subcategory
|
@@ -0,0 +1,22 @@
|
||||
class command():
|
||||
def initialize(self, environment):
|
||||
self.env = environment
|
||||
self.emoji = "😀"
|
||||
|
||||
def shutdown(self):
|
||||
pass
|
||||
|
||||
def setCallback(self, callback):
|
||||
pass
|
||||
|
||||
def getDescription(self):
|
||||
return "Grinning face emoji"
|
||||
|
||||
def run(self):
|
||||
self.env["runtime"]["MemoryManager"].add_value_to_first_index(
|
||||
"clipboardHistory", self.emoji
|
||||
)
|
||||
self.env["runtime"]["OutputManager"].present_text(
|
||||
"Added grinning face to clipboard",
|
||||
interrupt=False, flush=False
|
||||
)
|
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user