From 572c99b2ec6a57a18d4a911cf8d577805002811e Mon Sep 17 00:00:00 2001 From: "copilot-swe-agent[bot]" <198982749+Copilot@users.noreply.github.com> Date: Wed, 21 Jan 2026 22:18:32 +0000 Subject: [PATCH] feat(text): add GaugeUsed method to Percentage type Co-authored-by: JanDeDobbeleer <2492783+JanDeDobbeleer@users.noreply.github.com> --- src/text/percentage.go | 20 +++++- src/text/percentage_test.go | 63 +++++++++++++++++ ...2-28-oh-my-posh-claude-code-integration.md | 2 +- website/docs/segments/cli/claude.mdx | 9 +-- website/docs/segments/cli/copilot.mdx | 68 ++++++++++++------- 5 files changed, 130 insertions(+), 32 deletions(-) diff --git a/src/text/percentage.go b/src/text/percentage.go index b71a0212f..db7c03275 100644 --- a/src/text/percentage.go +++ b/src/text/percentage.go @@ -8,10 +8,15 @@ import ( // Percentage represents a percentage value with gauge visualization. type Percentage int +// clamp ensures the percentage value is within the valid range of 0-100. +func (p Percentage) clamp() int { + return min(max(int(p), 0), 100) +} + // Gauge returns a 5-character gauge visualization showing remaining capacity (▰▰▰▰▱ style). // The gauge displays remaining capacity, so 20% used shows 4 filled blocks (80% remaining). func (p Percentage) Gauge() string { - percent := min(max(int(p), 0), 100) + percent := p.clamp() // Calculate remaining percentage for gauge display remainingPercent := 100 - percent @@ -24,6 +29,19 @@ func (p Percentage) Gauge() string { return strings.Repeat("▰", filledBlocks) + strings.Repeat("▱", emptyBlocks) } +// GaugeUsed returns a 5-character gauge visualization showing used capacity (▰▱▱▱▱ style). +// The gauge displays used capacity, so 20% used shows 1 filled block (▰▱▱▱▱). +func (p Percentage) GaugeUsed() string { + percent := p.clamp() + + // 5 blocks total, calculate how many should be filled (representing used capacity) + filledBlocks := (percent * 5) / 100 + emptyBlocks := 5 - filledBlocks + + // Use ▰ for filled blocks (used) and ▱ for empty blocks (remaining) + return strings.Repeat("▰", filledBlocks) + strings.Repeat("▱", emptyBlocks) +} + // String returns the percentage as a string without % sign for template compatibility. func (p Percentage) String() string { return fmt.Sprintf("%d", int(p)) diff --git a/src/text/percentage_test.go b/src/text/percentage_test.go index e9d821b00..843d8eea0 100644 --- a/src/text/percentage_test.go +++ b/src/text/percentage_test.go @@ -6,6 +6,7 @@ import ( "github.com/stretchr/testify/assert" ) +//nolint:dupl func TestPercentageGauge(t *testing.T) { cases := []struct { Case string @@ -67,6 +68,68 @@ func TestPercentageGauge(t *testing.T) { } } +//nolint:dupl +func TestPercentageGaugeUsed(t *testing.T) { + cases := []struct { + Case string + ExpectedGauge string + Percent Percentage + }{ + { + Case: "0 percent used", + Percent: Percentage(0), + ExpectedGauge: "▱▱▱▱▱", + }, + { + Case: "20 percent used", + Percent: Percentage(20), + ExpectedGauge: "▰▱▱▱▱", + }, + { + Case: "40 percent used", + Percent: Percentage(40), + ExpectedGauge: "▰▰▱▱▱", + }, + { + Case: "60 percent used", + Percent: Percentage(60), + ExpectedGauge: "▰▰▰▱▱", + }, + { + Case: "80 percent used", + Percent: Percentage(80), + ExpectedGauge: "▰▰▰▰▱", + }, + { + Case: "100 percent used", + Percent: Percentage(100), + ExpectedGauge: "▰▰▰▰▰", + }, + { + Case: "50 percent used", + Percent: Percentage(50), + ExpectedGauge: "▰▰▱▱▱", + }, + { + Case: "Negative percent clamps to 0", + Percent: Percentage(-10), + ExpectedGauge: "▱▱▱▱▱", + }, + { + Case: "Over 100 percent clamps to 100", + Percent: Percentage(120), + ExpectedGauge: "▰▰▰▰▰", + }, + } + + for _, tc := range cases { + t.Run(tc.Case, func(t *testing.T) { + result := tc.Percent.GaugeUsed() + assert.Equal(t, tc.ExpectedGauge, result, tc.Case) + }) + } +} + func TestPercentageString(t *testing.T) { cases := []struct { Case string diff --git a/website/blog/2025-12-28-oh-my-posh-claude-code-integration.md b/website/blog/2025-12-28-oh-my-posh-claude-code-integration.md index 7c8426811..f79c0fde6 100644 --- a/website/blog/2025-12-28-oh-my-posh-claude-code-integration.md +++ b/website/blog/2025-12-28-oh-my-posh-claude-code-integration.md @@ -149,7 +149,7 @@ aligned prompt blocks to play with. "segments": [ { "leading_diamond": "\ue0b6", - "template": " \udb82\udfc9 {{ .Model.DisplayName }} \uf2d0 {{ .TokenUsagePercent.Gauge }} ", + "template": " \udb82\udfc9 {{ .Model.DisplayName }} \uf2d0 {{ .TokenUsagePercent.GaugeUsed }} ", "foreground": "p:white", "background": "accent", "type": "claude", diff --git a/website/docs/segments/cli/claude.mdx b/website/docs/segments/cli/claude.mdx index b07c3e79d..9094ce17f 100644 --- a/website/docs/segments/cli/claude.mdx +++ b/website/docs/segments/cli/claude.mdx @@ -93,10 +93,11 @@ import Config from "@site/src/components/Config.js"; The `TokenUsagePercent` property is a `Percentage` type that provides additional functionality: -| Method | Returns | Description | -| --------- | -------- | ------------------------------------------------------------------ | -| `.Gauge` | `string` | Visual gauge showing remaining capacity using 5 bar blocks (▰▰▰▰▱) | -| `.String` | `string` | Numeric percentage value (e.g., "75" for use in templates) | +| Method | Returns | Description | +| ------------ | -------- | ------------------------------------------------------------------ | +| `.Gauge` | `string` | Visual gauge showing remaining capacity using 5 bar blocks (▰▰▰▰▱) | +| `.GaugeUsed` | `string` | Visual gauge showing used capacity using 5 bar blocks (▰▱▱▱▱) | +| `.String` | `string` | Numeric percentage value (e.g., "75" for use in templates) | ## How it works diff --git a/website/docs/segments/cli/copilot.mdx b/website/docs/segments/cli/copilot.mdx index 2a2f5b7df..ae6cb45d9 100644 --- a/website/docs/segments/cli/copilot.mdx +++ b/website/docs/segments/cli/copilot.mdx @@ -53,7 +53,7 @@ import Config from "@site/src/components/Config.js"; | Name | Type | Default | Description | | -------------- | ----- | ------- | ----------------------------------------------------- | -| `http_timeout` | `int` | `20` | The default timeout for HTTP requests in milliseconds | +| `http_timeout` | `int` | `20` | The default timeout for HTTP requests in milliseconds | ## Template ([info][templates]) @@ -67,36 +67,37 @@ import Config from "@site/src/components/Config.js"; ### Properties -| Name | Type | Description | -| -------------------- | --------------- | --------------------------------------------- | -| `.Premium` | `CopilotUsage` | Premium interactions usage data | -| `.Premium.Used` | `int` | Number of premium interactions used | -| `.Premium.Limit` | `int` | Total premium interactions available | -| `.Premium.Percent` | `Percentage` | Percentage of premium quota used (0-100) | -| `.Premium.Remaining` | `Percentage` | Percentage of premium quota remaining (0-100) | -| `.Premium.Unlimited` | `bool` | Whether premium quota is unlimited | -| `.Inline` | `CopilotUsage` | Inline completions usage data | -| `.Inline.Used` | `int` | Number of inline completions used | -| `.Inline.Limit` | `int` | Total inline completions available | -| `.Inline.Percent` | `Percentage` | Percentage of inline quota used (0-100) | -| `.Inline.Remaining` | `Percentage` | Percentage of inline quota remaining (0-100) | -| `.Inline.Unlimited` | `bool` | Whether inline quota is unlimited | -| `.Chat` | `CopilotUsage` | Chat usage data | -| `.Chat.Used` | `int` | Number of chat interactions used | -| `.Chat.Limit` | `int` | Total chat interactions available | -| `.Chat.Percent` | `Percentage` | Percentage of chat quota used (0-100) | -| `.Chat.Remaining` | `Percentage` | Percentage of chat quota remaining (0-100) | -| `.Chat.Unlimited` | `bool` | Whether chat quota is unlimited | -| `.BillingCycleEnd` | `string` | End date of current billing cycle | +| Name | Type | Description | +| -------------------- | -------------- | --------------------------------------------- | +| `.Premium` | `CopilotUsage` | Premium interactions usage data | +| `.Premium.Used` | `int` | Number of premium interactions used | +| `.Premium.Limit` | `int` | Total premium interactions available | +| `.Premium.Percent` | `Percentage` | Percentage of premium quota used (0-100) | +| `.Premium.Remaining` | `Percentage` | Percentage of premium quota remaining (0-100) | +| `.Premium.Unlimited` | `bool` | Whether premium quota is unlimited | +| `.Inline` | `CopilotUsage` | Inline completions usage data | +| `.Inline.Used` | `int` | Number of inline completions used | +| `.Inline.Limit` | `int` | Total inline completions available | +| `.Inline.Percent` | `Percentage` | Percentage of inline quota used (0-100) | +| `.Inline.Remaining` | `Percentage` | Percentage of inline quota remaining (0-100) | +| `.Inline.Unlimited` | `bool` | Whether inline quota is unlimited | +| `.Chat` | `CopilotUsage` | Chat usage data | +| `.Chat.Used` | `int` | Number of chat interactions used | +| `.Chat.Limit` | `int` | Total chat interactions available | +| `.Chat.Percent` | `Percentage` | Percentage of chat quota used (0-100) | +| `.Chat.Remaining` | `Percentage` | Percentage of chat quota remaining (0-100) | +| `.Chat.Unlimited` | `bool` | Whether chat quota is unlimited | +| `.BillingCycleEnd` | `string` | End date of current billing cycle | ### Percentage Methods The `Percentage` type provides additional functionality beyond just the numeric value: -| Method | Returns | Description | -| ----------- | -------- | ------------------------------------------------------------------ | -| `.Gauge()` | `string` | Visual gauge showing remaining capacity using 5 bar blocks (▰▰▰▰▱) | -| `.String()` | `string` | Numeric percentage value (e.g., "75" for use in templates) | +| Method | Returns | Description | +| -------------- | -------- | ------------------------------------------------------------------ | +| `.Gauge()` | `string` | Visual gauge showing remaining capacity using 5 bar blocks (▰▰▰▰▱) | +| `.GaugeUsed()` | `string` | Visual gauge showing used capacity using 5 bar blocks (▰▱▱▱▱) | +| `.String()` | `string` | Numeric percentage value (e.g., "75" for use in templates) | **Example gauge visualization (shows remaining capacity):** @@ -107,12 +108,27 @@ The `Percentage` type provides additional functionality beyond just the numeric - 80% used (20% remaining): `▰▱▱▱▱` - 100% used (0% remaining): `▱▱▱▱▱` +**Example gaugeUsed visualization (shows used capacity):** + +- 0% used: `▱▱▱▱▱` +- 20% used: `▰▱▱▱▱` +- 40% used: `▰▰▱▱▱` +- 60% used: `▰▰▰▱▱` +- 80% used: `▰▰▰▰▱` +- 100% used: `▰▰▰▰▰` + **Example template with gauge:** ```json "template": "{{ .Premium.Percent.Gauge() }} {{ .Premium.Used }}/{{ .Premium.Limit }}" ``` +**Example template showing used capacity:** + +```json +"template": "{{ .Premium.Percent.GaugeUsed() }} {{ .Premium.Used }}/{{ .Premium.Limit }}" +``` + [copilot]: https://github.com/features/copilot [templates]: /docs/configuration/templates [tauri]: https://github.com/estruyf/github-copilot-usage-tauri