xaizek / libvle (License: GPLv3+) (since 2019-04-21)
Library for building Vim-like applications.
Commit 329e45fc6a8e92f7f2c7459714e581e91a36aa5d

Provide means for switching between modes
Author: xaizek
Author date (UTC): 2019-01-13 11:44
Committer name: xaizek
Committer date (UTC): 2019-01-13 11:44
Parent(s): ce574eb8a5dab20c0606cf3bf08ae2362ee6bbe1
Signing key:
Tree: 8c17567797dc8880a9688b60ed5be6fdca9055a5
File Lines added Lines deleted
Mode.cpp 3 0
Mode.hpp 7 2
Modes.cpp 24 6
Modes.hpp 11 4
engine/mode.h 9 0
File Mode.cpp changed (mode: 100644) (index 5cf602c..88d58b7)
... ... Shortcut::Shortcut(std::wstring shortcut, std::function<void(int)> handler,
39 39 descr(std::move(descr)) descr(std::move(descr))
40 40 { } { }
41 41
42 Mode::Mode(std::string id) : id(std::move(id))
43 { }
44
42 45 void void
43 46 Mode::addShortcut(Shortcut shortcut) Mode::addShortcut(Shortcut shortcut)
44 47 { {
File Mode.hpp changed (mode: 100644) (index 91970a8..21322f0)
... ... struct Shortcut
48 48 class Mode class Mode
49 49 { {
50 50 public: public:
51 // Initializes empty mode.
52 Mode() = default;
51 // Initializes empty mode with the specified id.
52 explicit Mode(std::string id);
53 53
54 54 Mode(const Mode &rhs) = delete; Mode(const Mode &rhs) = delete;
55 55 Mode(Mode &&rhs) = default; Mode(Mode &&rhs) = default;
 
... ... public:
57 57 Mode & operator=(Mode &&rhs) = default; Mode & operator=(Mode &&rhs) = default;
58 58
59 59 public: public:
60 // Retrieves id of the mode.
61 const std::string & getId() const
62 { return id; }
63
60 64 // Sets whether count is used by shortcuts. // Sets whether count is used by shortcuts.
61 65 void setUsesCount(bool uses) void setUsesCount(bool uses)
62 66 { useCount = uses; } { useCount = uses; }
 
... ... public:
72 76 { return shortcuts; } { return shortcuts; }
73 77
74 78 private: private:
79 std::string id; // Identifier of the mode.
75 80 std::deque<Shortcut> shortcuts; // Shortcuts of this mode. std::deque<Shortcut> shortcuts; // Shortcuts of this mode.
76 81 bool useCount = false; // Whether count is used by shortcuts. bool useCount = false; // Whether count is used by shortcuts.
77 82 }; };
File Modes.cpp changed (mode: 100644) (index 34cfeff..253b647)
20 20
21 21 #include <cassert> #include <cassert>
22 22
23 #include <iterator>
23 24 #include <stdexcept> #include <stdexcept>
24 25 #include <utility> #include <utility>
25 26 #include <vector> #include <vector>
26 27
27 28 #include "engine/keys.h" #include "engine/keys.h"
29 #include "engine/mode.h"
28 30 #include "Mode.hpp" #include "Mode.hpp"
29 31
30 32 using namespace vle; using namespace vle;
 
... ... Modes::reset()
72 74 void void
73 75 Modes::init(std::vector<Mode> &&modesInfo) Modes::init(std::vector<Mode> &&modesInfo)
74 76 { {
75 modes = std::move(modesInfo);
77 for (Mode &mode : modesInfo) {
78 if (!modes.emplace(mode.getId(), std::move(mode)).second) {
79 throw std::invalid_argument("Duplicated mode id:" + mode.getId());
80 }
81 }
76 82
77 83 modeKeyFlags.reserve(modes.size()); modeKeyFlags.reserve(modes.size());
78 for (const Mode &mode : modes) {
79 modeKeyFlags.push_back(mode.usesCount() ? MF_USES_COUNT : 0);
84 for (const auto &entry : modes) {
85 modeKeyFlags.push_back(entry.second.usesCount() ? MF_USES_COUNT : 0);
80 86 } }
81 87
82 88 auto silence = [](int /*more*/) { }; auto silence = [](int /*more*/) { };
83 89 vle_keys_init(modes.size(), &modeKeyFlags[0], silence); vle_keys_init(modes.size(), &modeKeyFlags[0], silence);
84 90
85 for (unsigned int i = 0U; i < modes.size(); ++i) {
91 int modeId = 0;
92 for (const auto &entry : modes) {
86 93 std::vector<keys_add_info_t> keys; std::vector<keys_add_info_t> keys;
87 for (const Shortcut &sh : modes[i].getShortcuts()) {
94 for (const Shortcut &sh : entry.second.getShortcuts()) {
88 95 keys_add_info_t addInfo = {}; keys_add_info_t addInfo = {};
89 96 wcscpy(const_cast<wchar_t *>(addInfo.keys), sh.shortcut.c_str()); wcscpy(const_cast<wchar_t *>(addInfo.keys), sh.shortcut.c_str());
90 97 addInfo.info.data.handler = &keyHandler; addInfo.info.data.handler = &keyHandler;
 
... ... Modes::init(std::vector<Mode> &&modesInfo)
95 102 keys.push_back(addInfo); keys.push_back(addInfo);
96 103 } }
97 104
98 int ret_code = vle_keys_add(&keys[0], keys.size(), i);
105 int ret_code = vle_keys_add(&keys[0], keys.size(), modeId++);
99 106 assert(ret_code == 0 && "Failed to add builtin keys"); assert(ret_code == 0 && "Failed to add builtin keys");
100 107 (void)ret_code; (void)ret_code;
101 108 } }
102 109 } }
110
111 void
112 Modes::switchTo(const std::string &modeId)
113 {
114 auto it = modes.find(modeId);
115 if (it == modes.end()) {
116 throw std::invalid_argument("Unknown mode id:" + modeId);
117 }
118
119 vle_mode_set(std::distance(modes.begin(), it), VMT_PRIMARY);
120 }
File Modes.hpp changed (mode: 100644) (index 4008b3b..ebabafc)
19 19 #ifndef LIBVLE__MODES_HPP__ #ifndef LIBVLE__MODES_HPP__
20 20 #define LIBVLE__MODES_HPP__ #define LIBVLE__MODES_HPP__
21 21
22 #include <string>
23 #include <unordered_map>
22 24 #include <vector> #include <vector>
23 25
24 namespace vle {
26 #include "Mode.hpp"
25 27
26 class Mode;
28 namespace vle {
27 29
28 30 // Handles initialization and deinitialization of modes. // Handles initialization and deinitialization of modes.
29 31 class Modes class Modes
 
... ... public:
43 45 // Initializes modes. Throws `std::invalid_argument` on duplicated mode ids // Initializes modes. Throws `std::invalid_argument` on duplicated mode ids
44 46 // or empty list of modes. // or empty list of modes.
45 47 void setModes(std::vector<Mode> modesInfo); void setModes(std::vector<Mode> modesInfo);
48 // Switches to the mode specified by its id. Throws `std::invalid_argument`
49 // on unknown mode id.
50 void switchTo(const std::string &modeId);
46 51
47 52 private: private:
48 53 // Deinitializes all modes. // Deinitializes all modes.
 
... ... private:
52 57 void init(std::vector<Mode> &&modesInfo); void init(std::vector<Mode> &&modesInfo);
53 58
54 59 private: private:
55 std::vector<Mode> modes; // Data that describes modes.
56 std::vector<int> modeKeyFlags; // Key processing flags of each mode.
60 // Data that describes modes.
61 std::unordered_map<std::string, Mode> modes;
62 // Key processing flags of each mode.
63 std::vector<int> modeKeyFlags;
57 64 }; };
58 65
59 66 } }
File engine/mode.h changed (mode: 100644) (index 9c88245..e18cf20)
34 34 * - secondary mode present, which makes "current" and "primary" modes be * - secondary mode present, which makes "current" and "primary" modes be
35 35 * different. */ * different. */
36 36
37 #ifdef __cplusplus
38 extern "C"
39 {
40 #endif
41
37 42 /* Type of mode. */ /* Type of mode. */
38 43 typedef enum typedef enum
39 44 { {
 
... ... int vle_primary_mode_is(vle_mode_t mode);
62 67 /* Sets current mode of the specified type. */ /* Sets current mode of the specified type. */
63 68 void vle_mode_set(vle_mode_t mode, VleModeType type); void vle_mode_set(vle_mode_t mode, VleModeType type);
64 69
70 #ifdef __cplusplus
71 }
72 #endif
73
65 74 #endif /* VIFM__ENGINE__MODE_H__ */ #endif /* VIFM__ENGINE__MODE_H__ */
66 75
67 76 /* vim: set tabstop=2 softtabstop=2 shiftwidth=2 noexpandtab cinoptions-=(0 : */ /* vim: set tabstop=2 softtabstop=2 shiftwidth=2 noexpandtab cinoptions-=(0 : */
Hints

Before first commit, do not forget to setup your git environment:
git config --global user.name "your_name_here"
git config --global user.email "your@email_here"

Clone this repository using HTTP(S):
git clone https://code.reversed.top/user/xaizek/libvle

Clone this repository using ssh (do not forget to upload a key first):
git clone ssh://rocketgit@code.reversed.top/user/xaizek/libvle

You are allowed to anonymously push to this repository.
This means that your pushed commits will automatically be transformed into a pull request:
... clone the repository ...
... make some changes and some commits ...
git push origin master