1 module creator.core.path; 2 import std.path; 3 import std.process; 4 import std.file : getcwd, mkdirRecurse, exists; 5 6 private { 7 string cachedConfigDir; 8 string cachedImguiFileDir; 9 string cachedFontDir; 10 string cachedLocaleDir; 11 string inForcedConfigDir; 12 } 13 14 /** 15 The name of the folder inochi creator config gets thrown in to. 16 */ 17 enum APP_FOLDER_NAME = "inochi-creator"; 18 19 /** 20 Name of environment variable to force a configuration path 21 */ 22 enum ENV_CONFIG_PATH = "INOCHI_CONFIG_PATH"; 23 24 /** 25 Returns the app configuration directory for the platform 26 */ 27 string incGetAppConfigPath() { 28 if (cachedConfigDir) return cachedConfigDir; 29 if (inForcedConfigDir) return inForcedConfigDir; 30 string appDataDir; 31 32 // Once this function has completed cache the result. 33 scope(success) { 34 35 if (inForcedConfigDir) { 36 37 // Also make sure the folder exists 38 if (!exists(inForcedConfigDir)) { 39 mkdirRecurse(inForcedConfigDir); 40 } 41 } else { 42 cachedConfigDir = appDataDir; 43 44 // Also make sure the folder exists 45 if (!exists(cachedConfigDir)) { 46 mkdirRecurse(cachedConfigDir); 47 } 48 } 49 } 50 51 // On Windows %AppData% is used. 52 // Example: C:/Users/USERNAME/AppData/Roaming/.inochi-creatorS 53 version(Windows) { 54 appDataDir = environment.get("AppData"); 55 } 56 57 // On Linux the app data dir is in $XDG_CONFIG_DIR, $HOME/.config or $HOME 58 // Example: /home/USERNAME/.inochi-creator 59 else version(linux) { 60 appDataDir = environment.get("XDG_CONFIG_HOME"); 61 if (!appDataDir) appDataDir = buildPath(environment.get("HOME"), ".config"); 62 } 63 64 // On macOS things are thrown in to $HOME/Library/Application Support 65 // Example: /home/USERNAME/Library/Application Support/.inochi-creator 66 else version(OSX) { 67 appDataDir = environment.get("HOME"); 68 if (appDataDir) appDataDir = buildPath(appDataDir, "Library", "Application Support"); 69 } 70 71 // On other POSIX platforms just assume $HOME exists. 72 // Example: /home/USERNAME/.inochi-creator 73 else version(posix) { 74 appDataDir = environment.get("HOME"); 75 } 76 77 // Allow packagers, etc. to specify a forced config directory. 78 inForcedConfigDir = environment.get(ENV_CONFIG_PATH); 79 if (inForcedConfigDir) return inForcedConfigDir; 80 81 82 if (!appDataDir) appDataDir = getcwd(); 83 84 version(linux) { 85 86 // On linux we're using standard XDG dirs, prior we 87 // used .inochi-creator there, but that's not correct 88 // This code will ensure we still use old config if it's there. 89 // Otherwise we create config for the *correct* path 90 string fdir = buildPath(appDataDir, "."~APP_FOLDER_NAME); 91 if (!exists(fdir)) fdir = buildPath(appDataDir, APP_FOLDER_NAME); 92 appDataDir = fdir; 93 return appDataDir; 94 } else version(OSX) { 95 96 // On OSX we're using standard directories, prior we 97 // used .inochi-creator there, but that's not correct 98 // This code will ensure we still use old config if it's there. 99 // Otherwise we create config for the *correct* path 100 string fdir = buildPath(appDataDir, "."~APP_FOLDER_NAME); 101 if (!exists(fdir)) fdir = buildPath(appDataDir, APP_FOLDER_NAME); 102 appDataDir = fdir; 103 return appDataDir; 104 } else { 105 106 // On other platforms we go for .(app name) 107 appDataDir = buildPath(appDataDir, "."~APP_FOLDER_NAME); 108 return appDataDir; 109 } 110 } 111 112 /** 113 Gets the directory for an imgui config file. 114 */ 115 string incGetAppImguiConfigFile() { 116 if (cachedImguiFileDir) return cachedImguiFileDir; 117 cachedImguiFileDir = buildPath(incGetAppConfigPath(), "imgui.ini"); 118 return cachedImguiFileDir; 119 } 120 121 /** 122 Gets directory for custom fonts 123 */ 124 string incGetAppFontsPath() { 125 if (cachedFontDir) return cachedFontDir; 126 cachedFontDir = buildPath(incGetAppConfigPath(), "fonts"); 127 if (!exists(cachedFontDir)) { 128 129 // Create our font directory 130 mkdirRecurse(cachedFontDir); 131 } 132 return cachedFontDir; 133 } 134 135 /** 136 Gets directory for custom locales 137 */ 138 string incGetAppLocalePath() { 139 if (cachedLocaleDir) return cachedLocaleDir; 140 141 cachedLocaleDir = buildPath(incGetAppConfigPath(), "i18n"); 142 if (!exists(cachedLocaleDir)) { 143 144 // Create our font directory 145 mkdirRecurse(cachedLocaleDir); 146 } 147 return cachedLocaleDir; 148 } 149 150 /** 151 Gets special directory for locales 152 */ 153 string incGetAppLocalePathExtra() { 154 155 // AppImage locale dir is the root of the appimage 156 version(linux) { 157 auto here = environment.get("HERE"); 158 if (here) { 159 return here; 160 } 161 } 162 163 return null; 164 }