A text editor inspired by the ISPF editor from z/OS mainframes, available as both a terminal app and a desktop GUI. Brings the prefix command area that ISPF users know and love to Linux, macOS, and Windows.
Go to the Releases page and download for your platform:
| Platform | GUI (recommended) | Terminal CLI |
|---|---|---|
| Linux | notispf-qt-x86_64.AppImage |
notispf-linux |
| macOS | notispf-qt.dmg |
notispf-macos |
| Windows | notispf-qt-setup.exe |
notispf-windows.exe |
Linux AppImage:
chmod +x notispf-qt-x86_64.AppImage
./notispf-qt-x86_64.AppImage myfile.txtmacOS DMG: Open the .dmg and drag notispf-qt to your Applications folder.
macOS note: Without code signing, Gatekeeper will block the app on first launch. Right-click the app → Open → Open to bypass the warning once. For the CLI binary:
xattr -d com.apple.quarantine ./notispf-macos
Windows installer: Run notispf-qt-setup.exe. Creates a Start Menu entry and an optional desktop shortcut.
Windows note: SmartScreen may warn about an unknown publisher. Click More info → Run anyway.
Linux / macOS CLI:
chmod +x notispf-linux # or notispf-macos
./notispf-linux myfile.txt
mv notispf-linux ~/.local/bin/notispf # optionally add to PATHpip install notispf # terminal version
pip install notispf[qt] # terminal + GUI (requires PyQt6)git clone https://github.com/mrthock/notispf
cd notispf
pip install -e . # terminal version
pip install -e ".[qt]" # terminal + GUIGUI (PyQt6):
notispf-qt <file>
notispf-qt # opens a file picker dialogTerminal:
notispf <file> notispf filename.txt Line 1/42 Col 1
===> _
000001|This is the first line of your file
000002|Second line here
000003|Third line
|~
|~
F1-HELP F3-SAVE F5-RFIND F6-CMD F7-UP F8-DOWN F10-LEFT F11-RIGHT F12-QUIT
[message bar]
- Status bar (top row) — filename, modified flag
[+], current line/total, cursor column,[HEX]when hex mode is active - Command bar (second row) — always visible; type commands here after pressing F6 to focus it
- Prefix column (left, 6 chars) — shows zero-padded line numbers; type prefix commands here
- Text area (right of
|) — edit your file - Function key bar (second-to-last row) — always-visible reference for function key shortcuts
- Message bar (bottom row) — status messages and feedback
| Key | Action |
|---|---|
| Arrow keys | Move cursor in text |
| Up (from top visible line) | Move to command bar |
| Page Up / Page Down | Scroll |
| Home | Focus command bar |
| Ctrl+A | Beginning of line |
| End / Ctrl+E | End of line |
| From | Key | To |
|---|---|---|
| Text | Home | Command bar |
| Text | Tab | Prefix column of next line (N+1) |
| Text (col 0) | Left arrow | Prefix column of same line |
| Text (top line) | Shift+Tab | Command bar |
| Text (any other line) | Shift+Tab | Prefix column of previous line (N-1) |
| Prefix | Right arrow | Text area of same line (col 0) |
| Prefix | Home | Command bar |
| Prefix | Tab | Text area of same line |
| Prefix | Shift+Tab | Text area of previous line (N-1) |
| Command bar | Tab | Prefix area of line 1 |
| Command bar | Down arrow | Text area (cursor position preserved) |
| Command bar | Escape | Text area (cursor position preserved, bar stays visible) |
Type a command into the prefix column, then press Enter to execute. You can stage commands on multiple lines before pressing Enter — they all execute at once.
| Command | Action |
|---|---|
D |
Delete line |
Dn |
Delete n lines (e.g. D5 deletes 5) |
I |
Insert blank line after |
In |
Insert n blank lines |
R |
Repeat line |
Rn |
Repeat line n times |
C |
Copy line to clipboard |
Cn |
Copy n lines to clipboard |
M |
Move line (cut to clipboard) |
Mn |
Move n lines |
A |
Paste clipboard after this line |
B |
Paste clipboard before this line |
O |
Overlay clipboard onto this line (merge; clipboard spaces don't overwrite) |
On |
Overlay clipboard onto n lines |
>n |
Indent right n columns (e.g. >4 adds 4 spaces) |
<n |
Indent left n columns (removes up to n leading spaces) |
HEX |
Replace this line with its hex representation |
HEXB |
Insert a hex copy of this line below it |
HEXA |
Convert a hex line back to ASCII text |
UC |
Uppercase this line |
UCn |
Uppercase n lines (e.g. UC3) |
LC |
Lowercase this line |
LCn |
Lowercase n lines |
Type the command on the first line of the block, then again on the last line.
| Command | Action |
|---|---|
DD |
Delete block |
CC |
Copy block to clipboard |
MM |
Move block (cut to clipboard) |
RR |
Repeat block (insert a copy below) |
OO |
Overlay clipboard onto block (merge clipboard text into block lines) |
>>n |
Indent block right n columns |
<<n |
Indent block left n columns |
Use A, B, or O/OO on a third line to place the clipboard after copying or moving.
Example — move lines 3–6 to after line 10:
- Tab to line 3 prefix → type
MM - Arrow down to line 6 → type
MM - Arrow down to line 10 → type
A - Press Enter
| Command | Action |
|---|---|
X |
Exclude line from display (collapse into fold row) |
Xn |
Exclude n lines |
S |
Show (un-exclude) line or the entire fold group it belongs to |
Sn |
Show n lines |
XX |
Exclude block |
SS |
Show block |
Excluded lines are collapsed into a single fold row showing the count. Use SHOW ALL on the command line to reveal everything at once.
| Key | Action |
|---|---|
| Enter | Execute all staged prefix commands |
| Escape | Cancel all staged commands and exit prefix mode |
| ↑ / ↓ | Move between lines (keeps staged commands) |
The command bar is always visible just below the status bar. Press F6 to focus it (the cursor moves to ===>), type a command, and press Enter to execute. After the command runs the input clears, the result appears in the message bar, and the cursor stays at ===> ready for another command. Press Escape or Down arrow to return to the text. Press F6 again while focused to hide the bar entirely; press F6 once more to bring it back.
| Command | Action |
|---|---|
SAVE |
Save file |
FILE |
Save and exit |
CANCEL or QUIT or CAN |
Exit without saving |
| Command | Action |
|---|---|
COPY filename |
Save a copy of the current file to filename (current file path unchanged) |
| Command | Action |
|---|---|
UNDO |
Undo last change |
REDO |
Redo last undone change |
| Command | Action |
|---|---|
HEX ON |
Convert entire file to hex (e.g. Hello → 48 65 6C 6C 6F) |
HEX OFF |
Convert hex back to text |
[HEX] appears in the status bar while hex mode is active. HEX ON and HEX OFF each count as a single undo step.
EXCLUDE 'pattern'
EXCLUDE 'pattern' ALL
EXCLUDE 'pattern' n
DELETE 'pattern'
DELETE 'pattern' ALL
DELETE 'pattern' n
DELETE X ALL
DELETE NX ALL
EXCLUDE 'pattern'— exclude the next matching line from displayEXCLUDE 'pattern' ALL— exclude all matching linesEXCLUDE 'pattern' n— exclude the next n matching linesDELETE 'pattern'— delete the next matching lineDELETE 'pattern' ALL— delete all matching linesDELETE X ALL— delete all currently excluded linesDELETE NX ALL— delete all non-excluded lines
| Command | Action |
|---|---|
SHOW ALL |
Reveal all excluded lines |
| Command | Action |
|---|---|
COLS |
Toggle the column ruler on/off |
CLEAR / RESET / RES |
Clear the current search highlight |
HELP |
Open the help screen |
FIND 'text'
CHANGE 'old' 'new'
CHANGE 'old' 'new' ALL
CHANGE 'old' 'new' ALL .labelA .labelB
Both single and double quotes are accepted as delimiters.
Aliases: F for FIND, C for CHANGE, CAN for CANCEL, RESET/RES for CLEAR.
FIND— locate next occurrence (case-insensitive by default)CHANGE— replace next occurrenceCHANGE ... ALL— replace all occurrences in fileCHANGE ... ALL .A .B— replace all occurrences between labeled lines
Type .A, .B etc. in the prefix column to assign a label to a line.
Labels are used to define ranges for CHANGE ... ALL .A .B.
| Key | Action |
|---|---|
| F1 | Help |
| F3 | Save and exit |
| F5 | Repeat last FIND (RFIND) |
| F6 | Focus command bar (or hide it if already focused) |
| F7 / Page Up | Scroll up |
| F8 / Page Down | Scroll down |
| F10 | Scroll left |
| F11 | Scroll right |
| F12 | Exit without saving |
| Ctrl+Z | Undo last change |
| Ctrl+Y | Redo last undone change |
notispf is designed to be easy to extend. Adding a new prefix command takes three steps:
- Write a handler function in
notispf/commands/line_cmds.py:
def cmd_trim(buffer: Buffer, line_idx: int, count: int) -> EditorResult:
for i in range(line_idx, min(line_idx + count, len(buffer))):
buffer.replace_line(i, buffer.lines[i].text.rstrip())
return EditorResult(success=True)- Register it in the same file's
register()function:
registry.register_line_cmd(CommandSpec("T", cmd_trim, description="Trim trailing whitespace"))- Add tests in
tests/test_line_cmds.py.
That's it — no changes to the prefix state machine, display, or app controller needed.
See ARCHITECTURE.md for a deeper overview of the codebase.
MIT