{"id":13736879,"url":"https://github.com/johnnovak/illwill","last_synced_at":"2025-04-09T05:13:32.097Z","repository":{"id":37579934,"uuid":"140159746","full_name":"johnnovak/illwill","owner":"johnnovak","description":"A curses inspired simple cross-platform console library for Nim","archived":false,"fork":false,"pushed_at":"2024-05-05T05:03:31.000Z","size":1091,"stargazers_count":419,"open_issues_count":8,"forks_count":25,"subscribers_count":16,"default_branch":"master","last_synced_at":"2025-04-02T04:07:28.284Z","etag":null,"topics":["gui","nim","nim-lang","terminal","tui"],"latest_commit_sha":null,"homepage":"","language":"Nim","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"wtfpl","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/johnnovak.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":"COPYING","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}},"created_at":"2018-07-08T10:55:36.000Z","updated_at":"2025-03-19T00:09:51.000Z","dependencies_parsed_at":"2024-01-06T12:02:52.971Z","dependency_job_id":"9909545c-a3f9-4dee-b277-cadb0b135547","html_url":"https://github.com/johnnovak/illwill","commit_stats":null,"previous_names":[],"tags_count":8,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/johnnovak%2Fillwill","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/johnnovak%2Fillwill/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/johnnovak%2Fillwill/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/johnnovak%2Fillwill/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/johnnovak","download_url":"https://codeload.github.com/johnnovak/illwill/tar.gz/refs/heads/master","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":247980843,"owners_count":21027808,"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","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":["gui","nim","nim-lang","terminal","tui"],"created_at":"2024-08-03T03:01:30.397Z","updated_at":"2025-04-09T05:13:32.062Z","avatar_url":"https://github.com/johnnovak.png","language":"Nim","funding_links":[],"categories":["User Interface"],"sub_categories":["Terminal"],"readme":"# illwill\n\n## Overview\n\n**illwill** is a *(n)curses* inspired simple terminal library that aims to make\nwriting cross-platform text mode applications easy. Having said that, it's\nmuch simpler than (n)curses and it's not as robust by far in terms of\nsupporting different encodings, terminal types, etc. The aim was to write\nsomething small and simple in pure Nim that works for 99% of users without\nrequiring any external dependencies or a terminfo database.\n\nFor \"serious\" applications, the best is always to write different backends for\n*nix and Windows (one of the main reasons being that the Windows Console is\nbuffer based, not file based). But I think this library is perfect for small\ncross-platform programs and utilities where you need something more than the\nbasic blocking console I/O, but you don't actually want to bother with\na full-blown GUI.\n\n### Main features\n\n* **Non-blocking** keyboard input.\n* Support for **key combinations** and **special keys** available both in the standard\n  Windows Console (`cmd.exe`) and most common POSIX terminals.\n* **Virtual terminal buffers** with **double-buffering** support (only display changes\n  from the previous frame and minimise the number of attribute changes to\n  reduce CPU usage).\n* Simple graphics using **UTF-8 box drawing** symbols.\n* **Full-screen support** with restoring the contents of the terminal after exit.\n* **Mouse support** with modifier key reporting.\n* **No dependencies**—only depends on the standard terminal module.\n\n\u003cimg src=\"https://github.com/johnnovak/illwill/raw/master/img/nim-mod-1.png\" align=\"left\" width=\"48%\" alt=\"illwill in action\" /\u003e\n\u003cimg src=\"https://github.com/johnnovak/illwill/raw/master/img/nim-mod-2.png\" width=\"48%\" alt=\"illwill in action\" /\u003e\n\n\u003cp align=\"center\"\u003e\u003cem\u003e\n\u003ca href=\"https://github.com/johnnovak/nim-mod\"\u003enim-mod\u003c/a\u003e is an oldschool MOD\nplayer that uses illwill for its awesome text-mode user interface\u003c/em\u003e\u003c/p\u003e\n\n\n### Use it if\n\n* You just want something simple that lets you write full-screen terminal\n  apps with non-blocking keyboard input that work on Windows, Mac OS X and\n  99.99% of modern Linux distributions.\n* You don't need to support any fancy encodings and terminal types other than\n  UTF-8.\n* You're developing a custom UI so you don't need any predefined widgets.\n* You don't mind the [immediate mode UI](https://github.com/ocornut/imgui)\n  style/approach.\n* You absolutely don't want any external dependencies.\n\n### Projects using illwill\n\n- [nim-mod](https://github.com/johnnovak/nim-mod) — A Nim MOD player just for fun \n- [ttop](https://github.com/inv2004/ttop) — System monitoring tool with historical data service, triggers and top-like TUI\n- [promexplorer](https://github.com/marcusramberg/promexplorer) — A simple tool to explore Prometheus exporter metrics\n- [clipclap](https://github.com/tttardigrado/clipclap) — A terminal-based ClipBoard Manager written in Nim\n- [illwillWidgets](https://github.com/enthus1ast/illwillWidgets) — Mouse enabled widgets for illwill\n- [tui_widget](https://github.com/jaar23/tui_widget) — Terminal UI widgets based on illwill\n- [nimSnake](https://github.com/ColTrez/nimSnake) — Classic game of snake implemented in nim using the illwill TUI library for graphics\n\n### Don't use it if\n\n* You need ultimate robustness in terms of supporting obscure terminals,\n  character encodings and Linux/Unix distributions.\n* You need predefined widgets.\n* You like complicating your life :sunglasses:\n\n### Limitations \u0026 known issues\n\n* Suspend/resume (SIGTSTP/SIGCONT handling) works, but it doesn't properly\n  reset the terminal when suspending the app.\n* The contents of the terminal is not restored after exiting a full-screen app\n  on Windows.\n\n## Installation\n\nThe best way to install the library is by using\n[nimble](https://github.com/nim-lang/nimble):\n\n```\nnimble install illwill\n```\n\n## Documentation\n\nhttps://www.johnnovak.net/illwill/\n\n\n## Usage\n\nThis is a simple example on the general structure of a fullscreen terminal\napplication. Check out the [examples](/examples) for more advanced use cases\n(e.g. using box drawing buffers, handling terminal resizes, etc.)\n\n\n```nimrod\nimport os, strutils\nimport illwill\n\n# 1. Initialise terminal in fullscreen mode and make sure we restore the state\n# of the terminal state when exiting.\nproc exitProc() {.noconv.} =\n  illwillDeinit()\n  showCursor()\n  quit(0)\n\nillwillInit(fullscreen=true)\nsetControlCHook(exitProc)\nhideCursor()\n\n# 2. We will construct the next frame to be displayed in this buffer and then\n# just instruct the library to display its contents to the actual terminal\n# (double buffering is enabled by default; only the differences from the\n# previous frame will be actually printed to the terminal).\nvar tb = newTerminalBuffer(terminalWidth(), terminalHeight())\n\n# 3. Display some simple static UI that doesn't change from frame to frame.\ntb.setForegroundColor(fgBlack, true)\ntb.drawRect(0, 0, 40, 5)\ntb.drawHorizLine(2, 38, 3, doubleStyle=true)\n\ntb.write(2, 1, fgWhite, \"Press any key to display its name\")\ntb.write(2, 2, \"Press \", fgYellow, \"ESC\", fgWhite,\n               \" or \", fgYellow, \"Q\", fgWhite, \" to quit\")\n\n# 4. This is how the main event loop typically looks like: we keep polling for\n# user input (keypress events), do something based on the input, modify the\n# contents of the terminal buffer (if necessary), and then display the new\n# frame.\nwhile true:\n  var key = getKey()\n  case key\n  of Key.None: discard\n  of Key.Escape, Key.Q: exitProc()\n  else:\n    tb.write(8, 4, ' '.repeat(31))\n    tb.write(2, 4, resetStyle, \"Key pressed: \", fgGreen, $key)\n\n  tb.display()\n  sleep(20)\n\n```\n\n## License\n\nCopyright © 2018-2024 John Novak \u003c\u003cjohn@johnnovak.net\u003e\u003e\n\nThis work is free. You can redistribute it and/or modify it under the terms of\nthe [Do What The Fuck You Want To Public License, Version 2](http://www.wtfpl.net/), as published\nby Sam Hocevar. See the [COPYING](./COPYING) file for more details.\n\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fjohnnovak%2Fillwill","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fjohnnovak%2Fillwill","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fjohnnovak%2Fillwill/lists"}