├── img ├── helm-nixos-options.gif ├── company-nixos-options.gif ├── ivy-nixos-options-actions.png ├── helm-nixos-options-candidates.png ├── helm-nixos-options-doc-buffer.png ├── ivy-nixos-options-candidates.png └── ivy-nixos-options-doc-buffer.png ├── TODO.org ├── helm-nixos-options.el ├── company-nixos-options.el ├── ivy-nixos-options.el ├── README.org ├── nixos-packages.el ├── nixos-options.el └── nix-sandbox.el /img/helm-nixos-options.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/nix-community/nix-emacs/HEAD/img/helm-nixos-options.gif -------------------------------------------------------------------------------- /img/company-nixos-options.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/nix-community/nix-emacs/HEAD/img/company-nixos-options.gif -------------------------------------------------------------------------------- /img/ivy-nixos-options-actions.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/nix-community/nix-emacs/HEAD/img/ivy-nixos-options-actions.png -------------------------------------------------------------------------------- /img/helm-nixos-options-candidates.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/nix-community/nix-emacs/HEAD/img/helm-nixos-options-candidates.png -------------------------------------------------------------------------------- /img/helm-nixos-options-doc-buffer.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/nix-community/nix-emacs/HEAD/img/helm-nixos-options-doc-buffer.png -------------------------------------------------------------------------------- /img/ivy-nixos-options-candidates.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/nix-community/nix-emacs/HEAD/img/ivy-nixos-options-candidates.png -------------------------------------------------------------------------------- /img/ivy-nixos-options-doc-buffer.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/nix-community/nix-emacs/HEAD/img/ivy-nixos-options-doc-buffer.png -------------------------------------------------------------------------------- /TODO.org: -------------------------------------------------------------------------------- 1 | * Todos 2 | ** TODO Figuring namespacing/style for functions and variables 3 | ** DONE Make this into a proper Emacs module for MELPA 4 | CLOSED: [2015-07-19 Sun 13:03] 5 | ** TODO Persistent Action should show info as in the webpage :feature: 6 | Create an action that prints the data in a nicely formated way in a temporary buffer 7 | ** DONE Create a company-mode backend for this for nix-mode? 8 | CLOSED: [2015-07-19 Sun 13:01] 9 | ** TODO Feature: Hyperlink Options file 10 | "Declared In" has link to the file where this option is. Query the system to 11 | find out where in the store this is. Make a hyperlink to this file. 12 | ** TODO Use also nixos-packages-json-file for helm completions <2015-07-20 Mon 00:47> 13 | 14 | In that way one can check for packages as well 15 | 16 | Link: file:~/spacemacs_conf/nix/extensions/nix-options/nixos-options.el::(defvar%20nixos-options-json-file 17 | ** TODO Figure out nixos options Data Structure for Company 18 | 19 | #+begin_src emacs-lisp 20 | ("xserver" . 21 | (("window-manager" . (("description" . meta) ("subcategories" . ("i3" . ( ("description" . description) ))))) 22 | ("enable" (("description" . description))))) 23 | #+end_src 24 | 25 | 26 | 27 | -------------------------------------------------------------------------------- /helm-nixos-options.el: -------------------------------------------------------------------------------- 1 | ;;; helm-nixos-options.el --- Helm Interface for nixos-options 2 | 3 | ;; Copyright (C) 2015 Diego Berrocal and Travis B. Hartwell 4 | 5 | ;; Author: Diego Berrocal 6 | ;; Travis B. Hartwell 7 | ;; Created: 18 July 2015 8 | 9 | ;; Keywords: unix 10 | ;; Homepage: http://www.github.com/travisbhartwell/nix-emacs/ 11 | ;; Version: 0.1.0 12 | ;; Package-Requires: ((nixos-options "0.0.1") (helm "1.5.6")) 13 | 14 | ;; This file is not part of GNU Emacs. 15 | 16 | ;;; License: GPLv3 17 | 18 | ;;; Commentary: 19 | 20 | ;; Useful functions for exploring the NixOS options. Inspired by 21 | ;; https://nixos.org/nixos/options.html. 22 | 23 | ;;; Code: 24 | (require 'nixos-options) 25 | (require 'helm) 26 | 27 | (defun helm-source-nixos-options-search () 28 | `((name . "NixOS Options") 29 | (requires-pattern . 2) 30 | (candidates . nixos-options) 31 | (follow . 1) 32 | (persistent-action . (lambda (f) (message (format "%s" (nixos-options-get-description f))))) 33 | (action . (("View documentation" . (lambda (f) 34 | (switch-to-buffer-other-window 35 | (nixos-options-doc-buffer 36 | (nixos-options-get-documentation-for-option f))))) 37 | ("Insert into buffer" . (lambda (f) (insert (nixos-options-get-name f)))) 38 | ("Pretty print" . (lambda (f) (message "Pretty Printed: %s" (pp f)))) 39 | ("Display name" . (lambda (f) (message "Name: %s" (nixos-options-get-name f)))))))) 40 | 41 | ;;;###autoload 42 | (defun helm-nixos-options () 43 | (interactive) 44 | (helm :sources `(,(helm-source-nixos-options-search)) 45 | :buffer "*helm-nixos-options*")) 46 | 47 | (provide 'helm-nixos-options) 48 | ;;; helm-nixos-options.el ends here 49 | -------------------------------------------------------------------------------- /company-nixos-options.el: -------------------------------------------------------------------------------- 1 | ;;; company-nixos-options.el --- Company Backend for nixos-options 2 | 3 | ;; Copyright (C) 2015 Diego Berrocal and Travis B. Hartwell 4 | 5 | ;; Author: Diego Berrocal 6 | ;; Travis B. Hartwell 7 | ;; Created: 18 July 2015 8 | 9 | ;; Keywords: unix 10 | ;; Homepage: http://www.github.com/travisbhartwell/nix-emacs/ 11 | ;; Version: 0.1.0 12 | ;; Package-Requires: ((company "0.8.0") (nixos-options "0.0.1") (cl-lib "0.5.0")) 13 | 14 | ;; This file is not part of GNU Emacs. 15 | 16 | ;;; License: GPLv3 17 | 18 | ;;; Commentary: 19 | 20 | ;; Useful functions for exploring the NixOS options. Inspired by 21 | ;; https://nixos.org/nixos/options.html. 22 | 23 | ;;; Code: 24 | (require 'nixos-options) 25 | (require 'company) 26 | (require 'cl-lib) 27 | 28 | (defun company-nixos-options--doc-buffer (candidate) 29 | "Return documentation buffer for chosen CANDIDATE." 30 | (let ((doc (nixos-options-get-documentation-for-option 31 | (nixos-options-get-option-by-name candidate)))) 32 | (and doc (nixos-options-doc-buffer doc)))) 33 | 34 | (defun company-nixos-options--candidates (prefix) 35 | (let ((res)) 36 | (dolist (option nixos-options) 37 | (let ((name (nixos-options-get-name option))) 38 | (when (string-prefix-p prefix name) 39 | (push name res)))) 40 | res)) 41 | 42 | (defun company-nixos-options--annotation (candidate) 43 | (let ((type (nixos-options-get-type 44 | (nixos-options-get-option-by-name 45 | candidate)))) 46 | (format " <%s>" type))) 47 | 48 | (defun company-nixos--grab-symbol () 49 | (buffer-substring (point) (save-excursion (skip-syntax-backward "w_.") 50 | (point)))) 51 | 52 | (defun company-nixos--in-nix-context-p () 53 | (or (eq major-mode 'nix-mode) 54 | (equal "nix" (file-name-extension 55 | (buffer-file-name (current-buffer)))))) 56 | 57 | (defun company-nixos-options--prefix () 58 | "Grab prefix at point." 59 | (and (company-nixos--in-nix-context-p) 60 | (or (company-nixos--grab-symbol) 61 | 'stop))) 62 | 63 | ;;;###autoload 64 | (defun company-nixos-options (command &optional arg &rest ignored) 65 | (interactive (list 'interactive)) 66 | (cl-case command 67 | (interactive (company-begin-backend 'company-nixos-options)) 68 | (prefix (company-nixos-options--prefix)) 69 | (candidates (company-nixos-options--candidates arg)) 70 | (doc-buffer (company-nixos-options--doc-buffer arg)) 71 | (annotation (company-nixos-options--annotation arg)))) 72 | 73 | (provide 'company-nixos-options) 74 | ;;; company-nixos-options.el ends here 75 | -------------------------------------------------------------------------------- /ivy-nixos-options.el: -------------------------------------------------------------------------------- 1 | ;;; ivy-nixos-options.el --- An Ivy Interface for nixos-options. 2 | 3 | ;; Copyright (C) 2020 Samuel Ruprecht 4 | 5 | ;; Author: Samuel Ruprecht 6 | ;; Created: 20 June 2020 7 | 8 | ;; Keywords: unix 9 | ;; Homepage: http://www.github.com/travisbhartwell/nix-emacs/ 10 | ;; Version: 0.1.0 11 | ;; Package-Requires: ((nixos-options "0.0.1") (ivy "0.13.0")) 12 | 13 | ;; This file is not part of GNU Emacs. 14 | 15 | ;;; License: GPLv3 16 | 17 | ;;; Commentary: 18 | 19 | ;; Useful functions for exploring the NixOS options. Inspired by 20 | ;; https://nixos.org/nixos/options.html. 21 | 22 | ;;; Code: 23 | (require 'nixos-options) 24 | (require 'ivy) 25 | 26 | (defun ivy-nixos-buffer-display (text) 27 | "Insert TEXT into a custom ivy-doc buffer and show it if it's not visible. 28 | This function should only be called by ivy, as ivy is automatically resumed with `ivy-resume`" 29 | (let ((buf (get-buffer-create "*nixos-options-ivy-doc*"))) 30 | (with-current-buffer buf 31 | (view-mode -1) 32 | (erase-buffer) 33 | (insert text) 34 | (goto-char (point-min)) 35 | (view-mode 1)) 36 | (cond ((get-buffer-window buf)) 37 | ((switch-to-buffer-other-window buf) 38 | (select-window (previous-window nil nil)))))) 39 | 40 | (defcustom ivy-nixos-options-default 1 41 | "Defines the default action when pressing enter for `ivy-nixos-options'. 42 | 1 - show the help buffer and resume ivy 43 | 2 - insert the string into the buffer 44 | 3 - show the description and resume ivy" 45 | :type 'integer 46 | :group 'nixos-options 47 | ) 48 | 49 | ;;;###autoload 50 | (defun ivy-nixos-options () 51 | "Opens an ivy buffer with all nixos options." 52 | (interactive) 53 | (ivy-read 54 | "NixOS Options: " nixos-options 55 | :caller 'ivy-nixos-options 56 | :history 'ivy-nixos-options-history 57 | :preselect (ivy-thing-at-point) 58 | :action (list ivy-nixos-options-default 59 | '("h" (lambda (f) (progn 60 | (ivy-nixos-buffer-display (nixos-options-get-documentation-for-option f)) 61 | (ivy-resume))) 62 | "View documentation") 63 | '("i" (lambda (f) (insert (nixos-options-get-name f))) 64 | "Insert into buffer") 65 | '("d" (lambda (f) (progn 66 | (ivy-nixos-buffer-display 67 | (message (format 68 | "%s: %s" 69 | (car f) 70 | (nixos-options-get-description f)))) 71 | (ivy-resume))) 72 | "Show the description")))) 73 | 74 | (add-to-list 'ivy-sort-matches-functions-alist '(ivy-nixos-options . ivy--prefix-sort)) 75 | (add-to-list 'ivy-re-builders-alist '(ivy-nixos-options . ivy--regex-plus)) 76 | 77 | (provide 'ivy-nixos-options) 78 | 79 | ;;; ivy-nixos-options.el ends here 80 | -------------------------------------------------------------------------------- /README.org: -------------------------------------------------------------------------------- 1 | #+TITLE: Nix Options -- A set of useful Emacs modes and functions for users of Nix and Nix OS. 2 | 3 | | nixos-options | helm-nixos-options | ivy-nixos-options | company-nixos-options | nix-sandbox | 4 | | [[http://melpa.org/#/nixos-options][http://melpa.org/packages/nixos-options-badge.svg]] | [[http://melpa.org/#/helm-nixos-options][http://melpa.org/packages/helm-nixos-options-badge.svg]] | [[http://melpa.org/packages/ivy-nixos-options-badge.svg]] | [[http://melpa.org/#/company-nixos-options][http://melpa.org/packages/company-nixos-options-badge.svg]] | [[https://melpa.org/#/nix-sandbox][file:https://melpa.org/packages/nix-sandbox-badge.svg]] | 5 | 6 | 7 | [[https://gitter.im/travisbhartwell/nix-emacs?utm_source=badge&utm_medium=badge&utm_campaign=pr-badge&utm_content=badge][https://badges.gitter.im/Join Chat.svg]] 8 | [[https://www.waffle.io/travisbhartwell/nix-emacs][https://badge.waffle.io/travisbhartwell/nix-emacs.svg]] 9 | 10 | ** Usage 11 | 12 | *** helm-nixos-options 13 | 14 | The function =helm-nixos-options= is the one that you want to bind. You are free 15 | to choose where and if you want it global you can have this. 16 | 17 | #+begin_src emacs-lisp 18 | (global-set-key (kbd "C-c C-S-n") 'helm-nixos-options) 19 | #+end_src 20 | 21 | It looks like this 22 | 23 | [[file:img/helm-nixos-options-candidates.png]] 24 | 25 | The description of the option is shown in the minibuffer 26 | 27 | If you want more information, there is a detailed buffer when you press =return= 28 | 29 | [[file:img/helm-nixos-options-doc-buffer.png]] 30 | 31 | There are also other actions like inserting the current match into the buffer 32 | 33 | [[file:img/helm-nixos-options.gif]] 34 | 35 | *** ivy-nixos-options 36 | 37 | Use this if you don't want the rather heavy =helm= dependency. 38 | The function =ivy-nixos-options= is the one that you want to bind. You are free 39 | to choose where and if you want it global you can have this. 40 | 41 | #+begin_src emacs-lisp 42 | (global-set-key (kbd "C-c C-S-n") 'ivy-nixos-options) 43 | 44 | (setq ivy-nixos-options-default 1) 45 | ; defines what function is being called when pressing return. I like to have it set to 2 46 | ; All of the actions can always be called when pressing M-o 47 | ; 1 = show the docs buffer (default) 48 | ; 2 = insert the string 49 | ; 3 = only show the description of the command 50 | #+end_src 51 | 52 | It looks like this 53 | 54 | [[file:img/ivy-nixos-options-candidates.png]] 55 | 56 | If you want more information, there is a detailed buffer when you press =return= 57 | 58 | [[file:img/ivy-nixos-options-doc-buffer.png]] 59 | 60 | There are also other actions like inserting the current match into the buffer. 61 | The builtin help menu from ivy (display with =M-o=) shows all possible options. e.g. =M-o i= will insert the option 62 | 63 | [[file:img/ivy-nixos-options-actions.png]] 64 | 65 | 66 | *** company-nixos-options 67 | 68 | Add company-nixos-options to allowed company-mode backends list 69 | 70 | #+begin_src emacs-lisp 71 | (add-to-list 'company-backends 'company-nixos-options) 72 | #+end_src 73 | 74 | For now it shows the documentation of the option in a popup-buffer. 75 | 76 | [[file:img/company-nixos-options.gif]] 77 | 78 | *** nix-sandbox 79 | 80 | Utility functions to work with nix sandboxes. 81 | 82 | - ~nix-shell-command~ composes command that can be executed in the given sandbox 83 | - ~nix-shell~ executes a command in the given sandbox 84 | - ~nix-compile~ compiles a program in the given sandbox 85 | - ~nix-find-sandbox~ searches from the given path upwards until it 86 | finds a =shell.nix= or =default.nix= file. 87 | - ~nix-current-sandbox~ searches for a sandbox file starting from the current working directory. 88 | - ~nix-executable-find~ a replacement for the built-in =executable-find=. The function searches in the given sandbox for executables. 89 | 90 | **** Flycheck 91 | 92 | With this configuration [[http://www.flycheck.org/][flycheck]] can find executables of checkers that would be only accessible via =nix-shell=: 93 | 94 | #+begin_src emacs-lisp 95 | (setq flycheck-command-wrapper-function 96 | (lambda (command) (apply 'nix-shell-command (nix-current-sandbox) command)) 97 | flycheck-executable-find 98 | (lambda (cmd) (nix-executable-find (nix-current-sandbox) cmd))) 99 | #+end_src 100 | 101 | **** Haskell Mode 102 | 103 | Add these lines to your configuration to allow [[https://github.com/haskell/haskell-mode][haskell-mode]] to look for =ghc= in the current sandbox. 104 | 105 | #+begin_src emacs-lisp 106 | (setq haskell-process-wrapper-function 107 | (lambda (args) (apply 'nix-shell-command (nix-current-sandbox) args))) 108 | #+end_src 109 | -------------------------------------------------------------------------------- /nixos-packages.el: -------------------------------------------------------------------------------- 1 | ;;; nixos-packages.el --- Interface for browsing and completing NixOS packages. 2 | 3 | ;; Copyright (C) 2015 Diego Berrocal and Travis B. Hartwell 4 | 5 | ;; Author: Diego Berrocal 6 | ;; Travis B. Hartwell 7 | ;; Created: 18 July 2015 8 | 9 | ;; Keywords: unix 10 | ;; Homepage: http://www.github.com/travisbhartwell/nix-emacs/ 11 | ;; Version: 0.0.1 12 | ;; Package-Requires: ((emacs "24")) 13 | 14 | ;; This file is not part of GNU Emacs. 15 | 16 | ;;; License: GPLv3 17 | 18 | ;;; Commentary: 19 | 20 | ;; Useful functions for exploring the NixOS packages. Inspired by 21 | ;; https://nixos.org/nixos/packages.html. 22 | 23 | ;;; Code: 24 | 25 | (require 'json) 26 | 27 | (defvar nixos-packages-json-file 28 | (expand-file-name "nixos-packages.json" spacemacs-cache-directory) 29 | "Where to store the nixos-packages in JSON format") 30 | 31 | (defvar nixos-packages-name-indent-amount 0 32 | "Indent by the maximum length, plus a colon, plus two spaces.") 33 | 34 | (setq nixos-packages 35 | (if (file-exists-p nixos-packages-json-file) 36 | (let ((json-key-type 'string)) 37 | (json-read-file nixos-packages-json-file)) 38 | (let* ((cmd "nix-env -qaP hello --json") 39 | (data (replace-regexp-in-string "\n\\'" "" 40 | (shell-command-to-string cmd))) 41 | (json-key-type 'string)) 42 | (append-to-file data nil nixos-packages-json-file) 43 | (json-read-from-string data)))) 44 | 45 | 46 | (assoc "name" (car nixos-packages)) 47 | (assoc "system" (car nixos-packages)) 48 | (assoc "description" (assoc "meta" (car nixos-packages))) 49 | (assoc "homepage" (assoc "meta" (car nixos-packages))) 50 | (assoc "license" (assoc "meta" (car nixos-packages))) 51 | (assoc "longDescription" (assoc "meta" (car nixos-packages))) 52 | (assoc "platforms" (assoc "meta" (car nixos-packages))) 53 | (assoc "position" (assoc "meta" (car nixos-packages))) 54 | (assoc "maintainers" (assoc "meta" (car nixos-packages))) 55 | (assoc "maintainers" (assoc "meta" (car nixos-packages))) 56 | 57 | ;; Macros for defining constants and functions for working with options 58 | (defmacro define-nixos-packages-item (item long-name &optional isMeta?) 59 | (let* ((name-const (intern (concat "nixos-packages-" item))) 60 | (long-name-const (intern (concat "nixos-packages-" item "-long-name"))) 61 | (long-name-length-plus-padding (+ 3 (length long-name))) 62 | (long-name-docstring (format "The long description for %s." item)) 63 | (item-getter (intern (concat "nixos-packages-get-" item))) 64 | (item-getter-docstring 65 | (format "Get the value of %s from PACKAGE" item)) 66 | (item-display (intern (concat "nixos-packages-display-" item))) 67 | (item-display-docstring 68 | (format "Display the value for %s from PACKAGE" item))) 69 | `(progn 70 | (defconst ,name-const ,item) 71 | (defconst ,long-name-const ,long-name ,long-name-docstring) 72 | (if (> ,long-name-length-plus-padding nixos-packages-name-indent-amount) 73 | (setq nixos-packages-name-indent-amount 74 | ,long-name-length-plus-padding)) 75 | (if ,isMeta? 76 | (defun ,item-getter (option) 77 | ,item-getter-docstring 78 | (cdr (assoc ,name-const (assoc "meta" option)))) 79 | (defun ,item-getter (option) 80 | ,item-getter-docstring 81 | (cdr (assoc ,name-const option)))) 82 | 83 | (defun ,item-display (option) 84 | ,item-display-docstring 85 | (let ((item (,item-getter option)) 86 | (format-string 87 | (format "%%-%ds %%s\n" nixos-packages-name-indent-amount))) 88 | (if (not (null item)) 89 | (format format-string (concat ,long-name-const ":") item) 90 | "")))))) 91 | 92 | (define-nixos-packages-item "description" "Description" t) 93 | (define-nixos-packages-item "homepage" "Home Page URL" t) 94 | (define-nixos-packages-item "license" "License" t) 95 | (define-nixos-packages-item "longDescription" "Long Description" t) 96 | (define-nixos-packages-item "platforms" "Supported Platforms" t) 97 | (define-nixos-packages-item "maintainers" "List of Maintainers" t) 98 | (define-nixos-packages-item "position" "Path to the nix-expression with line" t) 99 | (define-nixos-packages-item "name" "Name") 100 | (define-nixos-packages-item "system" "System") 101 | 102 | (defun nixos-packages--make-alist (package) 103 | (let ((name (car package)) 104 | (data (cdr package)) 105 | (default (nixos-options-get-default package)) 106 | (example (nixos-options-get-example package))) 107 | (progn 108 | (if (not (null default)) 109 | (setcdr (assoc nixos-options-default package) 110 | (nixos-options--boolean-string default))) 111 | (if (not (null example)) 112 | (setcdr (assoc nixos-options-example package) 113 | (nixos-options--boolean-string example))) 114 | (add-to-list 'data `(,nixos-options-name . ,name)) 115 | `(,name . ,data)))) 116 | -------------------------------------------------------------------------------- /nixos-options.el: -------------------------------------------------------------------------------- 1 | ;;; nixos-options.el --- Interface for browsing and completing NixOS options. 2 | 3 | ;; Copyright (C) 2015 Diego Berrocal and Travis B. Hartwell 4 | 5 | ;; Author: Diego Berrocal 6 | ;; Travis B. Hartwell 7 | ;; Created: 18 July 2015 8 | 9 | ;; Keywords: unix 10 | ;; Homepage: http://www.github.com/travisbhartwell/nix-emacs/ 11 | ;; Version: 0.0.1 12 | ;; Package-Requires: ((emacs "24")) 13 | 14 | ;; This file is not part of GNU Emacs. 15 | 16 | ;;; License: GPLv3 17 | 18 | ;;; Commentary: 19 | 20 | ;; Useful functions for exploring the NixOS options. Inspired by 21 | ;; https://nixos.org/nixos/options.html. 22 | 23 | ;;; Code: 24 | 25 | (require 'json) 26 | 27 | (defvar nixos-options-name-indent-amount 0 28 | "Indent by the maximum length, plus a colon, plus two spaces.") 29 | 30 | ;; Macros for defining constants and functions for working with options 31 | (defmacro define-nixos-options-item (item long-name) 32 | (let* ((name-const (intern (concat "nixos-options-" item))) 33 | (long-name-const (intern (concat "nixos-options-" item "-long-name"))) 34 | (long-name-length-plus-padding (+ 3 (length long-name))) 35 | (long-name-docstring (format "The long description for %s." item)) 36 | (item-getter (intern (concat "nixos-options-get-" item))) 37 | (item-getter-docstring 38 | (format "Get the value of %s from OPTION." item)) 39 | (item-display (intern (concat "nixos-options-display-" item))) 40 | (item-display-docstring 41 | (format "Display the value for %s from OPTION." item))) 42 | `(progn 43 | (defconst ,name-const ,item) 44 | (defconst ,long-name-const ,long-name ,long-name-docstring) 45 | (if (> ,long-name-length-plus-padding nixos-options-name-indent-amount) 46 | (setq nixos-options-name-indent-amount 47 | ,long-name-length-plus-padding)) 48 | (defun ,item-getter (option) 49 | ,item-getter-docstring 50 | (cdr (assoc ,name-const option))) 51 | (defun ,item-display (option) 52 | ,item-display-docstring 53 | (let ((item (,item-getter option)) 54 | (format-string 55 | (format "%%-%ds %%s\n" nixos-options-name-indent-amount))) 56 | (if (not (null item)) 57 | (format format-string (concat ,long-name-const ":") item) 58 | "")))))) 59 | 60 | (define-nixos-options-item "name" "Name") 61 | (define-nixos-options-item "type" "Type") 62 | (define-nixos-options-item "description" "Description") 63 | (define-nixos-options-item "default" "Default value") 64 | (define-nixos-options-item "example" "Example value") 65 | (define-nixos-options-item "declarations" "Declared in") 66 | 67 | (defvar nixos-options-json-file 68 | (let* ((cmd 69 | "export NIXPKGS_ALLOW_UNFREE=1; nix-build -Q --no-out-link '' -A options 2>/dev/null") 70 | (dir (replace-regexp-in-string "\n\\'" "" 71 | (shell-command-to-string cmd)))) 72 | (expand-file-name "share/doc/nixos/options.json" dir)) 73 | "Location of the options file.") 74 | 75 | (defun nixos-options--boolean-string (value) 76 | "Return the string representation of the boolean VALUE. 77 | Returns VALUE unchanged if not a boolean." 78 | (cond ((eq value 't) "true") 79 | ((eq value :json-false) "false") 80 | (t value))) 81 | 82 | (defun nixos-options--make-alist (option) 83 | (let ((name (car option)) 84 | (data (cdr option)) 85 | (default (nixos-options-get-default option)) 86 | (example (nixos-options-get-example option))) 87 | (progn 88 | (if (not (null default)) 89 | (setcdr (assoc nixos-options-default option) 90 | (nixos-options--boolean-string default))) 91 | (if (not (null example)) 92 | (setcdr (assoc nixos-options-example option) 93 | (nixos-options--boolean-string example))) 94 | (add-to-list 'data `(,nixos-options-name . ,name)) 95 | `(,name . ,data)))) 96 | 97 | (defvar nixos-options 98 | (if (file-exists-p nixos-options-json-file) 99 | (let* ((json-key-type 'string) 100 | (raw-options (json-read-file nixos-options-json-file))) 101 | (mapcar 'nixos-options--make-alist raw-options)) 102 | (message "Warning: Cannot find nixos option file."))) 103 | 104 | (defun nixos-options-get-documentation-for-option (option) 105 | (concat (nixos-options-display-name option) 106 | (nixos-options-display-type option) 107 | (nixos-options-display-description option) 108 | (nixos-options-display-default option) 109 | (nixos-options-display-example option) 110 | (nixos-options-display-declarations option))) 111 | 112 | ;; Borrowed from anaconda-mode 113 | (defun nixos-options-doc-buffer (doc) 114 | "Display documentation buffer with contents DOC." 115 | (let ((buf (get-buffer-create "*nixos-options-doc*"))) 116 | (with-current-buffer buf 117 | (view-mode -1) 118 | (erase-buffer) 119 | (insert doc) 120 | (goto-char (point-min)) 121 | (view-mode 1) 122 | buf))) 123 | 124 | (defun nixos-options-get-option-by-name (name) 125 | (assoc name nixos-options)) 126 | 127 | (provide 'nixos-options) 128 | ;;; nixos-options.el ends here 129 | -------------------------------------------------------------------------------- /nix-sandbox.el: -------------------------------------------------------------------------------- 1 | ;;; nix-sandbox.el --- Utility functions to work with nix-shell sandboxes 2 | 3 | ;; Copyright (C) 2015 Sven Keidel 4 | 5 | ;; Author: Sven Keidel 6 | ;; Package-Version: 0.1 7 | ;; Package-Requires: ((dash "2.12.1") (s "1.10.0")) 8 | ;; Homepage: https://github.com/travisbhartwell/nix-emacs 9 | 10 | ;; This file is not part of GNU Emacs. 11 | 12 | ;;; License: GPLv3 13 | 14 | ;;; Commentary: 15 | 16 | ;; Useful functions for working with nix-shell sandboxes 17 | 18 | ;;; Code: 19 | 20 | (require 'dash) 21 | (require 's) 22 | 23 | (defgroup nix nil 24 | "customizations for nix" 25 | :prefix "nix-" 26 | :group 'external) 27 | 28 | (defcustom nix-nixpkgs-path nil 29 | "Absolute path to a nixpkgs directory. 30 | 31 | Can be customized to select a nix-channel 32 | e.g. /home/user/.nix-defexpr/channels/unstable/nixpkgs" 33 | :group 'nix 34 | :type '(choice (const :tag "No channel" nil) 35 | (directory "Custom path to a nixpkgs distribution"))) 36 | 37 | (defun nix-create-sandbox-rc (sandbox) 38 | "Create a new rc file containing the environment for the given SANDBOX." 39 | (let ((env-str (shell-command-to-string 40 | (if sandbox 41 | (concat "nix-shell " 42 | (or (and nix-nixpkgs-path (concat "-I nixpkgs=" nix-nixpkgs-path)) 43 | "") 44 | " --run 'declare +x shellHook; declare -x; declare -xf' " 45 | (shell-quote-argument sandbox) 46 | " 2> /dev/null") 47 | "bash -c 'declare +x shellHook; declare -x; declare -xf'" 48 | ))) 49 | (tmp-file (make-temp-file "nix-sandbox-rc-"))) 50 | (write-region env-str nil tmp-file 'append) 51 | tmp-file)) 52 | 53 | (defvar nix-sandbox-rc-map (make-hash-table :test 'equal 54 | :size 4)) 55 | 56 | (defun nix-sandbox-rc (sandbox) 57 | "Return the rc file for the given SANDBOX or create one." 58 | (or (gethash sandbox nix-sandbox-rc-map) 59 | (puthash sandbox (nix-create-sandbox-rc sandbox) nix-sandbox-rc-map))) 60 | 61 | ;;;###autoload 62 | (defun nix-shell-command (sandbox &rest args) 63 | "Assemble a command from ARGS that can be executed in the specified SANDBOX." 64 | (list "bash" "-c" (format "source %s; %s" (nix-sandbox-rc sandbox) 65 | (mapconcat 'shell-quote-argument args " ")))) 66 | 67 | (defun nix-shell-string (sandbox &rest args) 68 | "Assemble a command string from ARGS that can be executed in the specifed SANDBOX." 69 | (combine-and-quote-strings 70 | (apply 'nix-shell-command sandbox args))) 71 | 72 | ;;;###autoload 73 | (defun nix-compile (sandbox &rest command) 74 | "Compile a program using the given COMMAND in SANDBOX." 75 | (interactive "Dsandbox: \nMcommand: ") 76 | (compile (apply 'nix-shell-string sandbox command))) 77 | 78 | ;;;###autoload 79 | (defun nix-sandbox/nix-shell (sandbox &rest command) 80 | "Run a COMMAND in the given SANDBOX and return the output." 81 | (shell-command-to-string (apply 'nix-shell-string sandbox command))) 82 | 83 | (defvar nix-exec-path-map (make-hash-table :test 'equal 84 | :size 4)) 85 | 86 | ;;;###autoload 87 | (defun nix-exec-path (sandbox) 88 | "Return the `exec-path' of the given SANDBOX." 89 | 90 | (or (gethash sandbox nix-exec-path-map) 91 | (puthash sandbox 92 | (split-string (s-trim (nix-sandbox/nix-shell sandbox "printenv" "PATH")) ":") 93 | nix-exec-path-map))) 94 | 95 | ;;;###autoload 96 | (defun nix-executable-find (sandbox executable) 97 | "Search for an EXECUTABLE in the given SANDBOX." 98 | (let ((exec-path (nix-exec-path sandbox))) 99 | (and exec-path (executable-find executable)))) 100 | 101 | ;;;###autoload 102 | (defun nix-find-sandbox (path) 103 | "Search for a sandbox starting at PATH traversing upwards the directory tree. 104 | If the directory contains a `shell.nix' file, the path to this 105 | file is returned. Otherwise if the directory contains a 106 | `default.nix' file, the parent directory is returned." 107 | (and (file-exists-p path) 108 | (let* ((map-nil (lambda (f x) (if x (funcall f x) nil))) 109 | (sandbox-directory 110 | (funcall map-nil 'expand-file-name 111 | (locate-dominating-file path 112 | '(lambda (dir) 113 | (seq-filter 114 | (lambda (candidate) 115 | (not (file-directory-p candidate))) 116 | (directory-files dir t ".*\\.nix$")))))) 117 | (shell-nix (and sandbox-directory (concat sandbox-directory "shell.nix")))) 118 | (if (and sandbox-directory (file-exists-p shell-nix)) 119 | shell-nix 120 | sandbox-directory)))) 121 | 122 | ;;;###autoload 123 | (defun nix-current-sandbox () 124 | "Return the path of the sandbox that is closest to the current working directory." 125 | (nix-find-sandbox default-directory)) 126 | 127 | (defun nix-clear-caches () 128 | "Clear cached information for all sandboxes." 129 | (interactive) 130 | (clrhash nix-sandbox-rc-map) 131 | (clrhash nix-exec-path-map)) 132 | 133 | (provide 'nix-sandbox) 134 | 135 | ;;; nix-sandbox.el ends here 136 | --------------------------------------------------------------------------------