Skip to content

Commit c544c0e

Browse files
authored
chore: add tests (#8)
* test: add more test * chore: add ci * fix: test dependencies * fix: tests
1 parent 56c6292 commit c544c0e

File tree

5 files changed

+449
-4
lines changed

5 files changed

+449
-4
lines changed

.github/workflows/test.yml

Lines changed: 43 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,43 @@
1+
name: Tests
2+
3+
on:
4+
pull_request:
5+
branches: [ master, main ]
6+
push:
7+
branches: [ master, main ]
8+
9+
jobs:
10+
test:
11+
name: Test Python ${{ matrix.python-version }} on ${{ matrix.os }}
12+
runs-on: ${{ matrix.os }}
13+
14+
strategy:
15+
fail-fast: false
16+
matrix:
17+
os: [ubuntu-latest, macos-latest]
18+
python-version: ['3.8', '3.9', '3.10', '3.11', '3.12', '3.13']
19+
20+
steps:
21+
- name: Checkout code
22+
uses: actions/checkout@v4
23+
24+
- name: Set up Python ${{ matrix.python-version }}
25+
uses: actions/setup-python@v5
26+
with:
27+
python-version: ${{ matrix.python-version }}
28+
cache: 'pip'
29+
cache-dependency-path: 'requirements-dev.txt'
30+
31+
- name: Install dependencies
32+
run: |
33+
python -m pip install --upgrade pip
34+
pip install -r requirements-dev.txt
35+
36+
- name: Run tests
37+
run: |
38+
pytest test_easymotion.py -v --cache-clear
39+
40+
- name: Test summary
41+
if: always()
42+
run: |
43+
echo "Tests completed for Python ${{ matrix.python-version }} on ${{ matrix.os }}"

CLAUDE.md

Lines changed: 89 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,89 @@
1+
# CLAUDE.md
2+
3+
This file provides guidance to Claude Code (claude.ai/code) when working with code in this repository.
4+
5+
## Project Overview
6+
7+
tmux-easymotion is a tmux plugin that provides vim-easymotion-like functionality for quickly jumping to visible text positions across tmux panes. The key feature that distinguishes this plugin is its ability to jump between split panes within a tmux window.
8+
9+
## Architecture
10+
11+
The plugin consists of three main components:
12+
13+
1. **easymotion.tmux** (bash): TPM plugin entry point that reads tmux options and sets up key bindings. It spawns a background tmux window that runs the Python script with environment variables for configuration.
14+
15+
2. **easymotion.py** (Python): Core implementation that:
16+
- Uses either curses or ANSI escape sequences for rendering (configurable)
17+
- Captures all visible pane contents via `tmux capture-pane`
18+
- Implements hint generation and assignment based on distance from cursor
19+
- Handles wide (CJK) characters with proper width calculations
20+
- Supports both normal mode and copy mode cursor positioning
21+
22+
3. **Rendering Strategy**: The plugin uses an abstract `Screen` class with two implementations:
23+
- `Curses`: Standard curses-based rendering (opt-in via `@easymotion-use-curses`)
24+
- `AnsiSequence`: ANSI escape sequence rendering (default, more portable)
25+
26+
## Key Technical Details
27+
28+
### Wide Character Handling
29+
The codebase has special handling for double-width characters (CJK characters). Functions like `get_char_width()`, `get_string_width()`, and `get_true_position()` convert between visual columns and string indices. When modifying character position logic, always use `get_true_position()` to convert visual columns to true string positions.
30+
31+
### Hint Generation Algorithm
32+
The `generate_hints()` function dynamically balances single-character and double-character hints to minimize keystrokes. It ensures double-character hints never start with characters used as single-character hints. The `assign_hints_by_distance()` function sorts matches by Euclidean distance from the cursor.
33+
34+
### Pane Information Gathering
35+
`get_initial_tmux_info()` makes a single tmux call to batch-fetch all pane information (positions, dimensions, cursor state, scroll position) for performance. It handles zoomed windows by filtering out non-active panes.
36+
37+
### Input Flow
38+
User input flows through a temporary file (created by `mktemp`) to handle the initial search character, then switches to direct stdin reading via `getch()` for hint selection. This avoids conflicts with tmux's command-prompt.
39+
40+
## Development Commands
41+
42+
### Running Tests
43+
```bash
44+
# First time: Install development dependencies
45+
pip install -r requirements-dev.txt
46+
47+
# Run tests
48+
pytest test_easymotion.py -v --cache-clear
49+
```
50+
51+
### Testing in tmux
52+
After making changes, reload the plugin in tmux:
53+
```bash
54+
# In tmux, press prefix + I to reload TPM plugins
55+
# Or source the config manually:
56+
tmux source-file ~/.tmux.conf
57+
```
58+
59+
### Debugging
60+
Enable debug logging by setting in ~/.tmux.conf:
61+
```bash
62+
set -g @easymotion-debug 'true'
63+
```
64+
Logs are written to ~/easymotion.log
65+
66+
Enable performance logging:
67+
```bash
68+
set -g @easymotion-perf 'true'
69+
```
70+
71+
## Configuration Options (tmux.conf)
72+
73+
All options are read from tmux options in easymotion.tmux and passed as environment variables to the Python script:
74+
75+
- `@easymotion-key`: Trigger key binding (default: 's')
76+
- `@easymotion-hints`: Characters used for hints (default: 'asdghklqwertyuiopzxcvbnmfj;')
77+
- `@easymotion-vertical-border`: Character for vertical borders (default: '│')
78+
- `@easymotion-horizontal-border`: Character for horizontal borders (default: '─')
79+
- `@easymotion-use-curses`: Use curses instead of ANSI sequences (default: 'false')
80+
- `@easymotion-case-sensitive`: Case-sensitive search (default: 'false')
81+
- `@easymotion-smartsign`: Enable smartsign feature to match shifted symbols (default: 'false')
82+
83+
## Important Implementation Notes
84+
85+
- The Python script runs in a detached tmux window (`neww -d`) to avoid interfering with the user's session
86+
- Cursor position differs between normal mode and copy mode - check `pane.copy_mode` flag
87+
- The `__slots__` optimization on `PaneInfo` reduces memory overhead
88+
- Functions decorated with `@perf_timer()` only log timing when `TMUX_EASYMOTION_PERF` is enabled
89+
- The `@functools.lru_cache` on width calculation functions significantly improves performance with repeated characters

README.md

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,7 @@
11
# TMUX Easymotion
22

3+
[![Tests](https://github.com/ddzero2c/tmux-easymotion/actions/workflows/test.yml/badge.svg)](https://github.com/ddzero2c/tmux-easymotion/actions/workflows/test.yml)
4+
35
- Tmux prefix is `Ctrl+q`:
46
- Trigger key is `s`
57

@@ -68,6 +70,10 @@ bind-key -T copy-mode-vi V send-keys -X select-line;
6870
### Run tests
6971

7072
```bash
73+
# Install development dependencies
74+
pip install -r requirements-dev.txt
75+
76+
# Run tests
7177
pytest test_easymotion.py -v --cache-clear
7278
```
7379

requirements-dev.txt

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
pytest>=7.0.0

0 commit comments

Comments
 (0)