{"slug": "lui-a-simple-ls-lah-like-terminal-file-manager", "title": "Lui: a simple `ls -lah`-like terminal file manager", "summary": "Developer lukeflo released lui, a terminal file manager written in Zig that reimplements an interactive version of `ls -lah --group-directories-first`, hosted on Codeberg. The tool reached version 0.3.0, which added a `.zon` config file for defining fast-selection directories, after earlier fixes to the `build.zig.zon` dependency URLs and hashes; lukeflo wrote that no LLM was used to write the code, though the sole external dependency, `libvaxis`, uses some LLM support. lukeflo said lui now serves as their everyday file manager and as a file picker for the Helix editor, while cautioning that complex or critical file operations should be run outside lui.", "body_md": "# `lui`:\n\n`lui` is a simple terminal file manager. Its main idea was building an interactive version of one of my most used Linux commands: `ls -lah --group-directories-first`.\n\n[https://codeberg.org/lukeflo/lui](https://codeberg.org/lukeflo/lui)\n\nWhile there are many fancy TUI file manager out there, I’ve tried most but found them bloated with features unnecessary to me. Thus, I just built my own one. Originally written in Rust called [`jafff`](https://codeberg.org/lukeflo/jafff) I wanted to rewrite in in Zig, since I almost fully abandoned Rust, plus the Rust version is much slower.\n\nAnd here it is! For now, only with very limited features. But it already serves as file picker for my Helix editor and as fast cd’ing tool. I will implement some more core features in the near future. However, if you’re looking for the next `yazi`, keep looking somewhere else \n\n### \n\n`0.16`\n\n### \n\nI did not use any LLM for writing my code. Neither as agents, nor for prompting questions, ideas, reviews to a chat bot.\n\nHowever, the only external dep I used for this program, `libvaxis`, is using some LLM support.\n\n### \n\n \n18 Likes\n\n \nGreat, exactly what I’m using when I run yazi. But there is an error with `build.zig.zon`, I opened an issue.\n\n \n2 Likes\n\n \nYeah, thanks. I worked with local copies of the deps repos and forgot to replace them with the correct URLs. Will update this asap.\n\n \n\n \nUpdated the `build.zig.zon` file with the correct deps URLs and hashes. Should build now without problems. \n\n[https://codeberg.org/lukeflo/lui/commit/11e9d6f5f0bbf1a6305339ad5afcd3d9e796e574](https://codeberg.org/lukeflo/lui/commit/11e9d6f5f0bbf1a6305339ad5afcd3d9e796e574)\n\nHowever, if you or anyone else find more errors, please report via issues. As said, its still very early and I for sure didn’t catch every error.\n\n \n2 Likes\n\n \nStaying busy improving `lui` I just implemented possibility to create files and dirs (as current user with default permissions), renaming items, as well as having feedback in form of simple status messages (success and error).\n\nIts tested, but not in uncommon scenarios. Thus, if you find some comp/runtime panics, just tell me.\n\n \n1 Like\n\n \nBooya, in `0.3.0` just implemented a config `.zon` file which lets you define directories for fast selection.\n\nNow, `lui` took over as my every day standard file manager TUI!\n\n \n\n \n[Just](https://codeberg.org/lukeflo/lui/src/commit/34155825302f434a6f4c72593cfa0c5fcc561ec6) implemented some more little features:\n\n- Use `X` to fast toggle exec bit on files (like`chmod +x|-x file` )\n- Open files with `l` |`->` |`Return`  - Set `file_opener` in`luiconfig.zon` for files which should be opened in external programms via a default opener like`xdg-open`\n  - Set `tui_opener` in`luiconfig.zon` to open plain text files with a terminal text editor (`vim` ,`helix` ,`nano` …) in the same terminal window that`lui` runs in; suspending the latter as long as the file is edited.`tui_opener` overrides`file_opener` for plain text files if both are set.\n- Some minor fixes. Adding “keybindings” section to README.\n\n \n\n \nNext feature implemented:\n\n- Mark items for one of the operations: yank/copy `y` / move`m` / delete`d` (toggles).\n- Process action for all marked items with `P` .  - Items that have been marked for yank/move will be yanked/moved to the currently opened directory.\n  - Items marked for deletion will either be deleted permanently, or, if the `.trash_folder` path in the config file is set, moved to the trash folder.\n- Unmark all items with `C` .\n\nAll of these actions are processed with default setting like permissions etc. Its a nice and quick way for moving some files while in the TUI. However, for more complex file operations or if the files are critical ones, I highly recommend running these processes outside of `lui` \n\n \n\n \nJust implemented optional git info. When `lui` is run with the `-g`/`--git` flag, it’ll provide a simple git info area at the top of the screen (when in a git root dir), printing current branch and changed/untracked files using git’s porcelain format version 1 specs (as explained in `man git-status`).\n\n \n\n \nThank you!\n\nI noticed a bug though. If I try to enter the .git sub-directory I get this:\n\n```\nthread 2210581 panic: start index 3 is larger than end index 0\n/home/jeremy/projects/zig/lui/src/git.zig:101:47: 0x121212a in getGitStatus (main.zig)\n        break :blk try allocator.dupe(u8, line[3..end]);\n                                              ^\n/home/jeremy/projects/zig/lui/src/DirContent.zig:275:38: 0x121377f in buildGitInfo (main.zig)\n    const git_info = git.getGitStatus(self.arena, self.io, self.dir) catch {\n                                     ^\n/home/jeremy/projects/zig/lui/src/DirList.zig:706:48: 0x12e39f1 in loadDir (main.zig)\n    self.luitui.git_info = try dir.buildGitInfo();\n                                               ^\n/home/jeremy/projects/zig/lui/src/DirList.zig:528:29: 0x12e595c in enterDirOrOpen (main.zig)\n            try self.loadDir(dir_to_load);\n                            ^\n/home/jeremy/projects/zig/lui/src/DirList.zig:156:40: 0x12efc70 in listEventHandler (main.zig)\n                try self.enterDirOrOpen(ctx);\n                                       ^\n/home/jeremy/projects/zig/lui/src/LuiTui.zig:177:56: 0x12e2720 in typeErasedEventHandler (main.zig)\n        .dir_list => try self.dir_list.listEventHandler(ctx, event),\n                                                       ^\n/home/jeremy/projects/zig/lui/zig-pkg/vaxis-0.6.0-BWNV_HHwCQCy33z_jb0RHLjoinqQ8tgQVZI9z2e5Yqdd/src/vxfw/vxfw.zig:287:26: 0x127add8 in handleEvent (main.zig)\n            return handle(self.userdata, ctx, event);\n                         ^\n/home/jeremy/projects/zig/lui/zig-pkg/vaxis-0.6.0-BWNV_HHwCQCy33z_jb0RHLjoinqQ8tgQVZI9z2e5Yqdd/src/vxfw/App.zig:598:31: 0x128f229 in handleEvent (main.zig)\n        try target.handleEvent(ctx, event);\n                              ^\n/home/jeremy/projects/zig/lui/zig-pkg/vaxis-0.6.0-BWNV_HHwCQCy33z_jb0RHLjoinqQ8tgQVZI9z2e5Yqdd/src/vxfw/App.zig:134:54: 0x12455ff in run (main.zig)\n                        try focus_handler.handleEvent(&ctx, event);\n                                                     ^\n/home/jeremy/projects/zig/lui/src/main.zig:69:20: 0x121e555 in main (main.zig)\n        try app.run(luitui.widget(), .{});\n                   ^\n/mnt/data/zig/0.16.0/lib/std/start.zig:737:30: 0x1220687 in callMain (std.zig)\n    return wrapMain(root.main(.{\n                             ^\n../sysdeps/nptl/libc_start_call_main.h:58:16: 0x7a722662a1c9 in __libc_start_call_main (../sysdeps/x86/libc-start.c)\n../csu/libc-start.c:360:3: 0x7a722662a28a in __libc_start_main_impl (../sysdeps/x86/libc-start.c)\n???:?:?: 0x143dc94 in ??? (???)`\n```\n\n \n1 Like\n\n \nThanks for posting. Would you reopen it as issue in the repo? Thats easier for me tracking it \n\n \n\n \nFixed with commit [7268ab07cfd0ccf](https://codeberg.org/lukeflo/lui/commit/7268ab07cfd0ccfffd01b4447899efa0fb940934)\n\n \n\n \n[lukeflo](https://ziggit.dev/u/lukeflo)\n14\n \nThe last weeks I spent writing my own TUI library in Zig. Background to do so was `lui`, my TUI file manager. Since its my hobby fun project I want it to be as AI/LLM-free as possible. Unfortunately, the Zig library I used for TUI rendering, [`libvaxis`](https://github.com/rockorager/libvaxis), makes heavy use of those tools (which doesn’t mean its a bad lib, indeed `libvaxis` works really good). Other alternatives like [`zigzag`](https://github.com/meszmate/zigzag) or [` xitui`](https://github.com/xit-vcs/xitui) were either mainly AI/LLM-generated too or didn’t fit my personal preferences regarding usability.\n\nNow, that my TUI lib [`dabeob`](https://ziggit.dev/t/dabeob-a-simple-tui-lib-for-zig/18166) is in a usable state, I adapted `lui`’s code to replace `libvaxis` with `dabeob`. Surprisingly, it only took me a few evenings to edit the code. Now, `lui` runs with my own TUI rendering lib (for now, not merged into main, but in a [specific branch](https://codeberg.org/lukeflo/lui/src/branch/switch_tui_to_dabeob)) and I already use this version daily; also to catch only sporadic occuring errors/segfaults.\n\nThe layout always looks almost identically (top term uses `dabeob`, bottom uses `libvaxis`):\n\nAdditionally, using `dabeob` reduced memory usage significantly: less than 50% of what the `libvaxis`-version uses (measured with [` ps_mem`](https://github.com/pixelb/ps_mem) on my `~/Downloads` dir which contains many different files):\n\n``` bash\n# dabeob version\n$ ps_mem -S -p $(pgrep lui)\n Private  +   Shared  =  RAM used   Swap used\tProgram\n\n  1.5 MiB +  28.5 KiB =   1.6 MiB     0.0 KiB\tlui\n---------------------------------------------\n                          1.6 MiB     0.0 KiB\n=============================================\n\n# libvaxis version\n$ ps_mem -S -p $(pgrep lui_old)\n Private  +   Shared  =  RAM used   Swap used\tProgram\n\n  4.2 MiB +  25.5 KiB =   4.2 MiB     0.0 KiB\tlui_old\n---------------------------------------------\n                          4.2 MiB     0.0 KiB\n=============================================\n```\n\nThe binary is smaller too. And I couldn’t notice a performance dropoff compared to the former version.\n\nI will run the binary build from the `dabeob` branch for some more days before merging into main to be sure there are no major errors which I didn’t catch until now. If anyone feels called to try the new branch out too, I’m happy for feedback (in form of repo issues if you encounter some errors).\n\nAfter all, I’m ***really happy*** that it was relatively easy and much fun to write my own TUI lib and already were able to adapt it to my favourite personal coding project \n\n \n7 Likes\n\n \n[lukeflo](https://ziggit.dev/u/lukeflo)\n15\n \nJust merged the `dabeob` branch into main.\n\nThat `lui` now runs with my own custom TUI lib really makes me happy. I did not expect it to be that satisfying \n\nAnd a special thanks to [@Wunka](https://ziggit.dev/u/wunka) and [@tranzystorekk](https://ziggit.dev/u/tranzystorekk) for their contributions to both projects in the last days which helped to eliminate some errors I missed out on!\n\n \n1 Like", "url": "https://wpnews.pro/news/lui-a-simple-ls-lah-like-terminal-file-manager", "canonical_source": "https://ziggit.dev/t/lui-a-simple-ls-lah-like-terminal-file-manager/15588#post_15", "published_at": "2026-11-05 20:01:26+00:00", "updated_at": "2026-11-05 20:20:31.635300+00:00", "lang": "en", "topics": ["developer-tools"], "entities": ["lui", "lukeflo", "Zig", "libvaxis", "Helix", "Codeberg", "jafff", "yazi"], "also_reported_by": [], "alternates": {"html": "https://wpnews.pro/news/lui-a-simple-ls-lah-like-terminal-file-manager", "markdown": "https://wpnews.pro/news/lui-a-simple-ls-lah-like-terminal-file-manager.md", "text": "https://wpnews.pro/news/lui-a-simple-ls-lah-like-terminal-file-manager.txt", "jsonld": "https://wpnews.pro/news/lui-a-simple-ls-lah-like-terminal-file-manager.jsonld"}}