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.
Files changed (20) hide show
  1. ipython_postfix_completion-0.2.1/CHANGELOG.md +47 -0
  2. {ipython_postfix_completion-0.1.1 → ipython_postfix_completion-0.2.1}/MANIFEST.in +2 -0
  3. ipython_postfix_completion-0.2.1/PKG-INFO +115 -0
  4. ipython_postfix_completion-0.2.1/README.md +80 -0
  5. ipython_postfix_completion-0.2.1/docs/REFERENCE.md +150 -0
  6. ipython_postfix_completion-0.2.1/ipython_postfix_completion/__init__.py +1038 -0
  7. ipython_postfix_completion-0.2.1/ipython_postfix_completion.egg-info/PKG-INFO +115 -0
  8. {ipython_postfix_completion-0.1.1 → ipython_postfix_completion-0.2.1}/ipython_postfix_completion.egg-info/SOURCES.txt +2 -0
  9. {ipython_postfix_completion-0.1.1 → ipython_postfix_completion-0.2.1}/ipython_postfix_completion.egg-info/requires.txt +3 -1
  10. {ipython_postfix_completion-0.1.1 → ipython_postfix_completion-0.2.1}/pyproject.toml +11 -2
  11. {ipython_postfix_completion-0.1.1 → ipython_postfix_completion-0.2.1}/tests/test_postfix_completion.py +332 -31
  12. ipython_postfix_completion-0.1.1/PKG-INFO +0 -218
  13. ipython_postfix_completion-0.1.1/README.md +0 -190
  14. ipython_postfix_completion-0.1.1/ipython_postfix_completion/__init__.py +0 -559
  15. ipython_postfix_completion-0.1.1/ipython_postfix_completion.egg-info/PKG-INFO +0 -218
  16. {ipython_postfix_completion-0.1.1 → ipython_postfix_completion-0.2.1}/LICENSE +0 -0
  17. {ipython_postfix_completion-0.1.1 → ipython_postfix_completion-0.2.1}/ipython_postfix_completion.egg-info/dependency_links.txt +0 -0
  18. {ipython_postfix_completion-0.1.1 → ipython_postfix_completion-0.2.1}/ipython_postfix_completion.egg-info/top_level.txt +0 -0
  19. {ipython_postfix_completion-0.1.1 → ipython_postfix_completion-0.2.1}/setup.cfg +0 -0
  20. {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.
@@ -1,3 +1,5 @@
1
1
  include LICENSE
2
2
  include README.md
3
+ include CHANGELOG.md
3
4
  recursive-include tests *.py
5
+ recursive-include docs *.md
@@ -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.