aboutsummaryrefslogtreecommitdiff
path: root/examples
diff options
context:
space:
mode:
Diffstat (limited to 'examples')
-rw-r--r--examples/hello-zig/.editorconfig6
-rw-r--r--examples/hello-zig/.gitignore2
-rw-r--r--examples/hello-zig/.nova/Configuration.json8
-rw-r--r--examples/hello-zig/.nova/Tasks/Zig Debug.json12
-rw-r--r--examples/hello-zig/.nova/Tasks/Zig Package (macOS Terminal).json7
-rw-r--r--examples/hello-zig/.nova/Tasks/Zig Package.json8
-rw-r--r--examples/hello-zig/build.zig47
-rw-r--r--examples/hello-zig/build.zig.zon12
-rw-r--r--examples/hello-zig/src/main.zig32
-rw-r--r--examples/hello-zig/src/root.zig83
-rw-r--r--examples/sample-config.zon19
-rw-r--r--examples/showcase.zig80
12 files changed, 316 insertions, 0 deletions
diff --git a/examples/hello-zig/.editorconfig b/examples/hello-zig/.editorconfig
new file mode 100644
index 0000000..d5f8c65
--- /dev/null
+++ b/examples/hello-zig/.editorconfig
@@ -0,0 +1,6 @@
+root = true
+
+[*]
+indent_style = space
+indent_size = 4
+insert_final_newline = true
diff --git a/examples/hello-zig/.gitignore b/examples/hello-zig/.gitignore
new file mode 100644
index 0000000..3389c86
--- /dev/null
+++ b/examples/hello-zig/.gitignore
@@ -0,0 +1,2 @@
+.zig-cache/
+zig-out/
diff --git a/examples/hello-zig/.nova/Configuration.json b/examples/hello-zig/.nova/Configuration.json
new file mode 100644
index 0000000..47e341a
--- /dev/null
+++ b/examples/hello-zig/.nova/Configuration.json
@@ -0,0 +1,8 @@
+{
+ "at.dcz.nova-zig.toolchain.lldb-dap-path" : "\/Library\/Developer\/CommandLineTools\/usr\/bin\/lldb-dap",
+ "at.dcz.nova-zig.toolchain.zig-path" : "\/opt\/homebrew\/bin\/zig",
+ "at.dcz.nova-zig.zls.build-on-save" : true,
+ "at.dcz.nova-zig.zls.enabled" : true,
+ "zls.enable_build_on_save" : true,
+ "zls.zig_exe_path" : "\/opt\/homebrew\/bin\/zig"
+}
diff --git a/examples/hello-zig/.nova/Tasks/Zig Debug.json b/examples/hello-zig/.nova/Tasks/Zig Debug.json
new file mode 100644
index 0000000..53b7f13
--- /dev/null
+++ b/examples/hello-zig/.nova/Tasks/Zig Debug.json
@@ -0,0 +1,12 @@
+{
+ "extension" : {
+ "identifier" : "at.dcz.nova-zig",
+ "name" : "Zig"
+ },
+ "extensionTemplate" : "zigDebug",
+ "extensionValues" : {
+ "console" : "internalConsole",
+ "programPath" : "zig-out\/bin\/hello-zig"
+ },
+ "openLogOnRun" : "start"
+}
diff --git a/examples/hello-zig/.nova/Tasks/Zig Package (macOS Terminal).json b/examples/hello-zig/.nova/Tasks/Zig Package (macOS Terminal).json
new file mode 100644
index 0000000..d1fa04d
--- /dev/null
+++ b/examples/hello-zig/.nova/Tasks/Zig Package (macOS Terminal).json
@@ -0,0 +1,7 @@
+{
+ "extension" : {
+ "identifier" : "at.dcz.nova-zig",
+ "name" : "Zig"
+ },
+ "extensionTemplate" : "zigBuildRunTerminal"
+}
diff --git a/examples/hello-zig/.nova/Tasks/Zig Package.json b/examples/hello-zig/.nova/Tasks/Zig Package.json
new file mode 100644
index 0000000..10830e6
--- /dev/null
+++ b/examples/hello-zig/.nova/Tasks/Zig Package.json
@@ -0,0 +1,8 @@
+{
+ "buildBeforeRunning" : true,
+ "extension" : {
+ "identifier" : "at.dcz.nova-zig",
+ "name" : "Zig"
+ },
+ "extensionTemplate" : "zigBuildRun"
+}
diff --git a/examples/hello-zig/build.zig b/examples/hello-zig/build.zig
new file mode 100644
index 0000000..5c56fb0
--- /dev/null
+++ b/examples/hello-zig/build.zig
@@ -0,0 +1,47 @@
+const std = @import("std");
+
+pub fn build(b: *std.Build) void {
+ const target = b.standardTargetOptions(.{});
+ const optimize = b.standardOptimizeOption(.{});
+
+ const lib_mod = b.addModule("hello_zig", .{
+ .root_source_file = b.path("src/root.zig"),
+ .target = target,
+ });
+
+ const exe = b.addExecutable(.{
+ .name = "hello-zig",
+ .root_module = b.createModule(.{
+ .root_source_file = b.path("src/main.zig"),
+ .target = target,
+ .optimize = optimize,
+ .imports = &.{
+ .{ .name = "hello_zig", .module = lib_mod },
+ },
+ }),
+ });
+
+ b.installArtifact(exe);
+
+ const run_step = b.step("run", "Run the sample app");
+ const run_cmd = b.addRunArtifact(exe);
+ run_step.dependOn(&run_cmd.step);
+
+ if (b.args) |args| {
+ run_cmd.addArgs(args);
+ }
+
+ const lib_tests = b.addTest(.{
+ .root_module = lib_mod,
+ });
+ const exe_tests = b.addTest(.{
+ .root_module = exe.root_module,
+ });
+
+ const run_lib_tests = b.addRunArtifact(lib_tests);
+ const run_exe_tests = b.addRunArtifact(exe_tests);
+
+ const test_step = b.step("test", "Run the sample tests");
+ test_step.dependOn(&run_lib_tests.step);
+ test_step.dependOn(&run_exe_tests.step);
+}
diff --git a/examples/hello-zig/build.zig.zon b/examples/hello-zig/build.zig.zon
new file mode 100644
index 0000000..09f7da2
--- /dev/null
+++ b/examples/hello-zig/build.zig.zon
@@ -0,0 +1,12 @@
+.{
+ .name = .hello_zig,
+ .version = "0.1.0",
+ .fingerprint = 0x1c1a468675f426fe, // Changing this has security and trust implications.
+ .minimum_zig_version = "0.15.2",
+ .dependencies = .{},
+ .paths = .{
+ "build.zig",
+ "build.zig.zon",
+ "src",
+ },
+}
diff --git a/examples/hello-zig/src/main.zig b/examples/hello-zig/src/main.zig
new file mode 100644
index 0000000..74eb590
--- /dev/null
+++ b/examples/hello-zig/src/main.zig
@@ -0,0 +1,32 @@
+const std = @import("std");
+const hello_zig = @import("hello_zig");
+
+pub fn main() !void {
+ var arena = std.heap.ArenaAllocator.init(std.heap.page_allocator);
+ defer arena.deinit();
+
+ const allocator = arena.allocator();
+ const args = try std.process.argsAlloc(allocator);
+ const name = if (args.len > 1) args[1] else "Nova";
+
+ var greeter = hello_zig.Greeter{
+ .name = name,
+ .punctuation = '!',
+ };
+
+ const stdout = std.fs.File.stdout().deprecatedWriter();
+ try greeter.write(stdout, .verbose);
+
+ const sample_values = [_]i32{ -3, -2, 0, 1, 2, 3, 4 };
+ var squares = try hello_zig.collectEvenSquares(allocator, &sample_values);
+ defer squares.deinit(allocator);
+
+ std.debug.print("even squares: {any}\n", .{squares.items});
+}
+
+test "main module can compute a summary" {
+ const greeting = try hello_zig.describeNumber(std.testing.allocator, 42);
+ defer std.testing.allocator.free(greeting);
+
+ try std.testing.expect(std.mem.startsWith(u8, greeting, "positive"));
+}
diff --git a/examples/hello-zig/src/root.zig b/examples/hello-zig/src/root.zig
new file mode 100644
index 0000000..f6600ac
--- /dev/null
+++ b/examples/hello-zig/src/root.zig
@@ -0,0 +1,83 @@
+const std = @import("std");
+
+pub const OutputStyle = enum {
+ compact,
+ verbose,
+};
+
+pub const NumberKind = union(enum) {
+ negative: i64,
+ zero,
+ positive: u64,
+};
+
+pub const Greeter = struct {
+ name: []const u8,
+ punctuation: u8 = '!',
+
+ pub fn write(self: Greeter, writer: anytype, style: OutputStyle) !void {
+ switch (style) {
+ .compact => try writer.print("hello, {s}{c}\n", .{ self.name, self.punctuation }),
+ .verbose => {
+ try writer.print(
+ \\hello, {s}{c}
+ \\this sample is here to exercise Zig syntax support in Nova.
+ \\
+ , .{ self.name, self.punctuation });
+ },
+ }
+ }
+};
+
+pub fn classifyNumber(value: i64) NumberKind {
+ if (value == 0) return .zero;
+ if (value < 0) return .{ .negative = value };
+ return .{ .positive = @intCast(value) };
+}
+
+pub fn describeNumber(allocator: std.mem.Allocator, value: i64) ![]u8 {
+ return switch (classifyNumber(value)) {
+ .zero => std.fmt.allocPrint(allocator, "zero", .{}),
+ .negative => |negative| std.fmt.allocPrint(allocator, "negative({d})", .{negative}),
+ .positive => |positive| std.fmt.allocPrint(allocator, "positive({d})", .{positive}),
+ };
+}
+
+pub fn collectEvenSquares(
+ allocator: std.mem.Allocator,
+ values: []const i32,
+) !std.ArrayList(i32) {
+ var result: std.ArrayList(i32) = .empty;
+ errdefer result.deinit(allocator);
+
+ for (values) |value| {
+ if (@mod(value, 2) != 0) continue;
+ try result.append(allocator, value * value);
+ }
+
+ return result;
+}
+
+test "classifyNumber covers the main branches" {
+ try std.testing.expectEqual(NumberKind{ .negative = -5 }, classifyNumber(-5));
+ try std.testing.expectEqual(NumberKind.zero, classifyNumber(0));
+ try std.testing.expectEqual(NumberKind{ .positive = 9 }, classifyNumber(9));
+}
+
+test "collectEvenSquares keeps only even numbers" {
+ const values = [_]i32{ -4, -3, 0, 1, 2, 7 };
+ var result = try collectEvenSquares(std.testing.allocator, &values);
+ defer result.deinit(std.testing.allocator);
+
+ try std.testing.expectEqualSlices(i32, &.{ 16, 0, 4 }, result.items);
+}
+
+test "Greeter.write renders verbose output" {
+ var list: std.ArrayList(u8) = .empty;
+ defer list.deinit(std.testing.allocator);
+
+ const writer = list.writer(std.testing.allocator);
+ try (Greeter{ .name = "Zig" }).write(writer, .verbose);
+
+ try std.testing.expect(std.mem.indexOf(u8, list.items, "exercise Zig syntax support") != null);
+}
diff --git a/examples/sample-config.zon b/examples/sample-config.zon
new file mode 100644
index 0000000..b346a84
--- /dev/null
+++ b/examples/sample-config.zon
@@ -0,0 +1,19 @@
+.{
+ .name = "nova-zig-example",
+ .enabled = true,
+ .targets = .{
+ "native",
+ "wasm32-wasi",
+ },
+ .retry = .{
+ .max_attempts = 3,
+ .backoff_seconds = 2.5,
+ },
+ .theme = .solarized,
+ .features = .{
+ .language_server = true,
+ .tree_sitter = true,
+ .run_tasks = true,
+ .debug_adapter = false,
+ },
+}
diff --git a/examples/showcase.zig b/examples/showcase.zig
new file mode 100644
index 0000000..54b195f
--- /dev/null
+++ b/examples/showcase.zig
@@ -0,0 +1,80 @@
+const std = @import("std");
+
+pub const AppError = error{
+ MissingName,
+ EmptyInput,
+};
+
+pub const Theme = enum {
+ light,
+ dark,
+ solarized,
+};
+
+pub const Settings = struct {
+ name: []const u8,
+ retries: u8 = 3,
+ theme: Theme = .dark,
+ tags: []const []const u8 = &.{},
+
+ pub fn validate(self: Settings) AppError!void {
+ if (self.name.len == 0) return error.MissingName;
+ if (self.tags.len == 0) return error.EmptyInput;
+ }
+};
+
+pub fn summarize(settings: Settings) []const u8 {
+ return switch (settings.theme) {
+ .light => "bright",
+ .dark => "focused",
+ .solarized => "balanced",
+ };
+}
+
+pub fn findLongestTag(tags: []const []const u8) ?[]const u8 {
+ var longest: ?[]const u8 = null;
+
+ for (tags) |tag| {
+ if (longest == null or tag.len > longest.?.len) {
+ longest = tag;
+ }
+ }
+
+ return longest;
+}
+
+pub fn renderExample(writer: anytype) !void {
+ const settings = Settings{
+ .name = "Nova Zig",
+ .tags = &.{ "tree-sitter", "zls", "tasks" },
+ };
+
+ try settings.validate();
+ try writer.print("theme summary: {s}\n", .{summarize(settings)});
+
+ if (findLongestTag(settings.tags)) |tag| {
+ try writer.print("longest tag: {s}\n", .{tag});
+ }
+
+ const block_value = label: {
+ var total: usize = 0;
+ for (settings.tags) |tag| total += tag.len;
+ break :label total;
+ };
+ try writer.print("combined tag length: {}\n", .{block_value});
+
+ const multiline =
+ \\sample text block
+ \\with enough lines to make folding obvious
+ \\inside Nova's editor
+ ;
+ _ = multiline;
+}
+
+test "showcase remains valid" {
+ var output: std.ArrayList(u8) = .empty;
+ defer output.deinit(std.testing.allocator);
+
+ try renderExample(output.writer(std.testing.allocator));
+ try std.testing.expect(std.mem.indexOf(u8, output.items, "theme summary") != null);
+}