From 40cc8ecd8b30a43b64044b6a943c7071cdc34869 Mon Sep 17 00:00:00 2001 From: namedkitten Date: Sat, 11 Jul 2020 15:14:55 +0100 Subject: [PATCH] Add terminal output and add memory widget. --- build.zig | 2 +- src/bar/bar.zig | 27 ++++++-- src/formatting/colour.zig | 72 +++++++++++++--------- src/main.zig | 3 +- src/widgets/memory/memory.zig | 111 ++++++++++++++++++++++++++++++--- untitled.sublime-workspace | 112 +++++++++++++++++++++++++++++++--- 6 files changed, 274 insertions(+), 53 deletions(-) diff --git a/build.zig b/build.zig index 3cd890f..632292b 100644 --- a/build.zig +++ b/build.zig @@ -4,7 +4,7 @@ const Builder = @import("std").build.Builder; pub fn build(b: *Builder) void { const mode = b.standardReleaseOptions(); const exe = b.addExecutable("zar", "src/main.zig"); - + exe.addBuildOption(bool, "terminal_version", false); exe.addPackage(.{ .name = "interfaces", .path = "deps/interfaces/interface.zig", diff --git a/src/bar/bar.zig b/src/bar/bar.zig index 245424d..a3e6183 100644 --- a/src/bar/bar.zig +++ b/src/bar/bar.zig @@ -2,6 +2,8 @@ const std = @import("std"); const Widget = @import("../types/widget.zig").Widget; const Info = @import("../types/info.zig").Info; +const terminal_version = @import("build_options").terminal_version; + pub const Bar = struct { allocator: *std.mem.Allocator, widgets: []const *Widget, @@ -11,7 +13,7 @@ pub const Bar = struct { out_file: std.fs.File, pub fn start(self: *Bar) !void { self.running = true; - try self.out_file.writer().writeAll("{\"version\": 1,\"click_events\": true}\n[\n"); + if (!terminal_version) try self.out_file.writer().writeAll("{\"version\": 1,\"click_events\": true}\n[\n"); for (self.widgets) |w| { std.debug.warn("Adding Initial Info: {}\n", .{w.name()}); try self.infos.append(try self.dupe_info(w.initial_info())); @@ -36,19 +38,32 @@ pub const Bar = struct { const lock = self.mutex.acquire(); defer lock.release(); } - try self.out_file.writer().writeAll("["); + if (!terminal_version) try self.out_file.writer().writeAll("["); for (self.infos.items) |info, i| { - try std.json.stringify(info, .{}, self.out_file.writer()); - if (i < self.infos.items.len - 1) { - try self.out_file.writer().writeAll(","); + if (!terminal_version) { + try std.json.stringify(info, .{}, self.out_file.writer()); + + if (i < self.infos.items.len - 1) { + try self.out_file.writer().writeAll(","); + } + } else { + try self.out_file.writer().writeAll(info.full_text); + if (i < self.infos.items.len - 1) { + try self.out_file.writer().writeAll("|"); + } } } - try self.out_file.writer().writeAll("],\n"); + if (!terminal_version) { + try self.out_file.writer().writeAll("],\n"); + } else { + try self.out_file.writer().writeAll("\n"); + } } fn process(self: *Bar) !void { while (self.running) { std.time.sleep(5000 * std.time.ns_per_ms); + //return; } } pub fn keep_running(self: *Bar) bool { diff --git a/src/formatting/colour.zig b/src/formatting/colour.zig index 4c26025..e9f87d1 100644 --- a/src/formatting/colour.zig +++ b/src/formatting/colour.zig @@ -1,48 +1,64 @@ const std = @import("std"); const eql = std.mem.eql; +const terminal_version = @import("build_options").terminal_version; const TextColour = "#D8DEE9"; const DarkerTextColour = "#E5E9F0"; const DarkestTextColour = "#ECEFF4"; - const AccentLightColour = "#88C0D0"; const AccentMediumColour = "#81A1C1"; const AccentDarkColour = "#5E81AC"; - const RedColour = "#BF616A"; const OrangeColour = "#D08770"; const YellowColour = "#EBCB8B"; const GreenColour = "#A3BE8C"; const PurpleColour = "#B48EAD"; +const TerminalResetColour = "\u{001b}[37m"; +const TerminalTextColour = TerminalResetColour; +const TerminalDarkerTextColour = TerminalResetColour; +const TerminalDarkestTextColour = TerminalResetColour; +const TerminalAccentLightColour = "\u{001b}[38;5;26m"; +const TerminalAccentMediumColour = "\u{001b}[38;5;32m"; +const TerminalAccentDarkColour = "\u{001b}[38;5;38m"; +const TerminalRedColour = "\u{001b}[31m"; +const TerminalOrangeColour = "\u{001b}[31;1m"; +const TerminalYellowColour = "\u{001b}[33m"; +const TerminalGreenColour = "\u{001b}[32m"; +const TerminalPurpleColour = "\u{001b}[35m"; + pub fn colour(alloc: *std.mem.Allocator, clr: []const u8, str: []const u8) ![]const u8 { - if (clr[0] == '#') { - return try std.fmt.allocPrint(alloc, "{}", .{ clr, str }); - } else { - if (eql(u8, clr, "text")) { - return colour(alloc, TextColour, str); - } else if (eql(u8, clr, "dark")) { - return colour(alloc, DarkerTextColour, str); - } else if (eql(u8, clr, "darkest")) { - return colour(alloc, DarkestTextColour, str); - } else if (eql(u8, clr, "accentlight")) { - return colour(alloc, AccentLightColour, str); - } else if (eql(u8, clr, "accentmedium")) { - return colour(alloc, AccentMediumColour, str); - } else if (eql(u8, clr, "accentdark")) { - return colour(alloc, AccentDarkColour, str); - } else if (eql(u8, clr, "red")) { - return colour(alloc, RedColour, str); - } else if (eql(u8, clr, "orange")) { - return colour(alloc, OrangeColour, str); - } else if (eql(u8, clr, "yellow")) { - return colour(alloc, YellowColour, str); - } else if (eql(u8, clr, "green")) { - return colour(alloc, GreenColour, str); - } else if (eql(u8, clr, "purple")) { - return colour(alloc, PurpleColour, str); + if (clr[0] == '#' or clr[0] == '\u{001b}') { + if (terminal_version) { + return try std.fmt.allocPrint(alloc, "{}{}" ++ TerminalResetColour, .{ clr, str }); } else { - return "what"; + return try std.fmt.allocPrint(alloc, "{}", .{ clr, str }); } + } else { + var colourText: []const u8 = ""; + if (eql(u8, clr, "text")) { + colourText = if (!terminal_version) TextColour else TerminalTextColour; + } else if (eql(u8, clr, "dark")) { + colourText = if (!terminal_version) DarkerTextColour else TerminalDarkerTextColour; + } else if (eql(u8, clr, "darkest")) { + colourText = if (!terminal_version) DarkestTextColour else TerminalDarkestTextColour; + } else if (eql(u8, clr, "accentlight")) { + colourText = if (!terminal_version) AccentLightColour else TerminalAccentLightColour; + } else if (eql(u8, clr, "accentmedium")) { + colourText = if (!terminal_version) AccentMediumColour else TerminalAccentMediumColour; + } else if (eql(u8, clr, "accentdark")) { + colourText = if (!terminal_version) AccentDarkColour else TerminalAccentDarkColour; + } else if (eql(u8, clr, "red")) { + colourText = if (!terminal_version) RedColour else TerminalRedColour; + } else if (eql(u8, clr, "orange")) { + colourText = if (!terminal_version) OrangeColour else TerminalOrangeColour; + } else if (eql(u8, clr, "yellow")) { + colourText = if (!terminal_version) YellowColour else TerminalYellowColour; + } else if (eql(u8, clr, "green")) { + colourText = if (!terminal_version) GreenColour else TerminalGreenColour; + } else if (eql(u8, clr, "purple")) { + colourText = if (!terminal_version) PurpleColour else TerminalPurpleColour; + } + return colour(alloc, colourText, str); } } diff --git a/src/main.zig b/src/main.zig index 95f2c5d..51acccc 100644 --- a/src/main.zig +++ b/src/main.zig @@ -6,7 +6,7 @@ const textWidget = @import("widgets/text/text.zig"); const weatherWidget = @import("widgets/weather/weather.zig"); const timeWidget = @import("widgets/time/time.zig"); const batteryWidget = @import("widgets/battery/battery.zig"); - +const memoryWidget = @import("widgets/memory/memory.zig"); const DebugAllocator = @import("debug_allocator.zig"); const Info = @import("types/info.zig").Info; @@ -27,6 +27,7 @@ pub fn main() !void { const widgets = [_]*Widget{ &Widget.init(&textWidget.New("owo", "potato")), // 4KiB &Widget.init(&textWidget.New("uwu", "tomato")), // 4KiB + &Widget.init(&memoryWidget.New(allocator, &br)), // 8.08KiB &Widget.init(&weatherWidget.New(allocator, &br, "London")), // 16KiB &Widget.init(&batteryWidget.New(allocator, &br)), // 12.11KiB &Widget.init(&timeWidget.New(allocator, &br)), // 32.46KiB diff --git a/src/widgets/memory/memory.zig b/src/widgets/memory/memory.zig index 285589d..99a4b80 100644 --- a/src/widgets/memory/memory.zig +++ b/src/widgets/memory/memory.zig @@ -1,28 +1,125 @@ const std = @import("std"); const Info = @import("../../types/info.zig").Info; +const Bar = @import("../../types/bar.zig").Bar; +const colour = @import("../../formatting/colour.zig").colour; + +const MemInfo = struct { + memTotal: u64, + memFree: u64, + buffers: u64, + cached: u64, +}; + +fn parseKibibytes(buf: []const u8) !u64 { + return try std.fmt.parseInt(u64, buf, 10); +} + +fn parseKibibytesToMegabytes(buf: []const u8) !u64 { + const kilobytes = try std.fmt.parseInt(u64, buf, 10); + return (kilobytes * 1024) / 1000 / 1000; +} + +fn formatMemoryPercent(allocator: *std.mem.Allocator, percent: f64) ![]const u8 { + var percentColour: []const u8 = ""; + if (percent > 80) { + percentColour = "red"; + } else if (percent > 60) { + percentColour = "orange"; + } else if (percent > 30) { + percentColour = "yellow"; + } else { + percentColour = "green"; + } + const percentString = try std.fmt.allocPrint(allocator, "{d:.3}{}", .{ percent, colour(allocator, "accentdark", "%") }); + + return colour(allocator, percentColour, percentString); +} + +fn fetchTotalMemory() !MemInfo { + var meminfo_file = try std.fs.cwd().openFile("/proc/meminfo", .{ .read = true, .write = false }); + defer meminfo_file.close(); + + var meminfo = MemInfo{ + .memTotal = 0, + .memFree = 0, + .buffers = 0, + .cached = 0, + }; + + while (true) { + var line_buffer: [128]u8 = undefined; + const line_opt = try meminfo_file.inStream().readUntilDelimiterOrEof(&line_buffer, '\n'); + if (line_opt) |line| { + var it = std.mem.tokenize(line, " "); + const line_header = it.next().?; + if (std.mem.eql(u8, line_header, "MemTotal:")) { + meminfo.memTotal = try parseKibibytes(it.next().?); + continue; + } + if (std.mem.eql(u8, line_header, "MemFree:")) { + meminfo.memFree = try parseKibibytes(it.next().?); + continue; + } + if (std.mem.eql(u8, line_header, "Buffers:")) { + meminfo.buffers = try parseKibibytes(it.next().?); + continue; + } + if (std.mem.eql(u8, line_header, "Cached:")) { + meminfo.cached = try parseKibibytes(it.next().?); + continue; + } + } else { + // reached eof + break; + } + } + + return meminfo; +} pub const MemoryWidget = struct { + bar: *Bar, + allocator: *std.mem.Allocator, pub fn name(self: *MemoryWidget) []const u8 { - return self.name; + return "mem"; } pub fn initial_info(self: *MemoryWidget) Info { return Info{ .name = "mem", - .full_text = self.text, + .full_text = "memory", .markup = "pango", - .color = "#ffaaff", }; } pub fn info(self: *MemoryWidget) Info { return self.initial_info(); } - pub fn start(self: *MemoryWidget) anyerror!void {} + fn update_bar(self: *MemoryWidget) !void { + var arena = std.heap.ArenaAllocator.init(self.allocator); + defer arena.deinit(); + var allocator = &arena.allocator; + const memInfo = try fetchTotalMemory(); + try self.bar.add(Info{ + .name = "mem", + .full_text = try std.fmt.allocPrint(allocator, "{} {}", .{ + colour(allocator, "accentlight", "mem"), + formatMemoryPercent(allocator, (@intToFloat(f64, memInfo.memTotal - memInfo.memFree - memInfo.buffers - memInfo.cached) / @intToFloat(f64, memInfo.memTotal)) * 100), + }), + .markup = "pango", + }); + } + + pub fn start(self: *MemoryWidget) anyerror!void { + while (self.bar.keep_running()) { + self.update_bar() catch {}; + std.time.sleep(250 * std.time.ns_per_ms); + } + } }; -pub inline fn New(name: []const u8, Memory: []const u8) MemoryWidget { +pub inline fn New(allocator: *std.mem.Allocator, bar: *Bar) MemoryWidget { return MemoryWidget{ - .name = name, - .Memory = Memory, + .allocator = allocator, + .bar = bar, }; } diff --git a/untitled.sublime-workspace b/untitled.sublime-workspace index 67beb6c..420c5b4 100644 --- a/untitled.sublime-workspace +++ b/untitled.sublime-workspace @@ -3,6 +3,38 @@ { "selected_items": [ + [ + "powe", + "power_now_path" + ], + [ + "cur", + "current_now_path" + ], + [ + "vol", + "voltage_now" + ], + [ + "volt", + "voltage_now_path" + ], + [ + "cu", + "current_now_path" + ], + [ + "capacit", + "capacity_path" + ], + [ + "w", + "w" + ], + [ + "stack_", + "stack_addresses_size" + ], [ "allo", "allocPrint" @@ -54,7 +86,11 @@ [ [ "lsp", - "LSP: Toggle Log Panel" + "LSP: Toggle Diagnostics Panel" + ], + [ + "enable lang", + "LSP: Enable Language Server Globally" ], [ "enable", @@ -131,14 +167,27 @@ }, "file_history": [ - "/home/kitteh/zar/src/types/widget.zig", - "/home/kitteh/zar/src/widgets/text/text.zig", + "/home/kitteh/zig-linux-x86_64-0.6.0+485231dea/lib/zig/std/std.zig", + "/home/kitteh/zar/src/debug_allocator.zig", "/home/kitteh/zar/src/bar/bar.zig", - "/home/kitteh/zar/src/types/bar.zig", + "/home/kitteh/bar/battery.go", "/home/kitteh/zar/src/formatting/colour.zig", - "/home/kitteh/zar/src/types/info.zig", - "/home/kitteh/zar/src/types/types.zig", "/home/kitteh/zar/build.zig", + "/home/kitteh/zar/deps/time/src/time.zig", + "/home/kitteh/bar/time.go", + "/home/kitteh/zar/src/widgets/weather/weather.zig", + "/home/kitteh/bar/main.go", + "/home/kitteh/zig-linux-x86_64-0.6.0+485231dea/lib/zig/std/valgrind/memcheck.zig", + "/home/kitteh/zig-linux-x86_64-0.6.0+485231dea/lib/zig/std/progress.zig", + "/home/kitteh/zig-linux-x86_64-0.6.0+485231dea/lib/zig/std/mutex.zig", + "/home/kitteh/zig-linux-x86_64-0.6.0+485231dea/lib/zig/std/meta.zig", + "/home/kitteh/zar/src/types/info.zig", + "/home/kitteh/zar/src/widgets/text/text.zig", + "/home/kitteh/bar/bar.go", + "/home/kitteh/zar/src/types/bar.zig", + "/home/kitteh/zar/src/widgets/memory/memory.zig", + "/home/kitteh/zar/src/types/widget.zig", + "/home/kitteh/zar/src/types/types.zig", "/home/kitteh/.config/sublime-text-3/Packages/ayu/widgets/Widget - ayu-dark.sublime-settings", "/home/kitteh/.config/sublime-text-3/Packages/Monokai++/themes/Monokai++.tmTheme", "/home/kitteh/zar/.gitignore", @@ -146,7 +195,7 @@ ], "find": { - "height": 41.0 + "height": 54.0 }, "find_in_files": { @@ -160,6 +209,43 @@ "case_sensitive": false, "find_history": [ + "_", + "secureZero", + "self.widgets", + "TextWidget", + ".linux", + "time(", + "Clock ", + "Clock", + "date.day % 10", + "date.day % 100", + " \"", + "%s", + "fn date(", + "isize", + "DateDetail", + "days", + "m: *mem.Allocator", + "initLocation", + "std.heap.page", + "utc_local", + "std.heap.page", + "fn init(", + "init(", + "std.heap.page_allocator", + "allocator", + "Febuary", + "month", + "colour", + "Memory", + "month", + "free_", + "error", + "self.allocator", + "Text", + "deinit", + "max_bytes", + "printRemainingStackTraces", "return colour(", ".Fn", "spawn", @@ -178,6 +264,12 @@ "regex": false, "replace_history": [ + "BatteryWidget", + "@mod(date.day, 10)", + "@mod(date.day, 100)", + "{}", + "Time", + "Memory", "return colour(allocator, ", "[]const u8" ], @@ -189,7 +281,7 @@ }, "incremental_find": { - "height": 39.0 + "height": 27.0 }, "input": { @@ -220,7 +312,7 @@ "menu_visible": true, "output.diagnostics": { - "height": 286.0 + "height": 37.0 }, "output.exec": { @@ -237,7 +329,7 @@ "pinned_build_system": "", "replace": { - "height": 69.0 + "height": 50.0 }, "save_all_on_build": false, "select_file":