TextMate is a graphical text editor for OS X 10.7+
修訂 | f0284c1983f573ee49452abdb912b8e684987953 (tree) |
---|---|
時間 | 2012-08-24 05:36:22 |
作者 | Allan Odgaard <git@abet...> |
Commiter | Allan Odgaard |
Add code to save Global.tmProperties
Instead of storing things in user defaults we will store them in ~/Library/Application Support/TextMate/Global.tmProperties.
This just makes things a lot easier than having to mix NSUserDefaults with our .tm_properties files, especially since changing a setting in the UI should sometimes be global, sometimes be for the current file’s type, and sometimes just for the current document (e.g. spelling language).
These features are already available with the .tm_properties.
@@ -7,6 +7,7 @@ | ||
7 | 7 | #include <oak/oak.h> |
8 | 8 | #include <regexp/format_string.h> |
9 | 9 | #include <regexp/glob.h> |
10 | +#include <text/tokenize.h> | |
10 | 11 | #include <oak/debug.h> |
11 | 12 | #include <io/io.h> |
12 | 13 |
@@ -14,6 +15,12 @@ OAK_DEBUG_VAR(Settings); | ||
14 | 15 | |
15 | 16 | namespace |
16 | 17 | { |
18 | + static std::string global_settings_path () | |
19 | + { | |
20 | + static std::string const res = path::join(path::home(), "Library/Application Support/TextMate/Global.tmProperties"); | |
21 | + return res; | |
22 | + } | |
23 | + | |
17 | 24 | static std::vector< std::pair<std::string, std::string> > global_variables () |
18 | 25 | { |
19 | 26 | std::vector< std::pair<std::string, std::string> > res; |
@@ -64,6 +71,7 @@ namespace | ||
64 | 71 | break; |
65 | 72 | } |
66 | 73 | res.push_back(oak::application_t::path("Contents/Resources/Default.tmProperties")); |
74 | + res.push_back(global_settings_path()); | |
67 | 75 | std::reverse(res.begin(), res.end()); |
68 | 76 | return res; |
69 | 77 | } |
@@ -189,3 +197,64 @@ std::map<std::string, std::string> variables_for_path (std::string const& path, | ||
189 | 197 | |
190 | 198 | return variables; |
191 | 199 | } |
200 | + | |
201 | +// =================== | |
202 | +// = Saving Settings = | |
203 | +// =================== | |
204 | + | |
205 | +void settings_t::set (std::string const& key, std::string const& value, std::string const& fileType, std::string const& path) | |
206 | +{ | |
207 | + ini_file_t iniFile(global_settings_path()); | |
208 | + std::string content = path::content(global_settings_path()); | |
209 | + if(content != NULL_STR) | |
210 | + parse_ini(content.data(), content.data() + content.size(), iniFile); | |
211 | + | |
212 | + std::map<std::string, std::map<std::string, std::string>> sections; | |
213 | + iterate(section, iniFile.sections) | |
214 | + { | |
215 | + std::vector<std::string> names = section->names.empty() ? std::vector<std::string>(1, "") : section->names; | |
216 | + iterate(name, names) | |
217 | + { | |
218 | + iterate(pair, section->values) | |
219 | + sections[*name].insert(std::make_pair(pair->name, pair->value)); | |
220 | + } | |
221 | + } | |
222 | + | |
223 | + std::vector<std::string> sectionNames(1, ""); | |
224 | + if(fileType != NULL_STR) | |
225 | + { | |
226 | + std::string sectionName = ""; | |
227 | + citerate(it, text::tokenize(fileType.begin(), fileType.end(), '.')) | |
228 | + { | |
229 | + sectionName.append(*it); | |
230 | + sectionNames.push_back(sectionName); | |
231 | + sectionName.append("."); | |
232 | + } | |
233 | + } | |
234 | + | |
235 | + if(path != NULL_STR) | |
236 | + sectionNames.push_back(path); | |
237 | + | |
238 | + iterate(sectionName, sectionNames) | |
239 | + { | |
240 | + if(value != NULL_STR) | |
241 | + sections[*sectionName][key] = value; | |
242 | + else sections[*sectionName].erase(key); | |
243 | + } | |
244 | + | |
245 | + if(FILE* fp = fopen(global_settings_path().c_str(), "w")) | |
246 | + { | |
247 | + iterate(section, sections) | |
248 | + { | |
249 | + if(section->second.empty()) | |
250 | + continue; | |
251 | + | |
252 | + if(!section->first.empty()) | |
253 | + fprintf(fp, "[ %s ]\n", section->first.c_str()); | |
254 | + | |
255 | + iterate(pair, section->second) | |
256 | + fprintf(fp, "%s = '%s'\n", pair->first.c_str(), pair->second.c_str()); | |
257 | + } | |
258 | + fclose(fp); | |
259 | + } | |
260 | +} |
@@ -29,8 +29,13 @@ struct PUBLIC settings_t | ||
29 | 29 | return get<std::string>(key, defaultValue); |
30 | 30 | } |
31 | 31 | |
32 | + static void set (std::string const& key, std::string const& value, std::string const& fileType = NULL_STR, std::string const& path = NULL_STR); | |
33 | + static void set (std::string const& key, double decimal, std::string const& fileType = NULL_STR, std::string const& path = NULL_STR) { settings_t::set(key, text::format("%f", decimal), fileType, path); } | |
34 | + static void set (std::string const& key, size_t number, std::string const& fileType = NULL_STR, std::string const& path = NULL_STR) { settings_t::set(key, text::format("%zu", number), fileType, path); } | |
35 | + static void set (std::string const& key, int32_t number, std::string const& fileType = NULL_STR, std::string const& path = NULL_STR) { settings_t::set(key, text::format("%d", number), fileType, path); } | |
36 | + static void set (std::string const& key, bool flag, std::string const& fileType = NULL_STR, std::string const& path = NULL_STR) { settings_t::set(key, std::string(flag ? "true" : "false"), fileType, path); } | |
37 | + | |
32 | 38 | private: |
33 | - friend settings_t settings_for_path (std::string const& documentPath, std::map<std::string, std::string> const& variables); | |
34 | 39 | std::map<std::string, std::string> settings; |
35 | 40 | |
36 | 41 | static bool convert (std::string const& value, bool) { return value != "0" && value != "false" ? true : false; } |