File | Mode | Size |
---|---|---|
compat/ | 040000 | |
engine/ | 040000 | |
utils/ | 040000 | |
Commands.cpp | 100644 | 3,995B |
Commands.hpp | 100644 | 2,337B |
KeyDispatcher.cpp | 100644 | 1,526B |
KeyDispatcher.hpp | 100644 | 1,800B |
Mode.cpp | 100644 | 2,317B |
Mode.hpp | 100644 | 3,181B |
Modes.cpp | 100644 | 3,316B |
Modes.hpp | 100644 | 1,989B |
README.md | 100644 | 4,309B |
keys.cpp | 100644 | 1,423B |
keys.hpp | 100644 | 1,353B |
xmake.lua | 100644 | 210B |
libvle, 2019 – 2022
This file last updated on 8 February, 2022
This is a C++11 library that provides basic classes for implementing Vim-like behaviour. Although the interface is in C++, core of the implementation is in C.
VLE stands for Vim-Like Engine/Experience.
The obvious purpose is to avoid reimplementing Vim-like functionality over and over again and instead do it once in a reusable manner.
It was extracted out of Vifm for a couple of projects, has minimally necessary functionality and can change quite a bit in the future. The implementations might diverge as there is currently no synchronization process in place.
There is no build system and nothing is getting built for the client. To use it clone the repository (possibly as a submodule) and handle the building with the build system that's used by the main project. Compile C++ files with C++11 enabled.
Alternatively one can use xmake to consume submodule as a subproject (example
assumes it's stored under libs/
):
add_includedirs("libs")
includes("libs/*/xmake.lua")
The API consists of classes in the vle
namespace.
As noted above, API is extended to accommodate use cases and currently includes only:
Modes
-- handles initialization, deinitialization and switching modesMode
-- contains mode configurationShortcut
-- shortcuts with optional support of countKeyDispatcher
-- input processor for key shortcutsCommands
-- parses and executes a single command-line :commandMode
objects and populate them with instances of Shortcut
.Mode
objects into Modes
.KeyDispatcher
, which will trigger shortcut handlers.Commands
and populate it with Command
objects.Commands
, which will trigger appropriate command handler.Very minimal application:
#include <cstdlib>
#include <iostream>
#include <string>
#include "vle/KeyDispatcher.hpp"
#include "vle/Mode.hpp"
#include "vle/Modes.hpp"
int
main()
{
vle::Mode normalMode("normal");
normalMode.setUsesCount(true);
normalMode.addShortcut({ L"gg", [&]() {
std::wcout << L"go to the top\n";
}, "go to the top" });
normalMode.addShortcut({ L"j", [&](int i) {
std::wcout << L"go down " << (i == -1 ? 1 : i) << L" item(s)\n";
}, "go down" });
std::vector<vle::Mode> allModes;
allModes.emplace_back(std::move(normalMode));
vle::Modes modes;
modes.setModes(std::move(allModes));
modes.switchTo("normal");
vle::KeyDispatcher dispatcher;
for (std::wstring ws; std::wcout << L" User input: ",
std::getline(std::wcin, ws); ) {
for (wchar_t wc : ws) {
std::wcout << L" > Sending in: " << wc << L'\n';
dispatcher.dispatch(wc);
std::wcout << L" > Buffered: " << dispatcher.getPendingInput()
<< L'\n';
}
std::wcout << L"\n";
}
return EXIT_SUCCESS;
}
Very minimal application:
#include <cstdlib>
#include <iostream>
#include <string>
#include "vle/Commands.hpp"
int
main()
{
bool quit = false;
vle::Commands commands;
commands.addCommand({ "q", "quit", "exit the app", 0, 0, [&](...) {
quit = true;
}});
commands.addCommand({ "", "echo", "print arguments", 0, -1,
[&](const std::vector<std::string> &args) {
for (const auto &arg : args) {
std::cout << arg << '\n';
}
}});
for (std::string s; !quit && (std::cout << " User input: ") &&
std::getline(std::cin, s); ) {
if (!commands.execute(s)) {
std::cout << "Some kind of error has occurred.\n";
}
}
return EXIT_SUCCESS;
}