From 30f516dd7d2859bc0c0e8554616c614d08deb5ba Mon Sep 17 00:00:00 2001 From: Michael Carlberg Date: Wed, 11 Jan 2017 01:42:55 +0100 Subject: [PATCH] fix(formatting): Make formats parse specs as-is This removes the spacing tinkering when parsing format specs. The following example uses the old behavoir: format-test = format-breaks = / `format-test` would replace all occurences of ' ' with the a space string with defined `spacing` as its width. `format-breaks` would not validate as the tags where split with ' ' as delimiter. All that nonsense has been removed and each tag is extracted as is. The `spacing` parameter can still be used to apply N extra whitespaces between the tags, but it is now 0 by default. --- doc/config.cmake | 13 ++++----- include/components/types.hpp | 2 +- include/modules/meta/base.hpp | 10 ++++--- include/modules/meta/base.inl | 50 +++++++++++++++++++++-------------- src/components/builder.cpp | 6 ++++- src/components/config.cpp | 17 +++++------- src/modules/menu.cpp | 14 ++++++---- src/modules/meta/base.cpp | 45 ++++++++++++++++++------------- src/modules/xkeyboard.cpp | 2 +- 9 files changed, 90 insertions(+), 69 deletions(-) diff --git a/doc/config.cmake b/doc/config.cmake index 4a108f5e..a8176e68 100644 --- a/doc/config.cmake +++ b/doc/config.cmake @@ -39,7 +39,6 @@ underline-color = #00f border-bottom = 2 border-bottom-color = #333 -spacing = 1 padding-left = 0 padding-right = 2 module-margin-left = 1 @@ -77,14 +76,10 @@ label = %title:0:30:...% [module/xkeyboard] type = internal/xkeyboard blacklist-0 = num lock - -format-underline = ${colors.secondary} -format-prefix = " " -format-prefix-foreground = ${colors.foreground-alt} - -label-layout = %layout% - +label-layout = %{F#55}%{F-} %layout% +label-layout-underline = ${colors.secondary} label-indicator-padding = 2 +label-indicator-margin = 1 label-indicator-background = ${colors.secondary} label-indicator-underline = ${colors.secondary} @@ -331,6 +326,8 @@ ramp-foreground = ${colors.foreground-alt} [module/powermenu] type = custom/menu +format-spacing = 1 + label-open =  power label-open-foreground = ${colors.secondary} label-close =  cancel diff --git a/include/components/types.hpp b/include/components/types.hpp index e92adf54..924eaafd 100644 --- a/include/components/types.hpp +++ b/include/components/types.hpp @@ -143,7 +143,7 @@ struct bar_settings { std::unordered_map borders{}; - uint8_t spacing{1U}; + uint8_t spacing{0}; string separator{}; string wmname{}; diff --git a/include/modules/meta/base.hpp b/include/modules/meta/base.hpp index 182e59b7..ca4dae42 100644 --- a/include/modules/meta/base.hpp +++ b/include/modules/meta/base.hpp @@ -68,10 +68,12 @@ namespace modules { string bg{}; string ul{}; string ol{}; - int spacing{}; - int padding{}; - int margin{}; - int offset{}; + size_t ulsize{0}; + size_t olsize{0}; + size_t spacing{0}; + size_t padding{0}; + size_t margin{0}; + int offset{0}; string decorate(builder* builder, string output); }; diff --git a/include/modules/meta/base.inl b/include/modules/meta/base.inl index fa3d3a5a..d75c896c 100644 --- a/include/modules/meta/base.inl +++ b/include/modules/meta/base.inl @@ -1,6 +1,6 @@ #include "components/builder.hpp" -#include "components/logger.hpp" #include "components/config.hpp" +#include "components/logger.hpp" #include "events/signal.hpp" #include "events/signal_emitter.hpp" @@ -13,13 +13,13 @@ namespace modules { template module::module(const bar_settings bar, string name) - : m_sig(signal_emitter::make()) - , m_bar(bar) - , m_log(logger::make()) - , m_conf(config::make()) - , m_name("module/" + name) - , m_builder(make_unique(bar)) - , m_formatter(make_unique(m_conf, m_name)) {} + : m_sig(signal_emitter::make()) + , m_bar(bar) + , m_log(logger::make()) + , m_conf(config::make()) + , m_name("module/" + name) + , m_builder(make_unique(bar)) + , m_formatter(make_unique(m_conf, m_name)) {} template module::~module() noexcept { @@ -123,24 +123,34 @@ namespace modules { auto format_name = CONST_MOD(Impl).get_format(); auto format = m_formatter->get(format_name); - int i = 0; - bool tag_built = true; + int i{0}; + bool prevtag{true}; - for (auto&& tag : string_util::split(format->value, ' ')) { - bool is_blankspace = tag.empty(); + auto mingap = std::max(1UL, format->spacing); - if (tag[0] == '<' && tag[tag.length() - 1] == '>') { + size_t start, end; + string value{format->value}; + while ((start = value.find('<')) != string::npos && (end = value.find('>', start)) != string::npos) { + if (start > 0) { + m_builder->node(value.substr(0, start)); + value.erase(0, start); + end -= start; + start = 0; + } + string tag{value.substr(start, end + 1)}; + if (tag[0] == '<' && tag[tag.size() - 1] == '>') { if (i > 0) m_builder->space(format->spacing); - if (!(tag_built = CONST_MOD(Impl).build(m_builder.get(), tag)) && i > 0) - m_builder->remove_trailing_space(format->spacing); - if (tag_built) + if (!(prevtag = CONST_MOD(Impl).build(m_builder.get(), tag)) && i > 0) + m_builder->remove_trailing_space(mingap); + if (prevtag) i++; - } else if (is_blankspace && tag_built) { - m_builder->space(1_z); - } else if (!is_blankspace) { - m_builder->node(tag); } + value.erase(0, tag.size()); + } + + if (!value.empty()) { + m_builder->append(value); } return format->decorate(&*m_builder, m_builder->flush()); diff --git a/src/components/builder.cpp b/src/components/builder.cpp index f66fbc9c..47607d09 100644 --- a/src/components/builder.cpp +++ b/src/components/builder.cpp @@ -301,7 +301,11 @@ void builder::offset(int pixels) { * Insert spaces */ void builder::space(size_t width) { - m_output.append(width, ' '); + if (width) { + m_output.append(width, ' '); + } else { + space(); + } } void builder::space() { m_output.append(m_bar.spacing, ' '); diff --git a/src/components/config.cpp b/src/components/config.cpp index 27ba0d91..b066ead7 100644 --- a/src/components/config.cpp +++ b/src/components/config.cpp @@ -1,20 +1,16 @@ -#include -#include +#include #include -#include -#include #include "components/config.hpp" #include "utils/env.hpp" #include "utils/factory.hpp" #include "utils/file.hpp" +#include "utils/math.hpp" #include "utils/string.hpp" #include "x11/color.hpp" POLYBAR_NS -namespace chrono = std::chrono; - /** * Create instance */ @@ -33,6 +29,7 @@ config::config(const logger& logger, string&& path, string&& bar) } parse_file(); + copy_inherited(); bool found_bar{false}; for (auto&& p : m_sections) { @@ -127,8 +124,6 @@ void config::parse_file() { m_sections[section].emplace_hint(it, move(key), move(value)); } - - copy_inherited(); } /** @@ -246,12 +241,14 @@ unsigned int config::convert(string&& value) const { template <> unsigned long config::convert(string&& value) const { - return std::strtoul(value.c_str(), nullptr, 10); + unsigned long v{std::strtoul(value.c_str(), nullptr, 10)}; + return v < ULONG_MAX ? v : 0UL; } template <> unsigned long long config::convert(string&& value) const { - return std::strtoull(value.c_str(), nullptr, 10); + unsigned long v{std::strtoull(value.c_str(), nullptr, 10)}; + return v < ULLONG_MAX ? v : 0ULL; } template <> diff --git a/src/modules/menu.cpp b/src/modules/menu.cpp index b8638511..41fa19e1 100644 --- a/src/modules/menu.cpp +++ b/src/modules/menu.cpp @@ -12,7 +12,9 @@ namespace modules { template class module; menu_module::menu_module(const bar_settings& bar, string name_) : static_module(bar, move(name_)) { - string default_format{TAG_LABEL_TOGGLE + string{" "} + TAG_MENU}; + string default_format; + default_format += TAG_LABEL_TOGGLE; + default_format += TAG_MENU; m_formatter->add(DEFAULT_FORMAT, default_format, {TAG_LABEL_TOGGLE, TAG_MENU}); @@ -63,12 +65,14 @@ namespace modules { builder->node(m_labelclose); builder->cmd_close(); } else if (tag == TAG_MENU && m_level > -1) { + auto spacing = m_formatter->get(get_format())->spacing; for (auto&& item : m_levels[m_level]->items) { - if (item != m_levels[m_level]->items.front()) { - builder->space(); - } if (*m_labelseparator) { - builder->node(m_labelseparator, true); + if (item != m_levels[m_level]->items[0]) { + builder->space(spacing); + } + builder->node(m_labelseparator); + builder->space(spacing); } builder->cmd(mousebtn::LEFT, item->exec); builder->node(item->label); diff --git a/src/modules/meta/base.cpp b/src/modules/meta/base.cpp index befa3cd7..4b499c24 100644 --- a/src/modules/meta/base.cpp +++ b/src/modules/meta/base.cpp @@ -69,19 +69,18 @@ namespace modules { // module_formatter {{{ void module_formatter::add(string name, string fallback, vector&& tags, vector&& whitelist) { - using namespace std::string_literals; - auto format = make_unique(); - format->value = m_conf.get(m_modname, name, move(fallback)); - format->fg = m_conf.get(m_modname, name + "-foreground", ""s); - format->bg = m_conf.get(m_modname, name + "-background", ""s); - format->ul = m_conf.get(m_modname, name + "-underline", ""s); - format->ol = m_conf.get(m_modname, name + "-overline", ""s); - format->spacing = m_conf.get(m_modname, name + "-spacing", 1_z); - format->padding = m_conf.get(m_modname, name + "-padding", 0_z); - format->margin = m_conf.get(m_modname, name + "-margin", 0_z); - format->offset = m_conf.get(m_modname, name + "-offset", 0_z); + format->fg = m_conf.get(m_modname, name + "-foreground", format->fg); + format->bg = m_conf.get(m_modname, name + "-background", format->bg); + format->ul = m_conf.get(m_modname, name + "-underline", format->ul); + format->ol = m_conf.get(m_modname, name + "-overline", format->ol); + format->ulsize = m_conf.get(m_modname, name + "-underline-size", format->ulsize); + format->olsize = m_conf.get(m_modname, name + "-overline-size", format->olsize); + format->spacing = m_conf.get(m_modname, name + "-spacing", format->spacing); + format->padding = m_conf.get(m_modname, name + "-padding", format->padding); + format->margin = m_conf.get(m_modname, name + "-margin", format->margin); + format->offset = m_conf.get(m_modname, name + "-offset", format->offset); format->tags.swap(tags); try { @@ -96,16 +95,24 @@ namespace modules { // suffix not defined } - for (auto&& tag : string_util::split(format->value, ' ')) { - if (tag[0] != '<' || tag[tag.length() - 1] != '>') { - continue; - } else if (find(format->tags.begin(), format->tags.end(), tag) != format->tags.end()) { - continue; - } else if (find(whitelist.begin(), whitelist.end(), tag) != whitelist.end()) { - continue; - } else { + vector tag_collection; + tag_collection.reserve(format->tags.size() + whitelist.size()); + tag_collection.insert(tag_collection.end(), format->tags.begin(), format->tags.end()); + tag_collection.insert(tag_collection.end(), whitelist.begin(), whitelist.end()); + + size_t start, end; + string value{format->value}; + while ((start = value.find('<')) != string::npos && (end = value.find('>', start)) != string::npos) { + if (start > 0) { + value.erase(0, start); + end -= start; + start = 0; + } + string tag{value.substr(start, end + 1)}; + if (find(tag_collection.begin(), tag_collection.end(), tag) == tag_collection.end()) { throw undefined_format_tag(tag + " is not a valid format tag for \"" + name + "\""); } + value.erase(0, tag.size()); } m_formats.insert(make_pair(move(name), move(format))); diff --git a/src/modules/xkeyboard.cpp b/src/modules/xkeyboard.cpp index a26be190..1c788e9c 100644 --- a/src/modules/xkeyboard.cpp +++ b/src/modules/xkeyboard.cpp @@ -100,7 +100,7 @@ namespace modules { bool xkeyboard_module::build(builder* builder, const string& tag) const { if (tag == TAG_LABEL_LAYOUT) { builder->node(m_layout); - } else if (tag == TAG_LABEL_INDICATOR) { + } else if (tag == TAG_LABEL_INDICATOR && !m_indicators.empty()) { size_t n{0}; for (auto&& indicator : m_indicators) { if (n++) {