osappdirs.nim 4.8 KB

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