TUI editor and editor backend written in Zig

move tui into src/ with libfn

reykjalin.org a7131bbf 1219b0b1

verified
+95 -134
+49 -11
README.md
··· 1 - # ❄️ libfn 1 + # ❄️ Fönn 2 2 3 3 [![Build and run Fönn tests](https://github.com/reykjalin/fn/actions/workflows/tests.yml/badge.svg?branch=main)](https://github.com/reykjalin/fn/actions/workflows/tests.yml) [![builds.sr.ht status](https://builds.sr.ht/~reykjalin/fn/commits/main/tests.yml.svg)](https://builds.sr.ht/~reykjalin/fn/commits/main/tests.yml?) 4 4 5 - If you're looking for the editor, you can find that in the [./tui](./tui) folder. 6 - 7 - `libfn` is an editor engine that I'm working on for fun. 8 - It's currently used to power my toy editor project [Fönn](./tui). 9 - 10 - If you're working on a Zig project and want to play around with the library itself you can do so by 11 - installing fun with `zig fetch --save git+https://git.sr.ht/~reykjalin/fn`. 12 - You can also try my toy editor by building the editor from the [./tui](./tui) folder. 5 + This repo contains 2 projects: `libfn`, and Fönn. `libfn` is an editor engine that I'm working on for fun. Fönn is a code editor powered by `libfn`. 13 6 14 7 My primary goal is to eventually have a modern, capable TUI code editor that's powered by a reusable 15 8 editing engine. The engine itself will eventually be exposed as a static library with a C API, but ··· 18 11 A secondary goal is for `fn` to eventually have both a GUI and a TUI powered by this same text 19 12 editing "engine". 20 13 21 - ## libfn build instructions 14 + ## Fönn (TUI) 15 + 16 + ❄️ Fönn: A code editor for _fun_. 17 + 18 + ![Screenshot of the fn TUI modifying its own source code](./screenshots/fn.webp) 19 + 20 + This is currently a toy project, but `fn` is stable enough that I'm exclusively using it when working on changes to the editor. 21 + 22 + My primary goal is to have a modern, capable TUI code editor. 23 + A secondary goal is for `fn` to eventually have both a GUI and a TUI powered by the same text editing "engine". 24 + 25 + ### Build instructions 26 + 27 + ```sh 28 + # Debug build in ./zig-out/bin/fn. 29 + zig build -Dtui 30 + 31 + # Run debug build in current directory. 32 + zig build run -Dtui 33 + 34 + # Open a file with debug build. 35 + zig build run -Dtui -- path/to/file 36 + 37 + # Release build in ~/.local/bin/fn. 38 + zig build -Dtui -Doptimize=ReleaseSafe --prefix ~/.local 39 + ``` 40 + 41 + ## Usage 42 + 43 + ```sh 44 + $ fn --help 45 + Usage: fn [file] 46 + 47 + General options: 48 + 49 + -h, --help Print fn help 50 + -v, --version Print fn version 51 + 52 + ``` 53 + 54 + ## libfn 55 + 56 + If you're working on a Zig project and want to play around with the library itself you can do so by 57 + installing fun with `zig fetch --save git+https://git.sr.ht/~reykjalin/fn`. 58 + 59 + ### Build instructions 22 60 23 61 ```sh 24 62 # Make sure libfn builds. ··· 28 66 zig build test 29 67 ``` 30 68 31 - ## Usage 69 + ### Usage 32 70 33 71 ```sh 34 72 $ zig fetch --save git+https://git.sr.ht/~reykjalin/fn
+35 -2
build.zig
··· 3 3 pub fn build(b: *std.Build) void { 4 4 const target = b.standardTargetOptions(.{}); 5 5 const optimize = b.standardOptimizeOption(.{}); 6 - const root_source_file = b.path("src/libfn.zig"); 6 + const root_source_file = b.path("src/libfn/libfn.zig"); 7 7 8 8 // Build zig module. 9 9 const libfn = b.addModule("libfn", .{ ··· 13 13 }); 14 14 15 15 // Check step for ZLS build-on-save. 16 - const libfn_check = b.addStaticLibrary(.{ 16 + const libfn_check = b.addLibrary(.{ 17 17 .name = "libfn", 18 18 .root_module = libfn, 19 + .linkage = .static, 19 20 }); 20 21 const check = b.step("check", "Check if libfn compiles"); 21 22 check.dependOn(&libfn_check.step); ··· 38 39 }); 39 40 const docs = b.step("docs", "Build libfn library docs"); 40 41 docs.dependOn(&install_docs.step); 42 + 43 + const tui = b.option(bool, "tui", "include this option to build the TUI") orelse false; 44 + 45 + // TUI. 46 + if (tui) { 47 + const vaxis = b.lazyDependency("vaxis", .{ .target = target, .optimize = optimize }); 48 + const ltf = b.lazyDependency("log_to_file", .{ .target = target, .optimize = optimize }); 49 + 50 + if (vaxis) |vaxis_dep| { 51 + if (ltf) |ltf_dep| { 52 + const exe = b.addExecutable(.{ 53 + .name = "fn", 54 + .root_source_file = b.path("src/tui/main.zig"), 55 + .target = target, 56 + .optimize = optimize, 57 + }); 58 + exe.root_module.addImport("vaxis", vaxis_dep.module("vaxis")); 59 + exe.root_module.addImport("log_to_file", ltf_dep.module("log_to_file")); 60 + exe.root_module.addImport("libfn", libfn); 61 + 62 + // Run step. 63 + const run_cmd = b.addRunArtifact(exe); 64 + run_cmd.step.dependOn(b.getInstallStep()); 65 + const run_step = b.step("run", "Run the app"); 66 + run_step.dependOn(&run_cmd.step); 67 + if (b.args) |args| run_cmd.addArgs(args); 68 + 69 + // Build TUI. 70 + b.installArtifact(exe); 71 + } 72 + } 73 + } 41 74 }
+11 -2
build.zig.zon
··· 3 3 .fingerprint = 0xe304ae87c91c388, 4 4 .version = "0.0.1", 5 5 .minimum_zig_version = "0.14.0", 6 - .dependencies = .{}, 6 + .dependencies = .{ 7 + .log_to_file = .{ 8 + .url = "git+https://git.sr.ht/~reykjalin/log_to_file?ref=2.1.0#add71ed5dcd94ca10d70477a869c552ed760d4e8", 9 + .hash = "log_to_file-2.1.0-vcE8Az8_AAB4FGmTuYb00TRPKdsoBP5bF7W8o6vYe51p", 10 + }, 11 + .vaxis = .{ 12 + .url = "git+https://github.com/rockorager/libvaxis#84d6cb381c0d628550fac3f6daa24c5faf7b2cd1", 13 + .hash = "vaxis-0.1.0-BWNV_O8OCQBC4w-MnOGaKw9zFVFgTxf3XfcvgScUagEJ", 14 + }, 15 + }, 7 16 .paths = .{ 8 - "src", 17 + "src/libfn", 9 18 "README.md", 10 19 "LICENSE", 11 20 },
src/Editor.zig src/libfn/Editor.zig
src/Range.zig src/libfn/Range.zig
src/Selection.zig src/libfn/Selection.zig
src/libfn.zig src/libfn/libfn.zig
src/pos.zig src/libfn/pos.zig
-41
tui/README.md
··· 1 - # ❄️ Fönn 2 - 3 - [![Build and run Fönn tests](https://github.com/reykjalin/fn/actions/workflows/tests.yml/badge.svg?branch=main)](https://github.com/reykjalin/fn/actions/workflows/tests.yml) [![builds.sr.ht status](https://builds.sr.ht/~reykjalin/fn/commits/main/tests.yml.svg)](https://builds.sr.ht/~reykjalin/fn/commits/main/tests.yml?) 4 - 5 - A code editor for _fun_. 6 - 7 - ![Screenshot of the fn TUI modifying its own source code](./screenshots/fn.webp) 8 - 9 - This is currently a toy project, but `fn` is stable enough that I'm exclusively using it when working on changes to the editor. 10 - 11 - My primary goal is to have a modern, capable TUI code editor. 12 - A secondary goal is for `fn` to eventually have both a GUI and a TUI powered by the same text editing "engine". 13 - 14 - ## Build instructions 15 - 16 - ```sh 17 - # Debug build in ./zig-out/bin/fn. 18 - zig build 19 - 20 - # Run debug build in current directory. 21 - zig build run 22 - 23 - # Open a file with debug build. 24 - zig build run -- path/to/file 25 - 26 - # Release build in ~/.local/bin/fn. 27 - zig build -Doptimize=ReleaseSafe --prefix ~/.local 28 - ``` 29 - 30 - ## Usage 31 - 32 - ```sh 33 - $ fn --help 34 - Usage: fn [file] 35 - 36 - General options: 37 - 38 - -h, --help Print fn help 39 - -v, --version Print fn version 40 - 41 - ```
-58
tui/build.zig
··· 1 - const std = @import("std"); 2 - 3 - pub fn build(b: *std.Build) void { 4 - const target = b.standardTargetOptions(.{}); 5 - const optimize = b.standardOptimizeOption(.{}); 6 - const root_source_file = b.path("src/main.zig"); 7 - 8 - const vaxis_dep = b.dependency("vaxis", .{ .target = target, .optimize = optimize }); 9 - const ltf_dep = b.dependency("log_to_file", .{ .target = target, .optimize = optimize }); 10 - const libfn_dep = b.dependency("libfn", .{ .target = target, .optimize = optimize }); 11 - 12 - // Build executable. 13 - const exe = b.addExecutable(.{ 14 - .name = "fn", 15 - .root_source_file = root_source_file, 16 - .target = target, 17 - .optimize = optimize, 18 - }); 19 - exe.root_module.addImport("vaxis", vaxis_dep.module("vaxis")); 20 - exe.root_module.addImport("log_to_file", ltf_dep.module("log_to_file")); 21 - exe.root_module.addImport("libfn", libfn_dep.module("libfn")); 22 - b.installArtifact(exe); 23 - 24 - // Check step for ZLS build-on-save. 25 - const exe_check = b.addExecutable(.{ 26 - .name = "fn", 27 - .root_source_file = root_source_file, 28 - .target = target, 29 - .optimize = optimize, 30 - }); 31 - exe_check.root_module.addImport("vaxis", vaxis_dep.module("vaxis")); 32 - exe_check.root_module.addImport("log_to_file", ltf_dep.module("log_to_file")); 33 - exe_check.root_module.addImport("libfn", libfn_dep.module("libfn")); 34 - const check = b.step("check", "Check if fn compiles"); 35 - check.dependOn(&exe_check.step); 36 - 37 - // Run step. 38 - const run_cmd = b.addRunArtifact(exe); 39 - run_cmd.step.dependOn(b.getInstallStep()); 40 - const run_step = b.step("run", "Run the app"); 41 - run_step.dependOn(&run_cmd.step); 42 - if (b.args) |args| { 43 - run_cmd.addArgs(args); 44 - } 45 - 46 - // Tests. 47 - const exe_unit_tests = b.addTest(.{ 48 - .root_source_file = root_source_file, 49 - .target = target, 50 - .optimize = optimize, 51 - }); 52 - exe_unit_tests.root_module.addImport("vaxis", vaxis_dep.module("vaxis")); 53 - exe_unit_tests.root_module.addImport("log_to_file", ltf_dep.module("log_to_file")); 54 - exe_unit_tests.root_module.addImport("libfn", libfn_dep.module("libfn")); 55 - const run_exe_unit_tests = b.addRunArtifact(exe_unit_tests); 56 - const test_step = b.step("test", "Run unit tests"); 57 - test_step.dependOn(&run_exe_unit_tests.step); 58 - }
-20
tui/build.zig.zon
··· 1 - .{ 2 - .name = .fonn, 3 - .fingerprint = 0x2df6f1a8026578fb, 4 - .version = "0.0.0", 5 - .minimum_zig_version = "0.14.0", 6 - .dependencies = .{ 7 - .vaxis = .{ 8 - .url = "git+https://github.com/rockorager/libvaxis.git#ae71b6545c099e73d45df7e5dd7c7a3081839468", 9 - .hash = "vaxis-0.1.0-BWNV_JEMCQBskZQsnlzh6GoyHSDgOi41bCoZIB2pW-E7", 10 - }, 11 - .log_to_file = .{ 12 - .url = "https://github.com/reykjalin/log_to_file/archive/refs/tags/2.0.0.zip", 13 - .hash = "log_to_file-2.0.0-vcE8A98wAAAo8BOvkPaEKIwpvGqXwpAVLzpmAL6myrHS", 14 - }, 15 - .libfn = .{ 16 - .path = "..", 17 - }, 18 - }, 19 - .paths = .{""}, 20 - }
tui/screenshots/fn.webp screenshots/fn.webp
tui/src/EditorWidget.zig src/tui/EditorWidget.zig
tui/src/Fonn.zig src/tui/Fonn.zig
tui/src/main.zig src/tui/main.zig
tui/src/menu_bar.zig src/tui/menu_bar.zig
tui/src/themes/catppuccin-mocha.zig src/tui/themes/catppuccin-mocha.zig