Skip to content

Commit 18a9835

Browse files
authored
Merge pull request #4246 from edeustua/master
feat: Add ISO 8601 calendar to clock module
2 parents 632af16 + be819be commit 18a9835

File tree

3 files changed

+34
-12
lines changed

3 files changed

+34
-12
lines changed

include/modules/clock.hpp

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -48,8 +48,9 @@ class Clock final : public ALabel {
4848
std::string cldYearCached_; // calendar Year mode. Cached calendar
4949
date::year_month cldMonShift_; // calendar Month mode. Cached ym
5050
std::string cldMonCached_; // calendar Month mode. Cached calendar
51-
date::day cldBaseDay_{0}; // calendar Cached day. Is used when today is changing(midnight)
52-
std::string cldText_{""}; // calendar text to print
51+
date::day cldBaseDay_{0}; // calendar Cached day. Is used when today is changing(midnight)
52+
std::string cldText_{""}; // calendar text to print
53+
bool iso8601Calendar_{false}; // whether the calendar is in ISO8601
5354
CldMode cldMode_{CldMode::MONTH};
5455
auto get_calendar(const date::year_month_day& today, const date::year_month_day& ymd,
5556
const date::time_zone* tz) -> const std::string;

man/waybar-clock.5.scd

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -132,6 +132,12 @@ View all valid format options in *strftime(3)* or have a look https://en.cpprefe
132132
:[ 1
133133
:[ Value to scroll months/years forward/backward. Can be negative. Is
134134
configured under *on-scroll* option
135+
|[ *iso8601*
136+
:[ bool
137+
:[ false
138+
:[ When enabled, the calendar follows the ISO 8601 standard: weeks begin on
139+
Monday, and the first week of the year is numbered 1. The default week format is
140+
'{:%V}'.
135141

136142
3. Addressed by *clock: calendar: format*
137143
[- *Option*

src/modules/clock.cpp

Lines changed: 25 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -74,6 +74,11 @@ waybar::modules::Clock::Clock(const std::string& id, const Json::Value& config)
7474
"using instead",
7575
cfgMode);
7676
}
77+
78+
if (config_[kCldPlaceholder]["iso8601"].isBool()) {
79+
iso8601Calendar_ = config_[kCldPlaceholder]["iso8601"].asBool();
80+
}
81+
7782
if (config_[kCldPlaceholder]["weeks-pos"].isString()) {
7883
if (config_[kCldPlaceholder]["weeks-pos"].asString() == "left") cldWPos_ = WS::LEFT;
7984
if (config_[kCldPlaceholder]["weeks-pos"].asString() == "right") cldWPos_ = WS::RIGHT;
@@ -98,16 +103,20 @@ waybar::modules::Clock::Clock(const std::string& id, const Json::Value& config)
98103
} else
99104
fmtMap_.insert({3, "{}"});
100105
if (config_[kCldPlaceholder]["format"]["weeks"].isString() && cldWPos_ != WS::HIDDEN) {
106+
const auto defaultFmt =
107+
iso8601Calendar_ ? "{:%V}" : ((first_day_of_week() == Monday) ? "{:%W}" : "{:%U}");
101108
fmtMap_.insert({4, std::regex_replace(config_[kCldPlaceholder]["format"]["weeks"].asString(),
102-
std::regex("\\{\\}"),
103-
(first_day_of_week() == Monday) ? "{:%W}" : "{:%U}")});
109+
std::regex("\\{\\}"), defaultFmt)});
104110
Glib::ustring tmp{std::regex_replace(fmtMap_[4], std::regex("</?[^>]+>|\\{.*\\}"), "")};
105111
cldWnLen_ += tmp.size();
106112
} else {
107-
if (cldWPos_ != WS::HIDDEN)
108-
fmtMap_.insert({4, (first_day_of_week() == Monday) ? "{:%W}" : "{:%U}"});
109-
else
113+
if (cldWPos_ != WS::HIDDEN) {
114+
const auto defaultFmt =
115+
iso8601Calendar_ ? "{:%V}" : ((first_day_of_week() == Monday) ? "{:%W}" : "{:%U}");
116+
fmtMap_.insert({4, defaultFmt});
117+
} else {
110118
cldWnLen_ = 0;
119+
}
111120
}
112121
if (config_[kCldPlaceholder]["mode-mon-col"].isInt()) {
113122
cldMonCols_ = config_[kCldPlaceholder]["mode-mon-col"].asInt();
@@ -218,9 +227,11 @@ const unsigned cldRowsInMonth(const year_month& ym, const weekday& firstdow) {
218227

219228
auto cldGetWeekForLine(const year_month& ym, const weekday& firstdow, const unsigned line)
220229
-> const year_month_weekday {
221-
unsigned index{line - 2};
222-
if (weekday{ym / 1} == firstdow) ++index;
223-
return ym / firstdow[index];
230+
const unsigned idx = line - 2;
231+
const std::chrono::weekday_indexed indexed_first_day_of_week =
232+
weekday{ym / 1} == firstdow ? firstdow[idx + 1] : firstdow[idx];
233+
234+
return ym / indexed_first_day_of_week;
224235
}
225236

226237
auto getCalendarLine(const year_month_day& currDate, const year_month ym, const unsigned line,
@@ -279,7 +290,7 @@ auto getCalendarLine(const year_month_day& currDate, const year_month ym, const
279290
}
280291
// Print non-first week
281292
default: {
282-
auto ymdTmp{cldGetWeekForLine(ym, firstdow, line)};
293+
const auto ymdTmp{cldGetWeekForLine(ym, firstdow, line)};
283294
if (ymdTmp.ok()) {
284295
auto d{year_month_day{ymdTmp}.day()};
285296
const auto dlast{(ym / last).day()};
@@ -370,8 +381,9 @@ auto waybar::modules::Clock::get_calendar(const year_month_day& today, const yea
370381
: static_cast<const zoned_seconds&&>(zoned_seconds{
371382
tz, local_days{cldGetWeekForLine(ymTmp, firstdow, line)}})))
372383
<< ' ';
373-
} else
384+
} else {
374385
os << pads;
386+
}
375387
}
376388
}
377389

@@ -495,6 +507,9 @@ using deleting_unique_ptr = std::unique_ptr<T, deleter_from_fn<fn>>;
495507

496508
// Computations done similarly to Linux cal utility.
497509
auto waybar::modules::Clock::first_day_of_week() -> weekday {
510+
if (iso8601Calendar_) {
511+
return Monday;
512+
}
498513
#ifdef HAVE_LANGINFO_1STDAY
499514
deleting_unique_ptr<std::remove_pointer<locale_t>::type, freelocale> posix_locale{
500515
newlocale(LC_ALL, m_locale_.name().c_str(), nullptr)};

0 commit comments

Comments
 (0)