https://github.com/mecaneer23/ndo
A VIM-inspired terminal line-based text editor
https://github.com/mecaneer23/ndo
application curses editor ncurses ndo python python3 todo todolist tui vim
Last synced: 7 months ago
JSON representation
A VIM-inspired terminal line-based text editor
- Host: GitHub
- URL: https://github.com/mecaneer23/ndo
- Owner: mecaneer23
- License: mit
- Created: 2023-03-18T17:40:17.000Z (over 3 years ago)
- Default Branch: main
- Last Pushed: 2025-09-24T17:08:35.000Z (9 months ago)
- Last Synced: 2025-09-24T19:13:40.189Z (9 months ago)
- Topics: application, curses, editor, ncurses, ndo, python, python3, todo, todolist, tui, vim
- Language: Python
- Homepage: http://mecaneer23.net/Ndo/
- Size: 724 KB
- Stars: 3
- Watchers: 1
- Forks: 1
- Open Issues: 0
-
Metadata Files:
- Readme: README.md
- License: LICENSE
Awesome Lists containing this project
README
# Ndo - an ncurses todo application
[](https://app.codacy.com/gh/mecaneer23/Ndo/dashboard?utm_source=gh&utm_medium=referral&utm_content=&utm_campaign=Badge_grade) [](https://www.codefactor.io/repository/github/mecaneer23/ndo)  
A terminal implementation of a todo list helper. Most of the keybindings are similar to Vim-bindings so Vim users should feel relatively comfortable.

## OS Support
### Default UI (Acurses - ANSI Curses)
- All major operating systems should be fully supported out-of-the-box. Please report a bug if you encounter any issues.
### Curses UI
- Ndo is optimized for Linux, as most Vim users use Linux.
- MacOS is also supported however some keyboard shortcuts use different modifier keys.
- In Windows, general editing is available using the following external package, although some keyboard shortcuts might not work.
## Setup
### Magnify, copy, and paste
```bash
pip install pyfiglet pyperclip
```
### Curses for Windows (unnecessary if running using acurses UI)
```bash
pip install windows-curses
```
## Running
```bash
python3 todo.py [options] [filename]
```
Or with Docker:
```bash
./docker_build.sh
./docker_run.sh filename
```
## Flags
Positional arguments:
| Argument | Description |
| -------- | -------------------------------------------------------------------- |
| filename | Provide a filename to store the todo list in. Default is `todo.txt`. |
Options:
| Option | Description |
| -------------------------------------------------------------------------- | ----------------------------------------------------------------------------------------------------------------------------------------------------- |
| --bullet-display, -b | Boolean: determine if Todos are displayed with a bullet point rather than a checkbox. Default is `False`. |
| --enumerate, -e | Boolean: determines if todos are numbered when printed or not. Default is `False`. |
| --user-interface {curses,ansi,tkinter,none}, -g {curses,ansi,tkinter,none} | UiType: determine how todos should be rendered. Default is `ansi`. If `none` is passed, print state of a todolist to stdout without a user interface. |
| --help, -h | Show this help message and exit. |
| --help-file HELP_FILE | Allows passing alternate file to specify help menu. Default is `README.md`. |
| --indentation-level INDENTATION_LEVEL, -i INDENTATION_LEVEL | Allows specification of indentation level. Default is `2`. |
| --relative-enumeration, -r | Boolean: determines if todos are numbered when printed. Numbers relatively rather than absolutely. Default is `False`. |
| --rename, -n | Boolean: if true, show prompt to rename file, rename file to input, and exit. Default is `False`. |
| --simple-boxes, -x | Boolean: allow rendering simpler checkboxes if terminal doesn't support default ascii checkboxes. Default is `False`. |
| --strikethrough, -s | Boolean: strikethrough completed todos - option to disable because some terminals don't support strikethroughs. Default is `False`. |
| --title TITLE, -t TITLE | Allows passing alternate header. Default is `filename`. |
## Controls (Normal mode)
| Key (arranged alphabetically) | Description |
| ----------------------------------------------------------------------------------------- | -------------------------------------- |
| - | Insert blank line |
| / | Search for a sequence |
| Alt+Shift+k/Alt+Shift+j | Select all todos above/below |
| Alt+k/j | Move todo up and down |
| Backspace | Combine with previous todo |
| Ctrl+a | Select all todos |
| Ctrl+r | Redo change |
| Ctrl+x, k | Toggle `toggle` and `entry` modes |
| Delete | Toggle between `Todo` and `Note` |
| Enter | Toggle a todo as completed |
| Numbers | Move a number of lines |
| Shift+k/j | Select/deselect multiple todos |
| Shift+o | Add a todo on current line |
| Shift+t | Move todo to top, keep cursor in place |
| Tab/Shift+Tab | Indent/unindent selected todo |
| a | Display selected todo as an alert |
| b | Make selected todo bigger (magnify) |
| c | Change selected todo color |
| d | Remove selected todo |
| f/Ctrl+g | Find & replace substrings in selection |
| g/Shift+g | Jump to top/bottom of todos |
| h | Show a list of controls |
| i | Edit an existing todo |
| k/j | Move cursor up and down |
| o | Add a new todo |
| n | Move to next search term location |
| p | New todo from clipboard |
| q, Ctrl+c, Esc | Quit |
| s | Sort top-level todos various ways |
| t | Move selected todo to top of list |
| u | Undo change |
| y | Copy todo to clipboard |
## Input box controls (Input mode)
| Key or shortcut | Description |
| ------------------------------------------------------------------- | ------------------------------------ |
| Letters, numbers, punctuation, etc. | Add character to textbox |
| Enter | Return to full list, saving changes |
| Ctrl+c, Esc | Return to full list without saving |
| Left/Right | Move the cursor left/right one space |
| Ctrl+Left/Ctrl+Right | Move the cursor left/right one word |
| Home | Move cursor to left end of textbox |
| End | Move cursor to right end of textbox |
| Backspace | Delete the character left of cursor |
| Delete | Delete the character right of cursor |
| Ctrl+Backspace | Delete the word left of cursor |
| Ctrl+Delete | Delete the word right of cursor |
| Tab | Indent line, to the right |
| Shift+Tab | De-indent line, to the left |
| Shift+Delete/Alt+Delete | Toggle whether line has checkbox |
| Ctrl+x, k | Toggle `toggle` and `entry` modes |
| Down | Split line at cursor |
| Alt+h | Show a list of controls |
## Style options (Markdown/LaTeX subset)
Ndo implements special formatting for certain sequences:
- `*italics*`
- `**bold**`
- `` `code` ``
- `__underline__`
- `~~strikethrough~~`
## Config files (`.ndoconfig`)
Pass arguments to `ndo` without specifying explicitly on the command line.
### Syntax
Allows any existing options, separated by newlines
```bash
--bullet-display
--strikethrough
--indentation-level=4
--user-interface ansi
```
### Precedence
Ordered from highest precedence to lowest. (Top of the list overrides bottom of the list).
1. Arguments passed directly to executable
2. `./.ndoconfig` file in working directory
3. `~/.ndoconfig` file in home directory
## View a todo list online
Go to [this link](https://mecaneer23.github.io/Ndo/web-display) and upload your file
## Contributing
Use the following linters and formatters:
### Python files
- pylint
- black
- ruff
- mypy
- vulture
### Markdown files
- markdownlint
### Testing
```bash
pytest test
```
## Troubleshooting
### Docker error
`Cannot connect to the Docker daemon at ... Is the Docker daemon running?`
```bash
systemctl start docker
```
## Bugs
| Description | Steps to reproduce | Expected result | Incorrect/actual result | Work-around or solution |
| ----------------------------------------------- | ----------------------------------------------------------------- | --------------------------------- | --------------------------------- | -------------------------------------------------------------------- |
| Attempt to delete word using Alacritty terminal | In Alacritty, enter insert mode, then press ctrl+backspace | Word is deleted | Character is deleted | Use ctrl+w or alt+backspace instead |
| Strikethrough completed todos using Curses UI | Run ndo with both `--ui curses` and `--strikethrough` (or `-sgc`) | Selected items show strikethrough | Program crashes with custom error | Run either with acurses rather than curses, or without strikethrough |