Klimi's new dotfiles with stow.
Nelze vybrat více než 25 témat Téma musí začínat písmenem nebo číslem, může obsahovat pomlčky („-“) a může být dlouhé až 35 znaků.

258 řádky
7.4 KiB

před 4 roky
  1. ;;; nix-shell.el -- run nix commands in Emacs -*- lexical-binding: t -*-
  2. ;; Author: Matthew Bauer <mjbauer95@gmail.com>
  3. ;; Homepage: https://github.com/NixOS/nix-mode
  4. ;; Keywords: nix
  5. ;; Version: 1.4.0
  6. ;; This file is NOT part of GNU Emacs.
  7. ;;; Commentary:
  8. ;; To use this just run:
  9. ;; M-x RET nix-shell RET
  10. ;; This will give you some
  11. ;;; Code:
  12. (require 'nix)
  13. (require 'nix-instantiate)
  14. (require 'nix-store)
  15. ;; Tell the byte compiler these are dynamically bound
  16. (defvar woman-manpath)
  17. (defvar Man-header-file-path)
  18. (defvar irony-additional-clang-options)
  19. (defvar eshell-path-env)
  20. (defvar ffap-c-path)
  21. (defgroup nix-shell nil
  22. "All nix-shell options."
  23. :group 'nix)
  24. (defcustom nix-shell-inputs '(depsBuildBuild
  25. depsBuildBuildPropagated
  26. nativeBuildInputs
  27. propagatedNativeBuildInputs
  28. depsBuildTarget
  29. depsBuildTargetPropagated)
  30. "List of inputs to collect for nix-shell."
  31. :type 'list
  32. :group 'nix-shell)
  33. (defcustom nix-shell-clear-environment nil
  34. "Whether to clear the old ‘exec-path’ & environment.
  35. Similar to --pure argument in command line nix-shell."
  36. :type 'boolean
  37. :group 'nix-shell)
  38. (defcustom nix-shell-auto-realise t
  39. "Whether we can realise paths in the built .drv file."
  40. :type 'boolean
  41. :group 'nix-shell)
  42. (defcustom nix-file nil
  43. "Nix file to build expressions from.
  44. Should only be set in dir-locals.el file."
  45. :type 'stringp
  46. :group 'nix-shell)
  47. (defcustom nix-attr nil
  48. "Nix attribute path to use.
  49. Should only be set in dir-locals.el file."
  50. :type 'stringp
  51. :group 'nix-shell)
  52. ;;;###autoload
  53. (defun nix-shell-unpack (file attr)
  54. "Run Nix’s unpackPhase.
  55. FILE is the file to unpack from.
  56. ATTR is the attribute to unpack."
  57. (interactive (list (nix-read-file) nil))
  58. (unless attr (setq attr (nix-read-attr file)))
  59. (nix-shell--run-phase "unpack" file attr))
  60. (defun nix-read-attr (_)
  61. "Get nix attribute from user."
  62. (read-string "Nix attr: "))
  63. (defun nix-read-file ()
  64. "Get nix file from user."
  65. (cond
  66. (nix-file nix-file)
  67. ((file-exists-p "shell.nix") "shell.nix")
  68. ((file-exists-p "default.nix") "default.nix")
  69. (t (read-file-name "Nix file: " nil "<nixpkgs>"))))
  70. ;;;###autoload
  71. (defun nix-shell-configure (file attr)
  72. "Run Nix’s configurePhase.
  73. FILE is the file to configure from.
  74. ATTR is the attribute to configure."
  75. (interactive (list (nix-read-file) nil))
  76. (unless attr (setq attr (nix-read-attr file)))
  77. (nix-shell--run-phase "configure" file attr))
  78. ;;;###autoload
  79. (defun nix-shell-build (file attr)
  80. "Run Nix’s buildPhase.
  81. FILE is the file to build from.
  82. ATTR is the attribute to build."
  83. (interactive (list (nix-read-file) nil))
  84. (unless attr (setq attr (nix-read-attr file)))
  85. (nix-shell--run-phase "build" file attr))
  86. (defun nix-shell--run-phase (phase file attr)
  87. "Get source from a Nix derivation.
  88. PHASE phase to run.
  89. FILE used for base of Nix expresions.
  90. ATTR from NIX-FILE to get Nix expressions from."
  91. (shell-command
  92. (format "%s '%s' -A '%s' --run 'if [ -z \"$%sPhase\" ]; then eval %sPhase; else eval \"$%sPhase\"; fi' &"
  93. nix-shell-executable
  94. file attr phase phase phase)))
  95. (declare-function flycheck-buffer "flycheck")
  96. (defun nix-shell--callback (buffer drv)
  97. "Run the nix-shell callback to setup the buffer.
  98. The BUFFER to run in.
  99. The DRV file to use."
  100. (let* ((env (alist-get 'env drv))
  101. (stdenv (alist-get 'stdenv env))
  102. (system (alist-get 'system env))
  103. (inputs (remove nil
  104. (apply 'append
  105. (mapcar (lambda (prop)
  106. (split-string (alist-get prop env)))
  107. nix-shell-inputs)))))
  108. ;; Prevent accidentally rebuilding the world.
  109. (unless (file-directory-p stdenv)
  110. (error
  111. "Your stdenv at %s has not been built. Please run: nix-store -r %s"
  112. stdenv stdenv))
  113. ;; Make sure this .drv file can actually be built here.
  114. (unless (string= system (nix-system))
  115. (error
  116. "Your system (%s) does not match .drv’s build system (%s)"
  117. (nix-system) system))
  118. (with-current-buffer buffer
  119. (when nix-shell-clear-environment
  120. (setq-local exec-path nil)
  121. (setq-local eshell-path-env "")
  122. ;; (setq-local process-environment nil)
  123. )
  124. (dolist (input inputs)
  125. (when (and (not (file-directory-p input))
  126. nix-shell-auto-realise)
  127. (nix-store-realise input))
  128. (let ((bin (expand-file-name "bin" input))
  129. (man (expand-file-name "share/man" input))
  130. (include (expand-file-name "include" input)))
  131. (add-to-list 'exec-path bin)
  132. (setq-local eshell-path-env
  133. (format "%s:%s" bin eshell-path-env))
  134. (add-to-list 'woman-manpath man)
  135. (add-to-list 'ffap-c-path include)
  136. (add-to-list 'Man-header-file-path include)
  137. (add-to-list 'irony-additional-clang-options
  138. (format "-I%s" include))))
  139. (when (bound-and-true-p flycheck-mode)
  140. (flycheck-buffer))
  141. )))
  142. (defun nix-shell-with-packages (packages &optional pkgs-file)
  143. "Create a nix shell environment from the listed package.
  144. PACKAGES a list of packages to use.
  145. PKGS-FILE the Nix file to get the packages from."
  146. (nix-instantiate-async (apply-partially 'nix-shell--callback
  147. (current-buffer))
  148. (nix-shell--with-packages-file packages pkgs-file)
  149. ))
  150. (defun nix-shell--with-packages-file (packages &optional pkgs-file)
  151. "Get a .nix file from the packages list.
  152. PACKAGES to put in the .nix file.
  153. PKGS-FILE package set to pull from."
  154. (unless pkgs-file (setq pkgs-file "<nixpkgs>"))
  155. (let ((nix-file (make-temp-file "nix-shell" nil ".nix")))
  156. (with-temp-file nix-file
  157. (insert (format "with import %s { };\n" pkgs-file))
  158. (insert "runCommandCC \"shell\" {\n")
  159. (insert " nativeBuildInputs = [\n")
  160. (mapc (lambda (x) (insert (format " %s\n" x))) packages)
  161. (insert " ];\n")
  162. (insert "} \"\"\n"))
  163. nix-file))
  164. (defun nix-eshell-with-packages (packages &optional pkgs-file)
  165. "Create an Eshell buffer that has the shell environment in it.
  166. PACKAGES a list of packages to pull in.
  167. PKGS-FILE a file to use to get the packages."
  168. (let ((buffer (generate-new-buffer "*nix-eshell*")))
  169. (pop-to-buffer-same-window buffer)
  170. (setq-local nix-shell-clear-environment t)
  171. (nix-shell--callback
  172. (current-buffer)
  173. (nix-instantiate
  174. (nix-shell--with-packages-file packages pkgs-file) nil t))
  175. (eshell-mode)
  176. buffer))
  177. (defun nix-eshell (file &optional attr)
  178. "Create an Eshell buffer that has the shell environment in it.
  179. FILE the .nix expression to create a shell for.
  180. ATTR attribute to instantiate in NIX-FILE."
  181. (interactive (list (nix-read-file) nil))
  182. (unless attr (setq attr (nix-read-attr nix-file)))
  183. (let ((buffer (generate-new-buffer "*nix-eshell*")))
  184. (pop-to-buffer-same-window buffer)
  185. (setq-local nix-shell-clear-environment t)
  186. (nix-shell--callback
  187. (current-buffer)
  188. (nix-instantiate file attr t))
  189. (eshell-mode)
  190. buffer))
  191. ;;;###autoload
  192. (defun nix-shell-with-string (string)
  193. "A nix-shell emulator in Emacs from a string.
  194. STRING the nix expression to use."
  195. (let ((file (make-temp-file "nix-shell" nil ".nix")))
  196. (with-temp-file file (insert string))
  197. (nix-instantiate-async (apply-partially 'nix-shell--callback
  198. (current-buffer))
  199. file)))
  200. ;;;###autoload
  201. (defun nix-shell (file &optional attr)
  202. "A nix-shell emulator in Emacs.
  203. FILE the file to instantiate.
  204. ATTR an attribute of the Nix file to use."
  205. (interactive (list (nix-read-file) nil))
  206. (unless attr (setq attr (nix-read-attr file)))
  207. (nix-instantiate-async (apply-partially 'nix-shell--callback
  208. (current-buffer))
  209. file attr))
  210. (provide 'nix-shell)
  211. ;;; nix-shell.el ends here