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 = <label-foo>  <label-bar>
    format-breaks = <label-foo><label-bar>/<bar-test>

`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.
This commit is contained in:
Michael Carlberg 2017-01-11 01:42:55 +01:00
parent f4e8051e9e
commit 30f516dd7d
9 changed files with 90 additions and 69 deletions

View File

@ -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

View File

@ -143,7 +143,7 @@ struct bar_settings {
std::unordered_map<edge, border_settings, enum_hash> borders{};
uint8_t spacing{1U};
uint8_t spacing{0};
string separator{};
string wmname{};

View File

@ -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);
};

View File

@ -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 <typename Impl>
module<Impl>::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<builder>(bar))
, m_formatter(make_unique<module_formatter>(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<builder>(bar))
, m_formatter(make_unique<module_formatter>(m_conf, m_name)) {}
template <typename Impl>
module<Impl>::~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());

View File

@ -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, ' ');

View File

@ -1,20 +1,16 @@
#include <algorithm>
#include <chrono>
#include <climits>
#include <fstream>
#include <istream>
#include <utility>
#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 <>

View File

@ -12,7 +12,9 @@ namespace modules {
template class module<menu_module>;
menu_module::menu_module(const bar_settings& bar, string name_) : static_module<menu_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);

View File

@ -69,19 +69,18 @@ namespace modules {
// module_formatter {{{
void module_formatter::add(string name, string fallback, vector<string>&& tags, vector<string>&& whitelist) {
using namespace std::string_literals;
auto format = make_unique<module_format>();
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<string> 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)));

View File

@ -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++) {