branch: elpa/nix-mode commit 4076a86333cb9ec4f8b8126b0c3ba006c98ab2eb Merge: 3e6fdd8311 66cc5478de Author: Matthew Justin Bauer <mjbaue...@gmail.com> Commit: GitHub <nore...@github.com>
Merge pull request #17 from matthewbauer/separate-files Move separate modes into own files. --- nix-company.el | 65 ++++++++++++++++++++++ nix-flycheck.el | 18 +++--- nix-format.el | 36 ++++++++++++ nix-mode.el | 168 ++------------------------------------------------------ nix-repl.el | 88 +++++++++++++++++++++++++++++ 5 files changed, 202 insertions(+), 173 deletions(-) diff --git a/nix-company.el b/nix-company.el new file mode 100644 index 0000000000..faddd7c15f --- /dev/null +++ b/nix-company.el @@ -0,0 +1,65 @@ +;; -*- lexical-binding: t -*- +;;; nix-company.el --- Company support for Nix + +;; This file is NOT part of GNU Emacs. + +;;; Commentary: + +;;; Code: + +(require 'nix-repl) +(require 'cl) + +(defun company-nix (command &optional arg &rest ignored) + (interactive '(interactive)) + (case command + (interactive (company-begin-backend 'company-nix)) + (prefix (and (member major-mode '(nix-mode nix-repl-mode)) + (nix-grab-attr-path))) + (candidates + (nix-get-completions (get-buffer-process (nix--get-company-buffer)) arg)) + (sorted t))) + +(defun nix-grab-attr-path () + (if (looking-at "[^a-zA-Z0-9'\\-_\\.]") + (buffer-substring (point) (save-excursion (skip-chars-backward "a-zA-Z0-9'\\-_\\.") + (point))) + (unless (and (char-after) + (string-match "[a-zA-Z0-9'\\-_]" (char-to-string (char-after))) + "")))) + +(defun nix--get-company-buffer (&optional buffer) + (let* ((buf (or buffer (current-buffer))) + (repl-buf (get-buffer "*Nix-REPL*"))) + (if (or (equal buf "*Nix-REPL*") (equal buf repl-buf)) + repl-buf + (nix--get-company-backend-buffer buf)))) + +(defvar nix-company-backend-buffer-name " *nix-company-backend*") +(defvar nix--company-last-buffer nil) + +(defun nix--get-company-backend-buffer (buffer) + (let* ((buf-file (buffer-file-name buffer)) + (backend-buf (get-buffer-create nix-company-backend-buffer-name)) + (last-buf nix--company-last-buffer) + (proc (get-buffer-process backend-buf))) + (with-current-buffer buffer + (if (and proc + (process-live-p proc)) + (if (not (string= last-buf (buffer-name))) + (progn (quit-process proc) + (nix--make-repl-in-buffer backend-buf) + (nix--send-repl (concat ":l " buf-file "\n") + (get-buffer-process backend-buf) t) + (setq nix--company-last-buffer (buffer-name))) + (nix--send-repl ":r\n" proc t)) + (progn (nix--make-repl-in-buffer backend-buf) + (nix--send-repl (concat ":l " buf-file "\n") + (get-buffer-process backend-buf) t) + (setq nix--company-last-buffer (buffer-name)))) + backend-buf))) + +(add-to-list 'company-backends 'company-nix) + +(provide 'nix-company) +;;; nix-company.el ends here diff --git a/nix-flycheck.el b/nix-flycheck.el index aca5ce8b36..505c296410 100644 --- a/nix-flycheck.el +++ b/nix-flycheck.el @@ -33,15 +33,15 @@ (flycheck-def-args-var flycheck-nix-args (nix)) -(flycheck-define-checker nix - "A syntax and evaluation checker for Nix using nix-instantiate." - :command ("nix-instantiate" "--eval" "--strict" "--show-trace" (eval flycheck-nix-args) "-") - :standard-input t - :error-parser nix--parse-errors - :modes (nix-mode) - ) - -(add-to-list 'flycheck-checkers 'nix) +(flycheck-define-checker flycheck-nix + "A syntax and evaluation checker for Nix using nix-instantiate." + :command ("nix-instantiate" "--eval" "--strict" "--show-trace" (eval flycheck-nix-args) "-") + :standard-input t + :error-parser nix--parse-errors + :modes (nix-mode) + ) + +(add-to-list 'flycheck-checkers 'flycheck-nix) (provide 'nix-flycheck) ;;; nix-flycheck.el ends here diff --git a/nix-format.el b/nix-format.el new file mode 100644 index 0000000000..b0b0b23f90 --- /dev/null +++ b/nix-format.el @@ -0,0 +1,36 @@ +;; -*- lexical-binding: t -*- +;;; nix-format.el --- Nix formatter + +;; This file is NOT part of GNU Emacs. + +;;; Commentary: + +;;; Code: + +(defcustom nix-nixfmt-bin "nixfmt" + "Path to nixfmt executable." + :group 'nix + :type 'string) + +(defun nix--format-call (buf) + "Format BUF using nixfmt." + (with-current-buffer (get-buffer-create "*nixfmt*") + (erase-buffer) + (insert-buffer-substring buf) + (if (zerop (call-process-region (point-min) (point-max) nix-nixfmt-bin t t nil)) + (progn + (if (not (string= (buffer-string) (with-current-buffer buf (buffer-string)))) + (copy-to-buffer buf (point-min) (point-max))) + (kill-buffer)) + (error "Nixfmt failed, see *nixfmt* buffer for details")))) + +(defun nix-format-buffer () + "Format the current buffer using nixfmt." + (interactive) + (unless (executable-find nix-nixfmt-bin) + (error "Could not locate executable \"%s\"" nix-nixfmt-bin)) + (nix--format-call (current-buffer)) + (message "Formatted buffer with rustfmt.")) + +(provide 'nix-format) +;;; nix-format.el ends here diff --git a/nix-mode.el b/nix-mode.el index a9b8337297..b8d2469ee6 100644 --- a/nix-mode.el +++ b/nix-mode.el @@ -16,13 +16,15 @@ ;;; Code: +(require 'cl) + ;; Emacs 24.2 compatability (unless (fboundp 'setq-local) (defmacro setq-local (var val) "Set variable VAR to value VAL in current buffer." `(set (make-local-variable ',var) ,val))) -(require 'cl) +(require 'nix-format) ;;; Syntax coloring @@ -258,139 +260,6 @@ ) start end)) - -;;; REPL - -(defvar nix-prompt-regexp "nix-repl> ") - -(define-derived-mode nix-repl-mode comint-mode "Nix-REPL" - "Interactive prompt for Nix." - (setq-local comint-prompt-regexp nix-prompt-regexp) - (setq-local comint-prompt-read-only t) - (add-to-list 'company-backends 'company-nix) - (company-mode)) - -(defun nix-repl-show () - "Load the Nix-REPL." - (interactive) - (pop-to-buffer-same-window - (get-buffer-create "*Nix-REPL*")) - (unless (comint-check-proc (current-buffer)) - (nix--make-repl-in-buffer (current-buffer)) - (nix-repl-mode))) - -(defun nix--make-repl-in-buffer (buffer) - (make-comint-in-buffer "Nix-REPL" buffer "nix-repl")) - -;;; Company - -(defun company-nix (command &optional arg &rest ignored) - (interactive '(interactive)) - (case command - (interactive (company-begin-backend 'company-nix)) - (prefix (and (member major-mode '(nix-mode nix-repl-mode)) - (nix-grab-attr-path))) - (candidates - (nix-get-completions (get-buffer-process (nix--get-company-buffer)) arg)) - (sorted t))) - -(defun nix-grab-attr-path () - (if (looking-at "[^a-zA-Z0-9'\\-_\\.]") - (buffer-substring (point) (save-excursion (skip-chars-backward "a-zA-Z0-9'\\-_\\.") - (point))) - (unless (and (char-after) - (string-match "[a-zA-Z0-9'\\-_]" (char-to-string (char-after))) - "")))) - -(defun nix--get-company-buffer (&optional buffer) - (let* ((buf (or buffer (current-buffer))) - (repl-buf (get-buffer "*Nix-REPL*"))) - (if (or (equal buf "*Nix-REPL*") (equal buf repl-buf)) - repl-buf - (nix--get-company-backend-buffer buf)))) - -(defvar nix-company-backend-buffer-name " *nix-company-backend*") -(defvar nix--company-last-buffer nil) - -(defun nix--get-company-backend-buffer (buffer) - (let* ((buf-file (buffer-file-name buffer)) - (backend-buf (get-buffer-create nix-company-backend-buffer-name)) - (last-buf nix--company-last-buffer) - (proc (get-buffer-process backend-buf))) - (with-current-buffer buffer - (if (and proc - (process-live-p proc)) - (if (not (string= last-buf (buffer-name))) - (progn (quit-process proc) - (nix--make-repl-in-buffer backend-buf) - (nix--send-repl (concat ":l " buf-file "\n") - (get-buffer-process backend-buf) t) - (setq nix--company-last-buffer (buffer-name))) - (nix--send-repl ":r\n" proc t)) - (progn (nix--make-repl-in-buffer backend-buf) - (nix--send-repl (concat ":l " buf-file "\n") - (get-buffer-process backend-buf) t) - (setq nix--company-last-buffer (buffer-name)))) - backend-buf))) - -(defun nix-get-completions (proc prefix) - (save-match-data - (nix--with-temp-process-filter proc - (goto-char (point-min)) - (process-send-string proc (concat prefix "\t\"" (nix--char-with-ctrl ?a) "\"\n")) - (setq i 0) - (while (and (< (setq i (1+ i)) 100) - (not (search-forward-regexp "\"\\([^\"]*\\)\"[\n]*nix-repl>" nil t))) - (sleep-for 0.01)) - (let ((new-prefix (match-string 1)) - (start-compl (point))) - (if (string-suffix-p " " new-prefix) - (list (substring new-prefix 0 -1)) - (process-send-string proc (concat new-prefix "\t\t" (nix--char-with-ctrl ?u) "\n")) - (goto-char start-compl) - (setq i 0) - (while (and (< (setq i (1+ i)) 100) - (not (search-forward-regexp - "[\n]+nix-repl>\\|Display all \\([0-9]+\\)" nil t))) - (sleep-for 0.01)) - (if (match-string 1) - (progn - (process-send-string proc "n") - '()) - (search-backward "\n" nil t) - (split-string (buffer-substring start-compl (1- (point)))))))))) - -(defun nix--send-repl (input &optional process mute) - (let ((proc (or process (get-buffer-process (current-buffer))))) - (if mute - (nix--with-temp-process-filter proc - (process-send-string proc input)) - (process-send-string proc input)))) - -(defun nix--char-with-ctrl (char) - (char-to-string (logand #b10011111 char))) - -(defmacro nix--with-temp-process-filter (proc &rest body) - (declare (indent defun)) - `(let* ((buf (generate-new-buffer " *temp-process-output*")) - (proc-filter-saved (process-filter ,proc)) - (proc-marker (with-current-buffer buf (point-marker)))) - (set-process-filter ,proc (nix--process-filter buf proc-marker)) - (unwind-protect - (with-current-buffer buf - ,@body) - (set-process-filter ,proc proc-filter-saved) - (kill-buffer buf)))) - -(defun nix--process-filter (buf marker) - (lambda (proc string) - (when (buffer-live-p buf) - (with-current-buffer buf - (save-excursion - (goto-char marker) - (insert string) - (set-marker marker (point))))))) - ;;; Indentation (defun nix-indent-level-parens () @@ -525,33 +394,6 @@ (if (looking-at nix-re-file-path) (find-file (match-string-no-properties 0))))) -;; Formatting - -(defcustom nix-nixfmt-bin "nixfmt" - "Path to nixfmt executable." - :group 'nix - :type 'string) - -(defun nix--format-call (buf) - "Format BUF using nixfmt." - (with-current-buffer (get-buffer-create "*nixfmt*") - (erase-buffer) - (insert-buffer-substring buf) - (if (zerop (call-process-region (point-min) (point-max) nix-nixfmt-bin t t nil)) - (progn - (if (not (string= (buffer-string) (with-current-buffer buf (buffer-string)))) - (copy-to-buffer buf (point-min) (point-max))) - (kill-buffer)) - (error "Nixfmt failed, see *nixfmt* buffer for details")))) - -(defun nix-format-buffer () - "Format the current buffer using nixfmt." - (interactive) - (unless (executable-find nix-nixfmt-bin) - (error "Could not locate executable \"%s\"" nix-nixfmt-bin)) - (nix--format-call (current-buffer)) - (message "Formatted buffer with rustfmt.")) - ;; Key maps (defvar nix-mode-menu (make-sparse-keymap "Nix") @@ -578,9 +420,7 @@ (when (featurep 'flycheck) (require 'nix-flycheck nil 'noerror)) -(when (require 'company nil 'noerror) (add-to-list - 'company-backends - 'company-nix)) +(when (require 'company nil 'noerror) (require 'nix-company nil 'noerror)) ;;;###autoload (define-derived-mode nix-mode prog-mode "Nix" diff --git a/nix-repl.el b/nix-repl.el new file mode 100644 index 0000000000..1096676186 --- /dev/null +++ b/nix-repl.el @@ -0,0 +1,88 @@ +;; -*- lexical-binding: t -*- +;;; nix-repl.el --- Nix repl + +;; This file is NOT part of GNU Emacs. + +;;; Commentary: + +;;; Code: + +(defvar nix-prompt-regexp "nix-repl> ") + +(define-derived-mode nix-repl-mode comint-mode "Nix-REPL" + "Interactive prompt for Nix." + (setq-local comint-prompt-regexp nix-prompt-regexp) + (setq-local comint-prompt-read-only t)) + +(defun nix-repl-show () + "Load the Nix-REPL." + (interactive) + (pop-to-buffer-same-window + (get-buffer-create "*Nix-REPL*")) + (unless (comint-check-proc (current-buffer)) + (nix--make-repl-in-buffer (current-buffer)) + (nix-repl-mode))) + +(defun nix--make-repl-in-buffer (buffer) + (make-comint-in-buffer "Nix-REPL" buffer "nix-repl")) + +(defun nix-get-completions (proc prefix) + (save-match-data + (nix--with-temp-process-filter proc + (goto-char (point-min)) + (process-send-string proc (concat prefix "\t\"" (nix--char-with-ctrl ?a) "\"\n")) + (setq i 0) + (while (and (< (setq i (1+ i)) 100) + (not (search-forward-regexp "\"\\([^\"]*\\)\"[\n]*nix-repl>" nil t))) + (sleep-for 0.01)) + (let ((new-prefix (match-string 1)) + (start-compl (point))) + (if (string-suffix-p " " new-prefix) + (list (substring new-prefix 0 -1)) + (process-send-string proc (concat new-prefix "\t\t" (nix--char-with-ctrl ?u) "\n")) + (goto-char start-compl) + (setq i 0) + (while (and (< (setq i (1+ i)) 100) + (not (search-forward-regexp + "[\n]+nix-repl>\\|Display all \\([0-9]+\\)" nil t))) + (sleep-for 0.01)) + (if (match-string 1) + (progn + (process-send-string proc "n") + '()) + (search-backward "\n" nil t) + (split-string (buffer-substring start-compl (1- (point)))))))))) + +(defun nix--send-repl (input &optional process mute) + (let ((proc (or process (get-buffer-process (current-buffer))))) + (if mute + (nix--with-temp-process-filter proc + (process-send-string proc input)) + (process-send-string proc input)))) + +(defun nix--char-with-ctrl (char) + (char-to-string (logand #b10011111 char))) + +(defmacro nix--with-temp-process-filter (proc &rest body) + (declare (indent defun)) + `(let* ((buf (generate-new-buffer " *temp-process-output*")) + (proc-filter-saved (process-filter ,proc)) + (proc-marker (with-current-buffer buf (point-marker)))) + (set-process-filter ,proc (nix--process-filter buf proc-marker)) + (unwind-protect + (with-current-buffer buf + ,@body) + (set-process-filter ,proc proc-filter-saved) + (kill-buffer buf)))) + +(defun nix--process-filter (buf marker) + (lambda (proc string) + (when (buffer-live-p buf) + (with-current-buffer buf + (save-excursion + (goto-char marker) + (insert string) + (set-marker marker (point))))))) + +(provide 'nix-repl) +;;; nix-repl.el ends here