diff --git a/docs/config.md b/docs/config.md index 75082f9..bb80e96 100644 --- a/docs/config.md +++ b/docs/config.md @@ -72,7 +72,7 @@ Because fancy-cat provides sensible defaults, you only need to specify the optio " ", { "view": { "text": "VIS" }, "command": { "text": "CMD" } }, " ", - { "idle": { "text": " " }, "reload": { "text": "*" } }, + { "idle": { "text": " " }, "reload": { "text": "*" }, "watching": { "text": " " } }, ": " ] }, @@ -297,7 +297,7 @@ The `items` property can be set to an array of status bar items, which include: * **[plain items](#plain-items)**: text with default styling * **[styled items](#styled-items)**: text with custom [styling](#style) * **[mode-aware items](#mode-aware-items)**: styled items to be displayed depending on the current mode -* **[reload-aware items](#reload-aware-items)**: styled items to be displayed depending on the current reload indicator state +* **[reload-aware items](#reload-aware-items)**: styled items to be displayed depending on the file monitor state and the reload activity #### Plain Items Plain items are just strings that may include placeholders (e.g., `:`). These placeholders are replaced with dynamic content at runtime. @@ -346,12 +346,13 @@ Mode-aware items switch their content based on the current mode. Each item must #### Reload-aware Items -Reload-aware items switch their content based on the reload indicator state. Each item must include at least one of: +Reload-aware items switch their content based on the file monitor state and the reload activity. Each item must include at least one of: | Property | Type | Description | | :--- | :--- | :--- | -| `idle` | [Styled item](#styled-items) | Item to display when the reload indicator is off | -| `reload` | [Styled item](#styled-items) | Item to display when the reload indicator is on | +| `idle` | [Styled item](#styled-items) | Item to display when the file monitor is disabled | +| `reload` | [Styled item](#styled-items) | Item to display when the file monitor is enabled and the reload indicator is on | +| `watching` | [Styled item](#styled-items) | Item to display when the file monitor is enabled and the reload indicator is off | >[!TIP] >Try using placeholders in mode- and reload-aware items to enhance feedback! diff --git a/src/Context.zig b/src/Context.zig index 9595756..36a717a 100644 --- a/src/Context.zig +++ b/src/Context.zig @@ -21,7 +21,7 @@ pub const Event = union(enum) { pub const ModeType = enum { view, command }; pub const Mode = union(ModeType) { view: ViewMode, command: CommandMode }; -pub const ReloadIndicatorState = enum { idle, reload }; +pub const ReloadIndicatorState = enum { idle, reload, watching }; pub const Context = struct { const Self = @This(); @@ -45,6 +45,7 @@ pub const Context = struct { should_check_cache: bool, reload_indicator_timer: ReloadIndicatorTimer, current_reload_indicator_state: ReloadIndicatorState, + reload_indicator_active: bool, buf: []u8, pub fn init(allocator: std.mem.Allocator, args: [][:0]u8) !Self { @@ -94,6 +95,7 @@ pub const Context = struct { .should_check_cache = config.cache.enabled, .reload_indicator_timer = reload_indicator_timer, .current_reload_indicator_state = .idle, + .reload_indicator_active = false, .buf = buf, }; } @@ -155,9 +157,16 @@ pub const Context = struct { if (self.watcher) |*w| { w.setCallback(callback, &loop); self.watcher_thread = try std.Thread.spawn(.{}, watcherWorker, .{ self, w }); - } - if (self.config.status_bar.enabled and self.config.file_monitor.reload_indicator_duration > 0) { - try self.reload_indicator_timer.start(&loop); + self.current_reload_indicator_state = .watching; + if (self.config.status_bar.enabled and self.config.file_monitor.reload_indicator_duration > 0) { + for (self.config.status_bar.items) |item| { + if (item == .reload_aware) { + try self.reload_indicator_timer.start(&loop); + self.reload_indicator_active = true; + break; + } + } + } } } @@ -221,13 +230,13 @@ pub const Context = struct { try self.document_handler.reloadDocument(); self.cache.clear(); self.reload_page = true; - if (self.config.status_bar.enabled and self.config.file_monitor.reload_indicator_duration > 0) { + if (self.reload_indicator_active) { self.current_reload_indicator_state = .reload; self.reload_indicator_timer.notifyChange(); } }, .reload_done => { - self.current_reload_indicator_state = .idle; + self.current_reload_indicator_state = .watching; }, } } @@ -346,8 +355,9 @@ pub const Context = struct { }, .reload_aware => |reload_aware| { switch (self.current_reload_indicator_state) { - .reload => try expandPlaceholders(&expanded_items, reload_aware.reload), .idle => try expandPlaceholders(&expanded_items, reload_aware.idle), + .reload => try expandPlaceholders(&expanded_items, reload_aware.reload), + .watching => try expandPlaceholders(&expanded_items, reload_aware.watching), } }, } diff --git a/src/config/Config.zig b/src/config/Config.zig index fc512ad..5d49baf 100644 --- a/src/config/Config.zig +++ b/src/config/Config.zig @@ -138,6 +138,7 @@ pub const StatusBar = struct { pub const ReloadAwareItem = struct { idle: StyledItem, reload: StyledItem, + watching: StyledItem, }; pub const Item = union(enum) { styled: StyledItem, @@ -167,6 +168,7 @@ pub const StatusBar = struct { .{ .reload_aware = .{ .idle = .{ .text = " ", .style = default_style }, .reload = .{ .text = "*", .style = default_style }, + .watching = .{ .text = " ", .style = default_style }, } }, .{ .styled = .{ .text = SEPARATOR, .style = default_style } }, .{ .styled = .{ .text = PAGE, .style = default_style } }, @@ -378,6 +380,7 @@ fn applyStyle(item: StatusBar.Item, style: vaxis.Cell.Style, allocator: std.mem. var reload_aware_item: StatusBar.Item = .{ .reload_aware = StatusBar.ReloadAwareItem{ .idle = StatusBar.StyledItem{ .text = "", .style = style }, .reload = StatusBar.StyledItem{ .text = "", .style = style }, + .watching = StatusBar.StyledItem{ .text = "", .style = style }, } }; switch (item) { @@ -391,8 +394,9 @@ fn applyStyle(item: StatusBar.Item, style: vaxis.Cell.Style, allocator: std.mem. return mode_aware_item; }, .reload_aware => |reload_aware| { - reload_aware_item.reload_aware.reload.text = allocator.dupe(u8, reload_aware.reload.text) catch reload_aware_item.reload_aware.reload.text; reload_aware_item.reload_aware.idle.text = allocator.dupe(u8, reload_aware.idle.text) catch reload_aware_item.reload_aware.idle.text; + reload_aware_item.reload_aware.reload.text = allocator.dupe(u8, reload_aware.reload.text) catch reload_aware_item.reload_aware.reload.text; + reload_aware_item.reload_aware.watching.text = allocator.dupe(u8, reload_aware.watching.text) catch reload_aware_item.reload_aware.watching.text; return reload_aware_item; }, } @@ -407,6 +411,7 @@ fn parseItem(val: std.json.Value, allocator: std.mem.Allocator, fallback_style: var reload_aware_item: StatusBar.Item = .{ .reload_aware = StatusBar.ReloadAwareItem{ .idle = StatusBar.StyledItem{ .text = "", .style = fallback_style }, .reload = StatusBar.StyledItem{ .text = "", .style = fallback_style }, + .watching = StatusBar.StyledItem{ .text = "", .style = fallback_style }, } }; switch (val) { @@ -421,9 +426,10 @@ fn parseItem(val: std.json.Value, allocator: std.mem.Allocator, fallback_style: mode_aware_item.mode_aware.command = parseStyledItem(obj.get("command"), allocator, mode_aware_item.mode_aware.command); return mode_aware_item; } - if (obj.contains("reload") or obj.contains("idle")) { + if (obj.contains("idle") or obj.contains("reload") or obj.contains("watching")) { reload_aware_item.reload_aware.idle = parseStyledItem(obj.get("idle"), allocator, reload_aware_item.reload_aware.idle); reload_aware_item.reload_aware.reload = parseStyledItem(obj.get("reload"), allocator, reload_aware_item.reload_aware.reload); + reload_aware_item.reload_aware.watching = parseStyledItem(obj.get("watching"), allocator, reload_aware_item.reload_aware.watching); return reload_aware_item; }