textual-searchable-selectionlist 0.0.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 (25) hide show
  1. textual_searchable_selectionlist-0.0.1/.editorconfig +21 -0
  2. textual_searchable_selectionlist-0.0.1/.gitignore +73 -0
  3. textual_searchable_selectionlist-0.0.1/LICENSE.txt +21 -0
  4. textual_searchable_selectionlist-0.0.1/PKG-INFO +52 -0
  5. textual_searchable_selectionlist-0.0.1/README.md +36 -0
  6. textual_searchable_selectionlist-0.0.1/WARP.md +143 -0
  7. textual_searchable_selectionlist-0.0.1/admin/__init__.py +5 -0
  8. textual_searchable_selectionlist-0.0.1/admin/build.py +381 -0
  9. textual_searchable_selectionlist-0.0.1/admin/lint.py +54 -0
  10. textual_searchable_selectionlist-0.0.1/admin/pip.py +178 -0
  11. textual_searchable_selectionlist-0.0.1/admin/requirements/requirements-dev.in +12 -0
  12. textual_searchable_selectionlist-0.0.1/admin/requirements/requirements-dev.txt +138 -0
  13. textual_searchable_selectionlist-0.0.1/admin/requirements/requirements.in +1 -0
  14. textual_searchable_selectionlist-0.0.1/admin/requirements/requirements.txt +25 -0
  15. textual_searchable_selectionlist-0.0.1/admin/utils.py +160 -0
  16. textual_searchable_selectionlist-0.0.1/pyproject.toml +84 -0
  17. textual_searchable_selectionlist-0.0.1/src/textual_searchable_selectionlist/__init__.py +1 -0
  18. textual_searchable_selectionlist-0.0.1/src/textual_searchable_selectionlist/options.py +40 -0
  19. textual_searchable_selectionlist-0.0.1/src/textual_searchable_selectionlist/py.typed +2 -0
  20. textual_searchable_selectionlist-0.0.1/src/textual_searchable_selectionlist/searchable_list_app.py +65 -0
  21. textual_searchable_selectionlist-0.0.1/src/textual_searchable_selectionlist/searchable_list_widget.py +216 -0
  22. textual_searchable_selectionlist-0.0.1/src/textual_searchable_selectionlist/select.py +63 -0
  23. textual_searchable_selectionlist-0.0.1/tests/__init__.py +0 -0
  24. textual_searchable_selectionlist-0.0.1/tests/manual/__init__.py +0 -0
  25. textual_searchable_selectionlist-0.0.1/tests/manual/searchable_selection_list_select.py +22 -0
