Skip to content

Commit fdb401f

Browse files
committed
chore: add ci
1 parent 63e3cd1 commit fdb401f

File tree

3 files changed

+129
-0
lines changed

3 files changed

+129
-0
lines changed

.github/workflows/test.yml

Lines changed: 42 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,42 @@
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+
30+
- name: Install dependencies
31+
run: |
32+
python -m pip install --upgrade pip
33+
pip install pytest
34+
35+
- name: Run tests
36+
run: |
37+
pytest test_easymotion.py -v --cache-clear
38+
39+
- name: Test summary
40+
if: always()
41+
run: |
42+
echo "Tests completed for Python ${{ matrix.python-version }} on ${{ matrix.os }}"

CLAUDE.md

Lines changed: 85 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,85 @@
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+
pytest test_easymotion.py -v --cache-clear
45+
```
46+
47+
### Testing in tmux
48+
After making changes, reload the plugin in tmux:
49+
```bash
50+
# In tmux, press prefix + I to reload TPM plugins
51+
# Or source the config manually:
52+
tmux source-file ~/.tmux.conf
53+
```
54+
55+
### Debugging
56+
Enable debug logging by setting in ~/.tmux.conf:
57+
```bash
58+
set -g @easymotion-debug 'true'
59+
```
60+
Logs are written to ~/easymotion.log
61+
62+
Enable performance logging:
63+
```bash
64+
set -g @easymotion-perf 'true'
65+
```
66+
67+
## Configuration Options (tmux.conf)
68+
69+
All options are read from tmux options in easymotion.tmux and passed as environment variables to the Python script:
70+
71+
- `@easymotion-key`: Trigger key binding (default: 's')
72+
- `@easymotion-hints`: Characters used for hints (default: 'asdghklqwertyuiopzxcvbnmfj;')
73+
- `@easymotion-vertical-border`: Character for vertical borders (default: '│')
74+
- `@easymotion-horizontal-border`: Character for horizontal borders (default: '─')
75+
- `@easymotion-use-curses`: Use curses instead of ANSI sequences (default: 'false')
76+
- `@easymotion-case-sensitive`: Case-sensitive search (default: 'false')
77+
- `@easymotion-smartsign`: Enable smartsign feature to match shifted symbols (default: 'false')
78+
79+
## Important Implementation Notes
80+
81+
- The Python script runs in a detached tmux window (`neww -d`) to avoid interfering with the user's session
82+
- Cursor position differs between normal mode and copy mode - check `pane.copy_mode` flag
83+
- The `__slots__` optimization on `PaneInfo` reduces memory overhead
84+
- Functions decorated with `@perf_timer()` only log timing when `TMUX_EASYMOTION_PERF` is enabled
85+
- The `@functools.lru_cache` on width calculation functions significantly improves performance with repeated characters

README.md

Lines changed: 2 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

0 commit comments

Comments
 (0)