{"id":13822604,"url":"https://github.com/skim-rs/tuikit","last_synced_at":"2025-12-12T16:24:11.915Z","repository":{"id":33990057,"uuid":"163847389","full_name":"skim-rs/tuikit","owner":"skim-rs","description":"Tool kit for writing TUI applications in Rust.","archived":false,"fork":false,"pushed_at":"2023-09-29T20:27:14.000Z","size":291,"stargazers_count":108,"open_issues_count":9,"forks_count":30,"subscribers_count":4,"default_branch":"master","last_synced_at":"2025-04-08T13:47:52.633Z","etag":null,"topics":["rust-crate","tui"],"latest_commit_sha":null,"homepage":null,"language":"Rust","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/skim-rs.png","metadata":{"files":{"readme":"README.md","changelog":"CHANGELOG.md","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}},"created_at":"2019-01-02T13:54:18.000Z","updated_at":"2025-03-05T17:19:50.000Z","dependencies_parsed_at":"2024-01-18T04:07:03.352Z","dependency_job_id":"c46785f8-6605-4f0e-972e-6b2f5962e6ec","html_url":"https://github.com/skim-rs/tuikit","commit_stats":{"total_commits":209,"total_committers":15,"mean_commits":"13.933333333333334","dds":"0.14832535885167464","last_synced_commit":"9a343ce28c5d7a52e29e6614e7617fab7645bb58"},"previous_names":["skim-rs/tuikit","lotabout/tuikit"],"tags_count":26,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/skim-rs%2Ftuikit","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/skim-rs%2Ftuikit/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/skim-rs%2Ftuikit/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/skim-rs%2Ftuikit/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/skim-rs","download_url":"https://codeload.github.com/skim-rs/tuikit/tar.gz/refs/heads/master","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":248681493,"owners_count":21144700,"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":["rust-crate","tui"],"created_at":"2024-08-04T08:02:08.372Z","updated_at":"2025-12-12T16:24:11.847Z","avatar_url":"https://github.com/skim-rs.png","language":"Rust","funding_links":[],"categories":["Rust"],"sub_categories":[],"readme":"[![Crates.io](https://img.shields.io/crates/v/tuikit.svg)](https://crates.io/crates/tuikit) [![Build Status](https://github.com/lotabout/tuikit/workflows/Build%20\u0026%20Test/badge.svg)](https://github.com/lotabout/tuikit/actions?query=workflow%3A%22Build+%26+Test%22)\n\n## Tuikit\n\nTuikit is a TUI library for writing terminal UI applications. Highlights:\n\n- Thread safe.\n- Support non-fullscreen mode as well as fullscreen mode.\n- Support `Alt` keys, mouse events, etc.\n- Buffering for efficient rendering.\n\nTuikit is modeld after [termbox](https://github.com/nsf/termbox) which views the\nterminal as a table of fixed-size cells and input being a stream of structured\nmessages.\n\n**WARNING**: The library is not stable yet, the API might change.\n\n## Usage\n\nIn your `Cargo.toml` add the following:\n\n```toml\n[dependencies]\ntuikit = \"*\"\n```\n\nAnd if you'd like to use the latest snapshot version:\n\n```toml\n[dependencies]\ntuikit = { git = \"https://github.com/lotabout/tuikit.git\" }\n```\n\nHere is an example (could also be run by `cargo run --example hello-world`):\n\n```rust\nuse tuikit::prelude::*;\nuse std::cmp::{min, max};\n\nfn main() {\n    let term: Term\u003c()\u003e = Term::with_height(TermHeight::Percent(30)).unwrap();\n    let mut row = 1;\n    let mut col = 0;\n\n    let _ = term.print(0, 0, \"press arrow key to move the text, (q) to quit\");\n    let _ = term.present();\n\n    while let Ok(ev) = term.poll_event() {\n        let _ = term.clear();\n        let _ = term.print(0, 0, \"press arrow key to move the text, (q) to quit\");\n\n        let (width, height) = term.term_size().unwrap();\n        match ev {\n            Event::Key(Key::ESC) | Event::Key(Key::Char('q')) =\u003e break,\n            Event::Key(Key::Up) =\u003e row = max(row-1, 1),\n            Event::Key(Key::Down) =\u003e row = min(row+1, height-1),\n            Event::Key(Key::Left) =\u003e col = max(col, 1)-1,\n            Event::Key(Key::Right) =\u003e col = min(col+1, width-1),\n            _ =\u003e {}\n        }\n\n        let attr = Attr{ fg: Color::RED, ..Attr::default() };\n        let _ = term.print_with_attr(row, col, \"Hello World! 你好！今日は。\", attr);\n        let _ = term.set_cursor(row, col);\n        let _ = term.present();\n    }\n}\n```\n\n## Layout\n\n`tuikit` provides `HSplit`, `VSplit` and `Win` for managing layouts:\n\n1. `HSplit` allow you to split area horizontally into pieces.\n2. `VSplit` works just like `HSplit` but splits vertically.\n3. `Win` do not split, it could have margin, padding and border.\n\nFor example:\n\n```rust\nuse tuikit::prelude::*;\n\nstruct Model(String);\n\nimpl Draw for Model {\n    fn draw(\u0026self, canvas: \u0026mut dyn Canvas) -\u003e DrawResult\u003c()\u003e {\n        let (width, height) = canvas.size()?;\n        let message_width = self.0.len();\n        let left = (width - message_width) / 2;\n        let top = height / 2;\n        let _ = canvas.print(top, left, \u0026self.0);\n        Ok(())\n    }\n}\n\nimpl Widget for Model{}\n\nfn main() {\n    let term: Term\u003c()\u003e = Term::with_height(TermHeight::Percent(50)).unwrap();\n    let model = Model(\"middle!\".to_string());\n\n    while let Ok(ev) = term.poll_event() {\n        if let Event::Key(Key::Char('q')) = ev {\n            break;\n        }\n        let _ = term.print(0, 0, \"press 'q' to exit\");\n\n        let hsplit = HSplit::default()\n            .split(\n                VSplit::default()\n                    .basis(Size::Percent(30))\n                    .split(Win::new(\u0026model).border(true).basis(Size::Percent(30)))\n                    .split(Win::new(\u0026model).border(true).basis(Size::Percent(30)))\n            )\n            .split(Win::new(\u0026model).border(true));\n\n        let _ = term.draw(\u0026hsplit);\n        let _ = term.present();\n    }\n}\n```\n\nThe split algorithm is simple:\n\n1. Both `HSplit` and `VSplit` will take several `Split` where a `Split` would\n   contains:\n    1. basis, the original size\n    2. grow, the factor to grow if there is still enough room\n    3. shrink, the factor to shrink if there is not enough room\n2. `HSplit/VSplit` will count the total width/height(basis) of the split items\n3. Judge if the current width/height is enough or not for the split items\n4. shrink/grow the split items according to their grow/shrink: `factor / sum(factors)`\n5. If still not enough room, the last one(s) would be set width/height 0\n\n## References\n\n`Tuikit` borrows ideas from lots of other projects:\n\n- [rustyline](https://github.com/kkawakam/rustyline) Readline Implementation in Rust.\n    - How to enter the raw mode.\n    - Part of the keycode parsing logic.\n- [termion](https://gitlab.redox-os.org/redox-os/termion) A bindless library for controlling terminals/TTY.\n    - How to parse mouse events.\n    - How to enter raw mode.\n- [rustbox](https://github.com/gchp/rustbox) and [termbox](https://github.com/nsf/termbox)\n    - The idea of viewing terminal as table of fixed cells.\n- [termfest](https://github.com/agatan/termfest) Easy TUI library written in Rust\n    - The buffering idea.\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fskim-rs%2Ftuikit","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fskim-rs%2Ftuikit","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fskim-rs%2Ftuikit/lists"}