1 module dlangide.workspace.idesettings;
2 
3 import dlangui.core.settings;
4 import dlangui.core.i18n;
5 import dlangui.graphics.fonts;
6 
7 import std.algorithm : equal;
8 
9 const AVAILABLE_THEMES = ["ide_theme_default", "ide_theme_dark"];
10 const AVAILABLE_LANGUAGES = ["en", "ru", "es", "cs"];
11 
12 class IDESettings : SettingsFile {
13 
14     this(string filename) {
15         super(filename);
16     }
17 
18     override void updateDefaults() {
19         Setting ed = editorSettings();
20         ed.setBooleanDef("useSpacesForTabs", true);
21         ed.setIntegerDef("tabSize", 4);
22         ed.setBooleanDef("smartIndents", true);
23         ed.setBooleanDef("smartIndentsAfterPaste", true);
24         ed.setBooleanDef("showWhiteSpaceMarks", true);
25         ed.setBooleanDef("showTabPositionMarks", true);
26         ed.setStringDef("fontFace", "Default");
27         Setting ui = uiSettings();
28         ui.setStringDef("theme", "ide_theme_default");
29         ui.setStringDef("language", "en");
30         ui.setIntegerDef("hintingMode", 1);
31         ui.setIntegerDef("minAntialiasedFontSize", 0);
32         ui.setFloatingDef("fontGamma", 0.8);
33         version (Windows) {
34             debuggerSettings.setStringDef("executable", "mago-mi");
35         } else {
36             debuggerSettings.setStringDef("executable", "gdb");
37         }
38         terminalSettings.setStringDef("executable", "xterm");
39         dubSettings.setStringDef("executable", "dub");
40         dubSettings.setStringDef("additional_params", "");
41         rdmdSettings.setStringDef("executable", "rdmd");
42         rdmdSettings.setStringDef("additional_params", "");
43         dmdToolchainSettings.setStringDef("executable", "dmd");
44         dmdToolchainSettings.setStringDef("dub_additional_params", "");
45         ldcToolchainSettings.setStringDef("executable", "ldc2");
46         ldcToolchainSettings.setStringDef("dub_additional_params", "");
47         ldmdToolchainSettings.setStringDef("executable", "ldmd2");
48         ldmdToolchainSettings.setStringDef("dub_additional_params", "");
49         gdcToolchainSettings.setStringDef("executable", "gdc");
50         gdcToolchainSettings.setStringDef("dub_additional_params", "");
51     }
52 
53     /// override to do something after loading - e.g. set defaults
54     override void afterLoad() {
55     }
56     
57     @property Setting editorSettings() {
58         Setting res = _setting.objectByPath("editors/textEditor", true);
59         return res;
60     }
61 
62     @property Setting uiSettings() {
63         Setting res = _setting.objectByPath("interface", true);
64         return res;
65     }
66 
67     @property Setting debuggerSettings() {
68         Setting res = _setting.objectByPath("dlang/debugger", true);
69         return res;
70     }
71 
72     @property Setting terminalSettings() {
73         Setting res = _setting.objectByPath("dlang/terminal", true);
74         return res;
75     }
76 
77     @property Setting dubSettings() {
78         Setting res = _setting.objectByPath("dlang/dub", true);
79         return res;
80     }
81 
82     @property Setting rdmdSettings() {
83         Setting res = _setting.objectByPath("dlang/rdmd", true);
84         return res;
85     }
86 
87     @property Setting dmdToolchainSettings() {
88         Setting res = _setting.objectByPath("dlang/toolchains/dmd", true);
89         return res;
90     }
91 
92     @property Setting ldcToolchainSettings() {
93         Setting res = _setting.objectByPath("dlang/toolchains/ldc", true);
94         return res;
95     }
96 
97     @property Setting ldmdToolchainSettings() {
98         Setting res = _setting.objectByPath("dlang/toolchains/ldmd", true);
99         return res;
100     }
101 
102     @property Setting gdcToolchainSettings() {
103         Setting res = _setting.objectByPath("dlang/toolchains/gdc", true);
104         return res;
105     }
106 
107     /// theme
108     @property string uiTheme() {
109         return limitString(uiSettings.getString("theme", "ide_theme_default"), AVAILABLE_THEMES);
110     }
111     /// theme
112     @property IDESettings uiTheme(string v) {
113         uiSettings.setString("theme", limitString(v, AVAILABLE_THEMES));
114         return this;
115     }
116 
117     /// language
118     @property string uiLanguage() {
119         return limitString(uiSettings.getString("language", "en"), AVAILABLE_LANGUAGES);
120     }
121     /// language
122     @property IDESettings uiLanguage(string v) {
123         uiSettings.setString("language", limitString(v, AVAILABLE_LANGUAGES));
124         return this;
125     }
126 
127     /// text editor setting, true if need to insert spaces instead of tabs
128     @property bool useSpacesForTabs() {
129         return editorSettings.getBoolean("useSpacesForTabs", true);
130     }
131     /// text editor setting, true if need to insert spaces instead of tabs
132     @property IDESettings useSpacesForTabs(bool v) {
133         editorSettings.setBoolean("useSpacesForTabs", v);
134         return this;
135     }
136 
137     /// text editor setting, true if need to insert spaces instead of tabs
138     @property int tabSize() {
139         return limitInt(editorSettings.getInteger("tabSize", 4), 1, 16);
140     }
141     /// text editor setting, true if need to insert spaces instead of tabs
142     @property IDESettings tabSize(int v) {
143         editorSettings.setInteger("tabSize", limitInt(v, 1, 16));
144         return this;
145     }
146 
147     /// true if smart indents are enabled
148     @property bool smartIndents() { return editorSettings.getBoolean("smartIndents", true); }
149     /// set smart indents enabled flag
150     @property IDESettings smartIndents(bool enabled) { editorSettings.setBoolean("smartIndents", enabled); return this; }
151 
152     /// true if white space marks are enabled
153     @property bool showWhiteSpaceMarks() { return editorSettings.getBoolean("showWhiteSpaceMarks", true); }
154     /// set white space marks enabled flag
155     @property IDESettings showWhiteSpaceMarks(bool enabled) { editorSettings.setBoolean("showWhiteSpaceMarks", enabled); return this; }
156 
157     /// true if tab position marks are enabled
158     @property bool showTabPositionMarks() { return editorSettings.getBoolean("showTabPositionMarks", true); }
159     /// set tab position marks enabled flag
160     @property IDESettings showTabPositionMarks(bool enabled) { editorSettings.setBoolean("showTabPositionMarks", enabled); return this; }
161     /// string value of font face
162     @property string editorFontFace() { return editorSettings.getString("fontFace", "Default"); }
163 
164     
165 
166     /// true if smart indents are enabled
167     @property bool smartIndentsAfterPaste() { return editorSettings.getBoolean("smartIndentsAfterPaste", true); }
168     /// set smart indents enabled flag
169     @property IDESettings smartIndentsAfterPaste(bool enabled) { editorSettings.setBoolean("smartIndentsAfterPaste", enabled); return this; }
170 
171     @property double fontGamma() {
172         double gamma = uiSettings.getFloating("fontGamma", 1.0);
173         if (gamma >= 0.5 && gamma <= 2.0)
174             return gamma;
175         return 1.0;
176     }
177 
178     @property HintingMode hintingMode() {
179         long mode = uiSettings.getInteger("hintingMode", HintingMode.Normal);
180         if (mode >= HintingMode.Normal && mode <= HintingMode.Light)
181             return cast(HintingMode)mode;
182         return HintingMode.Normal;
183     }
184 
185     @property int minAntialiasedFontSize() {
186         long sz = uiSettings.getInteger("minAntialiasedFontSize", 0);
187         if (sz >= 0)
188             return cast(int)sz;
189         return 0;
190     }
191 
192     @property string debuggerExecutable() {
193         version (Windows) {
194             return debuggerSettings.getString("executable", "mago-mi");
195         } else {
196             return debuggerSettings.getString("executable", "gdb");
197         }
198     }
199 
200     @property string terminalExecutable() {
201         return terminalSettings.getString("executable", "xterm");
202     }
203 
204     @property string dubExecutable() {
205         return dubSettings.getString("executable", "dub");
206     }
207 
208     @property string dubAdditionalParams() {
209         return dubSettings.getString("additional_params", "");
210     }
211 
212     @property string rdmdExecutable() {
213         return rdmdSettings.getString("executable", "rdmd");
214     }
215 
216     @property string rdmdAdditionalParams() {
217         return rdmdSettings.getString("additional_params", "");
218     }
219 
220     string getToolchainCompilerExecutable(string toolchainName) {
221         if (toolchainName.equal("dmd"))
222             return dmdToolchainSettings.getString("executable", "dmd");
223         if (toolchainName.equal("gdc"))
224             return gdcToolchainSettings.getString("executable", "gdc");
225         if (toolchainName.equal("ldc"))
226             return ldcToolchainSettings.getString("executable", "ldc2");
227         if (toolchainName.equal("ldmd"))
228             return ldmdToolchainSettings.getString("executable", "ldmd2");
229         return null;
230     }
231 
232     string getToolchainAdditionalDubParams(string toolchainName) {
233         if (toolchainName.equal("dmd"))
234             return dmdToolchainSettings.getString("dub_additional_params", "");
235         if (toolchainName.equal("gdc"))
236             return gdcToolchainSettings.getString("dub_additional_params", "");
237         if (toolchainName.equal("ldc"))
238             return ldcToolchainSettings.getString("dub_additional_params", "");
239         if (toolchainName.equal("ldmd"))
240             return ldmdToolchainSettings.getString("dub_additional_params", "");
241         return null;
242     }
243 
244     /// get recent path for category name, returns null if not found
245     @property string getRecentPath(string category = "FILE_OPEN_DLG_PATH") {
246         Setting obj = _setting.objectByPath("pathHistory", true);
247         return obj.getString(category, null);
248     }
249 
250     /// set recent path for category name
251     @property void setRecentPath(string value, string category = "FILE_OPEN_DLG_PATH") {
252         Setting obj = _setting.objectByPath("pathHistory", true);
253         obj.setString(category, value);
254         save();
255     }
256 
257     @property string[] recentWorkspaces() {
258         import std.file;
259         Setting obj = _setting.objectByPath("history", true);
260         string[] list = obj.getStringArray("recentWorkspaces");
261         string[] res;
262         foreach(fn; list) {
263             if (exists(fn) && isFile(fn))
264                 res ~= fn;
265         }
266         return res;
267     }
268 
269     void updateRecentWorkspace(string ws) {
270         import std.file;
271         string[] list;
272         list ~= ws;
273         string[] existing = recentWorkspaces;
274         foreach(fn; existing) {
275             if (exists(fn) && isFile(fn) && !ws.equal(fn))
276                 list ~= fn;
277         }
278         Setting obj = _setting.objectByPath("history", true);
279         obj["recentWorkspaces"] = list;
280         save();
281     }
282     
283     @property bool autoOpenLastProject() {
284         Setting obj =_setting.objectByPath("common", true);
285         return obj.getBoolean("autoOpenLastProject", false);
286     }
287 
288     @property void autoOpenLastProject(bool value) {
289         Setting obj =_setting.objectByPath("common", true);
290         obj.setBoolean("autoOpenLastProject", value);
291     }
292 }
293