osappdirs.nim 5.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177
  1. ## .. importdoc:: paths.nim, dirs.nim
  2. include system/inclrtl
  3. import std/envvars
  4. import std/private/ospaths2
  5. proc getHomeDir*(): string {.rtl, extern: "nos$1",
  6. tags: [ReadEnvEffect, ReadIOEffect].} =
  7. ## Returns the home directory of the current user.
  8. ##
  9. ## This proc is wrapped by the `expandTilde proc`_
  10. ## for the convenience of processing paths coming from user configuration files.
  11. ##
  12. ## See also:
  13. ## * `getDataDir proc`_
  14. ## * `getConfigDir proc`_
  15. ## * `getTempDir proc`_
  16. ## * `expandTilde proc`_
  17. ## * `getCurrentDir proc`_
  18. ## * `setCurrentDir proc`_
  19. runnableExamples:
  20. import std/os
  21. assert getHomeDir() == expandTilde("~")
  22. when defined(windows): return getEnv("USERPROFILE") & "\\"
  23. else: return getEnv("HOME") & "/"
  24. proc getDataDir*(): string {.rtl, extern: "nos$1"
  25. tags: [ReadEnvEffect, ReadIOEffect].} =
  26. ## Returns the data directory of the current user for applications.
  27. ##
  28. ## On non-Windows OSs, this proc conforms to the XDG Base Directory
  29. ## spec. Thus, this proc returns the value of the `XDG_DATA_HOME` environment
  30. ## variable if it is set, otherwise it returns the default configuration
  31. ## directory ("~/.local/share" or "~/Library/Application Support" on macOS).
  32. ##
  33. ## See also:
  34. ## * `getHomeDir proc`_
  35. ## * `getConfigDir proc`_
  36. ## * `getTempDir proc`_
  37. ## * `expandTilde proc`_
  38. ## * `getCurrentDir proc`_
  39. ## * `setCurrentDir proc`_
  40. when defined(windows):
  41. result = getEnv("APPDATA")
  42. elif defined(macosx):
  43. result = getEnv("XDG_DATA_HOME", getEnv("HOME") / "Library" / "Application Support")
  44. else:
  45. result = getEnv("XDG_DATA_HOME", getEnv("HOME") / ".local" / "share")
  46. result.normalizePathEnd(trailingSep = true)
  47. proc getConfigDir*(): string {.rtl, extern: "nos$1",
  48. tags: [ReadEnvEffect, ReadIOEffect].} =
  49. ## Returns the config directory of the current user for applications.
  50. ##
  51. ## On non-Windows OSs, this proc conforms to the XDG Base Directory
  52. ## spec. Thus, this proc returns the value of the `XDG_CONFIG_HOME` environment
  53. ## variable if it is set, otherwise it returns the default configuration
  54. ## directory ("~/.config/").
  55. ##
  56. ## An OS-dependent trailing slash is always present at the end of the
  57. ## returned string: `\\` on Windows and `/` on all other OSs.
  58. ##
  59. ## See also:
  60. ## * `getHomeDir proc`_
  61. ## * `getDataDir proc`_
  62. ## * `getTempDir proc`_
  63. ## * `expandTilde proc`_
  64. ## * `getCurrentDir proc`_
  65. ## * `setCurrentDir proc`_
  66. when defined(windows):
  67. result = getEnv("APPDATA")
  68. else:
  69. result = getEnv("XDG_CONFIG_HOME", getEnv("HOME") / ".config")
  70. result.normalizePathEnd(trailingSep = true)
  71. proc getCacheDir*(): string =
  72. ## Returns the cache directory of the current user for applications.
  73. ##
  74. ## This makes use of the following environment variables:
  75. ##
  76. ## * On Windows: `getEnv("LOCALAPPDATA")`
  77. ##
  78. ## * On macOS: `getEnv("XDG_CACHE_HOME", getEnv("HOME") / "Library/Caches")`
  79. ##
  80. ## * On other platforms: `getEnv("XDG_CACHE_HOME", getEnv("HOME") / ".cache")`
  81. ##
  82. ## **See also:**
  83. ## * `getHomeDir proc`_
  84. ## * `getTempDir proc`_
  85. ## * `getConfigDir proc`_
  86. ## * `getDataDir proc`_
  87. # follows https://crates.io/crates/platform-dirs
  88. when defined(windows):
  89. result = getEnv("LOCALAPPDATA")
  90. elif defined(osx):
  91. result = getEnv("XDG_CACHE_HOME", getEnv("HOME") / "Library/Caches")
  92. else:
  93. result = getEnv("XDG_CACHE_HOME", getEnv("HOME") / ".cache")
  94. result.normalizePathEnd(false)
  95. proc getCacheDir*(app: string): string =
  96. ## Returns the cache directory for an application `app`.
  97. ##
  98. ## * On Windows, this uses: `getCacheDir() / app / "cache"`
  99. ## * On other platforms, this uses: `getCacheDir() / app`
  100. when defined(windows):
  101. getCacheDir() / app / "cache"
  102. else:
  103. getCacheDir() / app
  104. when defined(windows):
  105. type DWORD = uint32
  106. when defined(nimPreviewSlimSystem):
  107. import std/widestrs
  108. proc getTempPath(
  109. nBufferLength: DWORD, lpBuffer: WideCString
  110. ): DWORD {.stdcall, dynlib: "kernel32.dll", importc: "GetTempPathW".} =
  111. ## Retrieves the path of the directory designated for temporary files.
  112. template getEnvImpl(result: var string, tempDirList: openArray[string]) =
  113. for dir in tempDirList:
  114. if existsEnv(dir):
  115. result = getEnv(dir)
  116. break
  117. template getTempDirImpl(result: var string) =
  118. when defined(windows):
  119. getEnvImpl(result, ["TMP", "TEMP", "USERPROFILE"])
  120. else:
  121. getEnvImpl(result, ["TMPDIR", "TEMP", "TMP", "TEMPDIR"])
  122. proc getTempDir*(): string {.rtl, extern: "nos$1",
  123. tags: [ReadEnvEffect, ReadIOEffect].} =
  124. ## Returns the temporary directory of the current user for applications to
  125. ## save temporary files in.
  126. ##
  127. ## On Windows, it calls [GetTempPath](https://docs.microsoft.com/en-us/windows/win32/api/fileapi/nf-fileapi-gettemppathw).
  128. ## On Posix based platforms, it will check `TMPDIR`, `TEMP`, `TMP` and `TEMPDIR` environment variables in order.
  129. ## On all platforms, `/tmp` will be returned if the procs fails.
  130. ##
  131. ## You can override this implementation
  132. ## by adding `-d:tempDir=mytempname` to your compiler invocation.
  133. ##
  134. ## **Note:** This proc does not check whether the returned path exists.
  135. ##
  136. ## See also:
  137. ## * `getHomeDir proc`_
  138. ## * `getConfigDir proc`_
  139. ## * `expandTilde proc`_
  140. ## * `getCurrentDir proc`_
  141. ## * `setCurrentDir proc`_
  142. const tempDirDefault = "/tmp"
  143. when defined(tempDir):
  144. const tempDir {.strdefine.}: string = tempDirDefault
  145. result = tempDir
  146. else:
  147. when nimvm:
  148. getTempDirImpl(result)
  149. else:
  150. when defined(windows):
  151. let size = getTempPath(0, nil)
  152. # If the function fails, the return value is zero.
  153. if size > 0:
  154. let buffer = newWideCString(size.int)
  155. if getTempPath(size, buffer) > 0:
  156. result = $buffer
  157. elif defined(android): result = "/data/local/tmp"
  158. else:
  159. getTempDirImpl(result)
  160. if result.len == 0:
  161. result = tempDirDefault
  162. normalizePathEnd(result, trailingSep=true)