keymap-align 0.2.0__tar.gz → 0.2.1__tar.gz
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- {keymap_align-0.2.0 → keymap_align-0.2.1}/.github/actionlint.yaml +3 -3
- {keymap_align-0.2.0 → keymap_align-0.2.1}/.github/workflows/validate.yml +48 -12
- keymap_align-0.2.1/.markdownlintignore +4 -0
- {keymap_align-0.2.0 → keymap_align-0.2.1}/.pre-commit-config.yaml +33 -10
- {keymap_align-0.2.0 → keymap_align-0.2.1}/CLAUDE.md +4 -4
- {keymap_align-0.2.0 → keymap_align-0.2.1}/PKG-INFO +1 -1
- {keymap_align-0.2.0 → keymap_align-0.2.1}/pyproject.toml +13 -14
- {keymap_align-0.2.0 → keymap_align-0.2.1}/src/keymap_align/align.py +2 -2
- {keymap_align-0.2.0 → keymap_align-0.2.1}/src/keymap_align/cli.py +25 -2
- {keymap_align-0.2.0 → keymap_align-0.2.1}/uv.lock +20 -20
- keymap_align-0.2.0/.markdownlintignore +0 -4
- {keymap_align-0.2.0 → keymap_align-0.2.1}/.editorconfig +0 -0
- {keymap_align-0.2.0 → keymap_align-0.2.1}/.github/workflows/release.yml +0 -0
- {keymap_align-0.2.0 → keymap_align-0.2.1}/.gitignore +0 -0
- {keymap_align-0.2.0 → keymap_align-0.2.1}/.markdownlint.yaml +0 -0
- {keymap_align-0.2.0 → keymap_align-0.2.1}/.python-version +0 -0
- {keymap_align-0.2.0 → keymap_align-0.2.1}/.shellcheckrc +0 -0
- {keymap_align-0.2.0 → keymap_align-0.2.1}/LICENSE +0 -0
- {keymap_align-0.2.0 → keymap_align-0.2.1}/README.md +0 -0
- {keymap_align-0.2.0 → keymap_align-0.2.1}/src/keymap_align/__init__.py +0 -0
- {keymap_align-0.2.0 → keymap_align-0.2.1}/src/keymap_align/config.py +0 -0
- {keymap_align-0.2.0 → keymap_align-0.2.1}/src/keymap_align/layout_resolver.py +0 -0
- {keymap_align-0.2.0 → keymap_align-0.2.1}/src/keymap_align/layouts/__init__.py +0 -0
- {keymap_align-0.2.0 → keymap_align-0.2.1}/src/keymap_align/layouts/corne42.json +0 -0
- {keymap_align-0.2.0 → keymap_align-0.2.1}/src/keymap_align/layouts/glove80.json +0 -0
- {keymap_align-0.2.0 → keymap_align-0.2.1}/src/keymap_align/layouts/piantor.json +0 -0
- {keymap_align-0.2.0 → keymap_align-0.2.1}/tests/layouts/corne_6key_simple_layout.json +0 -0
- {keymap_align-0.2.0 → keymap_align-0.2.1}/tests/layouts/glove80_80key_layout.json +0 -0
- {keymap_align-0.2.0 → keymap_align-0.2.1}/tests/simple_tests/corne_6key_simple_test.keymap +0 -0
- {keymap_align-0.2.0 → keymap_align-0.2.1}/tests/test_align_keymap.py +0 -0
- {keymap_align-0.2.0 → keymap_align-0.2.1}/tests/test_config.py +0 -0
- {keymap_align-0.2.0 → keymap_align-0.2.1}/tests/test_display_name_preservation.py +0 -0
- {keymap_align-0.2.0 → keymap_align-0.2.1}/tests/test_keymaps/correct/corne_6key_reference_comments_and_properties.keymap +0 -0
- {keymap_align-0.2.0 → keymap_align-0.2.1}/tests/test_keymaps/correct/glove80_reference_properly_aligned.keymap +0 -0
- {keymap_align-0.2.0 → keymap_align-0.2.1}/tests/test_keymaps/correct/glove80_reference_reverse_key_order.keymap +0 -0
- {keymap_align-0.2.0 → keymap_align-0.2.1}/tests/test_keymaps/misaligned/corne_6key_input_comments_and_properties.keymap +0 -0
- {keymap_align-0.2.0 → keymap_align-0.2.1}/tests/test_keymaps/misaligned/glove80_input_badly_aligned.keymap +0 -0
- {keymap_align-0.2.0 → keymap_align-0.2.1}/tests/test_keymaps/misaligned/glove80_input_cramped_no_spacing.keymap +0 -0
- {keymap_align-0.2.0 → keymap_align-0.2.1}/tests/test_keymaps/misaligned/glove80_input_excess_bindings.keymap +0 -0
- {keymap_align-0.2.0 → keymap_align-0.2.1}/tests/test_keymaps/misaligned/glove80_input_insufficient_bindings.keymap +0 -0
- {keymap_align-0.2.0 → keymap_align-0.2.1}/tests/test_layouts.py +0 -0
- {keymap_align-0.2.0 → keymap_align-0.2.1}/tests/test_update.py +0 -0
|
@@ -1,8 +1,8 @@
|
|
|
1
|
-
# forge-toolchain:
|
|
2
|
-
# Labels
|
|
1
|
+
# forge-toolchain: 56
|
|
2
|
+
# Labels jactionlint cannot discover. Its list of GitHub's hosted images is the
|
|
3
3
|
# one its release shipped with, and a self-hosted runner's labels are on no
|
|
4
4
|
# list. Without this every runs-on naming one is reported as a typo and the
|
|
5
|
-
#
|
|
5
|
+
# jactionlint hook fails.
|
|
6
6
|
self-hosted-runner:
|
|
7
7
|
labels:
|
|
8
8
|
- ubuntu-26.04
|
|
@@ -1,15 +1,18 @@
|
|
|
1
|
-
# forge-toolchain:
|
|
1
|
+
# forge-toolchain: 56
|
|
2
2
|
name: CI
|
|
3
3
|
|
|
4
4
|
on:
|
|
5
|
-
push:
|
|
6
|
-
branches: [main]
|
|
7
5
|
pull_request:
|
|
8
6
|
workflow_call:
|
|
9
7
|
|
|
10
8
|
permissions:
|
|
11
9
|
contents: read
|
|
12
10
|
|
|
11
|
+
# uv runs on this Python rather than whatever the runner happens to
|
|
12
|
+
# have. It is the highest requires-python floor among the components.
|
|
13
|
+
env:
|
|
14
|
+
UV_PYTHON: "3.13"
|
|
15
|
+
|
|
13
16
|
jobs:
|
|
14
17
|
|
|
15
18
|
python:
|
|
@@ -56,8 +59,8 @@ jobs:
|
|
|
56
59
|
- uses: actions/checkout@v7
|
|
57
60
|
|
|
58
61
|
# generated:hooks
|
|
59
|
-
# Every hook
|
|
60
|
-
#
|
|
62
|
+
# Every hook in the repo's committed pre-commit config. A push from a
|
|
63
|
+
# checkout that never ran `pre-commit
|
|
61
64
|
# install`, or a merge in the web UI, passes every hook by not running it,
|
|
62
65
|
# and this is the gate that catches both. CI runs the hooks themselves
|
|
63
66
|
# rather than copies of their checks, because a copy is a second spelling
|
|
@@ -66,6 +69,14 @@ jobs:
|
|
|
66
69
|
with:
|
|
67
70
|
version: "0.12.24"
|
|
68
71
|
|
|
72
|
+
# pre-commit takes a `language: node` hook's Node from PATH where node and
|
|
73
|
+
# npm are there, and otherwise downloads the newest release. That release
|
|
74
|
+
# can need libraries a runner image lacks, as Node 25 needs libatomic. So
|
|
75
|
+
# the job puts the declared Node on PATH, on every runner alike.
|
|
76
|
+
- uses: actions/setup-node@v7
|
|
77
|
+
with:
|
|
78
|
+
node-version: "24"
|
|
79
|
+
|
|
69
80
|
# A self-hosted runner keeps ~/.cache/pre-commit between jobs, so there
|
|
70
81
|
# the archive is a download of what is already on disk.
|
|
71
82
|
- uses: actions/cache@v6
|
|
@@ -92,8 +103,8 @@ jobs:
|
|
|
92
103
|
# name that path literally, and `load` resolves nothing, so BATS_LIB_PATH
|
|
93
104
|
# cannot move the libraries anywhere cheaper.
|
|
94
105
|
#
|
|
95
|
-
# On
|
|
96
|
-
#
|
|
106
|
+
# On a self-hosted runner, $HOME can outlive the job and be shared by
|
|
107
|
+
# several repos' runners, so concurrent jobs meet at ~/.local/lib. Each
|
|
97
108
|
# release is cloned once, into a directory named for its version, and
|
|
98
109
|
# nothing that has been loaded from is ever removed. The clone is staged
|
|
99
110
|
# beside its target and renamed into place, so a reader never sees a
|
|
@@ -106,19 +117,26 @@ jobs:
|
|
|
106
117
|
# The hook runs tests/*.bats, flat. Recursing would sweep an integration
|
|
107
118
|
# tier in beside the unit one, and only the repo knows which of its tiers
|
|
108
119
|
# is runner-safe. A nested layout is named in a notice rather than passed
|
|
109
|
-
# over in silence
|
|
120
|
+
# over in silence.
|
|
110
121
|
#
|
|
111
122
|
# jq is installed ahead of the runner's own, because the scripts under
|
|
112
123
|
# test evaluate jq programs and jq's grammar moves between releases. 1.8
|
|
113
124
|
# accepts an object value piped into `//` without parentheses, and 1.7
|
|
114
|
-
# rejects the whole program. The version is
|
|
115
|
-
#
|
|
125
|
+
# rejects the whole program. The version is pinned to the jq developers
|
|
126
|
+
# run locally, so a program parses here exactly when it parses there.
|
|
127
|
+
#
|
|
128
|
+
# yq and rg are installed for the same scripts, which read YAML and
|
|
129
|
+
# search with them. A self-hosted runner image ships neither, so every
|
|
130
|
+
# test reaching one exits 127. Each is pinned to the release developers
|
|
131
|
+
# run, as jq is.
|
|
116
132
|
- name: Set up bats
|
|
117
133
|
run: |
|
|
118
134
|
bats_version="1.14.0"
|
|
119
135
|
bats_support_version="0.3.0"
|
|
120
136
|
bats_assert_version="2.2.4"
|
|
121
137
|
jq_version="1.8.2"
|
|
138
|
+
yq_version="4.54.1"
|
|
139
|
+
rg_version="15.2.0"
|
|
122
140
|
|
|
123
141
|
if ! compgen -G "tests/*.bats" > /dev/null; then
|
|
124
142
|
if [ -n "$(find tests -name '*.bats' -print -quit 2>/dev/null)" ]; then
|
|
@@ -154,6 +172,20 @@ jobs:
|
|
|
154
172
|
echo "$RUNNER_TEMP/jq" >> "$GITHUB_PATH"
|
|
155
173
|
"$RUNNER_TEMP/jq/jq" --version
|
|
156
174
|
|
|
175
|
+
mkdir -p "$RUNNER_TEMP/yq"
|
|
176
|
+
curl -fsSL --retry 3 -o "$RUNNER_TEMP/yq/yq" \
|
|
177
|
+
"https://github.com/mikefarah/yq/releases/download/v${yq_version}/yq_linux_amd64"
|
|
178
|
+
chmod +x "$RUNNER_TEMP/yq/yq"
|
|
179
|
+
echo "$RUNNER_TEMP/yq" >> "$GITHUB_PATH"
|
|
180
|
+
"$RUNNER_TEMP/yq/yq" --version
|
|
181
|
+
|
|
182
|
+
rg_release="ripgrep-${rg_version}-x86_64-unknown-linux-musl"
|
|
183
|
+
mkdir -p "$RUNNER_TEMP/rg"
|
|
184
|
+
curl -fsSL --retry 3 "https://github.com/BurntSushi/ripgrep/releases/download/${rg_version}/${rg_release}.tar.gz" |
|
|
185
|
+
tar -xzf - -C "$RUNNER_TEMP/rg" --strip-components=1 "${rg_release}/rg"
|
|
186
|
+
echo "$RUNNER_TEMP/rg" >> "$GITHUB_PATH"
|
|
187
|
+
"$RUNNER_TEMP/rg/rg" --version
|
|
188
|
+
|
|
157
189
|
# Over what the push or pull request changed, which is what the hooks
|
|
158
190
|
# would have seen at commit time. --all-files would fail a push on every
|
|
159
191
|
# finding in a file it never touched, so it is the scope only where no
|
|
@@ -238,12 +270,16 @@ jobs:
|
|
|
238
270
|
ruff-format
|
|
239
271
|
ruff-check
|
|
240
272
|
mypy
|
|
241
|
-
|
|
273
|
+
jactionlint
|
|
242
274
|
)
|
|
243
275
|
# Every hook runs whatever the one before it found, so one push
|
|
244
276
|
# reports every failing hook rather than the first.
|
|
277
|
+
#
|
|
278
|
+
# pre-commit builds each `language: python` hook on the interpreter
|
|
279
|
+
# running it. Left to uv, that is whatever Python the runner ships,
|
|
280
|
+
# so pre-commit runs on the declared floor instead.
|
|
245
281
|
status=0
|
|
246
282
|
for hook in "${hooks[@]}"; do
|
|
247
|
-
uvx pre-commit run "$hook" "${scope[@]}" --show-diff-on-failure || status=1
|
|
283
|
+
uvx --python 3.13 pre-commit run "$hook" "${scope[@]}" --show-diff-on-failure || status=1
|
|
248
284
|
done
|
|
249
285
|
exit "$status"
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
# forge-toolchain:
|
|
1
|
+
# forge-toolchain: 56
|
|
2
2
|
fail_fast: true
|
|
3
3
|
default_stages: [pre-commit]
|
|
4
4
|
repos:
|
|
@@ -62,8 +62,12 @@ repos:
|
|
|
62
62
|
# worse than either erroring. identify already tags these files zsh,
|
|
63
63
|
# so this is the native exclusion rather than a path regex that would have to
|
|
64
64
|
# enumerate .zshrc, .zprofile, .zlogin and the rest.
|
|
65
|
-
|
|
66
|
-
|
|
65
|
+
#
|
|
66
|
+
# shellcheck-py installs shellcheck's own release binary through pip and
|
|
67
|
+
# checks its sha256, so the hook needs no Docker daemon and no system
|
|
68
|
+
# package. Its tag is the shellcheck release it wraps, plus a packaging digit.
|
|
69
|
+
- repo: https://github.com/shellcheck-py/shellcheck-py
|
|
70
|
+
rev: v0.10.0.1
|
|
67
71
|
hooks:
|
|
68
72
|
- id: shellcheck
|
|
69
73
|
exclude_types: [zsh]
|
|
@@ -94,11 +98,19 @@ repos:
|
|
|
94
98
|
# from a linked worktree exports GIT_DIR and GIT_INDEX_FILE into each hook,
|
|
95
99
|
# and GIT_DIR outranks `git -C`, so a test running `git config` in its own
|
|
96
100
|
# scratch repo writes into the repository being committed instead.
|
|
101
|
+
#
|
|
102
|
+
# The suite runs one job per online core. Most of a bats test's cost is the
|
|
103
|
+
# framework re-sourcing its file and loading the helper libraries for every
|
|
104
|
+
# test, which no change to the tests removes, so wall time falls roughly by
|
|
105
|
+
# the core count. --jobs needs GNU parallel, and where it is not on PATH the
|
|
106
|
+
# suite runs serially rather than failing. getconf rather than nproc, which
|
|
107
|
+
# macOS lacks. A suite that cannot share a file across jobs sets
|
|
108
|
+
# BATS_NO_PARALLELIZE_WITHIN_FILE=true in its setup_file.
|
|
97
109
|
- repo: local
|
|
98
110
|
hooks:
|
|
99
111
|
- id: bats
|
|
100
112
|
name: bats
|
|
101
|
-
entry: bash -c 'unset $(git rev-parse --local-env-vars); compgen -G "tests/*.bats" > /dev/null || exit 0; exec bats tests/'
|
|
113
|
+
entry: bash -c 'unset $(git rev-parse --local-env-vars); compgen -G "tests/*.bats" > /dev/null || exit 0; command -v parallel > /dev/null || exec bats tests/; exec bats --jobs "$(getconf _NPROCESSORS_ONLN)" tests/'
|
|
102
114
|
language: system
|
|
103
115
|
pass_filenames: false
|
|
104
116
|
|
|
@@ -157,7 +169,12 @@ repos:
|
|
|
157
169
|
# nobody may respell — which is why the class is excluded rather than any
|
|
158
170
|
# one repo's data. `.tsv` is named beside `.csv` as the same format with
|
|
159
171
|
# a different delimiter.
|
|
160
|
-
|
|
172
|
+
#
|
|
173
|
+
# `gotk-components.yaml` is `flux install --export`, under the name
|
|
174
|
+
# `flux bootstrap` gives it. Its CRD descriptions are Flux's prose, and
|
|
175
|
+
# the file says DO NOT EDIT, so a hit there is fixed by no edit: the next
|
|
176
|
+
# export writes it back, as `go mod tidy` writes back a module path.
|
|
177
|
+
exclude: '(^|/)(.*-lock\.json|.*\.lock|uv\.lock|package-lock\.json|go\.sum|go\.mod|gotk-components\.yaml|secrets?[^/]*\.(ya?ml|env|json)|.*\.enc\.[^/]+|.*\.[ct]sv)$'
|
|
161
178
|
|
|
162
179
|
# generated:refcheck - Reference checking
|
|
163
180
|
#
|
|
@@ -192,14 +209,20 @@ repos:
|
|
|
192
209
|
- id: uv-lock
|
|
193
210
|
|
|
194
211
|
# Python: formatting
|
|
212
|
+
#
|
|
213
|
+
# types_or leaves out markdown, which ruff-pre-commit's ruff-format selects.
|
|
214
|
+
# ruff formats a Python fence in Markdown as source, and a fence here is often
|
|
215
|
+
# a figure: aligned comments and right-aligned paths, which the reflow
|
|
216
|
+
# destroys.
|
|
195
217
|
- repo: https://github.com/astral-sh/ruff-pre-commit
|
|
196
|
-
rev: v0.
|
|
218
|
+
rev: v0.17.1
|
|
197
219
|
hooks:
|
|
198
220
|
- id: ruff-format
|
|
221
|
+
types_or: [python, pyi, jupyter]
|
|
199
222
|
|
|
200
223
|
# generated:python-lint - Python: linting
|
|
201
224
|
- repo: https://github.com/astral-sh/ruff-pre-commit
|
|
202
|
-
rev: v0.
|
|
225
|
+
rev: v0.17.1
|
|
203
226
|
hooks:
|
|
204
227
|
- id: ruff-check
|
|
205
228
|
args: [--fix]
|
|
@@ -230,8 +253,8 @@ repos:
|
|
|
230
253
|
pass_filenames: false
|
|
231
254
|
|
|
232
255
|
# generated:github-actions - GitHub Actions
|
|
233
|
-
- repo: https://github.com/
|
|
234
|
-
rev: v1.
|
|
256
|
+
- repo: https://github.com/jdx/jactionlint
|
|
257
|
+
rev: v1.8.2
|
|
235
258
|
hooks:
|
|
236
|
-
- id:
|
|
259
|
+
- id: jactionlint
|
|
237
260
|
args: ["-color", "-shellcheck="]
|
|
@@ -19,15 +19,15 @@ holds each of those beside the layers.
|
|
|
19
19
|
|
|
20
20
|
Before anything is written, each array's whitespace-separated tokens are compared with those of
|
|
21
21
|
its realigned rows. A token the rows would not reproduce is an error, and the run writes nothing.
|
|
22
|
-
That catches a comment inside an array, an undefined macro name before the first `&`, and a
|
|
23
|
-
multi-parameter behavior's count. The run also refuses, and writes nothing, when:
|
|
22
|
+
That catches a comment inside an array, an undefined macro name before the first `&`, and a
|
|
23
|
+
parameter past a multi-parameter behavior's count. The run also refuses, and writes nothing, when:
|
|
24
24
|
|
|
25
25
|
- a layer holds more bindings than the layout has keys;
|
|
26
26
|
- two layer nodes share a name, because the layers are keyed by name;
|
|
27
27
|
- a `bindings` property holds more than one `< >` array.
|
|
28
28
|
|
|
29
|
-
A layer with too few bindings gets a blank cell for each one missing. `--debug` prints
|
|
30
|
-
and then runs the same checks, so it exits 1 wherever a real run would.
|
|
29
|
+
A layer with too few bindings gets a blank cell for each one missing. `--debug` prints the layout
|
|
30
|
+
and each layer's grid, then runs the same checks, so it exits 1 wherever a real run would.
|
|
31
31
|
|
|
32
32
|
## A binding ends where the next one starts, so a behavior-valued parameter must be declared
|
|
33
33
|
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.5
|
|
2
2
|
Name: keymap-align
|
|
3
|
-
Version: 0.2.
|
|
3
|
+
Version: 0.2.1
|
|
4
4
|
Summary: ZMK keymap alignment tool for custom mechanical keyboards
|
|
5
5
|
Project-URL: Repository, https://github.com/datapointchris/keymap-align
|
|
6
6
|
Author-email: Chris Birch <datapointchris@gmail.com>
|
|
@@ -29,7 +29,7 @@ keymap-align = "keymap_align.cli:app"
|
|
|
29
29
|
dev = [
|
|
30
30
|
"bandit>=1.7.8",
|
|
31
31
|
"mypy>=1.10.0",
|
|
32
|
-
"ruff==0.
|
|
32
|
+
"ruff==0.17.1",
|
|
33
33
|
"pre-commit>=4.3.0",
|
|
34
34
|
]
|
|
35
35
|
test = [
|
|
@@ -77,6 +77,7 @@ exclude = [
|
|
|
77
77
|
"build",
|
|
78
78
|
"dist",
|
|
79
79
|
]
|
|
80
|
+
extend-exclude = ["*.md"]
|
|
80
81
|
|
|
81
82
|
[tool.ruff.format]
|
|
82
83
|
quote-style = "single"
|
|
@@ -131,12 +132,23 @@ dataclasses = "dc"
|
|
|
131
132
|
typeCheckingMode = "standard"
|
|
132
133
|
analyzeUnannotatedFunctions = true # or pylance stops analyzing in vscode
|
|
133
134
|
|
|
135
|
+
[tool.hatch.version]
|
|
136
|
+
source = "uv-dynamic-versioning"
|
|
137
|
+
|
|
138
|
+
[tool.uv-dynamic-versioning]
|
|
139
|
+
style = "semver"
|
|
140
|
+
|
|
141
|
+
# A new commit or tag changes the version, so it has to invalidate uv's cache.
|
|
142
|
+
[tool.uv]
|
|
143
|
+
cache-keys = [{ file = "pyproject.toml" }, { git = { commit = true, tags = true } }]
|
|
144
|
+
|
|
134
145
|
[tool.forge]
|
|
135
146
|
# Keys the shared toolchain standard owns, written by its generator.
|
|
136
147
|
# Dropping one from the template removes it here on the next sync; a key absent
|
|
137
148
|
# from this list belongs to the project and is never touched. Do not hand-edit.
|
|
138
149
|
managed = [
|
|
139
150
|
["ruff", "line-length"],
|
|
151
|
+
["ruff", "extend-exclude"],
|
|
140
152
|
["ruff", "format", "quote-style"],
|
|
141
153
|
["ruff", "format", "indent-style"],
|
|
142
154
|
["ruff", "format", "skip-magic-trailing-comma"],
|
|
@@ -170,19 +182,6 @@ managed = [
|
|
|
170
182
|
# and extra that names them, so a local run and CI cannot disagree.
|
|
171
183
|
pinned = ["ruff"]
|
|
172
184
|
|
|
173
|
-
# The release tag is the version. python-semantic-release finds no file to
|
|
174
|
-
# stamp, so it tags the merge commit itself and writes no release commit.
|
|
175
|
-
# uv_build cannot do this: its metadata has no dynamic version field.
|
|
176
|
-
[tool.hatch.version]
|
|
177
|
-
source = "uv-dynamic-versioning"
|
|
178
|
-
|
|
179
|
-
[tool.uv-dynamic-versioning]
|
|
180
|
-
style = "semver"
|
|
181
|
-
|
|
182
|
-
# A new commit or tag changes the version, so it has to invalidate uv's cache.
|
|
183
|
-
[tool.uv]
|
|
184
|
-
cache-keys = [{ file = "pyproject.toml" }, { git = { commit = true, tags = true } }]
|
|
185
|
-
|
|
186
185
|
[build-system]
|
|
187
186
|
requires = ["hatchling", "uv-dynamic-versioning"]
|
|
188
187
|
build-backend = "hatchling.build"
|
|
@@ -151,7 +151,6 @@ def handle_multi_param_behavior(tokens, i, binding_parts, binding_macros):
|
|
|
151
151
|
|
|
152
152
|
def handle_standard_behavior(tokens, i, binding_parts, binding_macros):
|
|
153
153
|
"""Handle standard behaviors with simple parameters."""
|
|
154
|
-
# Collect parameters until the next binding starts or the tokens run out
|
|
155
154
|
while i < len(tokens) and not tokens[i].startswith('&') and tokens[i] not in binding_macros:
|
|
156
155
|
binding_parts.append(tokens[i])
|
|
157
156
|
i += 1
|
|
@@ -614,7 +613,8 @@ def align_keymap_with_layout(
|
|
|
614
613
|
"""Align keymap bindings according to keyboard layout.
|
|
615
614
|
|
|
616
615
|
Only the inside of each layer's `bindings` array is rewritten. A keymap that cannot be
|
|
617
|
-
rewritten without losing text
|
|
616
|
+
rewritten without losing text gets each problem printed to stderr, nothing written, and a
|
|
617
|
+
return of False.
|
|
618
618
|
|
|
619
619
|
Args:
|
|
620
620
|
keymap_file: Path to the keymap file
|
|
@@ -54,6 +54,28 @@ Examples:
|
|
|
54
54
|
[b]keymap-align format -k corne.keymap -o aligned.keymap[/b] — write elsewhere, leave the original
|
|
55
55
|
"""
|
|
56
56
|
|
|
57
|
+
LAYOUTS_EPILOG = """
|
|
58
|
+
Examples:
|
|
59
|
+
|
|
60
|
+
[b]keymap-align layouts list[/b] — the boards --layout accepts
|
|
61
|
+
"""
|
|
62
|
+
|
|
63
|
+
LAYOUTS_LIST_EPILOG = """
|
|
64
|
+
Examples:
|
|
65
|
+
|
|
66
|
+
[b]keymap-align layouts list[/b] — every name --layout accepts, one per line
|
|
67
|
+
|
|
68
|
+
[b]keymap-align layouts list | grep -x corne42[/b] — whether a board ships with the tool, exit 0 if it does
|
|
69
|
+
"""
|
|
70
|
+
|
|
71
|
+
UPDATE_EPILOG = """
|
|
72
|
+
Examples:
|
|
73
|
+
|
|
74
|
+
[b]keymap-align update --check[/b] — whether a newer release exists, without installing it
|
|
75
|
+
|
|
76
|
+
[b]keymap-align update[/b] — install the latest release
|
|
77
|
+
"""
|
|
78
|
+
|
|
57
79
|
# One config for `update` and the notice, so the notice never names a release `update` would not install.
|
|
58
80
|
UPDATE_CONFIG = Config(tool='keymap-align', owner='datapointchris')
|
|
59
81
|
|
|
@@ -69,6 +91,7 @@ layouts_app = typer.Typer(
|
|
|
69
91
|
name='layouts',
|
|
70
92
|
no_args_is_help=True,
|
|
71
93
|
help='The keyboard layouts that ship with the tool, each one a name `format --layout` accepts.',
|
|
94
|
+
epilog=LAYOUTS_EPILOG,
|
|
72
95
|
)
|
|
73
96
|
app.add_typer(layouts_app, name='layouts')
|
|
74
97
|
|
|
@@ -149,14 +172,14 @@ def format_keymap(
|
|
|
149
172
|
raise typer.Exit(0 if success else 1)
|
|
150
173
|
|
|
151
174
|
|
|
152
|
-
@layouts_app.command('list')
|
|
175
|
+
@layouts_app.command('list', epilog=LAYOUTS_LIST_EPILOG)
|
|
153
176
|
def list_layouts() -> None:
|
|
154
177
|
"""Print the name of every bundled layout, one per line."""
|
|
155
178
|
for name in get_bundled_layout_names():
|
|
156
179
|
print(name)
|
|
157
180
|
|
|
158
181
|
|
|
159
|
-
@app.command(rich_help_panel='Manage')
|
|
182
|
+
@app.command(rich_help_panel='Manage', epilog=UPDATE_EPILOG)
|
|
160
183
|
def update(
|
|
161
184
|
check_only: Annotated[bool, typer.Option('--check', help='Report whether an update is available without installing it.')] = False,
|
|
162
185
|
) -> None:
|
|
@@ -110,7 +110,7 @@ dev = [
|
|
|
110
110
|
{ name = "bandit", specifier = ">=1.7.8" },
|
|
111
111
|
{ name = "mypy", specifier = ">=1.10.0" },
|
|
112
112
|
{ name = "pre-commit", specifier = ">=4.3.0" },
|
|
113
|
-
{ name = "ruff", specifier = "==0.
|
|
113
|
+
{ name = "ruff", specifier = "==0.17.1" },
|
|
114
114
|
]
|
|
115
115
|
test = [{ name = "pytest", specifier = ">=8.4.1" }]
|
|
116
116
|
|
|
@@ -363,27 +363,27 @@ wheels = [
|
|
|
363
363
|
|
|
364
364
|
[[package]]
|
|
365
365
|
name = "ruff"
|
|
366
|
-
version = "0.
|
|
366
|
+
version = "0.17.1"
|
|
367
367
|
source = { registry = "https://pypi.org/simple" }
|
|
368
|
-
sdist = { url = "https://files.pythonhosted.org/packages/
|
|
368
|
+
sdist = { url = "https://files.pythonhosted.org/packages/f9/e7/e6d5749983b020e6cb1055abec0a6f361a8e94f0184cdcf56d4760995f02/ruff-0.17.1.tar.gz", hash = "sha256:5bb796c5112e9fb9527f2ef2faa0a130d6312d19de92bcfaddd70dbb2d41020f", size = 5323349, upload-time = "2026-10-15T15:23:18.64Z" }
|
|
369
369
|
wheels = [
|
|
370
|
-
{ url = "https://files.pythonhosted.org/packages/
|
|
371
|
-
{ url = "https://files.pythonhosted.org/packages/
|
|
372
|
-
{ url = "https://files.pythonhosted.org/packages/
|
|
373
|
-
{ url = "https://files.pythonhosted.org/packages/
|
|
374
|
-
{ url = "https://files.pythonhosted.org/packages/
|
|
375
|
-
{ url = "https://files.pythonhosted.org/packages/
|
|
376
|
-
{ url = "https://files.pythonhosted.org/packages/
|
|
377
|
-
{ url = "https://files.pythonhosted.org/packages/
|
|
378
|
-
{ url = "https://files.pythonhosted.org/packages/62/
|
|
379
|
-
{ url = "https://files.pythonhosted.org/packages/
|
|
380
|
-
{ url = "https://files.pythonhosted.org/packages/
|
|
381
|
-
{ url = "https://files.pythonhosted.org/packages/
|
|
382
|
-
{ url = "https://files.pythonhosted.org/packages/
|
|
383
|
-
{ url = "https://files.pythonhosted.org/packages/
|
|
384
|
-
{ url = "https://files.pythonhosted.org/packages/
|
|
385
|
-
{ url = "https://files.pythonhosted.org/packages/
|
|
386
|
-
{ url = "https://files.pythonhosted.org/packages/
|
|
370
|
+
{ url = "https://files.pythonhosted.org/packages/2e/78/90c46ca6250709f7c37e397b60d06061adee8d0f7d13959ed6a8e49b14fd/ruff-0.17.1-py3-none-linux_armv6l.whl", hash = "sha256:1796c41eafec66f4635125dd1e074a7aa27b8d20c187d484360acf11d247fc4a", size = 10147528, upload-time = "2026-10-15T15:22:33.667Z" },
|
|
371
|
+
{ url = "https://files.pythonhosted.org/packages/aa/d2/a2e28bc35b083ae51fa07dfba5280a667c8b01ecaee7802fc8849dcd5c46/ruff-0.17.1-py3-none-macosx_10_12_x86_64.whl", hash = "sha256:8eadb09a788010be29c895418bdfa513e4e1c65e64b94e5b19e4cd381f6cc7fb", size = 10225974, upload-time = "2026-10-15T15:22:36.328Z" },
|
|
372
|
+
{ url = "https://files.pythonhosted.org/packages/8e/71/7a9029a81c8206ee01a98f6cfeeb56e6c095af86857581a37045c46d7e94/ruff-0.17.1-py3-none-macosx_11_0_arm64.whl", hash = "sha256:29b454f18ca3eeaf37fbf140841dcf27d36109e29dee9aae8acecb68c26c6f74", size = 9270361, upload-time = "2026-10-15T15:22:38.651Z" },
|
|
373
|
+
{ url = "https://files.pythonhosted.org/packages/c0/8c/e075e9c917cb0575297880c96768304e881240171c870cbd8d9b7b54bec2/ruff-0.17.1-py3-none-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:872e03dd231744d6c5ec5c8af6be52b71323fc6ee096e4c8b34d9f844ee3b978", size = 9938300, upload-time = "2026-10-15T15:22:41.284Z" },
|
|
374
|
+
{ url = "https://files.pythonhosted.org/packages/87/27/0b4bb926a49de2383f161272b4d863571a4c7ecdbf595a6bc58813a13367/ruff-0.17.1-py3-none-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:4c0d6cb5f8fbac77eec9af49f4fc0eaf856b05545e372b0694d24b4e76b1c640", size = 9948464, upload-time = "2026-10-15T15:22:43.681Z" },
|
|
375
|
+
{ url = "https://files.pythonhosted.org/packages/14/27/518d57e0e02aecb8ea4acac6b57b51a53173d25fa734952bfdd7d531e88e/ruff-0.17.1-py3-none-manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:78beced4a3c94dfedbee4b999b95b6a27b35820fdc0afbacc6d37a8da26c1cd1", size = 10638639, upload-time = "2026-10-15T15:22:46.081Z" },
|
|
376
|
+
{ url = "https://files.pythonhosted.org/packages/01/82/d89a4e498ade59e6cee52d67f8da569019372212b87468c1fdeae884601c/ruff-0.17.1-py3-none-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:7feefc63921202894f0e158b0e32f45a5950d70a7fb693ccb9264816c25b1c05", size = 11337238, upload-time = "2026-10-15T15:22:48.894Z" },
|
|
377
|
+
{ url = "https://files.pythonhosted.org/packages/a2/7c/3b0fdef9352656317c977086fe1d802902406e4f2a0d8578da90c0e6d1c5/ruff-0.17.1-py3-none-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:684154861a819bf1f433669d2a0ce9c3e54677c65b8ebb866cc2a7ec86345785", size = 10896327, upload-time = "2026-10-15T15:22:51.45Z" },
|
|
378
|
+
{ url = "https://files.pythonhosted.org/packages/62/86/5566290219708ce2928f3a29c4f843a1185b341ec6111c4631a33c5ceced/ruff-0.17.1-py3-none-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:a6ef98e51de8ef38082f90653ceeb84944bd7673783eea13e1647c5b9b064189", size = 10350811, upload-time = "2026-10-15T15:22:54.401Z" },
|
|
379
|
+
{ url = "https://files.pythonhosted.org/packages/ad/d2/ca8462dabb3c413990d49703ba306c30c862195a75448d080fa8fcce9775/ruff-0.17.1-py3-none-manylinux_2_31_riscv64.whl", hash = "sha256:8f9aa5b5bd5fa1937803ea609c8f153b8de39bf3e0e149897ae34b0c5b52f467", size = 10569994, upload-time = "2026-10-15T15:22:57.142Z" },
|
|
380
|
+
{ url = "https://files.pythonhosted.org/packages/e3/ad/dd1864c1f1db17c8cfb297ce70b352388e6977620f66f7182c52855407df/ruff-0.17.1-py3-none-musllinux_1_2_aarch64.whl", hash = "sha256:80e53b0e5faa3c5667f035daaa032893ae42b7cfe708c886d39ed131e54688ab", size = 10059672, upload-time = "2026-10-15T15:23:00.084Z" },
|
|
381
|
+
{ url = "https://files.pythonhosted.org/packages/65/45/3f56cf1d2168c2165cdd5ac6f9668aee66a4cfdd4caf2b2cc5ccb2b1d568/ruff-0.17.1-py3-none-musllinux_1_2_armv7l.whl", hash = "sha256:056c5d5fa0ac790051ae165d7035c7bf956d02de2db557f2e9b31d877a505fca", size = 9947803, upload-time = "2026-10-15T15:23:03.132Z" },
|
|
382
|
+
{ url = "https://files.pythonhosted.org/packages/aa/4b/5457cb2be4c1d1ea5e919558131a0f197a4a454a0530d9e30820e8206e4c/ruff-0.17.1-py3-none-musllinux_1_2_i686.whl", hash = "sha256:bd8f5a55b10f371642eacd0e8665a42a8b97da15c9a7187c79e697b77b5e0ce4", size = 10351807, upload-time = "2026-10-15T15:23:05.628Z" },
|
|
383
|
+
{ url = "https://files.pythonhosted.org/packages/49/fb/db15b4f8fa24a1e36b99e1401f42ef6df16ee299a48670d5d262b771e7d7/ruff-0.17.1-py3-none-musllinux_1_2_x86_64.whl", hash = "sha256:ce05e6f3973611d9550a600e04bb531061e368baba31610eb57c1509a8f21a0a", size = 10765716, upload-time = "2026-10-15T15:23:08.092Z" },
|
|
384
|
+
{ url = "https://files.pythonhosted.org/packages/0a/e8/1e186578076aff7a80735f625005fde678412ab609cd323ed182eb7d6b87/ruff-0.17.1-py3-none-win32.whl", hash = "sha256:1de0030a8aa78c65c5fecb84b2e5c390ac684c0452875a02afc7c083d49a496a", size = 9895093, upload-time = "2026-10-15T15:23:10.582Z" },
|
|
385
|
+
{ url = "https://files.pythonhosted.org/packages/6a/2e/da3d9589bae8e8b58f3a48bd5bc0b980232fb14a83bf02c3be7660f87c1b/ruff-0.17.1-py3-none-win_amd64.whl", hash = "sha256:5df76f16580fab58d0f6c98a3ac254a4abceb7b2489b8b678335869cff77b3d7", size = 10097955, upload-time = "2026-10-15T15:23:13.309Z" },
|
|
386
|
+
{ url = "https://files.pythonhosted.org/packages/df/c9/0f2a4dea06a5e12c1191ee3d96b1e1233797d0d5e18f97a2b909a95a9836/ruff-0.17.1-py3-none-win_arm64.whl", hash = "sha256:42400b9a6ff8515ff27796f07f92e0195be011c86e81e381606f58ea5502fef4", size = 9853542, upload-time = "2026-10-15T15:23:16.05Z" },
|
|
387
387
|
]
|
|
388
388
|
|
|
389
389
|
[[package]]
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|