1 // rime_patch.cc
2 // Foodgen <chen.sst@gmail.com>
3 //
4 #include <iostream>
5 #include <rime_api.h>
6 #include <rime_levers_api.h>
7 #include <rime/common.h>
8
9 // usage:
10 // rime_patch config_id key [yaml]
11 // example:
12 // rime_patch default "menu/page_size" 9
13 // rime_patch default schema_list/@0/schema combo_pinyin
14 // rime_patch default schema_list '[{schema: luna_pinyin}]'
15 // rime_patch default schema_list # read yaml from stdin
16
17 using namespace rime;
18
apply_patch(const string & config_id,const string & key,const string & yaml)19 int apply_patch(const string& config_id,
20 const string& key, const string& yaml) {
21 RimeApi* rime = rime_get_api();
22 RimeModule* module = rime->find_module("levers");
23 if (!module) {
24 std::cerr << "missing Rime module: levers" << std::endl;
25 return 1;
26 }
27 RimeLeversApi* levers = (RimeLeversApi*)module->get_api();
28
29 int ret = 1;
30
31 RimeConfig value = {0}; // should be zero-initialized
32 if (rime->config_load_string(&value, yaml.c_str())) {
33
34 RimeCustomSettings* settings =
35 levers->custom_settings_init(config_id.c_str(), "rime_patch");
36 levers->load_settings(settings);
37
38 if (levers->customize_item(settings, key.c_str(), &value)) {
39 levers->save_settings(settings);
40 std::cerr << "patch applied." << std::endl;
41 ret = 0;
42 }
43
44 levers->custom_settings_destroy(settings);
45 rime->config_close(&value);
46 }
47 else {
48 std::cerr << "bad yaml document." << std::endl;
49 }
50
51 return ret;
52 }
53
main(int argc,char * argv[])54 int main(int argc, char *argv[]) {
55 if (argc < 3 || argc > 4) {
56 std::cerr << "usage: " << argv[0] << " config_id key [yaml]" << std::endl;
57 return 1;
58 }
59
60 RimeApi* rime = rime_get_api();
61
62 RIME_STRUCT(RimeTraits, traits);
63 traits.app_name = "rime.patch";
64 rime->setup(&traits);
65
66 rime->deployer_initialize(&traits);
67
68 string config_id(argv[1]);
69 string key(argv[2]);
70 string yaml;
71 if (argc > 3) {
72 yaml.assign(argv[3]);
73 }
74 else {
75 // read yaml string from stdin
76 yaml.assign((std::istreambuf_iterator<char>(std::cin)),
77 std::istreambuf_iterator<char>());
78 }
79 int ret = apply_patch(config_id, key, yaml);
80
81 rime->finalize();
82
83 return ret;
84 }
85