|
| 1 | +package action |
| 2 | + |
| 3 | +import ( |
| 4 | + "runtime" |
| 5 | + |
| 6 | + "github.com/carapace-sh/carapace" |
| 7 | +) |
| 8 | + |
| 9 | +func ActionDateFormatSpecifiers() carapace.Action { |
| 10 | + return carapace.ActionCallback(func(c carapace.Context) carapace.Action { |
| 11 | + // see https://github.com/zsh-users/zsh/blob/master/Completion/Unix/Type/_date_formats |
| 12 | + exclusion := map[rune]string{ |
| 13 | + 'E': "cCgGxXyY", |
| 14 | + 'O': "BdeHImMSuUVwWy", |
| 15 | + '-': "OEdegHIjklmMSUz", |
| 16 | + '_': "OEdgHIjmMSUz", |
| 17 | + '0': "Oekl", |
| 18 | + '^': "OEaAbBchP", |
| 19 | + '#': "OEaAbBchpPrXZ", |
| 20 | + } |
| 21 | + |
| 22 | + specs := map[rune]string{ |
| 23 | + 'a': "abbreviated day name", |
| 24 | + 'A': "full day name", |
| 25 | + 'b': "abbreviated month name", |
| 26 | + 'h': "abbreviated month name", |
| 27 | + 'B': "full month name", |
| 28 | + 'c': "preferred locale date and time", |
| 29 | + 'C': "2-digit century", |
| 30 | + 'd': "day of month (01-31)", |
| 31 | + 'D': "American format month/day/year (%m/%d/%y)", |
| 32 | + 'e': "day of month ( 1-31)", |
| 33 | + 'F': "ISO 8601 year-month-date (%Y-%m-%d)", |
| 34 | + 'G': "4-digit ISO 8601 week-based year", |
| 35 | + 'g': "2-digit ISO 8601 week-based year", |
| 36 | + 'H': "hour (00-23)", |
| 37 | + 'I': "hour (01-12)", |
| 38 | + 'j': "day of year (001-366)", |
| 39 | + 'k': "hour ( 0-23)", |
| 40 | + 'l': "hour ( 1-12)", |
| 41 | + 'm': "month (01-12)", |
| 42 | + 'M': "minute (00-59)", |
| 43 | + 'n': "newline", |
| 44 | + 'p': "locale dependent AM/PM", |
| 45 | + 'r': "locale dependent a.m. or p.m. time (%I:%M:%S %p)", |
| 46 | + 'R': "24-hour notation time (%H:%M)", |
| 47 | + 's': "seconds since the epoch", |
| 48 | + 'S': "seconds (00-60)", |
| 49 | + 't': "tab", |
| 50 | + 'T': "24-hour notation with seconds (%H:%M:%S)", |
| 51 | + 'u': "day of week (1-7, 1=Monday)", |
| 52 | + 'U': "week number of current year, Sunday based (00-53)", |
| 53 | + 'V': "ISO 8601 week number of current year, week 1 has 4 days in current year (01-53)", |
| 54 | + 'w': "day of week (0-6, 0=Sunday)", |
| 55 | + 'W': "week number of current year, Monday based (00-53)", |
| 56 | + 'x': "locale dependent date representation without time", |
| 57 | + 'X': "locale dependent time representation without date", |
| 58 | + 'y': "2-digit year (00-99)", |
| 59 | + 'Y': "full year", |
| 60 | + 'z': "UTC offset", |
| 61 | + 'Z': "timezone name", |
| 62 | + '%': "literal %", |
| 63 | + } |
| 64 | + |
| 65 | + switch runtime.GOOS { |
| 66 | + case "linux": |
| 67 | + specs['N'] = "fractional part of seconds since epoch, in nanoseconds" |
| 68 | + fallthrough |
| 69 | + case "freebsd", "dragonfly", "darwin": |
| 70 | + specs['E'] = "alternate representation" |
| 71 | + specs['O'] = "alternative format modifier" |
| 72 | + specs['-'] = "don't pad numeric values" |
| 73 | + specs['0'] = "left pad numeric values with zeroes" |
| 74 | + specs['_'] = "left pad numeric values with spaces" |
| 75 | + } |
| 76 | + |
| 77 | + switch runtime.GOOS { |
| 78 | + case "linux", "darwin": |
| 79 | + specs['#'] = "swap case of alphabetic characters" |
| 80 | + specs['^'] = "convert lowercase characters to uppercase" |
| 81 | + specs['P'] = "lower case locale dependent am/pm" |
| 82 | + } |
| 83 | + |
| 84 | + switch runtime.GOOS { |
| 85 | + case "freebsd", "dragonfly", "darwin": |
| 86 | + specs['v'] = "date in short form (%e-%b-%Y)" |
| 87 | + } |
| 88 | + |
| 89 | + if c.Getenv("SHELL") == "zsh" { // TODO this is unlikely set |
| 90 | + specs['f'] = "day of month (1-31)" |
| 91 | + specs['K'] = "hour (0-23)" |
| 92 | + specs['L'] = "hour (0-12)" |
| 93 | + specs['N'] = "fractional part of seconds since epoch, in nanoseconds (%9.)" |
| 94 | + specs['.'] = "fractional part of seconds since epoch" |
| 95 | + specs['-'] = "don't pad numeric values" |
| 96 | + } |
| 97 | + |
| 98 | + length := len(c.Value) |
| 99 | + for i := 0; i < length; i++ { |
| 100 | + switch c.Value[i] { |
| 101 | + case '%': |
| 102 | + if i == length-1 { |
| 103 | + vals := make([]string, 0) |
| 104 | + for k, v := range specs { |
| 105 | + vals = append(vals, string(k), v) |
| 106 | + } |
| 107 | + return carapace.ActionValuesDescribed(vals...).Prefix(c.Value) |
| 108 | + } |
| 109 | + |
| 110 | + if exclusions, ok := exclusion[rune(c.Value[i+1])]; ok { |
| 111 | + for _, x := range exclusions { |
| 112 | + delete(specs, x) |
| 113 | + } |
| 114 | + } |
| 115 | + i += 1 |
| 116 | + } |
| 117 | + } |
| 118 | + |
| 119 | + // TODO repetitive |
| 120 | + vals := make([]string, 0) |
| 121 | + for k, v := range specs { |
| 122 | + vals = append(vals, string(k), v) |
| 123 | + } |
| 124 | + return carapace.ActionValuesDescribed(vals...).Prefix(c.Value + "%") |
| 125 | + }).NoSpace().Tag("date format specifiers") |
| 126 | +} |
0 commit comments