ipython-postfix-completion 0.1.1__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.
- ipython_postfix_completion-0.2.1/CHANGELOG.md +47 -0
- {ipython_postfix_completion-0.1.1 → ipython_postfix_completion-0.2.1}/MANIFEST.in +2 -0
- ipython_postfix_completion-0.2.1/PKG-INFO +115 -0
- ipython_postfix_completion-0.2.1/README.md +80 -0
- ipython_postfix_completion-0.2.1/docs/REFERENCE.md +150 -0
- ipython_postfix_completion-0.2.1/ipython_postfix_completion/__init__.py +1038 -0
- ipython_postfix_completion-0.2.1/ipython_postfix_completion.egg-info/PKG-INFO +115 -0
- {ipython_postfix_completion-0.1.1 → ipython_postfix_completion-0.2.1}/ipython_postfix_completion.egg-info/SOURCES.txt +2 -0
- {ipython_postfix_completion-0.1.1 → ipython_postfix_completion-0.2.1}/ipython_postfix_completion.egg-info/requires.txt +3 -1
- {ipython_postfix_completion-0.1.1 → ipython_postfix_completion-0.2.1}/pyproject.toml +11 -2
- {ipython_postfix_completion-0.1.1 → ipython_postfix_completion-0.2.1}/tests/test_postfix_completion.py +332 -31
- ipython_postfix_completion-0.1.1/PKG-INFO +0 -218
- ipython_postfix_completion-0.1.1/README.md +0 -190
- ipython_postfix_completion-0.1.1/ipython_postfix_completion/__init__.py +0 -559
- ipython_postfix_completion-0.1.1/ipython_postfix_completion.egg-info/PKG-INFO +0 -218
- {ipython_postfix_completion-0.1.1 → ipython_postfix_completion-0.2.1}/LICENSE +0 -0
- {ipython_postfix_completion-0.1.1 → ipython_postfix_completion-0.2.1}/ipython_postfix_completion.egg-info/dependency_links.txt +0 -0
- {ipython_postfix_completion-0.1.1 → ipython_postfix_completion-0.2.1}/ipython_postfix_completion.egg-info/top_level.txt +0 -0
- {ipython_postfix_completion-0.1.1 → ipython_postfix_completion-0.2.1}/setup.cfg +0 -0
- {ipython_postfix_completion-0.1.1 → ipython_postfix_completion-0.2.1}/tests/conftest.py +0 -0
|
@@ -0,0 +1,47 @@
|
|
|
1
|
+
# Changelog
|
|
2
|
+
|
|
3
|
+
All notable changes to this project are documented here.
|
|
4
|
+
|
|
5
|
+
## [0.2.1] - 2026-10-05
|
|
6
|
+
|
|
7
|
+
### Added
|
|
8
|
+
|
|
9
|
+
- Added built-in `.for`, `.fori`, `.ef`, `.type`, and `.range` templates.
|
|
10
|
+
- Added editable, sequential Tab stops for loop and conditional templates,
|
|
11
|
+
with Shift+Tab navigation to previous stops.
|
|
12
|
+
- Wrapped integer literals in `range(...)` for `.for` and `.fori` templates.
|
|
13
|
+
|
|
14
|
+
### Changed
|
|
15
|
+
|
|
16
|
+
- Updated the built-in `.if` template to include an editable `pass` body.
|
|
17
|
+
- Simplified the README and moved detailed usage and maintenance notes to
|
|
18
|
+
`docs/REFERENCE.md`.
|
|
19
|
+
|
|
20
|
+
## [0.2.0] - 2026-08-09
|
|
21
|
+
|
|
22
|
+
### Added
|
|
23
|
+
|
|
24
|
+
- Smart Tab navigation over Python string and bracket closing tokens.
|
|
25
|
+
- Editable `key` placeholder for the built-in `.var` template.
|
|
26
|
+
- Runtime configuration for enabling or disabling Smart Tab.
|
|
27
|
+
- CI coverage for Python 3.11–3.14 and IPython 9.x.
|
|
28
|
+
|
|
29
|
+
### Changed
|
|
30
|
+
|
|
31
|
+
- `.var` now expands `expr.var` to `key = expr` and selects `key`.
|
|
32
|
+
- Smart Tab navigation is enabled by default in terminal IPython.
|
|
33
|
+
- IPython 10+ is not currently supported.
|
|
34
|
+
|
|
35
|
+
### Migration from 0.1.x
|
|
36
|
+
|
|
37
|
+
The `.var` expansion changed from `expr = ` to `key = expr`. Users who
|
|
38
|
+
depend on the old cursor position or assignment shape should keep using a
|
|
39
|
+
custom template until they migrate.
|
|
40
|
+
|
|
41
|
+
## [0.1.1] - 2026-07-10
|
|
42
|
+
|
|
43
|
+
- Added the `.var` and `.await` templates.
|
|
44
|
+
|
|
45
|
+
## [0.1.0] - 2026-07-05
|
|
46
|
+
|
|
47
|
+
- Initial release.
|
|
@@ -0,0 +1,115 @@
|
|
|
1
|
+
Metadata-Version: 2.4
|
|
2
|
+
Name: ipython-postfix-completion
|
|
3
|
+
Version: 0.2.1
|
|
4
|
+
Summary: Configurable postfix completion extension for IPython.
|
|
5
|
+
Author: IPython Postfix Completion Contributors
|
|
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
|
|
11
|
+
Keywords: ipython,completion,postfix,extension
|
|
12
|
+
Classifier: Framework :: IPython
|
|
13
|
+
Classifier: Intended Audience :: Developers
|
|
14
|
+
Classifier: Programming Language :: Python :: 3
|
|
15
|
+
Classifier: Programming Language :: Python :: 3 :: Only
|
|
16
|
+
Classifier: Programming Language :: Python :: 3.11
|
|
17
|
+
Classifier: Programming Language :: Python :: 3.12
|
|
18
|
+
Classifier: Programming Language :: Python :: 3.13
|
|
19
|
+
Classifier: Programming Language :: Python :: 3.14
|
|
20
|
+
Classifier: Topic :: Software Development :: Libraries :: Python Modules
|
|
21
|
+
Requires-Python: >=3.11
|
|
22
|
+
Description-Content-Type: text/markdown
|
|
23
|
+
License-File: LICENSE
|
|
24
|
+
Requires-Dist: ipython<10,>=9.0
|
|
25
|
+
Requires-Dist: traitlets>=5.13
|
|
26
|
+
Provides-Extra: test
|
|
27
|
+
Requires-Dist: pytest>=7; extra == "test"
|
|
28
|
+
Provides-Extra: dev
|
|
29
|
+
Requires-Dist: build; extra == "dev"
|
|
30
|
+
Requires-Dist: pip-audit>=2.7; extra == "dev"
|
|
31
|
+
Requires-Dist: ruff>=0.8; extra == "dev"
|
|
32
|
+
Requires-Dist: twine; extra == "dev"
|
|
33
|
+
Requires-Dist: ipython-postfix-completion[test]; extra == "dev"
|
|
34
|
+
Dynamic: license-file
|
|
35
|
+
|
|
36
|
+
# IPython Postfix Completion
|
|
37
|
+
|
|
38
|
+
Complete Python expressions with postfix templates in IPython: type an
|
|
39
|
+
expression, a dot, and a template name, then press Tab.
|
|
40
|
+
|
|
41
|
+
## Install
|
|
42
|
+
|
|
43
|
+
```bash
|
|
44
|
+
uv tool install ipython --with ipython-postfix-completion
|
|
45
|
+
```
|
|
46
|
+
|
|
47
|
+
Start IPython and load the extension:
|
|
48
|
+
|
|
49
|
+
```python
|
|
50
|
+
%load_ext ipython_postfix_completion
|
|
51
|
+
```
|
|
52
|
+
|
|
53
|
+
## Common Templates
|
|
54
|
+
|
|
55
|
+
`items.for<Tab>` creates a loop. Tab selects `item`, then `pass`; type to
|
|
56
|
+
replace a selection.
|
|
57
|
+
|
|
58
|
+
```python
|
|
59
|
+
for item in items:
|
|
60
|
+
pass
|
|
61
|
+
```
|
|
62
|
+
|
|
63
|
+
An integer literal is wrapped in `range(...)`, so `10.for<Tab>` produces
|
|
64
|
+
`for item in range(10):`.
|
|
65
|
+
|
|
66
|
+
`items.fori<Tab>` creates an indexed loop. Tab selects `i`, `value`, then
|
|
67
|
+
`pass`. For an integer literal, it uses `enumerate(range(n))`.
|
|
68
|
+
|
|
69
|
+
`condition.if<Tab>` creates an `if` block with a selected `pass`:
|
|
70
|
+
|
|
71
|
+
```python
|
|
72
|
+
if condition:
|
|
73
|
+
pass
|
|
74
|
+
```
|
|
75
|
+
|
|
76
|
+
`condition.ef<Tab>` creates `if`/`elif`/`else` branches. Tab selects each
|
|
77
|
+
placeholder in order: `pass`, `cond`, `pass`, `pass`. The `cond` selection
|
|
78
|
+
does not include its colon.
|
|
79
|
+
|
|
80
|
+
Other built-ins: `print`, `len`, `not`, `par`, `var`, `await`, `return`,
|
|
81
|
+
`while`, `raise`, `yield`, `str`, `list`, `set`, `dict`, `tuple`, `type`, and
|
|
82
|
+
`range`. Use `%postfix_template list` to see their expansions.
|
|
83
|
+
|
|
84
|
+
Shift+Tab moves back to the previous placeholder. Custom Tab navigation is
|
|
85
|
+
supported in terminal IPython.
|
|
86
|
+
|
|
87
|
+
## Load Automatically
|
|
88
|
+
|
|
89
|
+
The default configuration file is:
|
|
90
|
+
|
|
91
|
+
```text
|
|
92
|
+
~/.ipython/profile_default/ipython_config.py
|
|
93
|
+
```
|
|
94
|
+
|
|
95
|
+
Create it with:
|
|
96
|
+
|
|
97
|
+
```bash
|
|
98
|
+
ipython profile create
|
|
99
|
+
```
|
|
100
|
+
|
|
101
|
+
Add the extension and any persistent templates there:
|
|
102
|
+
|
|
103
|
+
```python
|
|
104
|
+
c.InteractiveShellApp.extensions = ["ipython_postfix_completion"]
|
|
105
|
+
c.PostfixCompletionConfig.templates = {
|
|
106
|
+
"debug": "print({expr}=)",
|
|
107
|
+
}
|
|
108
|
+
```
|
|
109
|
+
|
|
110
|
+
`IPYTHONDIR` and `--ipython-dir` can change the configuration directory. Use
|
|
111
|
+
`ipython locate profile default` to find the active profile. See the [official
|
|
112
|
+
IPython configuration guide](https://ipython.readthedocs.io/en/stable/development/config.html).
|
|
113
|
+
|
|
114
|
+
For runtime template commands, detailed behavior, and contributor or release
|
|
115
|
+
steps, see [the extended guide](docs/REFERENCE.md).
|
|
@@ -0,0 +1,80 @@
|
|
|
1
|
+
# IPython Postfix Completion
|
|
2
|
+
|
|
3
|
+
Complete Python expressions with postfix templates in IPython: type an
|
|
4
|
+
expression, a dot, and a template name, then press Tab.
|
|
5
|
+
|
|
6
|
+
## Install
|
|
7
|
+
|
|
8
|
+
```bash
|
|
9
|
+
uv tool install ipython --with ipython-postfix-completion
|
|
10
|
+
```
|
|
11
|
+
|
|
12
|
+
Start IPython and load the extension:
|
|
13
|
+
|
|
14
|
+
```python
|
|
15
|
+
%load_ext ipython_postfix_completion
|
|
16
|
+
```
|
|
17
|
+
|
|
18
|
+
## Common Templates
|
|
19
|
+
|
|
20
|
+
`items.for<Tab>` creates a loop. Tab selects `item`, then `pass`; type to
|
|
21
|
+
replace a selection.
|
|
22
|
+
|
|
23
|
+
```python
|
|
24
|
+
for item in items:
|
|
25
|
+
pass
|
|
26
|
+
```
|
|
27
|
+
|
|
28
|
+
An integer literal is wrapped in `range(...)`, so `10.for<Tab>` produces
|
|
29
|
+
`for item in range(10):`.
|
|
30
|
+
|
|
31
|
+
`items.fori<Tab>` creates an indexed loop. Tab selects `i`, `value`, then
|
|
32
|
+
`pass`. For an integer literal, it uses `enumerate(range(n))`.
|
|
33
|
+
|
|
34
|
+
`condition.if<Tab>` creates an `if` block with a selected `pass`:
|
|
35
|
+
|
|
36
|
+
```python
|
|
37
|
+
if condition:
|
|
38
|
+
pass
|
|
39
|
+
```
|
|
40
|
+
|
|
41
|
+
`condition.ef<Tab>` creates `if`/`elif`/`else` branches. Tab selects each
|
|
42
|
+
placeholder in order: `pass`, `cond`, `pass`, `pass`. The `cond` selection
|
|
43
|
+
does not include its colon.
|
|
44
|
+
|
|
45
|
+
Other built-ins: `print`, `len`, `not`, `par`, `var`, `await`, `return`,
|
|
46
|
+
`while`, `raise`, `yield`, `str`, `list`, `set`, `dict`, `tuple`, `type`, and
|
|
47
|
+
`range`. Use `%postfix_template list` to see their expansions.
|
|
48
|
+
|
|
49
|
+
Shift+Tab moves back to the previous placeholder. Custom Tab navigation is
|
|
50
|
+
supported in terminal IPython.
|
|
51
|
+
|
|
52
|
+
## Load Automatically
|
|
53
|
+
|
|
54
|
+
The default configuration file is:
|
|
55
|
+
|
|
56
|
+
```text
|
|
57
|
+
~/.ipython/profile_default/ipython_config.py
|
|
58
|
+
```
|
|
59
|
+
|
|
60
|
+
Create it with:
|
|
61
|
+
|
|
62
|
+
```bash
|
|
63
|
+
ipython profile create
|
|
64
|
+
```
|
|
65
|
+
|
|
66
|
+
Add the extension and any persistent templates there:
|
|
67
|
+
|
|
68
|
+
```python
|
|
69
|
+
c.InteractiveShellApp.extensions = ["ipython_postfix_completion"]
|
|
70
|
+
c.PostfixCompletionConfig.templates = {
|
|
71
|
+
"debug": "print({expr}=)",
|
|
72
|
+
}
|
|
73
|
+
```
|
|
74
|
+
|
|
75
|
+
`IPYTHONDIR` and `--ipython-dir` can change the configuration directory. Use
|
|
76
|
+
`ipython locate profile default` to find the active profile. See the [official
|
|
77
|
+
IPython configuration guide](https://ipython.readthedocs.io/en/stable/development/config.html).
|
|
78
|
+
|
|
79
|
+
For runtime template commands, detailed behavior, and contributor or release
|
|
80
|
+
steps, see [the extended guide](docs/REFERENCE.md).
|
|
@@ -0,0 +1,150 @@
|
|
|
1
|
+
# Extended Reference
|
|
2
|
+
|
|
3
|
+
This guide contains detailed template, configuration, Tab behavior, development,
|
|
4
|
+
and release information. For installation and common usage, see the [README](../README.md).
|
|
5
|
+
|
|
6
|
+
## Template Reference
|
|
7
|
+
|
|
8
|
+
Templates take the expression to the left of the dot as `{expr}`. `{indent}` is
|
|
9
|
+
the leading indentation of the input line. These are the built-in templates:
|
|
10
|
+
|
|
11
|
+
| Name | Expansion |
|
|
12
|
+
| --- | --- |
|
|
13
|
+
| `print` | `print({expr})` |
|
|
14
|
+
| `len` | `len({expr})` |
|
|
15
|
+
| `not` | `not {expr}` |
|
|
16
|
+
| `par` | `({expr})` |
|
|
17
|
+
| `var` | `key = {expr}`; selects `key` |
|
|
18
|
+
| `await` | `await {expr}` |
|
|
19
|
+
| `return` | `return {expr}` |
|
|
20
|
+
| `if` | `if {expr}:` with an indented `pass` |
|
|
21
|
+
| `while` | `while {expr}:` with an indented blank body |
|
|
22
|
+
| `for` | `for item in {expr}:` with an indented `pass` |
|
|
23
|
+
| `fori` | `for i, value in enumerate({expr}):` with an indented `pass` |
|
|
24
|
+
| `ef` | `if {expr}:`, `elif cond:`, and `else:` branches, each with `pass` |
|
|
25
|
+
| `raise` | `raise {expr}` |
|
|
26
|
+
| `yield` | `yield {expr}` |
|
|
27
|
+
| `str` | `str({expr})` |
|
|
28
|
+
| `list` | `list({expr})` |
|
|
29
|
+
| `set` | `set({expr})` |
|
|
30
|
+
| `dict` | `dict({expr})` |
|
|
31
|
+
| `tuple` | `tuple({expr})` |
|
|
32
|
+
| `type` | `type({expr})` |
|
|
33
|
+
| `range` | `range({expr})` |
|
|
34
|
+
|
|
35
|
+
Integer literals used with `.for` or `.fori` are wrapped in `range(...)`.
|
|
36
|
+
Signed and underscored integer literals are recognized. A variable such as `n`
|
|
37
|
+
is left unchanged because completion cannot know its runtime type. Thus
|
|
38
|
+
`10.fori` uses `enumerate(range(10))`, while `items.fori` uses
|
|
39
|
+
`enumerate(items)`.
|
|
40
|
+
|
|
41
|
+
When a partial name matches multiple templates, the completion menu lists each
|
|
42
|
+
match. In particular, `.f` can show both `for` and `fori`; Tab on the exact
|
|
43
|
+
`.if` suffix expands `if`.
|
|
44
|
+
|
|
45
|
+
## Placeholder and Tab Behavior
|
|
46
|
+
|
|
47
|
+
For built-in `.var`, `.for`, `.if`, `.fori`, and `.ef` templates, Tab accepts
|
|
48
|
+
the selected placeholder and advances to the next one. Shift+Tab selects the
|
|
49
|
+
previous placeholder. Typing replaces the selected text. After the final stop,
|
|
50
|
+
Tab accepts it and places the cursor after the expansion. Enter accepts the
|
|
51
|
+
selected `.var` name; press Enter again to submit the input.
|
|
52
|
+
|
|
53
|
+
The built-in placeholder behavior is enabled only when the corresponding
|
|
54
|
+
template retains its built-in definition. Overriding a built-in template
|
|
55
|
+
disables its special selection behavior.
|
|
56
|
+
|
|
57
|
+
### Smart Tab Jump
|
|
58
|
+
|
|
59
|
+
Smart Tab jump is enabled by default in terminal IPython. When the cursor is
|
|
60
|
+
immediately before a valid Python closing token, Tab moves over it without
|
|
61
|
+
changing source text. Repeated presses exit nested constructs:
|
|
62
|
+
|
|
63
|
+
```text
|
|
64
|
+
"hello|" -> "hello"|
|
|
65
|
+
print("hello|") -> print("hello"|) -> print("hello")|
|
|
66
|
+
print(f"{name|}") -> print(f"{name}|") -> print(f"{name}"|) -> print(f"{name}")|
|
|
67
|
+
items[index|] -> items[index]|
|
|
68
|
+
list[dict[str, int|]] -> list[dict[str, int]|] -> list[dict[str, int]]|
|
|
69
|
+
{"name": value|} -> {"name": value}|
|
|
70
|
+
```
|
|
71
|
+
|
|
72
|
+
`|` marks the cursor and is not typed. Supported closers are single and triple
|
|
73
|
+
quotes plus `)`, `]`, and `}`. Detection follows Python tokens, including
|
|
74
|
+
multiline input, string prefixes, and f-string expressions. Tab processes an
|
|
75
|
+
active placeholder and an exact postfix template first, then falls back to
|
|
76
|
+
IPython completion, closer movement, or indentation. Ambiguous `< >`, colon,
|
|
77
|
+
and comma are not treated as closers.
|
|
78
|
+
|
|
79
|
+
Disable smart Tab jump while retaining postfix completion with:
|
|
80
|
+
|
|
81
|
+
```python
|
|
82
|
+
c.PostfixCompletionConfig.smart_tab_jump = False
|
|
83
|
+
```
|
|
84
|
+
|
|
85
|
+
## Runtime Template Commands
|
|
86
|
+
|
|
87
|
+
Add or override a template for the current IPython session:
|
|
88
|
+
|
|
89
|
+
```python
|
|
90
|
+
%postfix_template add debug "print({expr}=)"
|
|
91
|
+
%postfix_template add forin "for item in {expr}:\n{indent} pass"
|
|
92
|
+
```
|
|
93
|
+
|
|
94
|
+
Disable, reset one, or reset all runtime changes:
|
|
95
|
+
|
|
96
|
+
```python
|
|
97
|
+
%postfix_template remove tuple
|
|
98
|
+
%postfix_template reset forin
|
|
99
|
+
%postfix_template reset --all
|
|
100
|
+
```
|
|
101
|
+
|
|
102
|
+
Runtime changes last only for the current session. Use
|
|
103
|
+
`%postfix_template list` to see built-in, custom, and disabled entries.
|
|
104
|
+
|
|
105
|
+
Persistent configuration belongs in
|
|
106
|
+
`~/.ipython/profile_default/ipython_config.py` by default. Create the profile
|
|
107
|
+
with `ipython profile create`; locate the active path with
|
|
108
|
+
`ipython locate profile default`. `IPYTHONDIR` or `--ipython-dir` can change
|
|
109
|
+
the IPython directory. See the [official IPython configuration guide](https://ipython.readthedocs.io/en/stable/development/config.html).
|
|
110
|
+
|
|
111
|
+
Template names must match `[A-Za-z_][A-Za-z0-9_]*`. Templates must include
|
|
112
|
+
`{expr}` and may also use `{indent}`. No other fields, conversions, or format
|
|
113
|
+
specifiers are allowed.
|
|
114
|
+
|
|
115
|
+
## Development
|
|
116
|
+
|
|
117
|
+
Run tests and style checks:
|
|
118
|
+
|
|
119
|
+
```bash
|
|
120
|
+
uv run --extra test pytest -q
|
|
121
|
+
uv run --extra dev ruff check .
|
|
122
|
+
uv run --extra dev ruff format --check .
|
|
123
|
+
```
|
|
124
|
+
|
|
125
|
+
Run IPython against the current checkout without installing into system Python:
|
|
126
|
+
|
|
127
|
+
```bash
|
|
128
|
+
uv run --with ipython --with-editable . ipython
|
|
129
|
+
```
|
|
130
|
+
|
|
131
|
+
Then load `ipython_postfix_completion` in that IPython session.
|
|
132
|
+
|
|
133
|
+
Build and validate release artifacts:
|
|
134
|
+
|
|
135
|
+
```bash
|
|
136
|
+
uv run --extra dev python -m build
|
|
137
|
+
uv run --extra dev python -m twine check dist/*
|
|
138
|
+
```
|
|
139
|
+
|
|
140
|
+
## Publishing
|
|
141
|
+
|
|
142
|
+
Releases use GitHub Actions and PyPI Trusted Publishing. Configure the PyPI
|
|
143
|
+
publisher for the `fishandsheep/ipython-postfix-completion` repository, the
|
|
144
|
+
`publish.yml` workflow, and the `pypi` environment. Update the version in
|
|
145
|
+
`pyproject.toml`, push the change, then create and push the matching `v` tag.
|
|
146
|
+
The workflow checks the tag against the project version, runs tests, builds and
|
|
147
|
+
checks distributions, and publishes them. Published PyPI versions and release
|
|
148
|
+
tags are immutable; use a new version for fixes.
|
|
149
|
+
|
|
150
|
+
See [CHANGELOG.md](../CHANGELOG.md) for release history.
|