@@ -0,0 +1,21 @@
1
+ # http://editorconfig.org
2
+
3
+ root = true
4
+
5
+ [*]
6
+ indent_style = space
7
+ indent_size = 4
8
+ trim_trailing_whitespace = true
9
+ insert_final_newline = true
10
+ charset = utf-8
11
+ end_of_line = lf
12
+
13
+ [*.md]
14
+ trim_trailing_whitespace = false
15
+
16
+ [*.bat]
17
+ indent_style = tab
18
+ end_of_line = crlf
19
+
20
+ [Makefile]
21
+ indent_style = tab
@@ -0,0 +1,73 @@
1
+ # Byte-compiled / optimized / DLL files
2
+ __pycache__/
3
+ *.py[cod]
4
+ *$py.class
5
+
6
+ # Distribution / packaging
7
+ .Python
8
+ env/
9
+ build/
10
+ develop-eggs/
11
+ dist/
12
+ downloads/
13
+ eggs/
14
+ .eggs/
15
+ lib/
16
+ lib64/
17
+ parts/
18
+ sdist/
19
+ var/
20
+ wheels/
21
+ *.egg-info/
22
+ .installed.cfg
23
+ *.egg
24
+
25
+ # Installer logs
26
+ pip-log.txt
27
+ pip-delete-this-directory.txt
28
+
29
+ # Unit test / coverage reports
30
+ htmlcov/
31
+ .tox/
32
+ .coverage
33
+ .coverage.*
34
+ .cache
35
+ nosetests.xml
36
+ coverage.xml
37
+ *.cover
38
+ .hypothesis/
39
+ .pytest_cache/
40
+
41
+ # PyBuilder
42
+ target/
43
+
44
+ # pyenv
45
+ .python-version
46
+
47
+ # dotenv
48
+ .env
49
+
50
+ # virtualenv
51
+ .venv
52
+ venv/
53
+ ENV/
54
+
55
+ # Spyder project settings
56
+ .spyderproject
57
+ .spyproject
58
+
59
+ # mkdocs documentation
60
+ /site
61
+
62
+ # mypy
63
+ .mypy_cache/
64
+
65
+ # DS Store files
66
+ .DS_Store
67
+
68
+ # IDE settings
69
+ .vscode/
70
+ .idea/
71
+
72
+ # Misc
73
+ release-notes.md
@@ -0,0 +1,21 @@
1
+ MIT License
2
+
3
+ Copyright (c) 2026, Joao Coelho
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining a copy
6
+ of this software and associated documentation files (the "Software"), to deal
7
+ in the Software without restriction, including without limitation the rights
8
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9
+ copies of the Software, and to permit persons to whom the Software is
10
+ furnished to do so, subject to the following conditions:
11
+
12
+ The above copyright notice and this permission notice shall be included in all
13
+ copies or substantial portions of the Software.
14
+
15
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21
+ SOFTWARE.
@@ -0,0 +1,52 @@
1
+ Metadata-Version: 2.4
2
+ Name: textual-searchable-selectionlist
3
+ Version: 0.0.1
4
+ Summary: Add search to Textual SelectionList.
5
+ Author: Joao Coelho
6
+ Description-Content-Type: text/markdown
7
+ Classifier: License :: OSI Approved :: MIT License
8
+ Classifier: Framework :: Pytest
9
+ Classifier: Intended Audience :: Developers
10
+ Classifier: Programming Language :: Python
11
+ Classifier: Development Status :: 4 - Beta
12
+ License-File: LICENSE.txt
13
+ Requires-Dist: textual
14
+ Project-URL: Home, https://github.com/joaonc/textual-searchable-selectionlist
15
+
16
+ # Searchable SelectionList
17
+ Add search to Textual's [SelectionList](https://textual.textualize.io/widgets/selection_list/).
18
+
19
+ * Selectable items can be filtered by substring.
20
+ * Select one or multiple items.
21
+ * Search is case-insensitive.
22
+
23
+ ## Installation
24
+ ```bash
25
+ pip install searchable-selection-list
26
+ ```
27
+
28
+ ## Usage
29
+ ```python
30
+ from textual_searchable_selectionlist.options import SelectionStrategy
31
+ from textual_searchable_selectionlist.select import select, select_enum
32
+
33
+ selected = select(
34
+ ['John', 'Jane', 'James'],
35
+ selection_strategy=SelectionStrategy.MULTIPLE,
36
+ search_title='Select people',
37
+ )
38
+
39
+ # Enums
40
+ # class Color(Enum):
41
+ # RED = 'red'
42
+ # GREEN = 'green'
43
+ #
44
+ # selected_colors = select_enum(Color, selection_strategy=SelectionStrategy.ONE)
45
+ ```
46
+
47
+ ## Testing
48
+ There are currently no automated tests. Manual testing can be done by running:
49
+ ```bash
50
+ python tests/manual/searchable_selection_list_select.py
51
+ ```
52
+
@@ -0,0 +1,36 @@
1
+ # Searchable SelectionList
2
+ Add search to Textual's [SelectionList](https://textual.textualize.io/widgets/selection_list/).
3
+
4
+ * Selectable items can be filtered by substring.
5
+ * Select one or multiple items.
6
+ * Search is case-insensitive.
7
+
8
+ ## Installation
9
+ ```bash
10
+ pip install searchable-selection-list
11
+ ```
12
+
13
+ ## Usage
14
+ ```python
15
+ from textual_searchable_selectionlist.options import SelectionStrategy
16
+ from textual_searchable_selectionlist.select import select, select_enum
17
+
18
+ selected = select(
19
+ ['John', 'Jane', 'James'],
20
+ selection_strategy=SelectionStrategy.MULTIPLE,
21
+ search_title='Select people',
22
+ )
23
+
24
+ # Enums
25
+ # class Color(Enum):
26
+ # RED = 'red'
27
+ # GREEN = 'green'
28
+ #
29
+ # selected_colors = select_enum(Color, selection_strategy=SelectionStrategy.ONE)
30
+ ```
31
+
32
+ ## Testing
33
+ There are currently no automated tests. Manual testing can be done by running:
34
+ ```bash
35
+ python tests/manual/searchable_selection_list_select.py
36
+ ```
@@ -0,0 +1,143 @@
1
+ # WARP.md
2
+
3
+ This file provides guidance to WARP (warp.dev) when working with code in this repository.
4
+
5
+ ## Project Overview
6
+
7
+ A Textual widget library that adds search functionality to Textual's SelectionList widget. The widget provides case-insensitive substring filtering, supports single and multiple selection modes, and offers an API for programmatic selection in terminal-based applications.
8
+
9
+ ## Development Commands
10
+
11
+ ### Task Runner
12
+ This project uses `typer-invoke` to organize development tasks into admin modules. The configuration is in `pyproject.toml` under `[tool.typer-invoke]`.
13
+
14
+ Run tasks using Python module syntax:
15
+ ```bash
16
+ python -m admin.lint --help
17
+ python -m admin.build --help
18
+ python -m admin.pip --help
19
+ ```
20
+
21
+ ### Linting and Formatting
22
+ All linter configurations are in `pyproject.toml`.
23
+
24
+ Run all linters in sequence:
25
+ ```bash
26
+ python -m admin.lint all
27
+ ```
28
+
29
+ Run individual linters:
30
+ ```bash
31
+ python -m admin.lint black .
32
+ python -m admin.lint isort .
33
+ python -m admin.lint flake8 .
34
+ python -m admin.lint mypy .
35
+ ```
36
+
37
+ ### Building and Publishing
38
+
39
+ Clean build artifacts:
40
+ ```bash
41
+ python -m admin.build clean
42
+ ```
43
+
44
+ Update version (interactive or with flags):
45
+ ```bash
46
+ python -m admin.build version --bump patch
47
+ python -m admin.build version --version 1.2.3
48
+ ```
49
+
50
+ Build and publish package:
51
+ ```bash
52
+ python -m admin.build publish
53
+ ```
54
+
55
+ ### Package Management
56
+
57
+ Compile requirements files (uses pip-compile):
58
+ ```bash
59
+ python -m admin.pip compile
60
+ python -m admin.pip compile --clean
61
+ ```
62
+
63
+ Sync environment with requirements:
64
+ ```bash
65
+ python -m admin.pip sync
66
+ ```
67
+
68
+ Install requirements:
69
+ ```bash
70
+ python -m admin.pip install
71
+ ```
72
+
73
+ ### Testing
74
+
75
+ There are currently no automated unit tests. Manual testing can be done by running:
76
+ ```bash
77
+ python tests/manual/searchable_selection_list_select.py
78
+ ```
79
+
80
+ ## Code Architecture
81
+
82
+ ### Core Components
83
+
84
+ **SearchableListWidget** (`searchable_list_widget.py`)
85
+ - Main widget that combines a search Input with a SelectionList
86
+ - Handles keyboard navigation (arrow keys, enter, escape, ctrl+space/a/d)
87
+ - Implements real-time filtering by disabling non-matching options
88
+ - Generic over SelectionType for type safety
89
+ - Key behavior: when focused on SelectionList, alphanumeric keys are routed to the search input
90
+
91
+ **SearchableListApp** (`searchable_list_app.py`)
92
+ - Textual App wrapper for SearchableListWidget
93
+ - Provides full-screen or inline display modes
94
+ - Returns selected items via app.exit()
95
+ - Handles SelectionStrategy.ALL by immediately exiting with all items
96
+
97
+ **SelectionStrategy** (`options.py`)
98
+ - Enum defining selection modes: MULTIPLE, ONE, ALL, FAIL
99
+ - MULTIPLE/ALL: Allow selecting multiple items
100
+ - ONE: Single selection mode (deselects others when selecting)
101
+ - FAIL: Raises ValueError if multiple selections provided
102
+
103
+ **select() function** (`select.py`)
104
+ - High-level API for quick item selection
105
+ - Returns list of selected items
106
+ - Supports string, tuple, or Selection objects as input
107
+ - Includes select_enum() helper for selecting from Python enums
108
+
109
+ ### Module Structure
110
+ ```
111
+ src/textual_searchable_selectionlist/
112
+ ├── __init__.py # Version info
113
+ ├── searchable_list_widget.py # Core widget implementation
114
+ ├── searchable_list_app.py # Textual app wrapper
115
+ ├── options.py # Selection mode enum and filtering options
116
+ └── select.py # High-level selection API
117
+
118
+ admin/ # Development task modules
119
+ ├── __init__.py # Project constants (PROJECT_ROOT, SOURCE_DIR)
120
+ ├── utils.py # Shared utilities (run, logger, etc.)
121
+ ├── build.py # Build, version, and publish tasks
122
+ ├── lint.py # Linting tasks
123
+ ├── pip.py # Package management tasks
124
+ └── requirements/ # Requirements files (.in and .txt)
125
+ ```
126
+
127
+ ### Key Design Patterns
128
+
129
+ **Filtering mechanism**: Items are filtered by setting `option.disabled = not is_match` rather than removing them from the list, preserving indices.
130
+
131
+ **Keyboard routing**: When SelectionList is focused, single alphanumeric keypresses are intercepted and forwarded to the search Input via `input_widget.post_message(event)`.
132
+
133
+ **Callback-based selection**: Widget accepts `selected_callback` that's invoked on Enter key, receiving the list of selected items.
134
+
135
+ **Build system**: Uses flit for building/publishing. Version is tracked in both `pyproject.toml` and `src/textual_searchable_selectionlist/__init__.py`.
136
+
137
+ ## Code Style
138
+
139
+ - Follow PEP8 with 100 character line limit (enforced by black)
140
+ - Single quotes for strings, triple double quotes for docstrings
141
+ - Python 3.12+ syntax and type hints (use `str | None` not `Optional[str]`)
142
+ - 4 spaces for indentation
143
+ - Line endings: LF (Unix style, see `.editorconfig`)
@@ -0,0 +1,5 @@
1
+ from pathlib import Path
2
+
3
+ PROJECT_ROOT = Path(__file__).parents[1]
4
+ PROJECT_NAME = PROJECT_ROOT.name.replace('-', '_')
5
+ SOURCE_DIR = PROJECT_ROOT / 'src' / PROJECT_NAME