From fc512c06894ad8e0aaae9ac8a4a932d7f53f5ee3 Mon Sep 17 00:00:00 2001 From: CJ van den Berg Date: Tue, 12 Nov 2024 10:25:33 +0100 Subject: [PATCH 01/10] feat: update to latest flow-syntax for julia and swift support --- build.zig.zon | 8 ++++---- src/main.zig | 12 ++++++------ 2 files changed, 10 insertions(+), 10 deletions(-) diff --git a/build.zig.zon b/build.zig.zon index 8bfe8e8..fdf8c32 100644 --- a/build.zig.zon +++ b/build.zig.zon @@ -7,12 +7,12 @@ .hash = "12207ee987ce045596cb992cfb15b0d6d9456e50d4721c3061c69dabc2962053644d", }, .themes = .{ - .url = "https://github.com/neurocyte/flow-themes/releases/download/master-08c07e21c47abe41ebd16ee260438da5b4c2039e/flow-themes.tar.gz", - .hash = "12202be270e675e3b61d96845baad143494539b167bcb8b1ef32659bf146dd85d3e1", + .url = "https://github.com/neurocyte/flow-themes/releases/download/master-5f1ca2fd3c784d430306a5cd1df237681a196333/flow-themes.tar.gz", + .hash = "122095b1a6110b920571c7e49e61c124cd9a164fe9b1b0faa1bd11d04d89822d3304", }, .syntax = .{ - .url = "https://github.com/neurocyte/flow-syntax/archive/dcfa5cdf3f1f48411dc3c7ab8be26b7561673850.tar.gz", - .hash = "1220ea88bb77cba3cf85caeb8002823218503c601f9907ccffbd41329c632596ebc3", + .url = "https://github.com/neurocyte/flow-syntax/archive/3673787e55d4ac7df519d3918a7f9dc8ae4cf1a0.tar.gz", + .hash = "122092ac558d4b62e0850156899146f4335f8aefe082fc03dd62fd0660fac06e9a27", }, .thespian = .{ .url = "https://github.com/neurocyte/thespian/archive/d7dd27116398b17c8ab68327c384885f161d0cc1.tar.gz", diff --git a/src/main.zig b/src/main.zig index 5489158..1a24309 100644 --- a/src/main.zig +++ b/src/main.zig @@ -392,8 +392,8 @@ fn list_themes(writer: Writer) !void { fn set_ansi_style(writer: Writer, style: Theme.Style) Writer.Error!void { const ansi_style = .{ - .foreground = if (style.fg) |color| to_rgb_color(color) else .Default, - .background = if (style.bg) |color| to_rgb_color(color) else .Default, + .foreground = if (style.fg) |color| to_rgb_color(color.color) else .Default, + .background = if (style.bg) |color| to_rgb_color(color.color) else .Default, .font_style = switch (style.fs orelse .normal) { .normal => term.style.FontStyle{}, .bold => term.style.FontStyle.bold, @@ -409,8 +409,8 @@ fn set_ansi_style(writer: Writer, style: Theme.Style) Writer.Error!void { const unset_ansi_style = set_ansi_style; fn write_html_preamble(writer: Writer, style: Theme.Style) !void { - const color = if (style.fg) |color| color else 0; - const background = if (style.bg) |background| background else 0xFFFFFF; + const color = if (style.fg) |color| color.color else 0; + const background = if (style.bg) |background| background.color else 0xFFFFFF; try writer.writeAll("
Date: Thu, 14 Nov 2024 17:37:54 +0100 Subject: [PATCH 02/10] feat: update flow-syntax for gleam support --- build.zig.zon | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/build.zig.zon b/build.zig.zon index fdf8c32..3303322 100644 --- a/build.zig.zon +++ b/build.zig.zon @@ -11,8 +11,8 @@ .hash = "122095b1a6110b920571c7e49e61c124cd9a164fe9b1b0faa1bd11d04d89822d3304", }, .syntax = .{ - .url = "https://github.com/neurocyte/flow-syntax/archive/3673787e55d4ac7df519d3918a7f9dc8ae4cf1a0.tar.gz", - .hash = "122092ac558d4b62e0850156899146f4335f8aefe082fc03dd62fd0660fac06e9a27", + .url = "https://github.com/neurocyte/flow-syntax/archive/2345f2f3b1def47bbc9b34f1404cd4bc9a02c05e.tar.gz", + .hash = "1220ea8e786a7f7960b4ea7af84e340f630de5ff145dc94aedde00951ae8f58111f4", }, .thespian = .{ .url = "https://github.com/neurocyte/thespian/archive/d7dd27116398b17c8ab68327c384885f161d0cc1.tar.gz", From e3cef17b63a4f5e563c88f318b46c5fcef05c03e Mon Sep 17 00:00:00 2001 From: CJ van den Berg Date: Mon, 18 Nov 2024 17:39:35 +0100 Subject: [PATCH 03/10] feat: add windows support --- src/config_loader.zig | 31 +++++++++++++++++++++++++------ 1 file changed, 25 insertions(+), 6 deletions(-) diff --git a/src/config_loader.zig b/src/config_loader.zig index 14a55ae..491970b 100644 --- a/src/config_loader.zig +++ b/src/config_loader.zig @@ -1,5 +1,6 @@ const std = @import("std"); const cbor = @import("cbor"); +const builtin = @import("builtin"); const application_name = "flow"; @@ -48,18 +49,36 @@ pub fn get_config_dir() ![]const u8 { } fn get_app_config_dir(appname: []const u8) ![]const u8 { + const a = std.heap.c_allocator; const local = struct { var config_dir_buffer: [std.posix.PATH_MAX]u8 = undefined; var config_dir: ?[]const u8 = null; }; const config_dir = if (local.config_dir) |dir| dir - else if (std.posix.getenv("XDG_CONFIG_HOME")) |xdg| - try std.fmt.bufPrint(&local.config_dir_buffer, "{s}/{s}", .{ xdg, appname }) - else if (std.posix.getenv("HOME")) |home| - try std.fmt.bufPrint(&local.config_dir_buffer, "{s}/.config/{s}", .{ home, appname }) - else - return error.AppConfigDirUnavailable; + else if (std.process.getEnvVarOwned(a, "XDG_CONFIG_HOME") catch null) |xdg| ret: { + defer a.free(xdg); + break :ret try std.fmt.bufPrint(&local.config_dir_buffer, "{s}/{s}", .{ xdg, appname }); + } else if (std.process.getEnvVarOwned(a, "HOME") catch null) |home| ret: { + defer a.free(home); + const dir = try std.fmt.bufPrint(&local.config_dir_buffer, "{s}/.config", .{home}); + std.fs.makeDirAbsolute(dir) catch |e| switch (e) { + error.PathAlreadyExists => {}, + else => return e, + }; + break :ret try std.fmt.bufPrint(&local.config_dir_buffer, "{s}/.config/{s}", .{ home, appname }); + } else if (builtin.os.tag == .windows) ret: { + if (std.process.getEnvVarOwned(a, "APPDATA") catch null) |appdata| { + defer a.free(appdata); + const dir = try std.fmt.bufPrint(&local.config_dir_buffer, "{s}/{s}", .{ appdata, appname }); + std.fs.makeDirAbsolute(dir) catch |e| switch (e) { + error.PathAlreadyExists => {}, + else => return e, + }; + break :ret dir; + } else return error.AppConfigDirUnavailable; + } else return error.AppConfigDirUnavailable; + local.config_dir = config_dir; std.fs.makeDirAbsolute(config_dir) catch |e| switch (e) { error.PathAlreadyExists => {}, From ec79f693a58996127bd82563b5bbe3ef031216d4 Mon Sep 17 00:00:00 2001 From: CJ van den Berg Date: Mon, 18 Nov 2024 17:40:05 +0100 Subject: [PATCH 04/10] feat: act more like standard cat if stdout is not a tty --- src/main.zig | 37 ++++++++++++++++++++++++++++++++++--- 1 file changed, 34 insertions(+), 3 deletions(-) diff --git a/src/main.zig b/src/main.zig index 1a24309..5741878 100644 --- a/src/main.zig +++ b/src/main.zig @@ -53,8 +53,9 @@ pub fn main() !void { }; defer res.deinit(); - const stdout_file = std.io.getStdOut().writer(); - var bw = std.io.bufferedWriter(stdout_file); + const stdout_file = std.io.getStdOut(); + const stdout_writer = stdout_file.writer(); + var bw = std.io.bufferedWriter(stdout_writer); const writer = bw.writer(); defer bw.flush() catch {}; @@ -67,6 +68,9 @@ pub fn main() !void { if (res.args.@"list-languages" != 0) return list_langs(writer); + if (!stdout_file.supportsAnsiEscapeCodes()) + return plain_cat(res.positionals); + var conf_buf: ?[]const u8 = null; const conf = config_loader.read_config(a, &conf_buf); const theme_name = if (res.args.theme) |theme| theme else conf.theme; @@ -103,7 +107,10 @@ pub fn main() !void { if (res.positionals.len > 0) { for (res.positionals) |arg| { - const file = try std.fs.cwd().openFile(arg, .{ .mode = .read_only }); + const file = if (std.mem.eql(u8, arg, "-")) + std.io.getStdIn() + else + try std.fs.cwd().openFile(arg, .{ .mode = .read_only }); defer file.close(); const content = try file.readToEndAlloc(a, std.math.maxInt(u32)); defer a.free(content); @@ -478,3 +485,27 @@ fn render_file_type(writer: Writer, file_type: *const syntax.FileType, theme: *c try set_ansi_style(writer, plain); try writer.writeAll("\n"); } + +fn plain_cat(files: []const []const u8) !void { + const stdout = std.io.getStdOut(); + if (files.len == 0) { + try plain_cat_file(stdout, "-"); + } else { + for (files) |file| try plain_cat_file(stdout, file); + } +} + +fn plain_cat_file(out_file: std.fs.File, in_file_name: []const u8) !void { + var in_file = if (std.mem.eql(u8, in_file_name, "-")) + std.io.getStdIn() + else + try std.fs.cwd().openFile(in_file_name, .{}); + defer in_file.close(); + + var buf: [std.mem.page_size]u8 = undefined; + while (true) { + const bytes_read = try in_file.read(&buf); + if (bytes_read == 0) return; + try out_file.writeAll(buf[0..bytes_read]); + } +} From 641528ac84991624e7bd97a5da74c72cd6f1076b Mon Sep 17 00:00:00 2001 From: CJ van den Berg Date: Mon, 18 Nov 2024 17:40:47 +0100 Subject: [PATCH 05/10] build: add release packaging --- build.zig | 100 ++++++++++++++++++++++++++++++++++++++++++- scripts/make_release | 45 +++++++++++++++++++ 2 files changed, 143 insertions(+), 2 deletions(-) create mode 100755 scripts/make_release diff --git a/build.zig b/build.zig index ef43b99..7a108e6 100644 --- a/build.zig +++ b/build.zig @@ -1,9 +1,92 @@ const std = @import("std"); pub fn build(b: *std.Build) void { + const release = b.option(bool, "package_release", "Build all release targets") orelse false; + const strip = b.option(bool, "strip", "Disable debug information (default: no)"); + const pie = b.option(bool, "pie", "Produce an executable with position independent code (default: none)"); + + const run_step = b.step("run", "Run the app"); + + return (if (release) &build_release else &build_development)( + b, + run_step, + strip, + pie, + ); +} + +fn build_development( + b: *std.Build, + run_step: *std.Build.Step, + strip: ?bool, + pie: ?bool, +) void { const target = b.standardTargetOptions(.{}); const optimize = b.standardOptimizeOption(.{}); + return build_exe( + b, + run_step, + target, + optimize, + .{}, + strip orelse false, + pie, + ); +} + +fn build_release( + b: *std.Build, + run_step: *std.Build.Step, + strip: ?bool, + pie: ?bool, +) void { + const targets: []const std.Target.Query = &.{ + .{ .cpu_arch = .x86_64, .os_tag = .linux, .abi = .musl }, + .{ .cpu_arch = .aarch64, .os_tag = .linux, .abi = .musl }, + .{ .cpu_arch = .x86_64, .os_tag = .macos }, + .{ .cpu_arch = .aarch64, .os_tag = .macos }, + .{ .cpu_arch = .x86_64, .os_tag = .windows }, + .{ .cpu_arch = .aarch64, .os_tag = .windows }, + }; + const optimize = .ReleaseFast; + + var version = std.ArrayList(u8).init(b.allocator); + defer version.deinit(); + gen_version(b, version.writer()) catch unreachable; + const write_file_step = b.addWriteFiles(); + const version_file = write_file_step.add("version", version.items); + b.getInstallStep().dependOn(&b.addInstallFile(version_file, "version").step); + + for (targets) |t| { + const target = b.resolveTargetQuery(t); + var triple = std.mem.splitScalar(u8, t.zigTriple(b.allocator) catch unreachable, '-'); + const arch = triple.next() orelse unreachable; + const os = triple.next() orelse unreachable; + const target_path = std.mem.join(b.allocator, "-", &[_][]const u8{ os, arch }) catch unreachable; + + build_exe( + b, + run_step, + target, + optimize, + .{ .dest_dir = .{ .override = .{ .custom = target_path } } }, + strip orelse true, + pie, + ); + } +} + +pub fn build_exe( + b: *std.Build, + run_step: *std.Build.Step, + target: std.Build.ResolvedTarget, + optimize: std.builtin.OptimizeMode, + exe_install_options: std.Build.Step.InstallArtifact.Options, + strip: bool, + pie: ?bool, +) void { + const clap_dep = b.dependency("clap", .{ .target = target, .optimize = optimize }); const ansi_term_dep = b.dependency("ansi-term", .{ .target = target, .optimize = optimize }); const themes_dep = b.dependency("themes", .{}); @@ -15,18 +98,31 @@ pub fn build(b: *std.Build) void { .root_source_file = b.path("src/main.zig"), .target = target, .optimize = optimize, + .strip = strip, }); + if (pie) |value| exe.pie = value; exe.root_module.addImport("syntax", syntax_dep.module("syntax")); exe.root_module.addImport("theme", themes_dep.module("theme")); exe.root_module.addImport("themes", themes_dep.module("themes")); exe.root_module.addImport("clap", clap_dep.module("clap")); exe.root_module.addImport("ansi-term", ansi_term_dep.module("ansi-term")); exe.root_module.addImport("cbor", b.createModule(.{ .root_source_file = thespian_dep.path("src/cbor.zig") })); - b.installArtifact(exe); + const exe_install = b.addInstallArtifact(exe, exe_install_options); + b.getInstallStep().dependOn(&exe_install.step); const run_cmd = b.addRunArtifact(exe); run_cmd.step.dependOn(b.getInstallStep()); if (b.args) |args| run_cmd.addArgs(args); - const run_step = b.step("run", "Run the app"); run_step.dependOn(&run_cmd.step); } + +fn gen_version(b: *std.Build, writer: anytype) !void { + var code: u8 = 0; + + const describe = try b.runAllowFail(&[_][]const u8{ "git", "describe", "--always", "--tags" }, &code, .Ignore); + const diff_ = try b.runAllowFail(&[_][]const u8{ "git", "diff", "--stat", "--patch", "HEAD" }, &code, .Ignore); + const diff = std.mem.trimRight(u8, diff_, "\r\n "); + const version = std.mem.trimRight(u8, describe, "\r\n "); + + try writer.print("{s}{s}", .{ version, if (diff.len > 0) "-dirty" else "" }); +} diff --git a/scripts/make_release b/scripts/make_release new file mode 100755 index 0000000..7b35463 --- /dev/null +++ b/scripts/make_release @@ -0,0 +1,45 @@ +#!/bin/bash +set -e + +BASEDIR="$(cd "$(dirname "$0")/.." && pwd)" +APPNAME="$(basename "$BASEDIR")" + +cd "$BASEDIR" + +if [ -e "release" ]; then + echo directory \"release\" already exists + exit 1 +fi + +echo building... + +./zig build -Dpackage_release --prefix release/build + +cd release/build + +VERSION=$(/bin/cat version) +TARGETS=$(/bin/ls) + +for target in $TARGETS; do + if [ -d "$target" ]; then + cd "$target" + echo packing "$target"... + tar -czf "../../${APPNAME}-${VERSION}-${target}.tar.gz" -- * + cd .. + fi +done + +cd .. +rm -r build + +TARFILES=$(/bin/ls) + +for tarfile in $TARFILES; do + echo signing "$tarfile"... + gpg --local-user 4E6CF7234FFC4E14531074F98EB1E1BB660E3FB9 --detach-sig "$tarfile" +done + +echo "done making release $VERSION" +echo + +/bin/ls -lah From a84f21384815c505d65617da17073fa8b090d43a Mon Sep 17 00:00:00 2001 From: CJ van den Berg Date: Mon, 18 Nov 2024 17:42:43 +0100 Subject: [PATCH 06/10] build: update zon version number --- build.zig.zon | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/build.zig.zon b/build.zig.zon index 3303322..2b7a7ef 100644 --- a/build.zig.zon +++ b/build.zig.zon @@ -1,6 +1,6 @@ .{ .name = "zat", - .version = "0.0.1", + .version = "1.0.0", .dependencies = .{ .clap = .{ .url = "https://github.com/Hejsil/zig-clap/archive/c0193e9247335a6c1688b946325060289405de2a.tar.gz", From a3fc96418fa689faf542ed4031f63a8729a33159 Mon Sep 17 00:00:00 2001 From: CJ van den Berg Date: Mon, 2 Dec 2024 20:53:15 +0100 Subject: [PATCH 07/10] feat: add odin support --- build.zig.zon | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/build.zig.zon b/build.zig.zon index 2b7a7ef..fe4f4d6 100644 --- a/build.zig.zon +++ b/build.zig.zon @@ -11,8 +11,8 @@ .hash = "122095b1a6110b920571c7e49e61c124cd9a164fe9b1b0faa1bd11d04d89822d3304", }, .syntax = .{ - .url = "https://github.com/neurocyte/flow-syntax/archive/2345f2f3b1def47bbc9b34f1404cd4bc9a02c05e.tar.gz", - .hash = "1220ea8e786a7f7960b4ea7af84e340f630de5ff145dc94aedde00951ae8f58111f4", + .url = "https://github.com/neurocyte/flow-syntax/archive/cba2de651f03e3677bed91c46d2c841eb4137dd4.tar.gz", + .hash = "12201f879b91fc86fd718947a45488e08445c765137857b29a0536a6e7245f7dc522", }, .thespian = .{ .url = "https://github.com/neurocyte/thespian/archive/d7dd27116398b17c8ab68327c384885f161d0cc1.tar.gz", From 50d5b969a92034e362bacf25a17c6128c508882a Mon Sep 17 00:00:00 2001 From: CJ van den Berg Date: Thu, 12 Dec 2024 18:13:49 +0100 Subject: [PATCH 08/10] feat: add mail file type support --- build.zig.zon | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/build.zig.zon b/build.zig.zon index fe4f4d6..c7c0e8f 100644 --- a/build.zig.zon +++ b/build.zig.zon @@ -11,8 +11,8 @@ .hash = "122095b1a6110b920571c7e49e61c124cd9a164fe9b1b0faa1bd11d04d89822d3304", }, .syntax = .{ - .url = "https://github.com/neurocyte/flow-syntax/archive/cba2de651f03e3677bed91c46d2c841eb4137dd4.tar.gz", - .hash = "12201f879b91fc86fd718947a45488e08445c765137857b29a0536a6e7245f7dc522", + .url = "https://github.com/neurocyte/flow-syntax/archive/ba10d89670e19004bd3b958a407afc087c33ca9f.tar.gz", + .hash = "122054eecb1f4c9b669555225c8ae31b419f10231288004eec3247d6854f677a420b", }, .thespian = .{ .url = "https://github.com/neurocyte/thespian/archive/d7dd27116398b17c8ab68327c384885f161d0cc1.tar.gz", From ef0088a9235ad10fcd517cb41eda847a502be215 Mon Sep 17 00:00:00 2001 From: CJ van den Berg Date: Wed, 12 Feb 2025 12:02:23 +0100 Subject: [PATCH 09/10] feat: add sql and astro file types and mellow and zenbones themes --- build.zig.zon | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/build.zig.zon b/build.zig.zon index c7c0e8f..ffeae3c 100644 --- a/build.zig.zon +++ b/build.zig.zon @@ -7,12 +7,12 @@ .hash = "12207ee987ce045596cb992cfb15b0d6d9456e50d4721c3061c69dabc2962053644d", }, .themes = .{ - .url = "https://github.com/neurocyte/flow-themes/releases/download/master-5f1ca2fd3c784d430306a5cd1df237681a196333/flow-themes.tar.gz", - .hash = "122095b1a6110b920571c7e49e61c124cd9a164fe9b1b0faa1bd11d04d89822d3304", + .url = "https://github.com/neurocyte/flow-themes/releases/download/master-618a7801d3383049adfe18cc09f5f5086c66995f/flow-themes.tar.gz", + .hash = "1220019ed92f48fb94d4ae82bba17b11d0ba06f17ed31cd66613b3c048b1d2382095", }, .syntax = .{ - .url = "https://github.com/neurocyte/flow-syntax/archive/ba10d89670e19004bd3b958a407afc087c33ca9f.tar.gz", - .hash = "122054eecb1f4c9b669555225c8ae31b419f10231288004eec3247d6854f677a420b", + .url = "https://github.com/neurocyte/flow-syntax/archive/28bc77f4615488aaa269c25fc862864f4b3a7460.tar.gz", + .hash = "1220abddc10ca8f8b6b5477f8c007948c168504b9dd3516899fe37251890eeabf4ab", }, .thespian = .{ .url = "https://github.com/neurocyte/thespian/archive/d7dd27116398b17c8ab68327c384885f161d0cc1.tar.gz", From a6358d5156af0902600e542337e3548e957fd8aa Mon Sep 17 00:00:00 2001 From: CJ van den Berg Date: Tue, 18 Feb 2025 17:48:21 +0100 Subject: [PATCH 10/10] feat: add -C,--color option to enable color if stdout is not a tty --- src/main.zig | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/main.zig b/src/main.zig index 5741878..6b354ff 100644 --- a/src/main.zig +++ b/src/main.zig @@ -20,6 +20,7 @@ pub fn main() !void { \\-t, --theme Select theme to use. \\-d, --default Set the language to use if guessing failed (default: conf). \\-s, --show-language Show detected language in output. + \\-C, --color Always produce color output, even if stdout is not a tty. \\--html Output HTML instead of ansi escape codes. \\--list-themes Show available themes. \\--list-languages Show available language parsers. @@ -68,7 +69,7 @@ pub fn main() !void { if (res.args.@"list-languages" != 0) return list_langs(writer); - if (!stdout_file.supportsAnsiEscapeCodes()) + if (res.args.color == 0 and !stdout_file.supportsAnsiEscapeCodes()) return plain_cat(res.positionals); var conf_buf: ?[]const u8 = null;