diff --git a/CHANGELOG.md b/CHANGELOG.md index cf29e645..b07d6614 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -159,6 +159,9 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 - Increased the double click interval from 150ms to 400ms. - Stop ignoring actions if they arrive while the previous one hasn't been processed yet. ([`#2469`](https://github.com/polybar/polybar/issues/2469)) +- Polybar can now be run without passing the bar name as argument given that + the configuration file only defines one bar + ([`#2525`](https://github.com/polybar/polybar/issues/2525)) ### Fixed - `custom/script`: Concurrency issues with fast-updating tailed scripts. diff --git a/doc/man/polybar.1.rst b/doc/man/polybar.1.rst index ea7e0386..a568c838 100644 --- a/doc/man/polybar.1.rst +++ b/doc/man/polybar.1.rst @@ -3,11 +3,12 @@ polybar(1) SYNOPSIS -------- -**polybar** [*OPTIONS*]... *BAR* +**polybar** [*OPTIONS*]... [*BAR*] DESCRIPTION ----------- Polybar aims to help users build beautiful and highly customizable status bars for their desktop environment, without the need of having a black belt in shell scripting. +If the *BAR* argument is not provided and the configuration file only contains one bar definition, Polybar will display this bar. OPTIONS ------- diff --git a/include/components/config.hpp b/include/components/config.hpp index f00af679..289ed5d3 100644 --- a/include/components/config.hpp +++ b/include/components/config.hpp @@ -33,6 +33,8 @@ class config { const string& filepath() const; string section() const; + static constexpr const char* BAR_PREFIX = "bar/"; + /** * \brief Instruct the config to connect to the xresource manager */ diff --git a/include/components/config_parser.hpp b/include/components/config_parser.hpp index dc0900c5..0513f319 100644 --- a/include/components/config_parser.hpp +++ b/include/components/config_parser.hpp @@ -215,6 +215,8 @@ class config_parser { */ bool is_valid_name(const string& name); + vector get_bars(const sectionmap_t& sections) const; + /** * \brief Whether or not an xresource manager should be used * diff --git a/src/components/command_line.cpp b/src/components/command_line.cpp index 0ed11a94..22d096ee 100644 --- a/src/components/command_line.cpp +++ b/src/components/command_line.cpp @@ -9,7 +9,7 @@ namespace command_line { * Create instance */ parser::make_type parser::make(string&& scriptname, const options&& opts) { - return std::make_unique("Usage: " + scriptname + " [OPTION]... BAR", forward(opts)); + return std::make_unique("Usage: " + scriptname + " [OPTION]... [BAR]", forward(opts)); } /** diff --git a/src/components/config.cpp b/src/components/config.cpp index 2748a6b4..d72819f1 100644 --- a/src/components/config.cpp +++ b/src/components/config.cpp @@ -31,7 +31,7 @@ const string& config::filepath() const { * Get the section name of the bar in use */ string config::section() const { - return "bar/" + m_barname; + return BAR_PREFIX + m_barname; } void config::use_xrm() { diff --git a/src/components/config_parser.cpp b/src/components/config_parser.cpp index 090d0550..645ceda3 100644 --- a/src/components/config_parser.cpp +++ b/src/components/config_parser.cpp @@ -20,8 +20,23 @@ config::make_type config_parser::parse() { sectionmap_t sections = create_sectionmap(); - if (sections.find("bar/" + m_barname) == sections.end()) { - throw application_error("Undefined bar: " + m_barname); + vector bars = get_bars(sections); + if (m_barname.empty()) { + if (bars.size() == 1) { + m_barname = bars[0]; + } else if (bars.empty()) { + throw application_error("The config file contains no bar."); + } else { + throw application_error("The config file contains multiple bars, but no bar name was given. Available bars: " + + string_util::join(bars, ", ")); + } + } else if (sections.find("bar/" + m_barname) == sections.end()) { + if (bars.empty()) { + throw application_error("Undefined bar: " + m_barname + ". The config file contains no bar."); + } else { + throw application_error( + "Undefined bar: " + m_barname + ". Available bars: " + string_util::join(get_bars(sections), ", ")); + } } /* @@ -80,6 +95,19 @@ sectionmap_t config_parser::create_sectionmap() { return sections; } +/** + * Get the bars declared + */ +vector config_parser::get_bars(const sectionmap_t& sections) const { + vector bars; + for (const auto& it : sections) { + if (it.first.find(config::BAR_PREFIX) == 0) { + bars.push_back(it.first.substr(strlen(config::BAR_PREFIX))); + } + } + return bars; +} + void config_parser::parse_file(const string& file, file_list path) { if (std::find(path.begin(), path.end(), file) != path.end()) { string path_str{}; diff --git a/src/main.cpp b/src/main.cpp index 13539755..014011b1 100644 --- a/src/main.cpp +++ b/src/main.cpp @@ -98,10 +98,7 @@ int main(int argc, char** argv) { string confpath; // Make sure a bar name is passed in - if (!cli->has(0)) { - cli->usage(); - return EXIT_FAILURE; - } else if (cli->has(1)) { + if (cli->has(1)) { fprintf(stderr, "Unrecognized argument \"%s\"\n", cli->get(1).c_str()); cli->usage(); return EXIT_FAILURE; @@ -123,7 +120,12 @@ int main(int argc, char** argv) { throw application_error("Define configuration using --config=PATH"); } - config_parser parser{logger, move(confpath), cli->get(0)}; + string barname; + if (cli->has(0)) { + barname = cli->get(0); + } + + config_parser parser{logger, move(confpath), move(barname)}; config::make_type conf = parser.parse(); //==================================================