Skip to content
New issue

Have a question about this project? # for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “#”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? # to your account

feat: (WIP) add locale support for time formatting and implement GetLocale function #226

Draft
wants to merge 1 commit into
base: master
Choose a base branch
from
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions internal/cli/g.go
Original file line number Diff line number Diff line change
Expand Up @@ -42,6 +42,7 @@
r = render.NewRenderer(&theme.DefaultAll)
p = display.NewFitTerminal()
timeFormat = "Jan 02 15:04"
locale = "en_US"

Check failure on line 45 in internal/cli/g.go

View workflow job for this annotation

GitHub Actions / lint

var `locale` is unused (unused)
// ReturnCode - Exit status:
// 0 if OK,
// 1 if minor problems (e.g., cannot access subdirectory),
Expand Down
19 changes: 15 additions & 4 deletions internal/cli/view.go
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@ import (
contents "github.com/Equationzhao/g/internal/content"
"github.com/Equationzhao/g/internal/display"
"github.com/Equationzhao/g/internal/filter"
"github.com/Equationzhao/g/internal/util"
"github.com/gabriel-vasile/mimetype"
"github.com/urfave/cli/v2"
)
Expand Down Expand Up @@ -166,14 +167,14 @@ var viewFlag = []cli.Flag{
&cli.StringFlag{
Name: "time-style",
Usage: `time/date format with -l,
valid timestamp styles are default, iso, long-iso, full-iso, locale,
valid timestamp styles are default, iso, long-iso, full-iso,
custom +FORMAT like date(1).
(default: +%b %d %H:%M ,like Jan 02 15:04)`,
EnvVars: []string{"TIME_STYLE"},
Action: func(context *cli.Context, s string) error {
_ = context.Set("time", "1")
/*
The TIME_STYLE argument can be full-iso, long-iso, iso, locale, or +FORMAT.
The TIME_STYLE argument can be full-iso, long-iso, iso, or +FORMAT.
FORMAT is interpreted like in date(1).
Also, the TIME_STYLE environment variable sets the default style to use.
*/
Expand All @@ -187,8 +188,6 @@ var viewFlag = []cli.Flag{
timeFormat = "2006-01-02 15:04:05.000000000 -0700"
case "long-iso":
timeFormat = "2006-01-02 15:04"
case "locale":
timeFormat = "Jan 02 15:04"
case "iso":
timeFormat = "01-02 15:04"
case "default":
Expand All @@ -201,6 +200,18 @@ var viewFlag = []cli.Flag{
},
Category: "VIEW",
},
&cli.BoolFlag{
Name: "locale",
Usage: "show time in locale format",
DisableDefaultText: true,
Action: func(context *cli.Context, b bool) error {
if b {
locale = util.GetLocale()
}
return nil
},
Category: "VIEW",
},
&cli.BoolFlag{
Name: "full-time",
Usage: "like -all/l --time-style=full-iso",
Expand Down
27 changes: 27 additions & 0 deletions internal/util/util.go
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@ package util

import (
"fmt"
"os"
"path/filepath"
"strconv"
"strings"
Expand Down Expand Up @@ -65,3 +66,29 @@ func SplitNumberAndUnit(input string) (float64, string) {

return number, unit
}

// GetLocale returns the language code from the system locale
// It checks LC_ALL, LC_MESSAGES, and LANG environment variables in that order
// If none are set, it returns "en_US" as default
func GetLocale() string {
locale := ""

// Check environment variables in order of priority
for _, envVar := range []string{"LC_ALL", "LC_MESSAGES", "LANG"} {
if val := os.Getenv(envVar); val != "" {
locale = val
break
}
}

if locale == "" {
return "en_US" // default locale
}

// Extract just the language code part (e.g., "en_US" from "en_US.UTF-8")
if i := strings.IndexRune(locale, '.'); i > 0 {
locale = locale[:i]
}

return locale
}
84 changes: 83 additions & 1 deletion internal/util/util_test.go
Original file line number Diff line number Diff line change
@@ -1,6 +1,9 @@
package util

import "testing"
import (
"os"
"testing"
)

func TestSplitNumberAndUnit(t *testing.T) {
type args struct {
Expand Down Expand Up @@ -151,3 +154,82 @@ func TestEscape(t *testing.T) {
})
}
}

func TestGetLocale(t *testing.T) {
tests := []struct {
name string
envVars map[string]string
want string
saveEnvs map[string]string
}{
{
name: "No env vars set",
envVars: map[string]string{
"LC_ALL": "",
"LC_MESSAGES": "",
"LANG": "",
},
want: "en_US",
},
{
name: "Only LANG set",
envVars: map[string]string{
"LC_ALL": "",
"LC_MESSAGES": "",
"LANG": "fr_FR.UTF-8",
},
want: "fr_FR",
},
{
name: "LC_MESSAGES takes precedence over LANG",
envVars: map[string]string{
"LC_ALL": "",
"LC_MESSAGES": "de_DE.UTF-8",
"LANG": "fr_FR.UTF-8",
},
want: "de_DE",
},
{
name: "LC_ALL takes precedence over all",
envVars: map[string]string{
"LC_ALL": "ja_JP.UTF-8",
"LC_MESSAGES": "de_DE.UTF-8",
"LANG": "fr_FR.UTF-8",
},
want: "ja_JP",
},
{
name: "No UTF-8 suffix",
envVars: map[string]string{
"LC_ALL": "ko_KR",
},
want: "ko_KR",
},
}

// Save original env vars to restore later
saveEnvs := make(map[string]string)
for _, envVar := range []string{"LC_ALL", "LC_MESSAGES", "LANG"} {
saveEnvs[envVar] = os.Getenv(envVar)
}

// Restore env vars after test completes
defer func() {
for k, v := range saveEnvs {
os.Setenv(k, v)
}
}()

for _, tt := range tests {
t.Run(tt.name, func(t *testing.T) {
// Set environment variables for this test
for k, v := range tt.envVars {
os.Setenv(k, v)
}

if got := GetLocale(); got != tt.want {
t.Errorf("GetLocale() = %v, want %v", got, tt.want)
}
})
}
}
Loading