1 //this file is part of notepad++ 2 //Copyright (C)2003 Don HO <donho@altern.org> 3 // 4 //This program is free software; you can redistribute it and/or 5 //modify it under the terms of the GNU General Public License 6 //as published by the Free Software Foundation; either 7 //version 2 of the License, or (at your option) any later version. 8 // 9 //This program is distributed in the hope that it will be useful, 10 //but WITHOUT ANY WARRANTY; without even the implied warranty of 11 //MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 12 //GNU General Public License for more details. 13 // 14 //You should have received a copy of the GNU General Public License 15 //along with this program; if not, write to the Free Software 16 //Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. 17 /** 18 * npp menu 19 * 20 * Author: dokutoku, https://twitter.com/dokutoku3 21 * License: GPL-2.0 or later 22 */ 23 module npp_api.pluginfunc.path; 24 25 26 version (Windows): 27 version (Not_betterC): 28 29 private static import core.sys.windows.winbase; 30 private static import core.sys.windows.windef; 31 private static import core.sys.windows.winnt; 32 private static import npp_api.PowerEditor.MISC.PluginsManager.PluginInterface; 33 private static import npp_api.pluginfunc.npp_msgs; 34 private static import npp_api.pluginfunc.string; 35 private static import std.algorithm; 36 private static import std.array; 37 private static import std.file; 38 private static import std.path; 39 private static import std.process; 40 private static import std.string; 41 42 enum OS_MAX_PATH = 32768; 43 44 /** 45 * get file path 46 */ 47 nothrow @nogc 48 bool get_full_current_path(core.sys.windows.windef.HWND _nppHandle, ref core.sys.windows.winnt.WCHAR[.OS_MAX_PATH] path_temp) 49 50 do 51 { 52 path_temp[] = '\0'; 53 54 if (npp_api.pluginfunc.npp_msgs.send_NPPM_GETFULLCURRENTPATH(_nppHandle, .OS_MAX_PATH, &(path_temp[0])) == core.sys.windows.windef.TRUE) { 55 return true; 56 } else { 57 return false; 58 } 59 } 60 61 nothrow 62 wstring get_file_path(core.sys.windows.windef.HWND _nppHandle) 63 64 do 65 { 66 core.sys.windows.winnt.WCHAR[.OS_MAX_PATH] path_temp; 67 68 if (.get_full_current_path(_nppHandle, path_temp)) { 69 return npp_api.pluginfunc..string.from_stringz(path_temp); 70 } else { 71 return null; 72 } 73 } 74 75 nothrow 76 wstring get_directory_path(core.sys.windows.windef.HWND _nppHandle) 77 78 do 79 { 80 core.sys.windows.winnt.WCHAR[.OS_MAX_PATH] path_temp; 81 82 if (npp_api.pluginfunc.npp_msgs.send_NPPM_GETCURRENTDIRECTORY(_nppHandle, .OS_MAX_PATH, &(path_temp[0])) == core.sys.windows.windef.TRUE) { 83 return npp_api.pluginfunc..string.from_stringz(path_temp); 84 } else { 85 return null; 86 } 87 } 88 89 pure nothrow @safe 90 private immutable (C)[][] c_names(C)(const C[][] input) 91 92 do 93 { 94 immutable (C)[][] output = new immutable (C)[][input.length]; 95 96 for (size_t i = 0; i < input.length; i++) { 97 output[i] = (input[i] ~ '\0').idup; 98 } 99 100 return output; 101 } 102 103 deprecated 104 alias create_variable_identifiers = .create_variable_ids; 105 106 pure nothrow @safe 107 private immutable (C)[][] create_variable_ids(C)(const C[][] input) 108 109 do 110 { 111 immutable (C)[][] output = new immutable (C)[][input.length]; 112 113 for (size_t i = 0; i < input.length; i++) { 114 output[i] = ('%' ~ input[i] ~ '%').idup; 115 } 116 117 return output; 118 } 119 120 enum wstring[] windows_variable_names = 121 [ 122 `ALLUSERSPROFILE`w, 123 `APPDATA`w, 124 `CommonProgramFiles`w, 125 `CommonProgramFiles(x86)`w, 126 `CommonProgramW6432`w, 127 `COMPUTERNAME`w, 128 `ComSpec`w, 129 `DriverData`w, 130 `HOMEDRIVE`w, 131 `HOMEPATH`w, 132 `LOCALAPPDATA`w, 133 `LOGONSERVER`w, 134 `NUMBER_OF_PROCESSORS`w, 135 `OneDrive`w, 136 `OS`w, 137 `Path`w, 138 `PATHEXT`w, 139 `PROCESSOR_ARCHITECTURE`w, 140 `PROCESSOR_ARCHITEW6432`w, 141 `PROCESSOR_IDENTIFIER`w, 142 `PROCESSOR_LEVEL`w, 143 `PROCESSOR_REVISION`w, 144 `ProgramData`w, 145 `ProgramFiles`w, 146 `ProgramFiles(x86)`w, 147 `ProgramW6432`w, 148 `PROMPT`w, 149 `PSModulePath`w, 150 `PUBLIC`w, 151 `SESSIONNAME`w, 152 `SystemDrive`w, 153 `SystemRoot`w, 154 `TEMP`w, 155 `TMP`w, 156 `USERDOMAIN`w, 157 `USERDOMAIN_ROAMINGPROFILE`w, 158 `USERNAME`w, 159 `USERPROFILE`w, 160 `windir`w, 161 ]; 162 163 enum wstring[] windows_variable_wnames = c_names!(wchar)(windows_variable_names); 164 enum wstring[] windows_variables = create_variable_ids!(wchar)(windows_variable_names); 165 166 pure nothrow @safe @nogc 167 private size_t max_length(wstring[] list) 168 169 do 170 { 171 size_t max_length = 0; 172 173 for (size_t i = 0; i < list.length; i++) { 174 if (list[i].length > max_length) { 175 max_length = list[i].length; 176 } 177 } 178 179 return max_length; 180 } 181 182 nothrow 183 wstring echo_variables(wstring name) 184 185 do 186 { 187 enum buf_length = max_length(windows_variable_names) + 1; 188 189 core.sys.windows.winnt.WCHAR[buf_length] name_buf = '\0'; 190 core.sys.windows.winnt.WCHAR[.OS_MAX_PATH] buf = '\0'; 191 192 if (name.length > buf_length) { 193 return null; 194 } 195 196 npp_api.pluginfunc..string.copy_string(name_buf, name); 197 198 core.sys.windows.windef.DWORD Environment_length = core.sys.windows.winbase.GetEnvironmentVariableW(&(name_buf[0]), &(buf[0]), buf.length); 199 200 if (Environment_length == 0) { 201 return null; 202 } 203 204 return buf[0 .. Environment_length].idup; 205 } 206 207 nothrow 208 wstring repalce_variables(wstring path) 209 210 do 211 { 212 if (path == null) { 213 return path; 214 } 215 216 try { 217 if (!std.algorithm.canFind(path, '%')) { 218 return path; 219 } 220 } catch (Exception e) { 221 //ToDo: 222 return path; 223 } 224 225 core.sys.windows.winnt.WCHAR[.OS_MAX_PATH] buf = '\0'; 226 core.sys.windows.winnt.WCHAR[.OS_MAX_PATH] output_buf = '\0'; 227 228 for (size_t i = 0; i < windows_variable_wnames.length; i++) { 229 try { 230 if (!std.algorithm.canFind(path, windows_variables[i])) { 231 continue; 232 } 233 } catch (Exception e) { 234 //ToDo: 235 continue; 236 } 237 238 core.sys.windows.windef.DWORD Environment_length = core.sys.windows.winbase.GetEnvironmentVariableW(&(windows_variable_wnames[i][0]), &(buf[0]), buf.length); 239 240 if (Environment_length == 0) { 241 continue; 242 } 243 244 path = std.array.replace(path, windows_variables[i], buf[0 .. Environment_length]).idup; 245 } 246 247 return path; 248 } 249 250 /** 251 * search exe file from "PATH" 252 */ 253 nothrow 254 wstring search_exe(const wchar[] exe_name, wstring default_name = null) 255 256 in 257 { 258 assert(exe_name.length != 0); 259 260 for (size_t i = 0; i < exe_name.length; i++) { 261 assert(exe_name[i] != '\\'); 262 } 263 } 264 265 do 266 { 267 //dlang GC Bug? 268 version (none) { 269 //ToDo: インストールされたものの中から検索 270 try { 271 core.sys.windows.winnt.WCHAR[.OS_MAX_PATH] buf = '\0'; 272 core.sys.windows.windef.DWORD Environment_length = core.sys.windows.winbase.GetEnvironmentVariableW(&(npp_api.pluginfunc..string.c_wstring!(`PATH`w)[0]), &(buf[0]), buf.length); 273 274 if (Environment_length == 0) { 275 return (default_name != null) ? (default_name) : (exe_name.idup); 276 } 277 278 wstring[] PATH_directory = std.array.split(buf[0 .. Environment_length].idup, ';'); 279 280 foreach (PATH; PATH_directory) { 281 if ((!std.file.exists(PATH)) || (!std.file.isDir(PATH))) { 282 continue; 283 } 284 285 wstring file_exe = std.path.buildPath(PATH, exe_name); 286 287 if ((!std.file.exists(file_exe)) || (!std.file.isFile(file_exe))) { 288 continue; 289 } 290 291 return file_exe.idup; 292 } 293 } catch (Exception e) { 294 //ToDo: 295 } 296 297 return (default_name != null) ? (default_name) : (exe_name.idup); 298 } else { 299 return (default_name != null) ? (default_name) : (exe_name.idup); 300 } 301 } 302 303 //ToDo: dlang GC bug? 304 @disable 305 nothrow 306 string search_exe(const char[] exe_name, string default_name = null) 307 308 in 309 { 310 assert(exe_name.length != 0); 311 312 for (size_t i = 0; i < exe_name.length; i++) { 313 assert(exe_name[i] != '\\'); 314 } 315 } 316 317 do 318 { 319 try { 320 string[] PATH_directory = std.array.split(std.process.environment[`PATH`], ';'); 321 322 foreach (PATH; PATH_directory) { 323 if ((!std.file.exists(PATH)) || (!std.file.isDir(PATH))) { 324 continue; 325 } 326 327 string file_exe = std.path.buildPath(PATH, exe_name); 328 329 if ((!std.file.exists(file_exe)) || (!std.file.isFile(file_exe))) { 330 continue; 331 } 332 333 return file_exe.idup; 334 } 335 } catch (Exception e) { 336 } 337 338 return (default_name != null) ? (default_name) : (exe_name.idup); 339 }