diff --git a/doc/bindings b/doc/bindings index d5217b93..ab21cbf6 100644 --- a/doc/bindings +++ b/doc/bindings @@ -1,7 +1,8 @@ -########################################################## -## this is example bindings configuration file, copy it ## -## to ~/.ncmpcpp/bindings and set up your preferences ## -########################################################## +############################################################## +## This is the example bindings file. Copy it to ## +## ~/.ncmpcpp/bindings or $XDG_CONFIG_HOME/ncmpcpp/bindings ## +## and set up your preferences ## +############################################################## ## ##### General rules ##### ## diff --git a/src/bindings.cpp b/src/bindings.cpp index 00b0e446..51360bdb 100644 --- a/src/bindings.cpp +++ b/src/bindings.cpp @@ -467,6 +467,17 @@ bool BindingsConfiguration::read(const std::string &file) return result; } +bool BindingsConfiguration::read(const std::vector &binding_paths) +{ + return std::all_of( + binding_paths.begin(), + binding_paths.end(), + [&](const std::string &binding_path) { + return read(binding_path); + } + ); +} + void BindingsConfiguration::generateDefaults() { NC::Key::Type k = NC::Key::None; diff --git a/src/bindings.h b/src/bindings.h index 6cf277c6..ac9d5073 100644 --- a/src/bindings.h +++ b/src/bindings.h @@ -34,7 +34,7 @@ std::wstring keyToWString(const NC::Key::Type key); struct Binding { typedef std::vector> ActionChain; - + template Binding(ArgT &&actions_) : m_actions(std::forward(actions_)) { @@ -42,13 +42,13 @@ struct Binding } Binding(Actions::Type at) : Binding(ActionChain({Actions::get_(at)})) { } - + bool execute() const { return std::all_of(m_actions.begin(), m_actions.end(), std::bind(&Actions::BaseAction::execute, std::placeholders::_1) ); } - + bool isSingle() const { return m_actions.size() == 1; } @@ -73,10 +73,10 @@ struct Command template Command(ArgT &&binding_, bool immediate_) : m_impl(std::forward(binding_), immediate_) { } - + const Binding &binding() const { return std::get<0>(m_impl); } bool immediate() const { return std::get<1>(m_impl); } - + private: std::tuple m_impl; }; @@ -86,31 +86,33 @@ class BindingsConfiguration { typedef std::unordered_map CommandsSet; typedef std::unordered_map> BindingsMap; - + public: typedef BindingsMap::value_type::second_type::iterator BindingIterator; typedef BindingsMap::value_type::second_type::const_iterator ConstBindingIterator; typedef std::pair BindingIteratorPair; - bool read(const std::string &file); + bool read(const std::vector &binding_paths); void generateDefaults(); - + const Command *findCommand(const std::string &name); BindingIteratorPair get(const NC::Key::Type &k); - + BindingsMap::const_iterator begin() const { return m_bindings.begin(); } BindingsMap::const_iterator end() const { return m_bindings.end(); } - + private: bool notBound(const NC::Key::Type &k) const { return k != NC::Key::None && m_bindings.find(k) == m_bindings.end(); } - + template void bind(NC::Key::Type k, ArgT &&t) { m_bindings[k].push_back(std::forward(t)); } - + + bool read(const std::string &file); + BindingsMap m_bindings; CommandsSet m_commands; }; diff --git a/src/configuration.cpp b/src/configuration.cpp index e2a78596..5673c218 100644 --- a/src/configuration.cpp +++ b/src/configuration.cpp @@ -74,7 +74,12 @@ bool configure(int argc, char **argv) xdg_config_home() + "ncmpcpp/config" }; - std::string bindings_path; + const std::vector default_bindings_paths = { + "~/.ncmpcpp/bindings", + xdg_config_home() + "ncmpcpp/bindings" + }; + + std::vector bindings_paths; std::vector config_paths; po::options_description options("Options"); @@ -85,7 +90,7 @@ bool configure(int argc, char **argv) ("config,c", po::value>(&config_paths)->value_name("PATH")->default_value(default_config_paths, join(default_config_paths, " AND ")), "specify configuration file(s)") ("ignore-config-errors", "ignore unknown and invalid options in configuration files") ("test-lyrics-fetchers", "check if lyrics fetchers work") - ("bindings,b", po::value(&bindings_path)->value_name("PATH")->default_value("~/.ncmpcpp/bindings"), "specify bindings file") + ("bindings,b", po::value>(&bindings_paths)->value_name("PATH")->default_value(default_bindings_paths, join(default_bindings_paths, " AND ")), "specify bindings file(s)") ("screen,s", po::value()->value_name("SCREEN"), "specify the startup screen") ("slave-screen,S", po::value()->value_name("SCREEN"), "specify the startup slave screen") ("help,?", "show help message") @@ -190,14 +195,9 @@ bool configure(int argc, char **argv) if (Config.read(config_paths, vm.count("ignore-config-errors")) == false) exit(1); - // if bindings file was not specified, use the one from main directory. - if (vm["bindings"].defaulted()) - bindings_path = Config.ncmpcpp_directory + "bindings"; - else - expand_home(bindings_path); - // read bindings - if (Bindings.read(bindings_path) == false) + std::for_each(bindings_paths.begin(), bindings_paths.end(), expand_home); + if (Bindings.read(bindings_paths) == false) exit(1); Bindings.generateDefaults();