Skip to content

Commit 8eae8e7

Browse files
committed
Initial implementation of commit editor
Signed-off-by: Martin Prpič <martin.prpic@gmail.com>
1 parent f734570 commit 8eae8e7

File tree

15 files changed

+1288
-4
lines changed

15 files changed

+1288
-4
lines changed

.github/workflows/main.yml

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,16 @@
1+
name: main.yml
2+
on: [ push, pull_request ]
3+
4+
jobs:
5+
tox:
6+
name: Run Tox
7+
steps:
8+
- uses: actions/checkout@v2
9+
- name: Run all envs
10+
uses: fedora-python/tox-github-action@main
11+
with:
12+
tox_env: ${{ matrix.tox_env }}
13+
strategy:
14+
matrix:
15+
tox_env: [ py311, py312, py313, lint, check-format, typecheck ]
16+
runs-on: ubuntu-latest

.gitignore

Lines changed: 6 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -98,7 +98,7 @@ ipython_config.py
9898
# Similar to Pipfile.lock, it is generally recommended to include uv.lock in version control.
9999
# This is especially recommended for binary packages to ensure reproducibility, and is more
100100
# commonly ignored for libraries.
101-
#uv.lock
101+
uv.lock
102102

103103
# poetry
104104
# Similar to Pipfile.lock, it is generally recommended to include poetry.lock in version control.
@@ -182,9 +182,9 @@ cython_debug/
182182
.abstra/
183183

184184
# Visual Studio Code
185-
# Visual Studio Code specific template is maintained in a separate VisualStudioCode.gitignore
185+
# Visual Studio Code specific template is maintained in a separate VisualStudioCode.gitignore
186186
# that can be found at https://github.com/github/gitignore/blob/main/Global/VisualStudioCode.gitignore
187-
# and can be added to the global gitignore or merged into this file. However, if you prefer,
187+
# and can be added to the global gitignore or merged into this file. However, if you prefer,
188188
# you could uncomment the following to ignore the entire vscode folder
189189
# .vscode/
190190

@@ -205,3 +205,6 @@ cython_debug/
205205
marimo/_static/
206206
marimo/_lsp/
207207
__marimo__/
208+
209+
# AI assistants
210+
.claude/settings.local.json

CLAUDE.md

Lines changed: 113 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,113 @@
1+
# Development Guide
2+
3+
Read README.md to learn about this project.
4+
5+
This document describes how to work with the commit-editor project.
6+
7+
## Project Structure
8+
9+
```
10+
src/commit_editor/
11+
├── __init__.py # Package init with version
12+
├── cli.py # CLI entry point (argparse)
13+
├── app.py # Textual app, custom TextArea, StatusBar, MessageBar, wrap_line
14+
└── git.py # Git integration (user.name, user.email, Signed-off-by)
15+
16+
tests/
17+
├── conftest.py # Pytest fixtures (temp_file, temp_file_with_content)
18+
├── test_app.py # Integration tests using Textual's Pilot
19+
├── test_git.py # Unit tests for git module (mocked subprocess)
20+
└── test_wrap.py # Unit tests for text wrapping functions
21+
```
22+
23+
## Setup
24+
25+
Install dependencies:
26+
27+
```bash
28+
uv sync
29+
```
30+
31+
## Running the Tool
32+
33+
```bash
34+
# Run directly with uv
35+
uv run commit-editor path/to/file.txt
36+
37+
# Or after installing
38+
uv tool install -e .
39+
commit-editor path/to/file.txt
40+
```
41+
42+
## Running All Checks with Tox
43+
44+
The project uses tox to automate testing, linting, formatting, and type checking across multiple Python versions. Run
45+
all checks with:
46+
47+
```bash
48+
tox
49+
```
50+
51+
This runs:
52+
53+
- Tests on Python 3.11, 3.12, and 3.13
54+
- Linting with ruff
55+
- Format checking with ruff
56+
- Type checking with ty
57+
58+
### Running Specific Tox Environments
59+
60+
```bash
61+
# Run only tests on Python 3.13
62+
tox -e py313
63+
64+
# Run only linting
65+
tox -e lint
66+
67+
# Run only format check
68+
tox -e check-format
69+
70+
# Run only type checking
71+
tox -e typecheck
72+
73+
# Auto-fix linting issues
74+
tox -e lint-fix
75+
76+
# Auto-format code
77+
tox -e format
78+
```
79+
80+
## Running Tests Manually
81+
82+
```bash
83+
uv run pytest tests/
84+
85+
# With verbose output
86+
uv run pytest tests/ -v
87+
88+
# Run a specific test file
89+
uv run pytest tests/test_wrap.py -v
90+
91+
# Run a specific test
92+
uv run pytest tests/test_app.py::TestQuitBehavior::test_ctrl_q_clean_exits_immediately -v
93+
```
94+
95+
## Linting Manually
96+
97+
```bash
98+
# Check for linting issues
99+
uv run ruff check .
100+
101+
# Auto-fix linting issues
102+
uv run ruff check . --fix
103+
```
104+
105+
## Formatting Manually
106+
107+
```bash
108+
# Check formatting
109+
uv run ruff format --check .
110+
111+
# Apply formatting
112+
uv run ruff format .
113+
```

