|
|
|
@ -189,53 +189,110 @@ Key Key::read(NC::Window &w) |
|
|
|
|
|
|
|
|
|
|
|
bool BindingsConfiguration::read(const std::string &file) |
|
|
|
bool BindingsConfiguration::read(const std::string &file) |
|
|
|
{ |
|
|
|
{ |
|
|
|
|
|
|
|
enum class InProgress { None, Command, Key }; |
|
|
|
|
|
|
|
|
|
|
|
bool result = true; |
|
|
|
bool result = true; |
|
|
|
|
|
|
|
|
|
|
|
std::ifstream f(file); |
|
|
|
std::ifstream f(file); |
|
|
|
if (!f.is_open()) |
|
|
|
if (!f.is_open()) |
|
|
|
return result; |
|
|
|
return result; |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
// shared variables
|
|
|
|
|
|
|
|
InProgress in_progress = InProgress::None; |
|
|
|
size_t line_no = 0; |
|
|
|
size_t line_no = 0; |
|
|
|
bool key_def_in_progress = false; |
|
|
|
std::string line; |
|
|
|
Key key = Key::noOp; |
|
|
|
|
|
|
|
Binding::ActionChain actions; |
|
|
|
Binding::ActionChain actions; |
|
|
|
std::string line, strkey; |
|
|
|
|
|
|
|
|
|
|
|
// def_key specific variables
|
|
|
|
|
|
|
|
Key key = Key::noOp; |
|
|
|
|
|
|
|
std::string strkey; |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
// def_command specific variables
|
|
|
|
|
|
|
|
bool cmd_immediate = false; |
|
|
|
|
|
|
|
std::string cmd_name; |
|
|
|
|
|
|
|
|
|
|
|
auto error = [&]() -> std::ostream & { |
|
|
|
auto error = [&]() -> std::ostream & { |
|
|
|
std::cerr << file << ":" << line_no << ": "; |
|
|
|
std::cerr << file << ":" << line_no << ": error: "; |
|
|
|
key_def_in_progress = false; |
|
|
|
in_progress = InProgress::None; |
|
|
|
result = false; |
|
|
|
result = false; |
|
|
|
return std::cerr; |
|
|
|
return std::cerr; |
|
|
|
}; |
|
|
|
}; |
|
|
|
|
|
|
|
|
|
|
|
auto bind_key_def = [&]() -> bool { |
|
|
|
auto bind_in_progress = [&]() -> bool { |
|
|
|
if (!actions.empty()) |
|
|
|
if (in_progress == InProgress::Command) |
|
|
|
{ |
|
|
|
{ |
|
|
|
bind(key, actions); |
|
|
|
if (!actions.empty()) |
|
|
|
actions.clear(); |
|
|
|
{ |
|
|
|
return true; |
|
|
|
m_commands.insert(std::make_pair(cmd_name, Command(actions, cmd_immediate))); |
|
|
|
|
|
|
|
actions.clear(); |
|
|
|
|
|
|
|
return true; |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
else |
|
|
|
|
|
|
|
{ |
|
|
|
|
|
|
|
error() << "definition of command '" << cmd_name << "' cannot be empty\n"; |
|
|
|
|
|
|
|
return false; |
|
|
|
|
|
|
|
} |
|
|
|
} |
|
|
|
} |
|
|
|
else |
|
|
|
else if (in_progress == InProgress::Key) |
|
|
|
{ |
|
|
|
{ |
|
|
|
error() << "definition of key '" << strkey << "' cannot be empty.\n"; |
|
|
|
if (!actions.empty()) |
|
|
|
return false; |
|
|
|
{ |
|
|
|
|
|
|
|
bind(key, actions); |
|
|
|
|
|
|
|
actions.clear(); |
|
|
|
|
|
|
|
return true; |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
else |
|
|
|
|
|
|
|
{ |
|
|
|
|
|
|
|
error() << "definition of key '" << strkey << "' cannot be empty\n"; |
|
|
|
|
|
|
|
return false; |
|
|
|
|
|
|
|
} |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
return true; |
|
|
|
}; |
|
|
|
}; |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
const char def_command[] = "def_command"; |
|
|
|
|
|
|
|
const char def_key[] = "def_key"; |
|
|
|
|
|
|
|
|
|
|
|
while (!f.eof() && ++line_no) |
|
|
|
while (!f.eof() && ++line_no) |
|
|
|
{ |
|
|
|
{ |
|
|
|
getline(f, line); |
|
|
|
getline(f, line); |
|
|
|
if (line.empty() || line[0] == '#') |
|
|
|
if (line.empty() || line[0] == '#') |
|
|
|
continue; |
|
|
|
continue; |
|
|
|
|
|
|
|
|
|
|
|
if (!line.compare(0, 7, "def_key")) // beginning of key definition
|
|
|
|
// beginning of command definition
|
|
|
|
|
|
|
|
if (!line.compare(0, const_strlen(def_command), def_command)) |
|
|
|
{ |
|
|
|
{ |
|
|
|
if (key_def_in_progress) |
|
|
|
if (!bind_in_progress()) |
|
|
|
|
|
|
|
break; |
|
|
|
|
|
|
|
in_progress = InProgress::Command; |
|
|
|
|
|
|
|
cmd_name = getEnclosedString(line, '"', '"', 0); |
|
|
|
|
|
|
|
if (cmd_name.empty()) |
|
|
|
|
|
|
|
{ |
|
|
|
|
|
|
|
error() << "command must have non-empty name\n"; |
|
|
|
|
|
|
|
break; |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
if (m_commands.find(cmd_name) != m_commands.end()) |
|
|
|
|
|
|
|
{ |
|
|
|
|
|
|
|
error() << "redefinition of command '" << cmd_name << "'\n"; |
|
|
|
|
|
|
|
break; |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
std::string cmd_type = getEnclosedString(line, '[', ']', 0); |
|
|
|
|
|
|
|
if (cmd_type == "immediate") |
|
|
|
|
|
|
|
cmd_immediate = true; |
|
|
|
|
|
|
|
else if (cmd_type == "deferred") |
|
|
|
|
|
|
|
cmd_immediate = false; |
|
|
|
|
|
|
|
else |
|
|
|
{ |
|
|
|
{ |
|
|
|
if (!bind_key_def()) |
|
|
|
error() << "invalid type of command: '" << cmd_type << "'\n"; |
|
|
|
break; |
|
|
|
break; |
|
|
|
} |
|
|
|
} |
|
|
|
key_def_in_progress = true; |
|
|
|
} |
|
|
|
|
|
|
|
// beginning of key definition
|
|
|
|
|
|
|
|
else if (!line.compare(0, const_strlen(def_key), def_key)) |
|
|
|
|
|
|
|
{ |
|
|
|
|
|
|
|
if (!bind_in_progress()) |
|
|
|
|
|
|
|
break; |
|
|
|
|
|
|
|
in_progress = InProgress::Key; |
|
|
|
strkey = getEnclosedString(line, '"', '"', 0); |
|
|
|
strkey = getEnclosedString(line, '"', '"', 0); |
|
|
|
key = stringToKey(strkey); |
|
|
|
key = stringToKey(strkey); |
|
|
|
if (key == Key::noOp) |
|
|
|
if (key == Key::noOp) |
|
|
|
@ -262,8 +319,7 @@ bool BindingsConfiguration::read(const std::string &file) |
|
|
|
break; |
|
|
|
break; |
|
|
|
} |
|
|
|
} |
|
|
|
} |
|
|
|
} |
|
|
|
if (key_def_in_progress) |
|
|
|
bind_in_progress(); |
|
|
|
bind_key_def(); |
|
|
|
|
|
|
|
f.close(); |
|
|
|
f.close(); |
|
|
|
return result; |
|
|
|
return result; |
|
|
|
} |
|
|
|
} |
|
|
|
@ -318,6 +374,8 @@ void BindingsConfiguration::generateDefaults() |
|
|
|
} |
|
|
|
} |
|
|
|
if (notBound(k = stringToKey("-"))) |
|
|
|
if (notBound(k = stringToKey("-"))) |
|
|
|
bind(k, aVolumeDown); |
|
|
|
bind(k, aVolumeDown); |
|
|
|
|
|
|
|
if (notBound(k = stringToKey(":"))) |
|
|
|
|
|
|
|
bind(k, aExecuteCommand); |
|
|
|
if (notBound(k = stringToKey("tab"))) |
|
|
|
if (notBound(k = stringToKey("tab"))) |
|
|
|
bind(k, aNextScreen); |
|
|
|
bind(k, aNextScreen); |
|
|
|
if (notBound(k = stringToKey("shift_tab"))) |
|
|
|
if (notBound(k = stringToKey("shift_tab"))) |
|
|
|
|