1 /* 2 * SPDX-FileCopyrightText: 2020~2020 CSSlayer <wengxt@gmail.com> 3 * 4 * SPDX-License-Identifier: LGPL-2.1-or-later 5 * 6 */ 7 #ifndef _FCITX5_LUA_ADDONLOADER_LUAADDONSTATE_H_ 8 #define _FCITX5_LUA_ADDONLOADER_LUAADDONSTATE_H_ 9 10 #include "luahelper.h" 11 #include "luastate.h" 12 #include <fcitx/addoninfo.h> 13 #include <fcitx/addonmanager.h> 14 #include <fcitx/instance.h> 15 #include <quickphrase_public.h> 16 17 namespace fcitx { 18 19 #define DEFINE_LUA_FUNCTION(FUNCTION_NAME) \ 20 static int FUNCTION_NAME(lua_State *lua) { \ 21 auto state = GetLuaAddonState(lua); \ 22 auto args = LuaCheckArgument(state->state_.get(), \ 23 &LuaAddonState::FUNCTION_NAME##Impl); \ 24 try { \ 25 auto fn = std::mem_fn(&LuaAddonState::FUNCTION_NAME##Impl); \ 26 auto combined_args = std::tuple_cat(std::make_tuple(state), args); \ 27 return LuaReturn(state->state_.get(), \ 28 fcitx::callWithTuple(fn, combined_args)); \ 29 } catch (const std::exception &e) { \ 30 return luaL_error(state->state_, e.what()); \ 31 } \ 32 } 33 34 template <typename T> 35 class ScopedSetter { 36 public: ScopedSetter(T & t,const T & n)37 ScopedSetter(T &t, const T &n) : old_(t), orig_(&t) { t = n; } 38 ~ScopedSetter()39 ~ScopedSetter() { *orig_ = old_; } 40 41 private: 42 T old_; 43 T *orig_; 44 }; 45 46 using ScopedICSetter = ScopedSetter<TrackableObjectReference<InputContext>>; 47 48 class EventWatcher { 49 public: EventWatcher(std::string functionName,std::unique_ptr<HandlerTableEntry<EventHandler>> handler)50 EventWatcher(std::string functionName, 51 std::unique_ptr<HandlerTableEntry<EventHandler>> handler) 52 : functionName_(std::move(functionName)), handler_(std::move(handler)) { 53 } 54 FCITX_INLINE_DEFINE_DEFAULT_DTOR_AND_MOVE(EventWatcher); 55 function()56 const auto &function() const { return functionName_; } 57 58 private: 59 std::string functionName_; 60 std::unique_ptr<HandlerTableEntry<EventHandler>> handler_; 61 }; 62 63 /// 64 // @module fcitx 65 class Converter { 66 public: Converter(std::string functionName,ScopedConnection connection)67 Converter(std::string functionName, ScopedConnection connection) 68 : functionName_(std::move(functionName)), 69 connection_(std::move(connection)) {} 70 FCITX_INLINE_DEFINE_DEFAULT_DTOR_AND_MOVE(Converter); 71 function()72 const auto &function() const { return functionName_; } 73 74 private: 75 std::string functionName_; 76 ScopedConnection connection_; 77 }; 78 79 class LuaAddonState { 80 public: 81 LuaAddonState(Library &luaLibrary, const std::string &name, 82 const std::string &library, AddonManager *manager); 83 84 operator LuaState *() { return state_.get(); } 85 86 RawConfig invokeLuaFunction(InputContext *ic, const std::string &name, 87 const RawConfig &config); 88 89 private: currentInputContext()90 InputContext *currentInputContext() { return inputContext_.get(); } 91 92 /// Get the version of fcitx. 93 // @function version 94 // @treturn string The version of fcitx. 95 DEFINE_LUA_FUNCTION(version); 96 /// Get the last committed string. 97 // @function lastCommit 98 // @treturn string The last commit string from fcitx. 99 DEFINE_LUA_FUNCTION(lastCommit); 100 /// a helper function to split the string by delimiter. 101 // @function splitString 102 // @string str string to be split. 103 // @string delim string used as delimiter. 104 // @treturn table An array of string split by delimiter, empty string will 105 // be skipped. 106 DEFINE_LUA_FUNCTION(splitString); 107 /// a helper function to send Debug level log to fcitx. 108 // @function log 109 // @string str log string. 110 DEFINE_LUA_FUNCTION(log); 111 /// Watch for a event from fcitx. 112 // @function watchEvent 113 // @int event Event Type. 114 // @string function the function name. 115 // @return A unique integer identifier. 116 // @see EventType 117 DEFINE_LUA_FUNCTION(watchEvent); 118 /// Unwatch a certain event. 119 // @function unwatchEvent 120 // @int id id of the watcher. 121 // @see watchEvent 122 DEFINE_LUA_FUNCTION(unwatchEvent); 123 /// Return the current input method. 124 // @function currentInputMethod 125 // @treturn string the unique string of current input method. 126 DEFINE_LUA_FUNCTION(currentInputMethod); 127 /// Change the current input method 128 // @function setCurrentInputMethod 129 // @string name the unique string of the input method name. 130 DEFINE_LUA_FUNCTION(setCurrentInputMethod); 131 /// Return the current program name 132 // @function currentProgram 133 // @treturn string the string of current program name. 134 DEFINE_LUA_FUNCTION(currentProgram); 135 /// Add a string converter for committing string. 136 // @function addConverter 137 // @string function the function name. 138 // @treturn int A unique integer identifier. 139 DEFINE_LUA_FUNCTION(addConverter); 140 /// Remove a converter. 141 // @function removeConverter 142 // @int id id of this converter. 143 // @see addConverter 144 DEFINE_LUA_FUNCTION(removeConverter); 145 /// Add a quick phrase handler. 146 // @function addQuickPhraseHandler 147 // @string function the function name. 148 // @treturn int A unique integer identifier. 149 DEFINE_LUA_FUNCTION(addQuickPhraseHandler); 150 /// Remove a quickphrase handler. 151 // @function removeQuickPhraseHandler 152 // @int id id of this handler. 153 // @see addQuickPhraseHandler 154 DEFINE_LUA_FUNCTION(removeQuickPhraseHandler); 155 /// Commit string to current input context. 156 // @function commitString 157 // @string str string to be commit to input context. 158 DEFINE_LUA_FUNCTION(commitString); 159 /// Locate all files with given path and suffix. 160 // @function standardPathLocate 161 // @int type 162 // @string path 163 // @string suffix 164 // @treturn table A table of full file name. 165 // @see StandardPath 166 DEFINE_LUA_FUNCTION(standardPathLocate); 167 /// Helper function to convert UTF16 string to UTF8. 168 // @function UTF16ToUTF8 169 // @string str UTF16 string. 170 // @treturn string UTF8 string or empty string if it fails. 171 DEFINE_LUA_FUNCTION(UTF16ToUTF8) 172 /// Helper function to convert UTF8 string to UTF16. 173 // @function UTF8ToUTF16 174 // @string str UTF8 string. 175 // @treturn string UTF16 string or empty string if it fails. 176 DEFINE_LUA_FUNCTION(UTF8ToUTF16) 177 178 template <typename T> 179 std::unique_ptr<HandlerTableEntry<EventHandler>> watchEvent( 180 EventType type, int id, 181 std::function<int(std::unique_ptr<LuaState> &, T &)> pushArguments = 182 nullptr, 183 std::function<void(std::unique_ptr<LuaState> &, T &)> 184 handleReturnValue = nullptr); 185 versionImpl()186 std::tuple<std::string> versionImpl() { return Instance::version(); } 187 lastCommitImpl()188 std::tuple<std::string> lastCommitImpl() { return lastCommit_; } 189 std::tuple<> logImpl(const char *msg); 190 std::tuple<int> watchEventImpl(int eventType, const char *function); 191 std::tuple<> unwatchEventImpl(int id); 192 std::tuple<std::string> currentInputMethodImpl(); 193 std::tuple<> setCurrentInputMethodImpl(const char *str, bool local); 194 std::tuple<std::string> currentProgramImpl(); 195 196 std::tuple<int> addConverterImpl(const char *function); 197 std::tuple<> removeConverterImpl(int id); 198 199 std::tuple<int> addQuickPhraseHandlerImpl(const char *function); 200 std::tuple<> removeQuickPhraseHandlerImpl(int id); 201 splitStringImpl(const char * str,const char * delim)202 std::tuple<std::vector<std::string>> splitStringImpl(const char *str, 203 const char *delim) { 204 return stringutils::split(str, delim); 205 } 206 207 std::tuple<std::string> UTF8ToUTF16Impl(const char *str); 208 std::tuple<std::string> UTF16ToUTF8Impl(const char *str); 209 210 std::tuple<std::vector<std::string>> 211 standardPathLocateImpl(int type, const char *name, const char *suffix); 212 213 std::tuple<> commitStringImpl(const char *str); 214 FCITX_ADDON_DEPENDENCY_LOADER(quickphrase, instance_->addonManager()); 215 216 bool handleQuickPhrase(InputContext *ic, const std::string &input, 217 const QuickPhraseAddCandidateCallback &callback); 218 Instance *instance_; 219 std::unique_ptr<LuaState> state_; 220 TrackableObjectReference<InputContext> inputContext_; 221 222 std::unordered_map<int, EventWatcher> eventHandler_; 223 std::unordered_map<int, Converter> converter_; 224 std::map<int, std::string> quickphraseHandler_; 225 226 std::unique_ptr<HandlerTableEntry<QuickPhraseProviderCallback>> 227 quickphraseCallback_; 228 std::unique_ptr<HandlerTableEntry<EventHandler>> commitHandler_; 229 230 int currentId_ = 0; 231 std::string lastCommit_; 232 }; 233 234 } // namespace fcitx 235 236 #endif // _FCITX5_LUA_ADDONLOADER_LUAADDONSTATE_H_ 237