emacs-elpa-diffs
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

[nongnu] elpa/nix-mode 55b0ea2d96 132/500: Merge pull request #18 from m


From: ELPA Syncer
Subject: [nongnu] elpa/nix-mode 55b0ea2d96 132/500: Merge pull request #18 from matthewbauer/more-modes
Date: Sat, 29 Jan 2022 08:26:50 -0500 (EST)

branch: elpa/nix-mode
commit 55b0ea2d962d2403f2c1e0d80d083856f991341f
Merge: 414a40fe54 ae17e75812
Author: Matthew Justin Bauer <mjbauer95@gmail.com>
Commit: GitHub <noreply@github.com>

    Merge pull request #18 from matthewbauer/more-modes
    
    More modes
---
 company-nixos-options.el |  75 ++++++++++++++++
 helm-nixos-options.el    |  49 ++++++++++
 nix-buffer.el            | 227 +++++++++++++++++++++++++++++++++++++++++++++++
 nix-mode-mmm.el          |  23 +++++
 nix-sandbox.el           | 127 ++++++++++++++++++++++++++
 nix-smie.el              | 121 +++++++++++++++++++++++++
 nixos-options.el         | 128 ++++++++++++++++++++++++++
 nixos-packages.el        | 115 ++++++++++++++++++++++++
 8 files changed, 865 insertions(+)

