text-file-tree
January 8, 2026 · View on GitHub
A Zig library that converts ASCII and Unicode file trees to iterators of native file paths.
Trees
Trees can be defined using ASCII or Unicode.
ASCII
An ASCII file tree looks like the following:
home/username
|-- .config/nvim
|-- .local/bin
| |-- helix
| |-- nvim
|-- bin
|-- vim
|-- nano
Notice how a file path can be shortened if there is only one nested path as in
home/username. The expanded version of which is:
home
|-- username
Unicode
A Unicode file tree looks like the following:
home/username
├── .config/nvim
├── .local/bin
│ ├── helix
│ └── nvim
└── bin
├── vim
└── nano
The file paths are shortened as in the ASCII version.
Whitespace
You can also use spaces or tabs for indenting. The text may be ASCII or Unicode.
home/username
.config/nvim
.local/bin
helix
nvim
bin
vim
nano
Note
The Unicode format supported is UTF-8, which is the same as that supported by Zig source files.
Paths
The iterator returns native file paths. All trees shown in the Trees section would produce the same output.
Unix
On Unix and Unix-like systems (e.g. Linux and MacOS), the following would be the output:
home/username
home/username/.config/nvim
home/username/.local/bin
home/username/.local/bin/helix
home/username/.local/bin/nvim
home/username/bin
home/username/bin/vim
home/username/bin/nano
Windows
On Windows, the following would be the output:
home\username
home\username\.config\nvim
home\username\.local\bin
home\username\.local\bin\helix
home\username\.local\bin\nvim
home\username\bin
home\username\bin\vim
home\username\bin\nano
Usage
Requirements
- Minimum Zig version:
0.15.1
Note
For Zig version 0.14.0 use the zv0.14.0 branch.
Installation
zig fetch --save git+https://github.com/mishieck/text-file-tree.git
Build File Update
Add the following code snippet to your build.zig file.
const tft = b.dependency("tft", .{
.target = target,
.optimize = optimize,
});
exe.root_module.addImport("tft", tft.module("tft"));
Code
The following code snippet shows how to use the library.
const std = @import("std");
const TextFileTree = @import("tft").TextFileTree;
pub fn main() !void {
var gpa = std.heap.GeneralPurposeAllocator(.{}){};
defer std.debug.assert(gpa.deinit() == .ok); // Detects memory leaks
const allocator = gpa.allocator();
const ascii_tree =
\\home/username
\\|-- .config/nvim
\\|-- .local/bin
\\| |-- helix
\\| |-- nvim
\\|-- bin
\\ |-- vim
\\ |-- nano
;
const paths = TextFileTree.init(
allocator,
TextFileTree.ASCII_INDENTATION_LIST,
ascii_tree,
);
var iterator = paths.iterate();
defer iterator.deinit();
while (try iterator.next()) |path| {
std.debug.print("{s}\n", .{path});
allocator.free(path);
}
}
The output of the code would be one of the outputs shown in the Paths section depending on your operating system.
For Unicode file trees use TextFileTree.UNICODE_INDENTATION_LIST in place of
TextFileTree.ASCII_INDENTATION_LIST. You can find other kinds of indentation
lists under the namespace TextFileTree.
Custom Indentation
You can use custom indentation by creating a slice containing the indentations. You can use the following builtin definitions as reference for custom definitions.
/// A list of strings used for indenting ASCII file trees.
pub const ASCII_INDENTATION_LIST = &[_][]const u8{ " ", "| ", "|-- " };
/// A list of strings used for indenting Unicode file trees.
pub const UNICODE_INDENTATION_LIST = &[_][]const u8{
" ",
"│ ",
"├── ",
"└── ",
};
/// A list of strings used for indenting using spaces.
pub const SPACE_INDENTATION_LIST = &[_][]const u8{" "};
/// A list of strings used for indenting using tabs.
pub const TAB_INDENTATION_LIST = &[_][]const u8{"\t"};
You can use the definitions as follows:
const CUSTOM_INDENTATION_LIST = &[_][]const u8{
// Values
};
// Use your indentations in the tree.
const custom_tree =
\\
\\
;
const paths = TextFileTree.init(
allocator,
CUSTOM_INDENTATION_LIST,
custom_tree,
);
Contributing
Any improvement to the library is welcome.