README.md

Lines changed: 70 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1 +1,70 @@
1-
# commit-editor
1+
# Commit Editor
2+
3+
[![PyPI](https://img.shields.io/pypi/v/commit-editor.svg)](https://pypi.python.org/pypi/commit-editor)
4+
[![Python](https://img.shields.io/pypi/pyversions/commit-editor.svg)](https://pypi.python.org/pypi/commit-editor)
5+
[![License](https://img.shields.io/pypi/l/commit-editor.svg)](https://github.com/mprpic/commit-editor/blob/main/LICENSE)
6+
[![CI](https://github.com/mprpic/commit-editor/workflows/CI/badge.svg)](https://github.com/mprpic/commit-editor/actions)
7+
8+
An opinionated, terminal-based text editor for git commit messages, built
9+
with [Textual](https://textual.textualize.io/).
10+
11+
- **Title length warning**: Characters beyond position 50 on the first line are highlighted in red
12+
- **Auto-wrap body text**: Lines in the commit body (line 3+) are automatically wrapped at 72 characters (except for
13+
long strings that can't be wrapped, such as URLs)
14+
- **White space**: Trailing white space is automatically stripped when a file is saved; an empty newline is inserted
15+
at the end of the file if not present.
16+
- **Signed-off-by toggle**: Quickly add or remove a `Signed-off-by` trailer with a keyboard shortcut
17+
- **Status bar**: Shows current cursor position (line/column) and title length with warnings
18+
19+
## Installation
20+
21+
```bash
22+
# Using uv
23+
uv tool install commit-editor
24+
25+
# Using pip
26+
pip install commit-editor
27+
```
28+
29+
### Requirements
30+
31+
- Python 3.11 or later
32+
- Git (for Signed-off-by functionality)
33+
34+
## Usage
35+
36+
Configure `commit-editor` as your default git commit message editor:
37+
38+
```bash
39+
git config --global core.editor commit-editor
40+
```
41+
42+
When you run `git commit`, the editor will open automatically.
43+
44+
`commit-editor` can also be used as a standalone tool with:
45+
46+
```bash
47+
commit-editor path/to/file.txt
48+
```
49+
50+
## Keyboard Shortcuts
51+
52+
| Shortcut | Action |
53+
|----------|------------------------------|
54+
| `Ctrl+S` | Save the file |
55+
| `Ctrl+Q` | Quit |
56+
| `Ctrl+O` | Toggle Signed-off-by trailer |
57+
58+
## Commit Message Format
59+
60+
This editor enforces the widely-accepted git commit message conventions:
61+
62+
1. **Title (line 1)**: Should be 50 characters or less; characters beyond 50 are highlighted in red as a warning.
63+
64+
2. **Blank line (line 2)**: Separates the title from the body.
65+
66+
3. **Body (line 3+)**: Should wrap at 72 characters; long lines are wrapped automatically as you type.
67+
68+
## License
69+
70+
MIT

pyproject.toml

Lines changed: 51 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,51 @@
1+
[build-system]
2+
requires = ["uv_build>=0.9.28,<0.10.0"]
3+
build-backend = "uv_build"
4+
5+
[project]
6+
name = "commit-editor"
7+
version = "0.1.0"
8+
description = "A terminal-based git commit message editor with opinionated formatting"
9+
readme = "README.md"
10+
license = "MIT"
11+
requires-python = ">=3.11"
12+
authors = [
13+
{ name = "Martin Prpič", email = "martin.prpic@gmail.com" }
14+
]
15+
classifiers = [
16+
"Development Status :: 3 - Alpha",
17+
"Environment :: Console",
18+
"Intended Audience :: Developers",
19+
"License :: OSI Approved :: MIT License",
20+
"Operating System :: OS Independent",
21+
"Programming Language :: Python :: 3",
22+
"Programming Language :: Python :: 3.11",
23+
"Programming Language :: Python :: 3.12",
24+
"Programming Language :: Python :: 3.13",
25+
"Topic :: Software Development :: Version Control :: Git",
26+
"Topic :: Text Editors",
27+
]
28+
dependencies = [
29+
"textual>=0.50.0",
30+
]
31+
32+
[project.scripts]
33+
commit-editor = "commit_editor.cli:main"
34+
35+
36+
[project.optional-dependencies]
37+
dev = [
38+
"pytest",
39+
"pytest-asyncio",
40+
"ruff",
41+
]
42+
43+
[tool.ruff]
44+
line-length = 100
45+
46+
[tool.ruff.lint]
47+
select = ["F", "E", "W", "I", "N"]
48+
49+
[tool.pytest.ini_options]
50+
asyncio_mode = "auto"
51+
asyncio_default_fixture_loop_scope = "function"

src/commit_editor/__init__.py

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,3 @@
1+
"""A terminal-based git commit message editor with opinionated formatting."""
2+
3+
__version__ = "0.1.0"

0 commit comments

Comments
 (0)