ipython-postfix-completion 0.1.1__tar.gz → 0.2.0__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.
- ipython_postfix_completion-0.2.0/CHANGELOG.md +32 -0
- {ipython_postfix_completion-0.1.1 → ipython_postfix_completion-0.2.0}/MANIFEST.in +1 -0
- {ipython_postfix_completion-0.1.1/ipython_postfix_completion.egg-info → ipython_postfix_completion-0.2.0}/PKG-INFO +72 -8
- {ipython_postfix_completion-0.1.1 → ipython_postfix_completion-0.2.0}/README.md +63 -6
- {ipython_postfix_completion-0.1.1 → ipython_postfix_completion-0.2.0}/ipython_postfix_completion/__init__.py +377 -23
- {ipython_postfix_completion-0.1.1 → ipython_postfix_completion-0.2.0/ipython_postfix_completion.egg-info}/PKG-INFO +72 -8
- {ipython_postfix_completion-0.1.1 → ipython_postfix_completion-0.2.0}/ipython_postfix_completion.egg-info/SOURCES.txt +1 -0
- {ipython_postfix_completion-0.1.1 → ipython_postfix_completion-0.2.0}/ipython_postfix_completion.egg-info/requires.txt +3 -1
- {ipython_postfix_completion-0.1.1 → ipython_postfix_completion-0.2.0}/pyproject.toml +11 -2
- {ipython_postfix_completion-0.1.1 → ipython_postfix_completion-0.2.0}/tests/test_postfix_completion.py +253 -24
- {ipython_postfix_completion-0.1.1 → ipython_postfix_completion-0.2.0}/LICENSE +0 -0
- {ipython_postfix_completion-0.1.1 → ipython_postfix_completion-0.2.0}/ipython_postfix_completion.egg-info/dependency_links.txt +0 -0
- {ipython_postfix_completion-0.1.1 → ipython_postfix_completion-0.2.0}/ipython_postfix_completion.egg-info/top_level.txt +0 -0
- {ipython_postfix_completion-0.1.1 → ipython_postfix_completion-0.2.0}/setup.cfg +0 -0
- {ipython_postfix_completion-0.1.1 → ipython_postfix_completion-0.2.0}/tests/conftest.py +0 -0
|
@@ -0,0 +1,32 @@
|
|
|
1
|
+
# Changelog
|
|
2
|
+
|
|
3
|
+
All notable changes to this project are documented here.
|
|
4
|
+
|
|
5
|
+
## [0.2.0] - 2026-08-09
|
|
6
|
+
|
|
7
|
+
### Added
|
|
8
|
+
|
|
9
|
+
- Smart Tab navigation over Python string and bracket closing tokens.
|
|
10
|
+
- Editable `key` placeholder for the built-in `.var` template.
|
|
11
|
+
- Runtime configuration for enabling or disabling Smart Tab.
|
|
12
|
+
- CI coverage for Python 3.11–3.14 and IPython 9.x.
|
|
13
|
+
|
|
14
|
+
### Changed
|
|
15
|
+
|
|
16
|
+
- `.var` now expands `expr.var` to `key = expr` and selects `key`.
|
|
17
|
+
- Smart Tab navigation is enabled by default in terminal IPython.
|
|
18
|
+
- IPython 10+ is not currently supported.
|
|
19
|
+
|
|
20
|
+
### Migration from 0.1.x
|
|
21
|
+
|
|
22
|
+
The `.var` expansion changed from `expr = ` to `key = expr`. Users who
|
|
23
|
+
depend on the old cursor position or assignment shape should keep using a
|
|
24
|
+
custom template until they migrate.
|
|
25
|
+
|
|
26
|
+
## [0.1.1] - 2026-07-10
|
|
27
|
+
|
|
28
|
+
- Added the `.var` and `.await` templates.
|
|
29
|
+
|
|
30
|
+
## [0.1.0] - 2026-07-05
|
|
31
|
+
|
|
32
|
+
- Initial release.
|
|
@@ -1,9 +1,13 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: ipython-postfix-completion
|
|
3
|
-
Version: 0.
|
|
3
|
+
Version: 0.2.0
|
|
4
4
|
Summary: Configurable postfix completion extension for IPython.
|
|
5
5
|
Author: IPython Postfix Completion Contributors
|
|
6
6
|
License-Expression: BSD-3-Clause
|
|
7
|
+
Project-URL: Homepage, https://github.com/fishandsheep/ipython-postfix-completion
|
|
8
|
+
Project-URL: Repository, https://github.com/fishandsheep/ipython-postfix-completion
|
|
9
|
+
Project-URL: Issues, https://github.com/fishandsheep/ipython-postfix-completion/issues
|
|
10
|
+
Project-URL: Changelog, https://github.com/fishandsheep/ipython-postfix-completion/blob/main/CHANGELOG.md
|
|
7
11
|
Keywords: ipython,completion,postfix,extension
|
|
8
12
|
Classifier: Framework :: IPython
|
|
9
13
|
Classifier: Intended Audience :: Developers
|
|
@@ -12,16 +16,19 @@ Classifier: Programming Language :: Python :: 3 :: Only
|
|
|
12
16
|
Classifier: Programming Language :: Python :: 3.11
|
|
13
17
|
Classifier: Programming Language :: Python :: 3.12
|
|
14
18
|
Classifier: Programming Language :: Python :: 3.13
|
|
19
|
+
Classifier: Programming Language :: Python :: 3.14
|
|
15
20
|
Classifier: Topic :: Software Development :: Libraries :: Python Modules
|
|
16
21
|
Requires-Python: >=3.11
|
|
17
22
|
Description-Content-Type: text/markdown
|
|
18
23
|
License-File: LICENSE
|
|
19
|
-
Requires-Dist: ipython
|
|
24
|
+
Requires-Dist: ipython<10,>=9.0
|
|
20
25
|
Requires-Dist: traitlets>=5.13
|
|
21
26
|
Provides-Extra: test
|
|
22
27
|
Requires-Dist: pytest>=7; extra == "test"
|
|
23
28
|
Provides-Extra: dev
|
|
24
29
|
Requires-Dist: build; extra == "dev"
|
|
30
|
+
Requires-Dist: pip-audit>=2.7; extra == "dev"
|
|
31
|
+
Requires-Dist: ruff>=0.8; extra == "dev"
|
|
25
32
|
Requires-Dist: twine; extra == "dev"
|
|
26
33
|
Requires-Dist: ipython-postfix-completion[test]; extra == "dev"
|
|
27
34
|
Dynamic: license-file
|
|
@@ -60,6 +67,10 @@ To load it automatically, add this to `ipython_config.py`:
|
|
|
60
67
|
c.InteractiveShellApp.extensions = ["ipython_postfix_completion"]
|
|
61
68
|
```
|
|
62
69
|
|
|
70
|
+
Smart Tab key bindings are supported in terminal IPython. Postfix matcher
|
|
71
|
+
completion can also work in other IPython frontends, but this package does not
|
|
72
|
+
promise frontend-specific Tab behavior outside the terminal.
|
|
73
|
+
|
|
63
74
|
## Quick Example: Add a `for` Template
|
|
64
75
|
|
|
65
76
|
Add a template for the current IPython session:
|
|
@@ -130,11 +141,59 @@ c.PostfixCompletionConfig.templates = {
|
|
|
130
141
|
c.PostfixCompletionConfig.disabled_templates = ["tuple"]
|
|
131
142
|
```
|
|
132
143
|
|
|
144
|
+
Smart Tab jump is enabled by default. Disable it while keeping postfix
|
|
145
|
+
completion with:
|
|
146
|
+
|
|
147
|
+
```python
|
|
148
|
+
c.PostfixCompletionConfig.smart_tab_jump = False
|
|
149
|
+
```
|
|
150
|
+
|
|
133
151
|
Template names must match `[A-Za-z_][A-Za-z0-9_]*`.
|
|
134
152
|
|
|
135
153
|
Templates must include `{expr}` and may also use `{indent}`. No other template
|
|
136
154
|
fields are allowed.
|
|
137
155
|
|
|
156
|
+
## `.var` Placeholder
|
|
157
|
+
|
|
158
|
+
The built-in `.var` template creates an assignment and selects `key` as an
|
|
159
|
+
editable placeholder:
|
|
160
|
+
|
|
161
|
+
```text
|
|
162
|
+
"hello".var<Tab> -> key = "hello"
|
|
163
|
+
^^^ selected
|
|
164
|
+
```
|
|
165
|
+
|
|
166
|
+
While `key` remains selected:
|
|
167
|
+
|
|
168
|
+
- Tab accepts `key` and moves cursor to the end of the assignment.
|
|
169
|
+
- Enter behaves like Tab for this selection only; press Enter again to submit.
|
|
170
|
+
- Any other typed text replaces `key` with a custom variable name.
|
|
171
|
+
|
|
172
|
+
In 0.1.x, `.var` produced `expr = ` with the cursor after the assignment
|
|
173
|
+
target. Version 0.2.0 changes this to `key = expr` with an editable
|
|
174
|
+
placeholder; use a custom template if you need the old behavior.
|
|
175
|
+
|
|
176
|
+
## Smart Tab Jump
|
|
177
|
+
|
|
178
|
+
When cursor is immediately before a valid Python closing token, Tab moves over
|
|
179
|
+
it without changing source text. Repeated Tab presses exit nested constructs:
|
|
180
|
+
|
|
181
|
+
```text
|
|
182
|
+
"hello|" -> "hello"|
|
|
183
|
+
print("hello|") -> print("hello"|) -> print("hello")|
|
|
184
|
+
print(f"{name|}") -> print(f"{name}|") -> print(f"{name}"|) -> print(f"{name}")|
|
|
185
|
+
items[index|] -> items[index]|
|
|
186
|
+
list[dict[str, int|]] -> list[dict[str, int]|] -> list[dict[str, int]]|
|
|
187
|
+
{"name": value|} -> {"name": value}|
|
|
188
|
+
```
|
|
189
|
+
|
|
190
|
+
`|` marks cursor and is not typed. Supported closers are single and triple
|
|
191
|
+
quotes plus `)`, `]`, and `}`. Detection follows Python tokens, including
|
|
192
|
+
multiline input, string prefixes, and f-string expressions. Tab still accepts
|
|
193
|
+
the `.var` name selection or an exact postfix template first; otherwise it
|
|
194
|
+
falls back to IPython completion or indentation. Ambiguous `< >`, colon, and
|
|
195
|
+
comma are intentionally excluded.
|
|
196
|
+
|
|
138
197
|
## Built-in Templates
|
|
139
198
|
|
|
140
199
|
Default templates:
|
|
@@ -145,7 +204,7 @@ Default templates:
|
|
|
145
204
|
| `len` | `len({expr})` |
|
|
146
205
|
| `not` | `not {expr}` |
|
|
147
206
|
| `par` | `({expr})` |
|
|
148
|
-
| `var` | `{expr}
|
|
207
|
+
| `var` | `key = {expr}`; selects `key`; Tab or Enter accepts it |
|
|
149
208
|
| `await` | `await {expr}` |
|
|
150
209
|
| `return` | `return {expr}` |
|
|
151
210
|
| `if` | `if {expr}:\n{indent} ` |
|
|
@@ -167,6 +226,9 @@ Run tests:
|
|
|
167
226
|
|
|
168
227
|
```bash
|
|
169
228
|
uv run --extra test pytest -q
|
|
229
|
+
uv run --extra dev ruff check .
|
|
230
|
+
uv run --extra dev ruff format --check .
|
|
231
|
+
uv run --isolated --no-project --with "ipython>=9,<10" --with "traitlets>=5.13" --with "pip-audit>=2.7" pip-audit --strict --local
|
|
170
232
|
```
|
|
171
233
|
|
|
172
234
|
Build and check release artifacts:
|
|
@@ -205,14 +267,16 @@ existing PyPI project once under **Manage > Publishing > Add a new publisher**:
|
|
|
205
267
|
| Environment | `pypi` |
|
|
206
268
|
|
|
207
269
|
For each release, update `project.version` in `pyproject.toml`, commit and push
|
|
208
|
-
the change, then create a matching `v` tag. For
|
|
209
|
-
version to `0.1.1`:
|
|
270
|
+
the change, then create a matching `v` tag. For this release:
|
|
210
271
|
|
|
211
272
|
```bash
|
|
212
|
-
git tag v0.
|
|
213
|
-
git push origin v0.
|
|
273
|
+
git tag v0.2.0
|
|
274
|
+
git push origin v0.2.0
|
|
214
275
|
```
|
|
215
276
|
|
|
216
277
|
The workflow verifies the tag against `project.version`, runs tests, builds and
|
|
217
278
|
checks both distributions, then publishes them to PyPI using a short-lived OIDC
|
|
218
|
-
credential.
|
|
279
|
+
credential. PyPI versions are immutable: never reuse a published version or tag;
|
|
280
|
+
fixes require the next version.
|
|
281
|
+
|
|
282
|
+
See [CHANGELOG.md](CHANGELOG.md) for release notes and migration guidance.
|
|
@@ -32,6 +32,10 @@ To load it automatically, add this to `ipython_config.py`:
|
|
|
32
32
|
c.InteractiveShellApp.extensions = ["ipython_postfix_completion"]
|
|
33
33
|
```
|
|
34
34
|
|
|
35
|
+
Smart Tab key bindings are supported in terminal IPython. Postfix matcher
|
|
36
|
+
completion can also work in other IPython frontends, but this package does not
|
|
37
|
+
promise frontend-specific Tab behavior outside the terminal.
|
|
38
|
+
|
|
35
39
|
## Quick Example: Add a `for` Template
|
|
36
40
|
|
|
37
41
|
Add a template for the current IPython session:
|
|
@@ -102,11 +106,59 @@ c.PostfixCompletionConfig.templates = {
|
|
|
102
106
|
c.PostfixCompletionConfig.disabled_templates = ["tuple"]
|
|
103
107
|
```
|
|
104
108
|
|
|
109
|
+
Smart Tab jump is enabled by default. Disable it while keeping postfix
|
|
110
|
+
completion with:
|
|
111
|
+
|
|
112
|
+
```python
|
|
113
|
+
c.PostfixCompletionConfig.smart_tab_jump = False
|
|
114
|
+
```
|
|
115
|
+
|
|
105
116
|
Template names must match `[A-Za-z_][A-Za-z0-9_]*`.
|
|
106
117
|
|
|
107
118
|
Templates must include `{expr}` and may also use `{indent}`. No other template
|
|
108
119
|
fields are allowed.
|
|
109
120
|
|
|
121
|
+
## `.var` Placeholder
|
|
122
|
+
|
|
123
|
+
The built-in `.var` template creates an assignment and selects `key` as an
|
|
124
|
+
editable placeholder:
|
|
125
|
+
|
|
126
|
+
```text
|
|
127
|
+
"hello".var<Tab> -> key = "hello"
|
|
128
|
+
^^^ selected
|
|
129
|
+
```
|
|
130
|
+
|
|
131
|
+
While `key` remains selected:
|
|
132
|
+
|
|
133
|
+
- Tab accepts `key` and moves cursor to the end of the assignment.
|
|
134
|
+
- Enter behaves like Tab for this selection only; press Enter again to submit.
|
|
135
|
+
- Any other typed text replaces `key` with a custom variable name.
|
|
136
|
+
|
|
137
|
+
In 0.1.x, `.var` produced `expr = ` with the cursor after the assignment
|
|
138
|
+
target. Version 0.2.0 changes this to `key = expr` with an editable
|
|
139
|
+
placeholder; use a custom template if you need the old behavior.
|
|
140
|
+
|
|
141
|
+
## Smart Tab Jump
|
|
142
|
+
|
|
143
|
+
When cursor is immediately before a valid Python closing token, Tab moves over
|
|
144
|
+
it without changing source text. Repeated Tab presses exit nested constructs:
|
|
145
|
+
|
|
146
|
+
```text
|
|
147
|
+
"hello|" -> "hello"|
|
|
148
|
+
print("hello|") -> print("hello"|) -> print("hello")|
|
|
149
|
+
print(f"{name|}") -> print(f"{name}|") -> print(f"{name}"|) -> print(f"{name}")|
|
|
150
|
+
items[index|] -> items[index]|
|
|
151
|
+
list[dict[str, int|]] -> list[dict[str, int]|] -> list[dict[str, int]]|
|
|
152
|
+
{"name": value|} -> {"name": value}|
|
|
153
|
+
```
|
|
154
|
+
|
|
155
|
+
`|` marks cursor and is not typed. Supported closers are single and triple
|
|
156
|
+
quotes plus `)`, `]`, and `}`. Detection follows Python tokens, including
|
|
157
|
+
multiline input, string prefixes, and f-string expressions. Tab still accepts
|
|
158
|
+
the `.var` name selection or an exact postfix template first; otherwise it
|
|
159
|
+
falls back to IPython completion or indentation. Ambiguous `< >`, colon, and
|
|
160
|
+
comma are intentionally excluded.
|
|
161
|
+
|
|
110
162
|
## Built-in Templates
|
|
111
163
|
|
|
112
164
|
Default templates:
|
|
@@ -117,7 +169,7 @@ Default templates:
|
|
|
117
169
|
| `len` | `len({expr})` |
|
|
118
170
|
| `not` | `not {expr}` |
|
|
119
171
|
| `par` | `({expr})` |
|
|
120
|
-
| `var` | `{expr}
|
|
172
|
+
| `var` | `key = {expr}`; selects `key`; Tab or Enter accepts it |
|
|
121
173
|
| `await` | `await {expr}` |
|
|
122
174
|
| `return` | `return {expr}` |
|
|
123
175
|
| `if` | `if {expr}:\n{indent} ` |
|
|
@@ -139,6 +191,9 @@ Run tests:
|
|
|
139
191
|
|
|
140
192
|
```bash
|
|
141
193
|
uv run --extra test pytest -q
|
|
194
|
+
uv run --extra dev ruff check .
|
|
195
|
+
uv run --extra dev ruff format --check .
|
|
196
|
+
uv run --isolated --no-project --with "ipython>=9,<10" --with "traitlets>=5.13" --with "pip-audit>=2.7" pip-audit --strict --local
|
|
142
197
|
```
|
|
143
198
|
|
|
144
199
|
Build and check release artifacts:
|
|
@@ -177,14 +232,16 @@ existing PyPI project once under **Manage > Publishing > Add a new publisher**:
|
|
|
177
232
|
| Environment | `pypi` |
|
|
178
233
|
|
|
179
234
|
For each release, update `project.version` in `pyproject.toml`, commit and push
|
|
180
|
-
the change, then create a matching `v` tag. For
|
|
181
|
-
version to `0.1.1`:
|
|
235
|
+
the change, then create a matching `v` tag. For this release:
|
|
182
236
|
|
|
183
237
|
```bash
|
|
184
|
-
git tag v0.
|
|
185
|
-
git push origin v0.
|
|
238
|
+
git tag v0.2.0
|
|
239
|
+
git push origin v0.2.0
|
|
186
240
|
```
|
|
187
241
|
|
|
188
242
|
The workflow verifies the tag against `project.version`, runs tests, builds and
|
|
189
243
|
checks both distributions, then publishes them to PyPI using a short-lived OIDC
|
|
190
|
-
credential.
|
|
244
|
+
credential. PyPI versions are immutable: never reuse a published version or tag;
|
|
245
|
+
fixes require the next version.
|
|
246
|
+
|
|
247
|
+
See [CHANGELOG.md](CHANGELOG.md) for release notes and migration guidance.
|