diff --git a/company-nixos-options.el b/company-nixos-options.el
new file mode 100644
index 0000000000..d42cb30bb3
--- /dev/null
+++ b/company-nixos-options.el
@@ -0,0 +1,75 @@
+;;; company-nixos-options.el --- Company Backend for nixos-options
+
+;; Copyright (C) 2015 Diego Berrocal and Travis B. Hartwell
+
+;; Author: Diego Berrocal <cestdiego@gmail.com>
+;;      Travis B. Hartwell <nafai@travishartwell.net>
+;; Created: 18 July 2015
+
+;; Keywords: unix
+;; Homepage: http://www.github.com/travisbhartwell/nix-emacs/
+;; Version: 0.1.0
+;; Package-Requires: ((company "0.8.0") (nixos-options "0.0.1") (cl-lib 
"0.5.0"))
+
+;; This file is not part of GNU Emacs.
+
+;;; License: GPLv3
+
+;;; Commentary:
+
+;; Useful functions for exploring the NixOS options.  Inspired by
+;; https://nixos.org/nixos/options.html.
+
+;;; Code:
+(require 'nixos-options)
+(require 'company)
+(require 'cl-lib)
+
+(defun company-nixos-options--doc-buffer (candidate)
+  "Return documentation buffer for chosen CANDIDATE."
+  (let ((doc (nixos-options-get-documentation-for-option
+              (nixos-options-get-option-by-name candidate))))
+    (and doc (nixos-options-doc-buffer doc))))
+
+(defun company-nixos-options--candidates (prefix)
+  (let ((res))
+    (dolist (option nixos-options)
+      (let ((name (nixos-options-get-name option)))
+        (when (string-prefix-p prefix name)
+          (push name res))))
+    res))
+
+(defun company-nixos-options--annotation (candidate)
+  (let ((type (nixos-options-get-type
+               (nixos-options-get-option-by-name
+                candidate))))
+    (format "  <%s>" type)))
+
+(defun company-nixos--grab-symbol ()
+  (buffer-substring (point) (save-excursion (skip-syntax-backward "w_.")
+                                            (point))))
+
+(defun company-nixos--in-nix-context-p ()
+  (or (eq major-mode 'nix-mode)
+      (equal "nix" (file-name-extension
+                    (buffer-file-name (current-buffer))))))
+
+(defun company-nixos-options--prefix ()
+  "Grab prefix at point."
+  (and (company-nixos--in-nix-context-p)
+       (or (company-nixos--grab-symbol)
+           'stop)))
+
+;;;###autoload
+(defun company-nixos-options (command &optional arg &rest ignored)
+  (interactive (list 'interactive))
+  (cl-case command
+    (interactive (company-begin-backend 'company-nixos-options))
+    (prefix (company-nixos-options--prefix))
+    (candidates (company-nixos-options--candidates arg))
+    (doc-buffer (company-nixos-options--doc-buffer arg))
+    (annotation (company-nixos-options--annotation arg))))
+
+(provide 'company-nixos-options)
+;;; company-nixos-options.el ends here
+
diff --git a/helm-nixos-options.el b/helm-nixos-options.el
new file mode 100644
index 0000000000..974274d425
--- /dev/null
+++ b/helm-nixos-options.el
@@ -0,0 +1,49 @@
+;;; helm-nixos-options.el --- Helm Interface for nixos-options
+
+;; Copyright (C) 2015 Diego Berrocal and Travis B. Hartwell
+
+;; Author: Diego Berrocal <cestdiego@gmail.com>
+;;      Travis B. Hartwell <nafai@travishartwell.net>
+;; Created: 18 July 2015
+
+;; Keywords: unix
+;; Homepage: http://www.github.com/travisbhartwell/nix-emacs/
+;; Version: 0.1.0
+;; Package-Requires: ((nixos-options "0.0.1") (helm "1.5.6"))
+
+;; This file is not part of GNU Emacs.
+
+;;; License: GPLv3
+
+;;; Commentary:
+
+;; Useful functions for exploring the NixOS options.  Inspired by
+;; https://nixos.org/nixos/options.html.
+
+;;; Code:
+(require 'nixos-options)
+(require 'helm)
+
+(defun helm-source-nixos-options-search ()
+  `((name . "NixOS Options")
+    (requires-pattern . 2)
+    (candidates . nixos-options)
+    (follow . 1)
+    (persistent-action . (lambda (f) (message (format "%s" 
(nixos-options-get-description f)))))
+    (action . (("View documentation" . (lambda (f)
+                                         (switch-to-buffer-other-window
+                                          (nixos-options-doc-buffer
+                                           
(nixos-options-get-documentation-for-option f)))))
+               ("Insert into buffer" . (lambda (f) (insert 
(nixos-options-get-name f))))
+               ("Pretty print" . (lambda (f) (message "Pretty Printed: %s" (pp 
f))))
+               ("Display name" . (lambda (f) (message "Name: %s" 
(nixos-options-get-name f))))))))
+
+;;;###autoload
+(defun helm-nixos-options ()
+  (interactive)
+  (helm :sources `(,(helm-source-nixos-options-search))
+        :buffer "*helm-nixos-options*"))
+
+(provide 'helm-nixos-options)
+;;; helm-nixos-options.el ends here
+
diff --git a/nix-buffer.el b/nix-buffer.el
new file mode 100644
index 0000000000..539009427c
--- /dev/null
+++ b/nix-buffer.el
@@ -0,0 +1,227 @@
+;;; nix-buffer.el --- Set up buffer environments with nix
+
+;; Copyright (C) 2016, 2017 Shea Levy
+
+;; Author: Shea Levy
+;; URL: https://github.com/shlevy/nix-buffer/tree/master/
+;; Version: 3.0.0
+;; Package-Requires: ((f "0.17.3") (emacs "24.4"))
+
+;;; Commentary:
+
+;; This package provides 'nix-buffer', to modify your buffer
+;; according to a directory-local nix expression.  Think of it as
+;; nix-shell for Emacs.  See the documentation for 'nix-buffer' for
+;; more details.
+
+;; It may be desirable to run 'nix-buffer' before 'normal-mode' is
+;; called so it affects all modes.
+
+;;; Code:
+
+(require 'f)
+(require 'subr-x)
+
+(defgroup nix-buffer nil "Customization for nix-buffer."
+  :prefix "nix-buffer-"
+  :group 'environment
+  :package-version '('nix-buffer . "2.3.0"))
+
+(defun nix-buffer--directory-name-setter (opt val)
+  "Defcustom setter for nix-buffer-directory-name.
+OPT The option we're setting.
+
+VAL The value it's being set to."
+  (nix-buffer-update-directory-name val))
+
+(defcustom nix-buffer-directory-name
+  (locate-user-emacs-file "nix-buffer")
+  "Path where nix-buffer keeps its data.
+To update this variable outside of Customize, please use
+'nix-buffer-update-directory-name'."
+  :group 'nix-buffer
+  :type '(directory)
+  :set 'nix-buffer--directory-name-setter
+  :initialize 'custom-initialize-default
+  :risky t)
+
+(defvar nix-buffer--trust-exprs-file
+  (f-join nix-buffer-directory-name "trusted-exprs"))
+
+(defun nix-buffer--load-trusted-exprs ()
+  "Load the trusted nix-buffer exprs."
+  (let ((tbl (ignore-errors
+               (with-temp-buffer
+                 (insert-file-contents-literally
+                  nix-buffer--trust-exprs-file)
+                 (read (current-buffer))))))
+    (if (hash-table-p tbl)
+        tbl
+      (make-hash-table :test 'equal))))
+
+(defvar nix-buffer--trusted-exprs (nix-buffer--load-trusted-exprs))
+
+(defun nix-buffer-update-directory-name (path)
+  "Update the nix-buffer state directory.
+PATH The path to store the nix-buffer state."
+  (setq nix-buffer-directory-name path)
+  (setq nix-buffer--trust-exprs-file
+        (f-join nix-buffer-directory-name "trusted-exprs"))
+  (setq nix-buffer--trusted-exprs (nix-buffer--load-trusted-exprs)))
+
+(defun nix-buffer-unload-function ()
+  "Save state on unload."
+  (ignore-errors (make-directory nix-buffer-directory-name t))
+  (with-temp-buffer
+    (prin1 nix-buffer--trusted-exprs (current-buffer))
+    (write-region nil nil nix-buffer--trust-exprs-file))
+  nil)
+
+(defun nix-buffer--unique-filename (path)
+  "Create a unix-safe filename from an entire path.
+PATH the path to generate the name from."
+  (replace-regexp-in-string "[|\\/]"
+                            (lambda (str)
+                              (if (equal str "/")
+                                  "|"
+                                (concat "\\\\" str)))
+                            path))
+
+(defun nix-buffer--query-safety (expr-file lisp-file)
+  "Ask the user whether to trust a Lisp file.
+EXPR-FILE The nix expression leading to this file.
+
+LISP-FILE The file in question."
+  (let ((res (yes-or-no-p (concat expr-file
+                                  " resulted in unknown Lisp file "
+                                  lisp-file
+                                  "; trust it? "))))
+    (puthash lisp-file res nix-buffer--trusted-exprs)
+    res))
+
+(defvar nix-buffer-after-load-hook nil
+  "Hook run after nix-buffer loads an expression.")
+
+(defun nix-buffer--load-result (expr-file out)
+  "Load the result of a nix-buffer build, checking for safety.
+EXPR-FILE The nix expression being built.
+
+OUT The build result."
+  (when (or (gethash out nix-buffer--trusted-exprs)
+            (nix-buffer--query-safety expr-file out))
+    (load-file out)
+    (run-hooks 'nix-buffer-after-load-hook)))
+
+(defun nix-buffer--sentinel
+    (out-link last-out expr-file user-buf err-buf process event)
+  "Handle the results of the nix build.
+OUT-LINK The path to the output symlink.
+
+LAST-OUT The previous build result, if any.
+
+EXPR-FILE The nix expression being built.
+
+USER-BUF The buffer to apply the results to.
+
+ERR-BUF The standard error buffer of the nix-build
+
+PROCESS The process whose status changed.
+
+EVENT The process status change event string."
+  (unless (process-live-p process)
+    (let ((out-buf (process-buffer process)))
+      (progn
+        (if (= (process-exit-status process) 0)
+            (let ((cur-out (with-current-buffer out-buf
+                             (string-trim-right (buffer-string)))))
+              (if (string= "" cur-out)
+                  (ignore-errors (delete-file out-link))
+                (unless (string= last-out cur-out)
+                  (with-current-buffer user-buf
+                    (nix-buffer--load-result expr-file cur-out)))))
+          (with-current-buffer
+              (get-buffer-create "*nix-buffer errors*")
+            (insert "nix-build for nix-buffer for "
+                    (buffer-name user-buf)
+                    " "
+                    (string-trim-right event)
+                    " with error output: \n")
+            (insert-buffer-substring err-buf)
+            (pop-to-buffer (current-buffer))))
+        (kill-buffer out-buf)
+        (kill-buffer err-buf)))))
+
+(defun nix-buffer--nix-build (root expr-file)
+  "Start the nix build.
+ROOT The path we started from.
+
+EXPR-FILE The file containing the nix expression to build."
+  (let* ((state-dir (f-join nix-buffer-directory-name
+                            (nix-buffer--unique-filename root)))
+         (out-link (f-join state-dir "result"))
+         (current-out (file-symlink-p out-link))
+         (err (generate-new-buffer " nix-buffer-nix-build-stderr")))
+    (progn
+      (ignore-errors (make-directory state-dir t))
+      (make-process
+       :name "nix-buffer-nix-build"
+       :buffer (generate-new-buffer " nix-buffer-nix-build-stdout")
+       :command (list
+                 "nix-build"
+                 "--arg" "root" root
+                 "--out-link" out-link
+                 expr-file
+                 )
+       :noquery t
+       :sentinel (apply-partially 'nix-buffer--sentinel
+                                  out-link
+                                  current-out
+                                  expr-file
+                                  (current-buffer)
+                                  err)
+       :stderr err)
+      (when current-out
+        (nix-buffer--load-result expr-file current-out)))))
+
+;;;###autoload
+(defun nix-buffer ()
+  "Set up the buffer according to the directory-local nix expression.
+Looks for dir-locals.nix upward from the current directory.  If found,
+asynchronously builds the derivation defined there with the 'root' arg
+set to the current buffer file name or directory and evaluates the
+resulting elisp if safe to do so.  'nix-buffer-after-load-hook' can be
+used to detect when the elisp load occurs.
+
+If we have previously built dir-locals.nix for the current file or
+directory, the elisp corresponding to the last build is evaluated
+synchronously and the new elisp is evaluated when the build completes,
+unless the newly-built file is identical.  As such, the elisp
+generated by dir-locals.nix should be written with multiple
+evaluations in mind.
+
+Because in practice dir-locals.nix will always want to do things that
+are unsafe in dir-locals.el (e.g. append to 'exec-path'), we don't
+reuse that mechanism and instead just load the file as elisp.  Because
+this allows arbitrary code execution, the first time we're asked to
+load a particular store path we query the user to verify if it's safe
+to load beforehand.
+
+The Lisp code generated by dir-locals.nix should limit itself to
+modifying buffer-local variables, but there is no actual enforcement
+of this.  'setq-local' is your friend.
+
+If dir-locals.nix does not evaluate to any derivations (e.g. it
+evaluates to {}), then nothing is loaded and the cached result, if any,
+is removed."
+  (interactive)
+  (let* ((root (or (buffer-file-name) default-directory))
+         (expr-dir (locate-dominating-file root "dir-locals.nix")))
+    (when expr-dir
+      (let ((expr-file (f-expand "dir-locals.nix" expr-dir)))
+        (nix-buffer--nix-build root expr-file)))))
+
+(add-hook 'kill-emacs-hook 'nix-buffer-unload-function)
+
+(provide 'nix-buffer)
+
+;;; nix-buffer.el ends here
diff --git a/nix-mode-mmm.el b/nix-mode-mmm.el
new file mode 100644
index 0000000000..acfc8fef15
--- /dev/null
+++ b/nix-mode-mmm.el
@@ -0,0 +1,23 @@
+;;; nix-mode-mmm --- Summary
+
+;;; Commentary:
+
+;;; Code:
+
+(require 'mmm-mode)
+
+(mmm-add-group 'nix-sh
+ '((sh-command
+    :submode sh-mode
+    :face mmm-output-submode-face
+    :front "''"
+    :back "''"
+    :include-front t
+    :front-offset 2
+    )))
+
+(setq mmm-global-mode 'maybe)
+(mmm-add-mode-ext-class 'nix-mode "\\.nix\\'" 'nix-sh)
+
+(provide 'nix-mode-mmm)
+;;; nix-mode-mmm.el ends here
diff --git a/nix-sandbox.el b/nix-sandbox.el
new file mode 100644
index 0000000000..492a68d422
--- /dev/null
+++ b/nix-sandbox.el
@@ -0,0 +1,127 @@
+;;; nix-sandbox.el --- Utility functions to work with nix-shell sandboxes
+
+;; Copyright (C) 2015 Sven Keidel
+
+;; Author: Sven Keidel <svenkeidel@gmail.com>
+;; Package-Version: 0.1
+;; Package-Requires: ((dash "2.12.1") (s "1.10.0"))
+;; Homepage: https://github.com/travisbhartwell/nix-emacs
+
+;; This file is not part of GNU Emacs.
+
+;;; License: GPLv3
+
+;;; Commentary:
+
+;; Useful functions for working with nix-shell sandboxes
+
+;;; Code:
+
+(require 'dash)
+(require 's)
+
+(defgroup nix nil
+  "customizations for nix"
+  :prefix "nix-"
+  :group 'external)
+
+(defcustom nix-nixpkgs-path nil
+  "Absolute path to a nixpkgs directory.
+
+Can be customized to select a nix-channel
+e.g. /home/user/.nix-defexpr/channels/unstable/nixpkgs"
+  :group 'nix
+  :type '(choice (const :tag "No channel" nil)
+                 (directory "Custom path to a nixpkgs distribution")))
+
+(defun nix-create-sandbox-rc (sandbox)
+  "Create a new rc file containing the environment for the given SANDBOX."
+  (let ((env-str (shell-command-to-string
+                  (concat "nix-shell "
+                          (or (and nix-nixpkgs-path (concat "-I nixpkgs=" 
nix-nixpkgs-path))
+                              "")
+                          " --run 'declare +x shellHook; declare -x; declare 
-xf' "
+                          (shell-quote-argument sandbox)
+                          " 2> /dev/null")))
+        (tmp-file (make-temp-file "nix-sandbox-rc-")))
+    (write-region env-str nil tmp-file 'append)
+    tmp-file))
+
+(defvar nix-sandbox-rc-map (make-hash-table :test 'equal
+                                            :size 4))
+
+(defun nix-sandbox-rc (sandbox)
+  "Return the rc file for the given SANDBOX or create one."
+  (or (gethash sandbox nix-sandbox-rc-map)
+      (puthash sandbox (nix-create-sandbox-rc sandbox) nix-sandbox-rc-map)))
+
+;;;###autoload
+(defun nix-shell-command (sandbox &rest args)
+  "Assemble a command from ARGS that can be executed in the specified SANDBOX."
+  (list "bash" "-c" (format "source %s; %s" (nix-sandbox-rc sandbox) (s-join " 
" args))))
+
+(defun nix-shell-string (sandbox &rest args)
+  "Assemble a command string from ARGS that can be executed in the specifed 
SANDBOX."
+  (combine-and-quote-strings
+   (apply 'nix-shell-command sandbox args)))
+
+;;;###autoload
+(defun nix-compile (sandbox &rest command)
+  "Compile a program using the given COMMAND in SANDBOX."
+  (interactive "Dsandbox: \nMcommand: ")
+  (compile (apply 'nix-shell-string sandbox command)))
+
+;;;###autoload
+(defun nix-shell (sandbox &rest command)
+  "Run a COMMAND in the given SANDBOX and return the output."
+  (shell-command-to-string (apply 'nix-shell-string sandbox command)))
+
+(defvar nix-exec-path-map (make-hash-table :test 'equal
+                                           :size 4))
+
+;;;###autoload
+(defun nix-exec-path (sandbox)
+  "Return the `exec-path' of the given SANDBOX."
+
+  (or (gethash sandbox nix-exec-path-map)
+      (puthash sandbox
+               (split-string (nix-shell sandbox "printenv" "PATH") ":")
+               nix-exec-path-map)))
+
+;;;###autoload
+(defun nix-executable-find (sandbox executable)
+  "Search for an EXECUTABLE in the given SANDBOX."
+  (let ((exec-path (nix-exec-path sandbox)))
+    (and exec-path (executable-find executable))))
+
+;;;###autoload
+(defun nix-find-sandbox (path)
+  "Search for a sandbox starting at PATH traversing upwards the directory tree.
+If the directory contains a `shell.nix' file, the path to this
+file is returned.  Otherwise if the directory contains a
+`default.nix' file, the parent directory is returned."
+  (and (file-exists-p path)
+       (let* ((map-nil (lambda (f x) (if x (funcall f x) nil)))
+              (sandbox-directory
+               (funcall map-nil 'expand-file-name
+                        (locate-dominating-file path
+                                                '(lambda (dir) 
(directory-files dir t ".*\.nix$")))))
+              (shell-nix (and sandbox-directory (concat sandbox-directory 
"shell.nix"))))
+         (if (and sandbox-directory (file-exists-p shell-nix))
+             shell-nix
+           sandbox-directory))))
+
+;;;###autoload
+(defun nix-current-sandbox ()
+  "Return the path of the sandbox that is closest to the current working 
directory."
+  (nix-find-sandbox default-directory))
+
+(defun nix-clear-caches ()
+  "Clear cached information for all sandboxes."
+  (interactive)
+  (clrhash nix-sandbox-rc-map)
+  (clrhash nix-exec-path-map))
+
+(provide 'nix-sandbox)
+
+;;; nix-sandbox.el ends here
diff --git a/nix-smie.el b/nix-smie.el
new file mode 100644
index 0000000000..cad6eb7077
--- /dev/null
+++ b/nix-smie.el
@@ -0,0 +1,121 @@
+;;; nix-mode+.el --- Major mode to edit Nix files
+
+;; Copyright (C) 2014 Jenny Cassou
+
+;; Author: Jenny Cassou <damien.cassou@gmail.com>
+;; Version: 0.1
+
+;; This file is not part of GNU Emacs.
+
+;; This program is free software: you can redistribute it and/or modify
+;; it under the terms of the GNU General Public License as published by
+;; the Free Software Foundation, either version 3 of the License, or
+;; (at your option) any later version.
+
+;; This program is distributed in the hope that it will be useful,
+;; but WITHOUT ANY WARRANTY; without even the implied warranty of
+;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+;; GNU General Public License for more details.
+
+;; You should have received a copy of the GNU General Public License
+;; along with this program.  If not, see <http://www.gnu.org/licenses/>.
+
+;;; Commentary:
+
+;; Major mode to edit Nix files
+
+;;; Code:
+(require 'smie)
+
+(defvar nix+-smie-grammar
+  (smie-prec2->grammar
+   (smie-bnf->prec2
+    '((id)
+      (expr (exprfunction))
+      (exprfunction ("{" formals "}" ":" exprfunction)
+                    (exprassert))
+      (exprassert ("assert" expr ";" exprassert)
+                  (exprif))
+      (exprif ("if" expr "then" expr "else" expr)
+              (exprop))
+      (exprop ("!" exprop)
+              (exprop "==" exprop)
+              (exprop "!=" exprop)
+              (exprop "&&" exprop)
+              (exprop "||" exprop)
+              (exprop "->" exprop)
+              (exprop "//" exprop)
+              (exprop "~" exprop)
+              (exprop "?" id)
+              (exprapp))
+      (exprapp (exprapp "." exprselect)
+               (exprselect))
+      (exprselect (exprsimple))
+      (exprsimple (id)
+                  ("true")
+                  ("false")
+                  ("null")
+                  ("(" expr ")")
+                  ("{" binds "}")
+                  ("let" "{" binds "}")
+                  ("rec" "{" binds "}")
+                  ("[" exprselects "]"))
+      (binds (binds ";" binds)
+             (bind))
+      (exprselects (expreselect))
+      (bind (id "=" expr)
+            ("inherit" exprp))
+      (exprp ("(" expr ")"))
+      (formals (formals "," formals)
+               (formal))
+      (formal (id)
+              (id "?" expr)))
+    '((assoc ";"))
+    '((assoc ","))
+    '((assoc "==")
+      (assoc "!=")
+      (assoc "&&")
+      (assoc "||")
+      (assoc "->")
+      (assoc "//")
+      (assoc "~")
+      (assoc "?")
+      (assoc "!")))))
+
+(defvar nix+-syntax-table
+  (let ((table (make-syntax-table)))
+    (modify-syntax-entry ?/ ". 14" table)
+    (modify-syntax-entry ?* ". 23" table)
+    (modify-syntax-entry ?# "< b" table)
+    (modify-syntax-entry ?\n "> b" table)
+    table)
+  "Syntax table for Nix mode.")
+
+;;;###autoload
+(define-derived-mode nix-mode+ prog-mode "Nix"
+  "Major mode for editing Nix expressions.
+
+The following commands may be useful:
+
+  '\\[newline-and-indent]'
+    Insert a newline and move the cursor to align with the previous
+    non-empty line.
+
+  '\\[fill-paragraph]'
+    Refill a paragraph so that all lines are at most `fill-column'
+    lines long.  This should do the right thing for comments beginning
+    with `#'.  However, this command doesn't work properly yet if the
+    comment is adjacent to code (i.e., no intervening empty lines).
+    In that case, select the text to be refilled and use
+    `\\[fill-region]' instead.
+
+The hook `nix-mode-hook' is run when Nix mode is started.
+
+\\{nix-mode-map}
+"
+  (set-syntax-table nix+-syntax-table)
+  (smie-setup nix+-smie-grammar #'ignore))
+
+(provide 'nix-mode+)
+
+;;; nix-mode+.el ends here
diff --git a/nixos-options.el b/nixos-options.el
new file mode 100644
index 0000000000..89ace9bbc4
--- /dev/null
+++ b/nixos-options.el
@@ -0,0 +1,128 @@
+;;; nixos-options.el --- Interface for browsing and completing NixOS options.
+
+;; Copyright (C) 2015 Diego Berrocal and Travis B. Hartwell
+
+;; Author: Diego Berrocal <cestdiego@gmail.com>
+;;      Travis B. Hartwell <nafai@travishartwell.net>
+;; Created: 18 July 2015
+
+;; Keywords: unix
+;; Homepage: http://www.github.com/travisbhartwell/nix-emacs/
+;; Version: 0.0.1
+;; Package-Requires: ((emacs "24"))
+
+;; This file is not part of GNU Emacs.
+
+;;; License: GPLv3
+
+;;; Commentary:
+
+;; Useful functions for exploring the NixOS options.  Inspired by
+;; https://nixos.org/nixos/options.html.
+
+;;; Code:
+
+(require 'json)
+
+(defvar nixos-options-name-indent-amount 0
+  "Indent by the maximum length, plus a colon, plus two spaces.")
+
+;; Macros for defining constants and functions for working with options
+(defmacro define-nixos-options-item (item long-name)
+  (let* ((name-const (intern (concat "nixos-options-" item)))
+         (long-name-const (intern (concat "nixos-options-" item "-long-name")))
+         (long-name-length-plus-padding (+ 3 (length long-name)))
+         (long-name-docstring (format "The long description for %s." item))
+         (item-getter (intern (concat "nixos-options-get-" item)))
+         (item-getter-docstring
+          (format "Get the value of %s from OPTION." item))
+         (item-display (intern (concat "nixos-options-display-" item)))
+         (item-display-docstring
+          (format "Display the value for %s from OPTION." item)))
+    `(progn
+       (defconst ,name-const ,item)
+       (defconst ,long-name-const ,long-name ,long-name-docstring)
+       (if (> ,long-name-length-plus-padding nixos-options-name-indent-amount)
+           (setq nixos-options-name-indent-amount
+                 ,long-name-length-plus-padding))
+       (defun ,item-getter (option)
+         ,item-getter-docstring
+         (cdr (assoc ,name-const option)))
+       (defun ,item-display (option)
+         ,item-display-docstring
+         (let ((item (,item-getter option))
+               (format-string
+                (format "%%-%ds %%s\n" nixos-options-name-indent-amount)))
+           (if (not (null item))
+               (format format-string (concat ,long-name-const ":") item)
+             ""))))))
+
+(define-nixos-options-item "name" "Name")
+(define-nixos-options-item "type" "Type")
+(define-nixos-options-item "description" "Description")
+(define-nixos-options-item "default" "Default value")
+(define-nixos-options-item "example" "Example value")
+(define-nixos-options-item "declarations" "Declared in")
+
+(defvar nixos-options-json-file
+  (let* ((cmd
+          "export NIXPKGS_ALLOW_UNFREE=1; nix-build -Q --no-out-link 
'<nixpkgs/nixos/release.nix>' -A options 2>/dev/null")
+         (dir (replace-regexp-in-string "\n\\'" ""
+                                        (shell-command-to-string cmd))))
+    (expand-file-name "share/doc/nixos/options.json" dir))
+  "Location of the options file.")
+
+(defun nixos-options--boolean-string (value)
+  "Return the string representation of the boolean VALUE.
+Returns VALUE unchanged if not a boolean."
+  (cond ((eq value 't) "true")
+        ((eq value :json-false) "false")
+        (t value)))
+
+(defun nixos-options--make-alist (option)
+  (let ((name (car option))
+        (data (cdr option))
+        (default (nixos-options-get-default option))
+        (example (nixos-options-get-example option)))
+    (progn
+      (if (not (null default))
+          (setcdr (assoc nixos-options-default option)
+                  (nixos-options--boolean-string default)))
+      (if (not (null example))
+          (setcdr (assoc nixos-options-example option)
+                  (nixos-options--boolean-string example)))
+      (add-to-list 'data `(,nixos-options-name . ,name))
+      `(,name . ,data))))
+
+(defvar nixos-options
+  (if (file-exists-p nixos-options-json-file)
+      (let* ((json-key-type 'string)
+             (raw-options (json-read-file nixos-options-json-file)))
+        (mapcar 'nixos-options--make-alist raw-options))
+    (message "Warning: Cannot find nixos option file.")))
+
+(defun nixos-options-get-documentation-for-option (option)
+  (concat (nixos-options-display-name option)
+          (nixos-options-display-type option)
+          (nixos-options-display-description option)
+          (nixos-options-display-default option)
+          (nixos-options-display-example option)
+          (nixos-options-display-declarations option)))
+
+;; Borrowed from anaconda-mode
+(defun nixos-options-doc-buffer (doc)
+  "Display documentation buffer with contents DOC."
+  (let ((buf (get-buffer-create "*nixos-options-doc*")))
+    (with-current-buffer buf
+      (view-mode -1)
+      (erase-buffer)
+      (insert doc)
+      (goto-char (point-min))
+      (view-mode 1)
+      buf)))
+
+(defun nixos-options-get-option-by-name (name)
+  (assoc name nixos-options))
+
+(provide 'nixos-options)
+;;; nixos-options.el ends here
diff --git a/nixos-packages.el b/nixos-packages.el
new file mode 100644
index 0000000000..bc21c4e3e4
--- /dev/null
+++ b/nixos-packages.el
@@ -0,0 +1,115 @@
+;;; nixos-packages.el --- Interface for browsing and completing NixOS packages.
+
+;; Copyright (C) 2015 Diego Berrocal and Travis B. Hartwell
+
+;; Author: Diego Berrocal <cestdiego@gmail.com>
+;;      Travis B. Hartwell <nafai@travishartwell.net>
+;; Created: 18 July 2015
+
+;; Keywords: unix
+;; Homepage: http://www.github.com/travisbhartwell/nix-emacs/
+;; Version: 0.0.1
+;; Package-Requires: ((emacs "24"))
+
+;; This file is not part of GNU Emacs.
+
+;;; License: GPLv3
+
+;;; Commentary:
+
+;; Useful functions for exploring the NixOS packages.  Inspired by
+;; https://nixos.org/nixos/packages.html.
+
+;;; Code:
+
+(require 'json)
+
+(defvar nixos-packages-json-file
+  (expand-file-name "nixos-packages.json" spacemacs-cache-directory)
+  "Where to store the nixos-packages in JSON format")
+
+(defvar nixos-packages-name-indent-amount 0
+  "Indent by the maximum length, plus a colon, plus two spaces.")
+
+(setq nixos-packages
+      (if (file-exists-p nixos-packages-json-file)
+          (let ((json-key-type 'string))
+            (json-read-file nixos-packages-json-file))
+        (let* ((cmd "nix-env -qaP hello --json")
+               (data (replace-regexp-in-string "\n\\'" ""
+                                               (shell-command-to-string cmd)))
+               (json-key-type 'string))
+          (append-to-file data nil nixos-packages-json-file)
+          (json-read-from-string data))))
+
+
+(assoc "name" (car nixos-packages))
+(assoc "system" (car nixos-packages))
+(assoc "description" (assoc "meta" (car nixos-packages)))
+(assoc "homepage" (assoc "meta" (car nixos-packages)))
+(assoc "license" (assoc "meta" (car nixos-packages)))
+(assoc "longDescription" (assoc "meta" (car nixos-packages)))
+(assoc "platforms" (assoc "meta" (car nixos-packages)))
+(assoc "position" (assoc "meta" (car nixos-packages)))
+(assoc "maintainers" (assoc "meta" (car nixos-packages)))
+(assoc "maintainers" (assoc "meta" (car nixos-packages)))
+
+;; Macros for defining constants and functions for working with options
+(defmacro define-nixos-packages-item (item long-name &optional isMeta?)
+  (let* ((name-const (intern (concat "nixos-packages-" item)))
+         (long-name-const (intern (concat "nixos-packages-" item 
"-long-name")))
+         (long-name-length-plus-padding (+ 3 (length long-name)))
+         (long-name-docstring (format "The long description for %s." item))
+         (item-getter (intern (concat "nixos-packages-get-" item)))
+         (item-getter-docstring
+          (format "Get the value of %s from PACKAGE" item))
+         (item-display (intern (concat "nixos-packages-display-" item)))
+         (item-display-docstring
+          (format "Display the value for %s from PACKAGE" item)))
+    `(progn
+       (defconst ,name-const ,item)
+       (defconst ,long-name-const ,long-name ,long-name-docstring)
+       (if (> ,long-name-length-plus-padding nixos-packages-name-indent-amount)
+           (setq nixos-packages-name-indent-amount
+                 ,long-name-length-plus-padding))
+       (if ,isMeta?
+           (defun ,item-getter (option)
+             ,item-getter-docstring
+             (cdr (assoc ,name-const (assoc "meta" option))))
+         (defun ,item-getter (option)
+           ,item-getter-docstring
+           (cdr (assoc ,name-const option))))
+
+       (defun ,item-display (option)
+         ,item-display-docstring
+         (let ((item (,item-getter option))
+               (format-string
+                (format "%%-%ds %%s\n" nixos-packages-name-indent-amount)))
+           (if (not (null item))
+               (format format-string (concat ,long-name-const ":") item)
+             ""))))))
+
+(define-nixos-packages-item "description" "Description" t)
+(define-nixos-packages-item "homepage" "Home Page URL" t)
+(define-nixos-packages-item "license" "License" t)
+(define-nixos-packages-item "longDescription" "Long Description" t)
+(define-nixos-packages-item "platforms" "Supported Platforms" t)
+(define-nixos-packages-item "maintainers" "List of Maintainers" t)
+(define-nixos-packages-item "position" "Path to the nix-expression with line" 
t)
+(define-nixos-packages-item "name" "Name")
+(define-nixos-packages-item "system" "System")
+
+(defun nixos-packages--make-alist (package)
+  (let ((name (car package))
+        (data (cdr package))
+        (default (nixos-options-get-default package))
+        (example (nixos-options-get-example package)))
+    (progn
+      (if (not (null default))
+          (setcdr (assoc nixos-options-default package)
+                  (nixos-options--boolean-string default)))
+      (if (not (null example))
+          (setcdr (assoc nixos-options-example package)
+                  (nixos-options--boolean-string example)))
+      (add-to-list 'data `(,nixos-options-name . ,name))
+      `(,name . ,data))))



reply via email to

[Prev in Thread] Current Thread [Next in Thread]