notispf 1.0.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.
- notispf-1.0.0/PKG-INFO +229 -0
- notispf-1.0.0/README.md +206 -0
- notispf-1.0.0/notispf/__init__.py +1 -0
- notispf-1.0.0/notispf/__main__.py +14 -0
- notispf-1.0.0/notispf/app.py +621 -0
- notispf-1.0.0/notispf/buffer.py +173 -0
- notispf-1.0.0/notispf/commands/__init__.py +4 -0
- notispf-1.0.0/notispf/commands/block_cmds.py +51 -0
- notispf-1.0.0/notispf/commands/exclude_cmds.py +38 -0
- notispf-1.0.0/notispf/commands/line_cmds.py +88 -0
- notispf-1.0.0/notispf/commands/registry.py +66 -0
- notispf-1.0.0/notispf/display.py +401 -0
- notispf-1.0.0/notispf/find_change.py +186 -0
- notispf-1.0.0/notispf/prefix.py +102 -0
- notispf-1.0.0/notispf.egg-info/PKG-INFO +229 -0
- notispf-1.0.0/notispf.egg-info/SOURCES.txt +25 -0
- notispf-1.0.0/notispf.egg-info/dependency_links.txt +1 -0
- notispf-1.0.0/notispf.egg-info/entry_points.txt +2 -0
- notispf-1.0.0/notispf.egg-info/top_level.txt +1 -0
- notispf-1.0.0/pyproject.toml +42 -0
- notispf-1.0.0/setup.cfg +4 -0
- notispf-1.0.0/tests/test_buffer.py +90 -0
- notispf-1.0.0/tests/test_exclude.py +150 -0
- notispf-1.0.0/tests/test_find_change.py +289 -0
- notispf-1.0.0/tests/test_line_cmds.py +152 -0
- notispf-1.0.0/tests/test_overlay.py +145 -0
- notispf-1.0.0/tests/test_prefix.py +155 -0
notispf-1.0.0/PKG-INFO
ADDED
|
@@ -0,0 +1,229 @@
|
|
|
1
|
+
Metadata-Version: 2.4
|
|
2
|
+
Name: notispf
|
|
3
|
+
Version: 1.0.0
|
|
4
|
+
Summary: A terminal text editor inspired by the ISPF editor from z/OS
|
|
5
|
+
Author-email: mrthock <m64357@gmail.com>
|
|
6
|
+
License: MIT
|
|
7
|
+
Project-URL: Homepage, https://github.com/mrthock/notispf
|
|
8
|
+
Project-URL: Repository, https://github.com/mrthock/notispf
|
|
9
|
+
Project-URL: Bug Tracker, https://github.com/mrthock/notispf/issues
|
|
10
|
+
Keywords: editor,ispf,terminal,tui,mainframe,zos
|
|
11
|
+
Classifier: Development Status :: 4 - Beta
|
|
12
|
+
Classifier: Environment :: Console
|
|
13
|
+
Classifier: Intended Audience :: Developers
|
|
14
|
+
Classifier: Intended Audience :: System Administrators
|
|
15
|
+
Classifier: License :: OSI Approved :: MIT License
|
|
16
|
+
Classifier: Operating System :: POSIX :: Linux
|
|
17
|
+
Classifier: Programming Language :: Python :: 3
|
|
18
|
+
Classifier: Programming Language :: Python :: 3.11
|
|
19
|
+
Classifier: Programming Language :: Python :: 3.12
|
|
20
|
+
Classifier: Topic :: Text Editors
|
|
21
|
+
Requires-Python: >=3.11
|
|
22
|
+
Description-Content-Type: text/markdown
|
|
23
|
+
|
|
24
|
+
# notispf
|
|
25
|
+
|
|
26
|
+
A terminal text editor for Linux and macOS inspired by the ISPF editor from z/OS mainframes.
|
|
27
|
+
Runs in your terminal like vim or nano, with the prefix command area that ISPF users know and love.
|
|
28
|
+
|
|
29
|
+
## Installation
|
|
30
|
+
|
|
31
|
+
### Download a binary (no Python required)
|
|
32
|
+
|
|
33
|
+
Go to the [Releases page](https://github.com/mrthock/notispf/releases) and download the binary for your platform:
|
|
34
|
+
|
|
35
|
+
| Platform | File |
|
|
36
|
+
|----------|------|
|
|
37
|
+
| Linux | `notispf-linux` |
|
|
38
|
+
| macOS | `notispf-macos` |
|
|
39
|
+
| Windows | `notispf-windows.exe` |
|
|
40
|
+
|
|
41
|
+
**Linux / macOS:**
|
|
42
|
+
```bash
|
|
43
|
+
chmod +x notispf-linux # or notispf-macos
|
|
44
|
+
./notispf-linux myfile.txt
|
|
45
|
+
```
|
|
46
|
+
|
|
47
|
+
Optionally move it somewhere on your PATH:
|
|
48
|
+
```bash
|
|
49
|
+
mv notispf-linux ~/.local/bin/notispf
|
|
50
|
+
```
|
|
51
|
+
|
|
52
|
+
**macOS note:** macOS will warn that the binary is from an unidentified developer. To clear the warning:
|
|
53
|
+
```bash
|
|
54
|
+
xattr -d com.apple.quarantine ./notispf-macos
|
|
55
|
+
```
|
|
56
|
+
Then run it normally.
|
|
57
|
+
|
|
58
|
+
### Via pip
|
|
59
|
+
|
|
60
|
+
```bash
|
|
61
|
+
pip install notispf
|
|
62
|
+
```
|
|
63
|
+
|
|
64
|
+
### From source
|
|
65
|
+
|
|
66
|
+
```bash
|
|
67
|
+
git clone https://github.com/mrthock/notispf
|
|
68
|
+
cd notispf
|
|
69
|
+
pip install -e .
|
|
70
|
+
```
|
|
71
|
+
|
|
72
|
+
## Usage
|
|
73
|
+
|
|
74
|
+
```bash
|
|
75
|
+
notispf <file>
|
|
76
|
+
```
|
|
77
|
+
|
|
78
|
+
## Screen Layout
|
|
79
|
+
|
|
80
|
+
```
|
|
81
|
+
notispf filename.txt Line 1/42
|
|
82
|
+
000001|This is the first line of your file
|
|
83
|
+
000002|Second line here
|
|
84
|
+
000003|Third line
|
|
85
|
+
|~
|
|
86
|
+
|~
|
|
87
|
+
Type prefix command, Enter to execute, Esc to cancel
|
|
88
|
+
```
|
|
89
|
+
|
|
90
|
+
- **Status bar** (top) — filename, modified flag `[+]`, current line/total
|
|
91
|
+
- **Prefix column** (left, 6 chars) — shows line numbers; type commands here
|
|
92
|
+
- **Text area** (right of `|`) — edit your file
|
|
93
|
+
- **Message/command line** (bottom) — status messages and command input
|
|
94
|
+
|
|
95
|
+
## Navigation
|
|
96
|
+
|
|
97
|
+
| Key | Action |
|
|
98
|
+
|-----|--------|
|
|
99
|
+
| Arrow keys | Move cursor |
|
|
100
|
+
| Page Up / Page Down | Scroll |
|
|
101
|
+
| Home / Ctrl+A | Beginning of line |
|
|
102
|
+
| End / Ctrl+E | End of line |
|
|
103
|
+
|
|
104
|
+
## Switching Between Text and Prefix Area
|
|
105
|
+
|
|
106
|
+
| Key | Action |
|
|
107
|
+
|-----|--------|
|
|
108
|
+
| Tab | text(N) → prefix(N+1) |
|
|
109
|
+
| Tab | prefix(N) → text(N) |
|
|
110
|
+
| Shift+Tab | text(N) → prefix(N) |
|
|
111
|
+
| Shift+Tab | prefix(N) → text(N-1) |
|
|
112
|
+
|
|
113
|
+
## Prefix Commands
|
|
114
|
+
|
|
115
|
+
Type a command into the prefix column, then press **Enter** to execute.
|
|
116
|
+
You can stage commands on multiple lines before pressing Enter — they all execute at once.
|
|
117
|
+
|
|
118
|
+
### Single-Line Commands
|
|
119
|
+
|
|
120
|
+
| Command | Action |
|
|
121
|
+
|---------|--------|
|
|
122
|
+
| `D` | Delete line |
|
|
123
|
+
| `Dn` | Delete n lines (e.g. `D5` deletes 5) |
|
|
124
|
+
| `I` | Insert blank line after |
|
|
125
|
+
| `In` | Insert n blank lines |
|
|
126
|
+
| `R` | Repeat line |
|
|
127
|
+
| `Rn` | Repeat line n times |
|
|
128
|
+
| `C` | Copy line to clipboard |
|
|
129
|
+
| `Cn` | Copy n lines to clipboard |
|
|
130
|
+
| `M` | Move line (cut to clipboard) |
|
|
131
|
+
| `Mn` | Move n lines |
|
|
132
|
+
| `A` | Paste clipboard **after** this line |
|
|
133
|
+
| `B` | Paste clipboard **before** this line |
|
|
134
|
+
|
|
135
|
+
### Block Commands
|
|
136
|
+
|
|
137
|
+
Type the command on the **first** line of the block, then again on the **last** line.
|
|
138
|
+
|
|
139
|
+
| Command | Action |
|
|
140
|
+
|---------|--------|
|
|
141
|
+
| `DD` | Delete block |
|
|
142
|
+
| `CC` | Copy block to clipboard |
|
|
143
|
+
| `MM` | Move block (cut to clipboard) |
|
|
144
|
+
| `RR` | Repeat block (insert a copy below) |
|
|
145
|
+
|
|
146
|
+
Use `A` or `B` on a third line to place the clipboard after copying or moving.
|
|
147
|
+
|
|
148
|
+
**Example — move lines 3–6 to after line 10:**
|
|
149
|
+
1. Tab to line 3 prefix → type `MM`
|
|
150
|
+
2. Arrow down to line 6 → type `MM`
|
|
151
|
+
3. Arrow down to line 10 → type `A`
|
|
152
|
+
4. Press Enter
|
|
153
|
+
|
|
154
|
+
### Prefix Mode Controls
|
|
155
|
+
|
|
156
|
+
| Key | Action |
|
|
157
|
+
|-----|--------|
|
|
158
|
+
| Enter | Execute all staged prefix commands |
|
|
159
|
+
| Escape | Cancel all staged commands and exit prefix mode |
|
|
160
|
+
| ↑ / ↓ | Move between lines (keeps staged commands) |
|
|
161
|
+
|
|
162
|
+
## Command Line
|
|
163
|
+
|
|
164
|
+
Press **`=`** or **`F6`** to open the command line, then type a command and press Enter.
|
|
165
|
+
|
|
166
|
+
### File Commands
|
|
167
|
+
|
|
168
|
+
| Command | Action |
|
|
169
|
+
|---------|--------|
|
|
170
|
+
| `SAVE` | Save file |
|
|
171
|
+
| `FILE` | Save and exit |
|
|
172
|
+
| `CANCEL` or `QUIT` | Exit without saving |
|
|
173
|
+
|
|
174
|
+
### Find and Change
|
|
175
|
+
|
|
176
|
+
```
|
|
177
|
+
FIND "text"
|
|
178
|
+
CHANGE "old" "new"
|
|
179
|
+
CHANGE "old" "new" ALL
|
|
180
|
+
CHANGE "old" "new" ALL .labelA .labelB
|
|
181
|
+
```
|
|
182
|
+
|
|
183
|
+
- `FIND` — locate next occurrence (case-insensitive by default)
|
|
184
|
+
- `CHANGE` — replace next occurrence
|
|
185
|
+
- `CHANGE ... ALL` — replace all occurrences in file
|
|
186
|
+
- `CHANGE ... ALL .A .B` — replace all occurrences between labeled lines
|
|
187
|
+
|
|
188
|
+
### Labels
|
|
189
|
+
|
|
190
|
+
Type `.A`, `.B` etc. in the prefix column to assign a label to a line.
|
|
191
|
+
Labels are used to define ranges for `CHANGE ... ALL .A .B`.
|
|
192
|
+
|
|
193
|
+
## Function Keys
|
|
194
|
+
|
|
195
|
+
| Key | Action |
|
|
196
|
+
|-----|--------|
|
|
197
|
+
| F3 | Save and exit |
|
|
198
|
+
| F5 | Save without exiting |
|
|
199
|
+
| F6 | Open command line |
|
|
200
|
+
| F12 | Exit without saving |
|
|
201
|
+
|
|
202
|
+
## Contributing
|
|
203
|
+
|
|
204
|
+
notispf is designed to be easy to extend. Adding a new prefix command takes three steps:
|
|
205
|
+
|
|
206
|
+
1. Write a handler function in `notispf/commands/line_cmds.py`:
|
|
207
|
+
|
|
208
|
+
```python
|
|
209
|
+
def cmd_trim(buffer: Buffer, line_idx: int, count: int) -> EditorResult:
|
|
210
|
+
for i in range(line_idx, min(line_idx + count, len(buffer))):
|
|
211
|
+
buffer.replace_line(i, buffer.lines[i].text.rstrip())
|
|
212
|
+
return EditorResult(success=True)
|
|
213
|
+
```
|
|
214
|
+
|
|
215
|
+
2. Register it in the same file's `register()` function:
|
|
216
|
+
|
|
217
|
+
```python
|
|
218
|
+
registry.register_line_cmd(CommandSpec("T", cmd_trim, description="Trim trailing whitespace"))
|
|
219
|
+
```
|
|
220
|
+
|
|
221
|
+
3. Add tests in `tests/test_line_cmds.py`.
|
|
222
|
+
|
|
223
|
+
That's it — no changes to the prefix state machine, display, or app controller needed.
|
|
224
|
+
|
|
225
|
+
See [ARCHITECTURE.md](ARCHITECTURE.md) for a deeper overview of the codebase.
|
|
226
|
+
|
|
227
|
+
## License
|
|
228
|
+
|
|
229
|
+
MIT
|
notispf-1.0.0/README.md
ADDED
|
@@ -0,0 +1,206 @@
|
|
|
1
|
+
# notispf
|
|
2
|
+
|
|
3
|
+
A terminal text editor for Linux and macOS inspired by the ISPF editor from z/OS mainframes.
|
|
4
|
+
Runs in your terminal like vim or nano, with the prefix command area that ISPF users know and love.
|
|
5
|
+
|
|
6
|
+
## Installation
|
|
7
|
+
|
|
8
|
+
### Download a binary (no Python required)
|
|
9
|
+
|
|
10
|
+
Go to the [Releases page](https://github.com/mrthock/notispf/releases) and download the binary for your platform:
|
|
11
|
+
|
|
12
|
+
| Platform | File |
|
|
13
|
+
|----------|------|
|
|
14
|
+
| Linux | `notispf-linux` |
|
|
15
|
+
| macOS | `notispf-macos` |
|
|
16
|
+
| Windows | `notispf-windows.exe` |
|
|
17
|
+
|
|
18
|
+
**Linux / macOS:**
|
|
19
|
+
```bash
|
|
20
|
+
chmod +x notispf-linux # or notispf-macos
|
|
21
|
+
./notispf-linux myfile.txt
|
|
22
|
+
```
|
|
23
|
+
|
|
24
|
+
Optionally move it somewhere on your PATH:
|
|
25
|
+
```bash
|
|
26
|
+
mv notispf-linux ~/.local/bin/notispf
|
|
27
|
+
```
|
|
28
|
+
|
|
29
|
+
**macOS note:** macOS will warn that the binary is from an unidentified developer. To clear the warning:
|
|
30
|
+
```bash
|
|
31
|
+
xattr -d com.apple.quarantine ./notispf-macos
|
|
32
|
+
```
|
|
33
|
+
Then run it normally.
|
|
34
|
+
|
|
35
|
+
### Via pip
|
|
36
|
+
|
|
37
|
+
```bash
|
|
38
|
+
pip install notispf
|
|
39
|
+
```
|
|
40
|
+
|
|
41
|
+
### From source
|
|
42
|
+
|
|
43
|
+
```bash
|
|
44
|
+
git clone https://github.com/mrthock/notispf
|
|
45
|
+
cd notispf
|
|
46
|
+
pip install -e .
|
|
47
|
+
```
|
|
48
|
+
|
|
49
|
+
## Usage
|
|
50
|
+
|
|
51
|
+
```bash
|
|
52
|
+
notispf <file>
|
|
53
|
+
```
|
|
54
|
+
|
|
55
|
+
## Screen Layout
|
|
56
|
+
|
|
57
|
+
```
|
|
58
|
+
notispf filename.txt Line 1/42
|
|
59
|
+
000001|This is the first line of your file
|
|
60
|
+
000002|Second line here
|
|
61
|
+
000003|Third line
|
|
62
|
+
|~
|
|
63
|
+
|~
|
|
64
|
+
Type prefix command, Enter to execute, Esc to cancel
|
|
65
|
+
```
|
|
66
|
+
|
|
67
|
+
- **Status bar** (top) — filename, modified flag `[+]`, current line/total
|
|
68
|
+
- **Prefix column** (left, 6 chars) — shows line numbers; type commands here
|
|
69
|
+
- **Text area** (right of `|`) — edit your file
|
|
70
|
+
- **Message/command line** (bottom) — status messages and command input
|
|
71
|
+
|
|
72
|
+
## Navigation
|
|
73
|
+
|
|
74
|
+
| Key | Action |
|
|
75
|
+
|-----|--------|
|
|
76
|
+
| Arrow keys | Move cursor |
|
|
77
|
+
| Page Up / Page Down | Scroll |
|
|
78
|
+
| Home / Ctrl+A | Beginning of line |
|
|
79
|
+
| End / Ctrl+E | End of line |
|
|
80
|
+
|
|
81
|
+
## Switching Between Text and Prefix Area
|
|
82
|
+
|
|
83
|
+
| Key | Action |
|
|
84
|
+
|-----|--------|
|
|
85
|
+
| Tab | text(N) → prefix(N+1) |
|
|
86
|
+
| Tab | prefix(N) → text(N) |
|
|
87
|
+
| Shift+Tab | text(N) → prefix(N) |
|
|
88
|
+
| Shift+Tab | prefix(N) → text(N-1) |
|
|
89
|
+
|
|
90
|
+
## Prefix Commands
|
|
91
|
+
|
|
92
|
+
Type a command into the prefix column, then press **Enter** to execute.
|
|
93
|
+
You can stage commands on multiple lines before pressing Enter — they all execute at once.
|
|
94
|
+
|
|
95
|
+
### Single-Line Commands
|
|
96
|
+
|
|
97
|
+
| Command | Action |
|
|
98
|
+
|---------|--------|
|
|
99
|
+
| `D` | Delete line |
|
|
100
|
+
| `Dn` | Delete n lines (e.g. `D5` deletes 5) |
|
|
101
|
+
| `I` | Insert blank line after |
|
|
102
|
+
| `In` | Insert n blank lines |
|
|
103
|
+
| `R` | Repeat line |
|
|
104
|
+
| `Rn` | Repeat line n times |
|
|
105
|
+
| `C` | Copy line to clipboard |
|
|
106
|
+
| `Cn` | Copy n lines to clipboard |
|
|
107
|
+
| `M` | Move line (cut to clipboard) |
|
|
108
|
+
| `Mn` | Move n lines |
|
|
109
|
+
| `A` | Paste clipboard **after** this line |
|
|
110
|
+
| `B` | Paste clipboard **before** this line |
|
|
111
|
+
|
|
112
|
+
### Block Commands
|
|
113
|
+
|
|
114
|
+
Type the command on the **first** line of the block, then again on the **last** line.
|
|
115
|
+
|
|
116
|
+
| Command | Action |
|
|
117
|
+
|---------|--------|
|
|
118
|
+
| `DD` | Delete block |
|
|
119
|
+
| `CC` | Copy block to clipboard |
|
|
120
|
+
| `MM` | Move block (cut to clipboard) |
|
|
121
|
+
| `RR` | Repeat block (insert a copy below) |
|
|
122
|
+
|
|
123
|
+
Use `A` or `B` on a third line to place the clipboard after copying or moving.
|
|
124
|
+
|
|
125
|
+
**Example — move lines 3–6 to after line 10:**
|
|
126
|
+
1. Tab to line 3 prefix → type `MM`
|
|
127
|
+
2. Arrow down to line 6 → type `MM`
|
|
128
|
+
3. Arrow down to line 10 → type `A`
|
|
129
|
+
4. Press Enter
|
|
130
|
+
|
|
131
|
+
### Prefix Mode Controls
|
|
132
|
+
|
|
133
|
+
| Key | Action |
|
|
134
|
+
|-----|--------|
|
|
135
|
+
| Enter | Execute all staged prefix commands |
|
|
136
|
+
| Escape | Cancel all staged commands and exit prefix mode |
|
|
137
|
+
| ↑ / ↓ | Move between lines (keeps staged commands) |
|
|
138
|
+
|
|
139
|
+
## Command Line
|
|
140
|
+
|
|
141
|
+
Press **`=`** or **`F6`** to open the command line, then type a command and press Enter.
|
|
142
|
+
|
|
143
|
+
### File Commands
|
|
144
|
+
|
|
145
|
+
| Command | Action |
|
|
146
|
+
|---------|--------|
|
|
147
|
+
| `SAVE` | Save file |
|
|
148
|
+
| `FILE` | Save and exit |
|
|
149
|
+
| `CANCEL` or `QUIT` | Exit without saving |
|
|
150
|
+
|
|
151
|
+
### Find and Change
|
|
152
|
+
|
|
153
|
+
```
|
|
154
|
+
FIND "text"
|
|
155
|
+
CHANGE "old" "new"
|
|
156
|
+
CHANGE "old" "new" ALL
|
|
157
|
+
CHANGE "old" "new" ALL .labelA .labelB
|
|
158
|
+
```
|
|
159
|
+
|
|
160
|
+
- `FIND` — locate next occurrence (case-insensitive by default)
|
|
161
|
+
- `CHANGE` — replace next occurrence
|
|
162
|
+
- `CHANGE ... ALL` — replace all occurrences in file
|
|
163
|
+
- `CHANGE ... ALL .A .B` — replace all occurrences between labeled lines
|
|
164
|
+
|
|
165
|
+
### Labels
|
|
166
|
+
|
|
167
|
+
Type `.A`, `.B` etc. in the prefix column to assign a label to a line.
|
|
168
|
+
Labels are used to define ranges for `CHANGE ... ALL .A .B`.
|
|
169
|
+
|
|
170
|
+
## Function Keys
|
|
171
|
+
|
|
172
|
+
| Key | Action |
|
|
173
|
+
|-----|--------|
|
|
174
|
+
| F3 | Save and exit |
|
|
175
|
+
| F5 | Save without exiting |
|
|
176
|
+
| F6 | Open command line |
|
|
177
|
+
| F12 | Exit without saving |
|
|
178
|
+
|
|
179
|
+
## Contributing
|
|
180
|
+
|
|
181
|
+
notispf is designed to be easy to extend. Adding a new prefix command takes three steps:
|
|
182
|
+
|
|
183
|
+
1. Write a handler function in `notispf/commands/line_cmds.py`:
|
|
184
|
+
|
|
185
|
+
```python
|
|
186
|
+
def cmd_trim(buffer: Buffer, line_idx: int, count: int) -> EditorResult:
|
|
187
|
+
for i in range(line_idx, min(line_idx + count, len(buffer))):
|
|
188
|
+
buffer.replace_line(i, buffer.lines[i].text.rstrip())
|
|
189
|
+
return EditorResult(success=True)
|
|
190
|
+
```
|
|
191
|
+
|
|
192
|
+
2. Register it in the same file's `register()` function:
|
|
193
|
+
|
|
194
|
+
```python
|
|
195
|
+
registry.register_line_cmd(CommandSpec("T", cmd_trim, description="Trim trailing whitespace"))
|
|
196
|
+
```
|
|
197
|
+
|
|
198
|
+
3. Add tests in `tests/test_line_cmds.py`.
|
|
199
|
+
|
|
200
|
+
That's it — no changes to the prefix state machine, display, or app controller needed.
|
|
201
|
+
|
|
202
|
+
See [ARCHITECTURE.md](ARCHITECTURE.md) for a deeper overview of the codebase.
|
|
203
|
+
|
|
204
|
+
## License
|
|
205
|
+
|
|
206
|
+
MIT
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
__version__ = "1.0.0"
|