{"id":20036896,"url":"https://github.com/mecaneer23/ndo","last_synced_at":"2025-11-26T08:03:56.218Z","repository":{"id":155090843,"uuid":"615793919","full_name":"mecaneer23/Ndo","owner":"mecaneer23","description":"A VIM-inspired terminal line-based text editor","archived":false,"fork":false,"pushed_at":"2025-09-24T17:08:35.000Z","size":741,"stargazers_count":3,"open_issues_count":0,"forks_count":1,"subscribers_count":1,"default_branch":"main","last_synced_at":"2025-09-24T19:13:40.189Z","etag":null,"topics":["application","curses","editor","ncurses","ndo","python","python3","todo","todolist","tui","vim"],"latest_commit_sha":null,"homepage":"http://mecaneer23.net/Ndo/","language":"Python","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"mit","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/mecaneer23.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":"LICENSE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null,"zenodo":null,"notice":null,"maintainers":null,"copyright":null,"agents":null,"dco":null,"cla":null}},"created_at":"2023-03-18T17:40:17.000Z","updated_at":"2025-09-24T17:08:38.000Z","dependencies_parsed_at":"2024-02-14T04:31:48.192Z","dependency_job_id":"f75d9b57-d9b3-4cb1-aa99-11815245208d","html_url":"https://github.com/mecaneer23/Ndo","commit_stats":null,"previous_names":[],"tags_count":0,"template":false,"template_full_name":null,"purl":"pkg:github/mecaneer23/Ndo","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/mecaneer23%2FNdo","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/mecaneer23%2FNdo/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/mecaneer23%2FNdo/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/mecaneer23%2FNdo/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/mecaneer23","download_url":"https://codeload.github.com/mecaneer23/Ndo/tar.gz/refs/heads/main","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/mecaneer23%2FNdo/sbom","scorecard":null,"host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":286079811,"owners_count":27282121,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","status":"online","status_checked_at":"2025-11-26T02:00:06.075Z","response_time":193,"last_error":null,"robots_txt_status":"success","robots_txt_updated_at":"2025-07-24T06:49:26.215Z","robots_txt_url":"https://github.com/robots.txt","online":true,"can_crawl_api":true,"host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["application","curses","editor","ncurses","ndo","python","python3","todo","todolist","tui","vim"],"created_at":"2024-11-13T10:17:09.444Z","updated_at":"2025-11-26T08:03:56.213Z","avatar_url":"https://github.com/mecaneer23.png","language":"Python","funding_links":[],"categories":[],"sub_categories":[],"readme":"# Ndo - an ncurses todo application\n\n[![Codacy Badge](https://app.codacy.com/project/badge/Grade/746b6de92fed4209aa46905463efd3f4)](https://app.codacy.com/gh/mecaneer23/Ndo/dashboard?utm_source=gh\u0026utm_medium=referral\u0026utm_content=\u0026utm_campaign=Badge_grade) [![CodeFactor](https://www.codefactor.io/repository/github/mecaneer23/ndo/badge)](https://www.codefactor.io/repository/github/mecaneer23/ndo) ![GitHub License](https://img.shields.io/github/license/mecaneer23/ndo?color=blue) ![Repo Size](https://img.shields.io/github/repo-size/mecaneer23/ndo)\n\nA terminal implementation of a todo list helper. Most of the keybindings are similar to Vim-bindings so Vim users should feel relatively comfortable.\n\n![Screenshot of Ndo displaying a shopping list](res/shopping-list.png)\n\n## OS Support\n\n### Default UI (Acurses - ANSI Curses)\n\n- All major operating systems should be fully supported out-of-the-box. Please report a bug if you encounter any issues.\n\n### Curses UI\n\n- Ndo is optimized for Linux, as most Vim users use Linux.\n- MacOS is also supported however some keyboard shortcuts use different modifier keys.\n- In Windows, general editing is available using the following external package, although some keyboard shortcuts might not work.\n\n## Setup\n\n### Magnify, copy, and paste\n\n```bash\npip install pyfiglet pyperclip\n```\n\n### Curses for Windows (unnecessary if running using acurses UI)\n\n```bash\npip install windows-curses\n```\n\n## Running\n\n```bash\npython3 todo.py [options] [filename]\n```\n\nOr with Docker:\n\n```bash\n./docker_build.sh\n./docker_run.sh filename\n```\n\n## Flags\n\nPositional arguments:\n\n| Argument | Description                                                          |\n| -------- | -------------------------------------------------------------------- |\n| filename | Provide a filename to store the todo list in. Default is `todo.txt`. |\n\nOptions:\n\n| Option                                                                     | Description                                                                                                                                           |\n| -------------------------------------------------------------------------- | ----------------------------------------------------------------------------------------------------------------------------------------------------- |\n| --bullet-display, -b                                                       | Boolean: determine if Todos are displayed with a bullet point rather than a checkbox. Default is `False`.                                             |\n| --enumerate, -e                                                            | Boolean: determines if todos are numbered when printed or not. Default is `False`.                                                                    |\n| --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. |\n| --help, -h                                                                 | Show this help message and exit.                                                                                                                      |\n| --help-file HELP_FILE                                                      | Allows passing alternate file to specify help menu. Default is `README.md`.                                                                           |\n| --indentation-level INDENTATION_LEVEL, -i INDENTATION_LEVEL                | Allows specification of indentation level. Default is `2`.                                                                                            |\n| --relative-enumeration, -r                                                 | Boolean: determines if todos are numbered when printed. Numbers relatively rather than absolutely. Default is `False`.                                |\n| --rename, -n                                                               | Boolean: if true, show prompt to rename file, rename file to input, and exit. Default is `False`.                                                     |\n| --simple-boxes, -x                                                         | Boolean: allow rendering simpler checkboxes if terminal doesn't support default ascii checkboxes. Default is `False`.                                 |\n| --strikethrough, -s                                                        | Boolean: strikethrough completed todos - option to disable because some terminals don't support strikethroughs. Default is `False`.                   |\n| --title TITLE, -t TITLE                                                    | Allows passing alternate header. Default is `filename`.                                                                                               |\n\n## Controls (Normal mode)\n\n| Key (arranged alphabetically)                                                             | Description                            |\n| ----------------------------------------------------------------------------------------- | -------------------------------------- |\n| \u003ckbd\u003e-\u003c/kbd\u003e                                                                              | Insert blank line                      |\n| \u003ckbd\u003e/\u003c/kbd\u003e                                                                              | Search for a sequence                  |\n| \u003ckbd\u003eAlt\u003c/kbd\u003e+\u003ckbd\u003eShift\u003c/kbd\u003e+\u003ckbd\u003ek\u003c/kbd\u003e/\u003ckbd\u003eAlt\u003c/kbd\u003e+\u003ckbd\u003eShift\u003c/kbd\u003e+\u003ckbd\u003ej\u003c/kbd\u003e | Select all todos above/below           |\n| \u003ckbd\u003eAlt\u003c/kbd\u003e+\u003ckbd\u003ek\u003c/kbd\u003e/\u003ckbd\u003ej\u003c/kbd\u003e                                                  | Move todo up and down                  |\n| \u003ckbd\u003eBackspace\u003c/kbd\u003e                                                                      | Combine with previous todo             |\n| \u003ckbd\u003eCtrl\u003c/kbd\u003e+\u003ckbd\u003ea\u003c/kbd\u003e                                                              | Select all todos                       |\n| \u003ckbd\u003eCtrl\u003c/kbd\u003e+\u003ckbd\u003er\u003c/kbd\u003e                                                              | Redo change                            |\n| \u003ckbd\u003eCtrl\u003c/kbd\u003e+\u003ckbd\u003ex\u003c/kbd\u003e, \u003ckbd\u003ek\u003c/kbd\u003e                                                | Toggle `toggle` and `entry` modes      |\n| \u003ckbd\u003eDelete\u003c/kbd\u003e                                                                         | Toggle between `Todo` and `Note`       |\n| \u003ckbd\u003eEnter\u003c/kbd\u003e                                                                          | Toggle a todo as completed             |\n| Numbers                                                                                   | Move a number of lines                 |\n| \u003ckbd\u003eShift\u003c/kbd\u003e+\u003ckbd\u003ek\u003c/kbd\u003e/\u003ckbd\u003ej\u003c/kbd\u003e                                                | Select/deselect multiple todos         |\n| \u003ckbd\u003eShift\u003c/kbd\u003e+\u003ckbd\u003eo\u003c/kbd\u003e                                                             | Add a todo on current line             |\n| \u003ckbd\u003eShift\u003c/kbd\u003e+\u003ckbd\u003et\u003c/kbd\u003e                                                             | Move todo to top, keep cursor in place |\n| \u003ckbd\u003eTab\u003c/kbd\u003e/\u003ckbd\u003eShift\u003c/kbd\u003e+\u003ckbd\u003eTab\u003c/kbd\u003e                                            | Indent/unindent selected todo          |\n| \u003ckbd\u003ea\u003c/kbd\u003e                                                                              | Display selected todo as an alert      |\n| \u003ckbd\u003eb\u003c/kbd\u003e                                                                              | Make selected todo bigger (magnify)    |\n| \u003ckbd\u003ec\u003c/kbd\u003e                                                                              | Change selected todo color             |\n| \u003ckbd\u003ed\u003c/kbd\u003e                                                                              | Remove selected todo                   |\n| \u003ckbd\u003ef\u003c/kbd\u003e/\u003ckbd\u003eCtrl\u003c/kbd\u003e+\u003ckbd\u003eg\u003c/kbd\u003e                                                 | Find \u0026 replace substrings in selection |\n| \u003ckbd\u003eg\u003c/kbd\u003e/\u003ckbd\u003eShift\u003c/kbd\u003e+\u003ckbd\u003eg\u003c/kbd\u003e                                                | Jump to top/bottom of todos            |\n| \u003ckbd\u003eh\u003c/kbd\u003e                                                                              | Show a list of controls                |\n| \u003ckbd\u003ei\u003c/kbd\u003e                                                                              | Edit an existing todo                  |\n| \u003ckbd\u003ek\u003c/kbd\u003e/\u003ckbd\u003ej\u003c/kbd\u003e                                                                 | Move cursor up and down                |\n| \u003ckbd\u003eo\u003c/kbd\u003e                                                                              | Add a new todo                         |\n| \u003ckbd\u003en\u003c/kbd\u003e                                                                              | Move to next search term location      |\n| \u003ckbd\u003ep\u003c/kbd\u003e                                                                              | New todo from clipboard                |\n| \u003ckbd\u003eq\u003c/kbd\u003e, \u003ckbd\u003eCtrl\u003c/kbd\u003e+\u003ckbd\u003ec\u003c/kbd\u003e, \u003ckbd\u003eEsc\u003c/kbd\u003e                                | Quit                                   |\n| \u003ckbd\u003es\u003c/kbd\u003e                                                                              | Sort top-level todos various ways      |\n| \u003ckbd\u003et\u003c/kbd\u003e                                                                              | Move selected todo to top of list      |\n| \u003ckbd\u003eu\u003c/kbd\u003e                                                                              | Undo change                            |\n| \u003ckbd\u003ey\u003c/kbd\u003e                                                                              | Copy todo to clipboard                 |\n\n## Input box controls (Input mode)\n\n| Key or shortcut                                                     | Description                          |\n| ------------------------------------------------------------------- | ------------------------------------ |\n| Letters, numbers, punctuation, etc.                                 | Add character to textbox             |\n| \u003ckbd\u003eEnter\u003c/kbd\u003e                                                    | Return to full list, saving changes  |\n| \u003ckbd\u003eCtrl\u003c/kbd\u003e+\u003ckbd\u003ec\u003c/kbd\u003e, \u003ckbd\u003eEsc\u003c/kbd\u003e                        | Return to full list without saving   |\n| \u003ckbd\u003eLeft\u003c/kbd\u003e/\u003ckbd\u003eRight\u003c/kbd\u003e                                    | Move the cursor left/right one space |\n| \u003ckbd\u003eCtrl\u003c/kbd\u003e+\u003ckbd\u003eLeft\u003c/kbd\u003e/\u003ckbd\u003eCtrl\u003c/kbd\u003e+\u003ckbd\u003eRight\u003c/kbd\u003e    | Move the cursor left/right one word  |\n| \u003ckbd\u003eHome\u003c/kbd\u003e                                                     | Move cursor to left end of textbox   |\n| \u003ckbd\u003eEnd\u003c/kbd\u003e                                                      | Move cursor to right end of textbox  |\n| \u003ckbd\u003eBackspace\u003c/kbd\u003e                                                | Delete the character left of cursor  |\n| \u003ckbd\u003eDelete\u003c/kbd\u003e                                                   | Delete the character right of cursor |\n| \u003ckbd\u003eCtrl\u003c/kbd\u003e+\u003ckbd\u003eBackspace\u003c/kbd\u003e                                | Delete the word left of cursor       |\n| \u003ckbd\u003eCtrl\u003c/kbd\u003e+\u003ckbd\u003eDelete\u003c/kbd\u003e                                   | Delete the word right of cursor      |\n| \u003ckbd\u003eTab\u003c/kbd\u003e                                                      | Indent line, to the right            |\n| \u003ckbd\u003eShift\u003c/kbd\u003e+\u003ckbd\u003eTab\u003c/kbd\u003e                                     | De-indent line, to the left          |\n| \u003ckbd\u003eShift\u003c/kbd\u003e+\u003ckbd\u003eDelete\u003c/kbd\u003e/\u003ckbd\u003eAlt\u003c/kbd\u003e+\u003ckbd\u003eDelete\u003c/kbd\u003e | Toggle whether line has checkbox     |\n| \u003ckbd\u003eCtrl\u003c/kbd\u003e+\u003ckbd\u003ex\u003c/kbd\u003e, \u003ckbd\u003ek\u003c/kbd\u003e                          | Toggle `toggle` and `entry` modes    |\n| \u003ckbd\u003eDown\u003c/kbd\u003e                                                     | Split line at cursor                 |\n| \u003ckbd\u003eAlt\u003c/kbd\u003e+\u003ckbd\u003eh\u003c/kbd\u003e                                         | Show a list of controls              |\n\n## Style options (Markdown/LaTeX subset)\n\nNdo implements special formatting for certain sequences:\n\n- `*italics*`\n- `**bold**`\n- `` `code` ``\n- `__underline__`\n- `~~strikethrough~~`\n\n## Config files (`.ndoconfig`)\n\nPass arguments to `ndo` without specifying explicitly on the command line.\n\n### Syntax\n\nAllows any existing options, separated by newlines\n\n```bash\n--bullet-display\n--strikethrough\n--indentation-level=4\n--user-interface ansi\n```\n\n### Precedence\n\nOrdered from highest precedence to lowest. (Top of the list overrides bottom of the list).\n\n1. Arguments passed directly to executable\n2. `./.ndoconfig` file in working directory\n3. `~/.ndoconfig` file in home directory\n\n## View a todo list online\n\nGo to [this link](https://mecaneer23.github.io/Ndo/web-display) and upload your file\n\n## Contributing\n\nUse the following linters and formatters:\n\n### Python files\n\n- pylint\n- black\n- ruff\n- mypy\n- vulture\n\n### Markdown files\n\n- markdownlint\n\n### Testing\n\n```bash\npytest test\n```\n\n## Troubleshooting\n\n### Docker error\n\n`Cannot connect to the Docker daemon at ... Is the Docker daemon running?`\n\n```bash\nsystemctl start docker\n```\n\n## Bugs\n\n| Description                                     | Steps to reproduce                                                | Expected result                   | Incorrect/actual result           | Work-around or solution                                              |\n| ----------------------------------------------- | ----------------------------------------------------------------- | --------------------------------- | --------------------------------- | -------------------------------------------------------------------- |\n| 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                                  |\n| 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 |\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fmecaneer23%2Fndo","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fmecaneer23%2Fndo","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fmecaneer23%2Fndo/lists"}