Skip to content

Commit 4543e7d

Browse files
author
Dmytro Pavlov
committed
improve(ui):improvements to formatting, colors, spacings, shortcut hints, readability
1 parent 1c21618 commit 4543e7d

File tree

7 files changed

+41
-43
lines changed

7 files changed

+41
-43
lines changed

internal/adapters/ui/header.go

Lines changed: 1 addition & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -16,7 +16,6 @@ package ui
1616

1717
import (
1818
"strings"
19-
"time"
2019

2120
"github.com/gdamore/tcell/v2"
2221
"github.com/rivo/tview"
@@ -98,8 +97,7 @@ func (h *AppHeader) buildRightSection(bg tcell.Color) *tview.TextView {
9897
SetDynamicColors(true).
9998
SetTextAlign(tview.AlignRight)
10099
right.SetBackgroundColor(bg)
101-
currentTime := time.Now().Format("Mon, 02 Jan 2006 15:04")
102-
right.SetText("[#55AAFF::u]🔗 " + h.repoURL + "[-] [#AAAAAA]• " + currentTime + "[-]")
100+
right.SetText("[#55AAFF::u]" + h.repoURL + "[-]")
103101
return right
104102
}
105103

internal/adapters/ui/hint_bar.go

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -22,6 +22,6 @@ import (
2222
func NewHintBar() *tview.TextView {
2323
hint := tview.NewTextView().SetDynamicColors(true)
2424
hint.SetBackgroundColor(tcell.Color233)
25-
hint.SetText("[#BBBBBB]Press [::b]/[-:-:b] to search… • ↑↓ Navigate Enter SSH • c Copy SSH • g Ping • r Refresh • a Add • e Edit • t Tags • d Delete • p Pin/Unpin • s Sort[-]")
25+
hint.SetText(" [red]/[-] Search [red]↑↓[-] Navigate [red]Enter[-] SSH [red]c[-] Copy [red]g[-] Ping [red]r[-] Refresh [red]a[-] Add [red]e[-] Edit [red]t[-] Tags [red]d[-] Delete [red]p[-] Pin/Unpin [red]s[-] Sort")
2626
return hint
2727
}

internal/adapters/ui/search_bar.go

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -34,7 +34,7 @@ func NewSearchBar() *SearchBar {
3434
}
3535

3636
func (s *SearchBar) build() {
37-
s.InputField.SetLabel(" 🔍 Search: ").
37+
s.InputField.SetLabel(" Search: ").
3838
SetFieldBackgroundColor(tcell.Color233).
3939
SetFieldTextColor(tcell.Color252).
4040
SetFieldWidth(30).

internal/adapters/ui/server_details.go

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -60,7 +60,7 @@ func renderTagChips(tags []string) string {
6060
func (sd *ServerDetails) UpdateServer(server domain.Server) {
6161
lastSeen := server.LastSeen.Format("2006-01-02 15:04:05")
6262
if server.LastSeen.IsZero() {
63-
lastSeen = "Never"
63+
lastSeen = "never"
6464
}
6565
serverKey := strings.Join(server.IdentityFiles, ", ")
6666

@@ -83,7 +83,7 @@ func (sd *ServerDetails) UpdateServer(server domain.Server) {
8383
}
8484

8585
text := fmt.Sprintf(
86-
"[::b]%s[-]\n\n[::b]Basic Settings:[-]\n Host: [white]%s[-]\n User: [white]%s[-]\n Port: [white]%s[-]\n Key: [white]%s[-]\n Tags: %s\n Pinned: [white]%s[-]\n Last SSH: %s\n SSH Count: [white]%d[-]\n",
86+
"[yellow::b]%s[-::-]\n\n[::b]Basic Settings[-::-]\n\n Host: [white]%s[-]\n User: [white]%s[-]\n Port: [white]%s[-]\n Key: [white]%s[-]\n Tags: %s\n Pinned: [white]%s[-]\n Last SSH: %s\n SSH Count: [white]%d[-]\n",
8787
aliasText, hostText, userText, portText,
8888
serverKey, tagsText, pinnedStr,
8989
lastSeen, server.SSHCount)
@@ -197,7 +197,7 @@ func (sd *ServerDetails) UpdateServer(server domain.Server) {
197197

198198
// Build advanced settings text without group labels for cleaner display
199199
hasAdvanced := false
200-
advancedText := "\n[::b]Advanced Settings:[-]\n"
200+
advancedText := "\n[::b]Advanced Settings[-::-]\n\n"
201201

202202
for _, group := range groups {
203203
for _, field := range group.fields {
@@ -213,7 +213,7 @@ func (sd *ServerDetails) UpdateServer(server domain.Server) {
213213
}
214214

215215
// Commands list
216-
text += "\n[::b]Commands:[-]\n Enter: SSH connect\n c: Copy SSH command\n g: Ping server\n r: Refresh list\n a: Add new server\n e: Edit entry\n t: Edit tags\n d: Delete entry\n p: Pin/Unpin"
216+
text += "\n[::b]Commands[-::-]\n\n Enter: SSH connect\n c: Copy SSH command\n g: Ping server\n r: Refresh list\n a: Add new server\n e: Edit entry\n t: Edit tags\n d: Delete entry\n p: Pin/Unpin"
217217

218218
sd.TextView.SetText(text)
219219
}

internal/adapters/ui/server_form.go

Lines changed: 22 additions & 22 deletions
Original file line numberDiff line numberDiff line change
@@ -171,8 +171,8 @@ func (sf *ServerForm) build() {
171171
// Create hint bar with same background as main screen's status bar
172172
hintBar := tview.NewTextView().SetDynamicColors(true)
173173
hintBar.SetBackgroundColor(tcell.Color235)
174-
hintBar.SetTextAlign(tview.AlignCenter)
175-
hintBar.SetText("[white]^H/^L[-] Navigate • [white]^S[-] Save • [white]Esc[-] Cancel")
174+
hintBar.SetTextAlign(tview.AlignLeft)
175+
hintBar.SetText(" [red]^H/^L[-] Navigate [red]^S[-] Save [red]Esc[-] Cancel")
176176

177177
// Setup main container - header at top, hint bar at bottom
178178
sf.Flex.AddItem(sf.header, 2, 0, false).
@@ -451,7 +451,7 @@ func (sf *ServerForm) updateHelp(fieldName string) {
451451
if len(help.Examples) > 0 {
452452
example = help.Examples[0]
453453
}
454-
content = fmt.Sprintf("[yellow]%s:[-] %s", help.Field, escapeForTview(help.Description))
454+
content = fmt.Sprintf("[yellow]%s:[-]%s", help.Field, escapeForTview(help.Description))
455455
if example != "" {
456456
content += fmt.Sprintf(" [dim](e.g., %s)[-]", escapeForTview(example))
457457
}
@@ -484,7 +484,7 @@ func (sf *ServerForm) formatDetailedHelp(help *FieldHelp) string {
484484
}
485485

486486
// Title with field name and separator below
487-
b.WriteString(fmt.Sprintf("[yellow::b]📖 %s[-::-]\n", help.Field))
487+
b.WriteString(fmt.Sprintf("[yellow::b]%s[-::-]\n", help.Field))
488488
b.WriteString("[#444444]" + strings.Repeat("─", separatorWidth) + "[-]\n\n")
489489

490490
// Description - needs escaping as it might contain brackets
@@ -1270,7 +1270,7 @@ func (sf *ServerForm) createConnectionForm() {
12701270
form := tview.NewForm()
12711271
defaultValues := sf.getDefaultValues()
12721272

1273-
form.AddTextView("\n[yellow]Proxy & Command[-]", "", 0, 1, true, false)
1273+
form.AddTextView("\n[yellow]Proxy & Command[-]", "", 0, 1, true, false)
12741274
sf.addInputFieldWithHelp(form, "ProxyJump:", "ProxyJump", defaultValues.ProxyJump, 40, GetFieldPlaceholder("ProxyJump"))
12751275
sf.addInputFieldWithHelp(form, "ProxyCommand:", "ProxyCommand", defaultValues.ProxyCommand, 40, GetFieldPlaceholder("ProxyCommand"))
12761276
sf.addInputFieldWithHelp(form, "RemoteCommand:", "RemoteCommand", defaultValues.RemoteCommand, 40, GetFieldPlaceholder("RemoteCommand"))
@@ -1285,7 +1285,7 @@ func (sf *ServerForm) createConnectionForm() {
12851285
sessionTypeIndex := sf.findOptionIndex(sessionTypeOptions, defaultValues.SessionType)
12861286
sf.addDropDownWithHelp(form, "SessionType:", "SessionType", sessionTypeOptions, sessionTypeIndex)
12871287

1288-
form.AddTextView("\n[yellow]Connection Settings[-]", "", 0, 1, true, false)
1288+
form.AddTextView("\n[yellow]Connection Settings[-]", "", 0, 1, true, false)
12891289
sf.addValidatedInputField(form, "ConnectTimeout:", "ConnectTimeout", defaultValues.ConnectTimeout, 10, GetFieldPlaceholder("ConnectTimeout"))
12901290
sf.addValidatedInputField(form, "ConnectionAttempts:", "ConnectionAttempts", defaultValues.ConnectionAttempts, 10, GetFieldPlaceholder("ConnectionAttempts"))
12911291
sf.addValidatedInputField(form, "IPQoS:", "IPQoS", defaultValues.IPQoS, 20, GetFieldPlaceholder("IPQoS"))
@@ -1295,7 +1295,7 @@ func (sf *ServerForm) createConnectionForm() {
12951295
batchModeIndex := sf.findOptionIndex(batchModeOptions, defaultValues.BatchMode)
12961296
sf.addDropDownWithHelp(form, "BatchMode:", "BatchMode", batchModeOptions, batchModeIndex)
12971297

1298-
form.AddTextView("\n[yellow]Bind Options[-]", "", 0, 1, true, false)
1298+
form.AddTextView("\n[yellow]Bind Options[-]", "", 0, 1, true, false)
12991299
sf.addValidatedInputField(form, "BindAddress:", "BindAddress", defaultValues.BindAddress, 40, GetFieldPlaceholder("BindAddress"))
13001300

13011301
// BindInterface dropdown with available network interfaces
@@ -1308,7 +1308,7 @@ func (sf *ServerForm) createConnectionForm() {
13081308
addressFamilyIndex := sf.findOptionIndex(addressFamilyOptions, defaultValues.AddressFamily)
13091309
sf.addDropDownWithHelp(form, "AddressFamily:", "AddressFamily", addressFamilyOptions, addressFamilyIndex)
13101310

1311-
form.AddTextView("\n[yellow]Hostname Canonicalization[-]", "", 0, 1, true, false)
1311+
form.AddTextView("\n[yellow]Hostname Canonicalization[-]", "", 0, 1, true, false)
13121312

13131313
// CanonicalizeHostname dropdown
13141314
canonicalizeOptions := createOptionsWithDefault("CanonicalizeHostname", []string{"", "yes", "no", "always"})
@@ -1326,7 +1326,7 @@ func (sf *ServerForm) createConnectionForm() {
13261326

13271327
sf.addInputFieldWithHelp(form, "CanonicalizePermittedCNAMEs:", "CanonicalizePermittedCNAMEs", defaultValues.CanonicalizePermittedCNAMEs, 40, GetFieldPlaceholder("CanonicalizePermittedCNAMEs"))
13281328

1329-
form.AddTextView("\n[yellow]Keep-Alive[-]", "", 0, 1, true, false)
1329+
form.AddTextView("\n[yellow]Keep-Alive[-]", "", 0, 1, true, false)
13301330
sf.addValidatedInputField(form, "ServerAliveInterval:", "ServerAliveInterval", defaultValues.ServerAliveInterval, 10, GetFieldPlaceholder("ServerAliveInterval"))
13311331
sf.addValidatedInputField(form, "ServerAliveCountMax:", "ServerAliveCountMax", defaultValues.ServerAliveCountMax, 10, GetFieldPlaceholder("ServerAliveCountMax"))
13321332

@@ -1340,7 +1340,7 @@ func (sf *ServerForm) createConnectionForm() {
13401340
tcpKeepAliveIndex := sf.findOptionIndex(tcpKeepAliveOptions, defaultValues.TCPKeepAlive)
13411341
sf.addDropDownWithHelp(form, "TCPKeepAlive:", "TCPKeepAlive", tcpKeepAliveOptions, tcpKeepAliveIndex)
13421342

1343-
form.AddTextView("\n[yellow]Multiplexing[-]", "", 0, 1, true, false)
1343+
form.AddTextView("\n[yellow]Multiplexing[-]", "", 0, 1, true, false)
13441344
// ControlMaster dropdown
13451345
controlMasterOptions := createOptionsWithDefault("ControlMaster", []string{"", "yes", "no", "auto", "ask", "autoask"})
13461346
controlMasterIndex := sf.findOptionIndex(controlMasterOptions, defaultValues.ControlMaster)
@@ -1364,7 +1364,7 @@ func (sf *ServerForm) createForwardingForm() {
13641364
form := tview.NewForm()
13651365
defaultValues := sf.getDefaultValues()
13661366

1367-
form.AddTextView("\n[yellow]Port Forwarding[-]", "", 0, 1, true, false)
1367+
form.AddTextView("\n[yellow]Port Forwarding[-]", "", 0, 1, true, false)
13681368
sf.addValidatedInputField(form, "LocalForward:", "LocalForward", defaultValues.LocalForward, 40, GetFieldPlaceholder("LocalForward"))
13691369
sf.addValidatedInputField(form, "RemoteForward:", "RemoteForward", defaultValues.RemoteForward, 40, GetFieldPlaceholder("RemoteForward"))
13701370
sf.addValidatedInputField(form, "DynamicForward:", "DynamicForward", defaultValues.DynamicForward, 40, GetFieldPlaceholder("DynamicForward"))
@@ -1384,7 +1384,7 @@ func (sf *ServerForm) createForwardingForm() {
13841384
gatewayPortsIndex := sf.findOptionIndex(gatewayPortsOptions, defaultValues.GatewayPorts)
13851385
sf.addDropDownWithHelp(form, "GatewayPorts:", "GatewayPorts", gatewayPortsOptions, gatewayPortsIndex)
13861386

1387-
form.AddTextView("\n[yellow]Agent & X11 Forwarding[-]", "", 0, 1, true, false)
1387+
form.AddTextView("\n[yellow]Agent & X11 Forwarding[-]", "", 0, 1, true, false)
13881388

13891389
// ForwardAgent dropdown
13901390
forwardAgentOptions := createOptionsWithDefault("ForwardAgent", []string{"", "yes", "no"})
@@ -1479,7 +1479,7 @@ func (sf *ServerForm) createAuthenticationForm() {
14791479
defaultValues := sf.getDefaultValues()
14801480

14811481
// Most common: Public key authentication
1482-
form.AddTextView("\n[yellow]Public Key Authentication[-]", "", 0, 1, true, false)
1482+
form.AddTextView("\n[yellow]Public Key Authentication[-]", "", 0, 1, true, false)
14831483

14841484
// PubkeyAuthentication dropdown
14851485
pubkeyOptions := createOptionsWithDefault("PubkeyAuthentication", []string{"", "yes", "no"})
@@ -1492,7 +1492,7 @@ func (sf *ServerForm) createAuthenticationForm() {
14921492
sf.addDropDownWithHelp(form, "IdentitiesOnly:", "IdentitiesOnly", identitiesOnlyOptions, identitiesOnlyIndex)
14931493

14941494
// SSH Agent settings
1495-
form.AddTextView("\n[yellow]SSH Agent[-]", "", 0, 1, true, false)
1495+
form.AddTextView("\n[yellow]SSH Agent[-]", "", 0, 1, true, false)
14961496

14971497
// AddKeysToAgent dropdown
14981498
addKeysOptions := createOptionsWithDefault("AddKeysToAgent", []string{"", "yes", "no", "ask", "confirm"})
@@ -1502,7 +1502,7 @@ func (sf *ServerForm) createAuthenticationForm() {
15021502
sf.addInputFieldWithHelp(form, "IdentityAgent:", "IdentityAgent", defaultValues.IdentityAgent, 40, GetFieldPlaceholder("IdentityAgent"))
15031503

15041504
// Password/Interactive authentication
1505-
form.AddTextView("\n[yellow]Password & Interactive[-]", "", 0, 1, true, false)
1505+
form.AddTextView("\n[yellow]Password & Interactive[-]", "", 0, 1, true, false)
15061506

15071507
// PasswordAuthentication dropdown
15081508
passwordOptions := createOptionsWithDefault("PasswordAuthentication", []string{"", "yes", "no"})
@@ -1518,7 +1518,7 @@ func (sf *ServerForm) createAuthenticationForm() {
15181518
sf.addValidatedInputField(form, "NumberOfPasswordPrompts:", "NumberOfPasswordPrompts", defaultValues.NumberOfPasswordPrompts, 10, GetFieldPlaceholder("NumberOfPasswordPrompts"))
15191519

15201520
// Advanced: Authentication order preference
1521-
form.AddTextView("\n[yellow]Advanced[-]", "", 0, 1, true, false)
1521+
form.AddTextView("\n[yellow]Advanced[-]", "", 0, 1, true, false)
15221522

15231523
sf.addInputFieldWithHelp(form, "PreferredAuthentications:", "PreferredAuthentications", defaultValues.PreferredAuthentications, 40, GetFieldPlaceholder("PreferredAuthentications"))
15241524

@@ -1546,7 +1546,7 @@ func (sf *ServerForm) createAdvancedForm() {
15461546
form := tview.NewForm()
15471547
defaultValues := sf.getDefaultValues()
15481548

1549-
form.AddTextView("\n[yellow]Security[-]", "", 0, 1, true, false)
1549+
form.AddTextView("\n[yellow]Security[-]", "", 0, 1, true, false)
15501550

15511551
// StrictHostKeyChecking dropdown
15521552
strictHostKeyOptions := createOptionsWithDefault("StrictHostKeyChecking", []string{"", "yes", "no", "ask", "accept-new"})
@@ -1587,7 +1587,7 @@ func (sf *ServerForm) createAdvancedForm() {
15871587
knownHostsField := sf.addValidatedInputField(form, "UserKnownHostsFile:", "UserKnownHostsFile", defaultValues.UserKnownHostsFile, 40, GetFieldPlaceholder("UserKnownHostsFile"))
15881588
knownHostsField.SetAutocompleteFunc(sf.createKnownHostsAutocomplete())
15891589

1590-
form.AddTextView("\n[yellow]Cryptography[-]", "", 0, 1, true, false)
1590+
form.AddTextView("\n[yellow]Cryptography[-]", "", 0, 1, true, false)
15911591

15921592
// Ciphers with autocomplete support
15931593
ciphersField := sf.addInputFieldWithHelp(form, "Ciphers:", "Ciphers", defaultValues.Ciphers, 40, GetFieldPlaceholder("Ciphers"))
@@ -1605,7 +1605,7 @@ func (sf *ServerForm) createAdvancedForm() {
16051605
hostKeyField := sf.addInputFieldWithHelp(form, "HostKeyAlgorithms:", "HostKeyAlgorithms", defaultValues.HostKeyAlgorithms, 40, GetFieldPlaceholder("HostKeyAlgorithms"))
16061606
hostKeyField.SetAutocompleteFunc(sf.createAlgorithmAutocomplete(hostKeyAlgorithms))
16071607

1608-
form.AddTextView("\n[yellow]Command Execution[-]", "", 0, 1, true, false)
1608+
form.AddTextView("\n[yellow]Command Execution[-]", "", 0, 1, true, false)
16091609
sf.addInputFieldWithHelp(form, "LocalCommand:", "LocalCommand", defaultValues.LocalCommand, 40, GetFieldPlaceholder("LocalCommand"))
16101610

16111611
// PermitLocalCommand dropdown
@@ -1616,11 +1616,11 @@ func (sf *ServerForm) createAdvancedForm() {
16161616
// EscapeChar input field
16171617
sf.addValidatedInputField(form, "EscapeChar:", "EscapeChar", defaultValues.EscapeChar, 10, GetFieldPlaceholder("EscapeChar"))
16181618

1619-
form.AddTextView("\n[yellow]Environment[-]", "", 0, 1, true, false)
1619+
form.AddTextView("\n[yellow]Environment[-]", "", 0, 1, true, false)
16201620
sf.addInputFieldWithHelp(form, "SendEnv:", "SendEnv", defaultValues.SendEnv, 40, GetFieldPlaceholder("SendEnv"))
16211621
sf.addInputFieldWithHelp(form, "SetEnv:", "SetEnv", defaultValues.SetEnv, 40, GetFieldPlaceholder("SetEnv"))
16221622

1623-
form.AddTextView("\n[yellow]Debugging[-]", "", 0, 1, true, false)
1623+
form.AddTextView("\n[yellow]Debugging[-]", "", 0, 1, true, false)
16241624

16251625
// LogLevel dropdown
16261626
logLevelOptions := createOptionsWithDefault("LogLevel", []string{"", "QUIET", "FATAL", "ERROR", "INFO", "VERBOSE", "DEBUG", "DEBUG1", "DEBUG2", "DEBUG3"})
@@ -1948,7 +1948,7 @@ func (sf *ServerForm) handleCancel() {
19481948
if sf.app != nil {
19491949
modal := tview.NewModal().
19501950
SetText("You have unsaved changes. Are you sure you want to exit?").
1951-
AddButtons([]string{"[yellow]S[-]ave", "[yellow]D[-]iscard", "[yellow]C[-]ancel"}).
1951+
AddButtons([]string{"[red]S[-]ave", "[red]D[-]iscard", "[red]C[-]ancel"}).
19521952
SetDoneFunc(func(buttonIndex int, buttonLabel string) {
19531953
switch buttonIndex {
19541954
case 0: // Save

internal/adapters/ui/status_bar.go

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -20,13 +20,13 @@ import (
2020
)
2121

2222
func DefaultStatusText() string {
23-
return "[white]↑↓[-] Navigate • [white]Enter[-] SSH • [white]c[-] Copy SSH • [white]a[-] Add • [white]e[-] Edit • [white]g[-] Ping • [white]d[-] Delete • [white]p[-] Pin/Unpin • [white]/[-] Search • [white]q[-] Quit"
23+
return " [red]↑↓[-] Navigate [red]Enter[-] SSH [red]c[-] Copy [red]a[-] Add [red]e[-] Edit [red]g[-] Ping [red]d[-] Delete [red]p[-] Pin/Unpin [red]/[-] Search [red]q[-] Quit"
2424
}
2525

2626
func NewStatusBar() *tview.TextView {
2727
status := tview.NewTextView().SetDynamicColors(true)
2828
status.SetBackgroundColor(tcell.Color235)
29-
status.SetTextAlign(tview.AlignCenter)
29+
status.SetTextAlign(tview.AlignLeft)
3030
status.SetText(DefaultStatusText())
3131
return status
3232
}

internal/adapters/ui/utils.go

Lines changed: 10 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -73,51 +73,51 @@ func cellPad(s string, width int) string {
7373
func pinnedIcon(pinnedAt time.Time) string {
7474
// Use emojis for a nicer UI; combined with cellPad to keep widths consistent in tview.
7575
if pinnedAt.IsZero() {
76-
return "📡" // not pinned
76+
return "" // not pinned
7777
}
78-
return "📌" // pinned
78+
return "" // pinned
7979
}
8080

8181
func formatServerLine(s domain.Server) (primary, secondary string) {
8282
icon := cellPad(pinnedIcon(s.PinnedAt), 2)
8383
// Use a consistent color for alias; the icon reflects pinning
84-
primary = fmt.Sprintf("%s [white::b]%-12s[-] [#AAAAAA]%-18s[-] [#888888]Last SSH: %s[-] %s", icon, s.Alias, s.Host, humanizeDuration(s.LastSeen), renderTagBadgesForList(s.Tags))
84+
primary = fmt.Sprintf("[red] %s[-][white]%s[-] [green]%s[-] [yellow]%s[-] %s", icon, s.Alias, s.Host, humanizeDuration(s.LastSeen), renderTagBadgesForList(s.Tags))
8585
secondary = ""
8686
return
8787
}
8888

8989
func humanizeDuration(t time.Time) string {
9090
if t.IsZero() {
91-
return "never"
91+
return ""
9292
}
9393
d := time.Since(t)
9494
if d < time.Minute {
95-
return "just now"
95+
return "(just now)"
9696
}
9797
if d < time.Hour {
9898
m := int(d.Minutes())
99-
return fmt.Sprintf("%dm ago", m)
99+
return fmt.Sprintf("(%dm ago)", m)
100100
}
101101
if d < 48*time.Hour {
102102
h := int(d.Hours())
103-
return fmt.Sprintf("%dh ago", h)
103+
return fmt.Sprintf("(%dh ago)", h)
104104
}
105105
if d < 60*24*time.Hour {
106106
days := int(d.Hours()) / 24
107-
return fmt.Sprintf("%dd ago", days)
107+
return fmt.Sprintf("(%dd ago)", days)
108108
}
109109
if d < 365*24*time.Hour {
110110
months := int(d.Hours()) / (24 * 30)
111111
if months < 1 {
112112
months = 1
113113
}
114-
return fmt.Sprintf("%dmo ago", months)
114+
return fmt.Sprintf("(%dmo ago)", months)
115115
}
116116
years := int(d.Hours()) / (24 * 365)
117117
if years < 1 {
118118
years = 1
119119
}
120-
return fmt.Sprintf("%dy ago", years)
120+
return fmt.Sprintf("(%dy ago)", years)
121121
}
122122

123123
// BuildSSHCommand constructs a ready-to-run ssh command for the given server.

0 commit comments

Comments
 (0)