tvl-depot/configs/shared/emacs/.emacs.d/elpa/nix-mode-20180822.214/nix-repl.el
William Carroll 17ee0e400b Support Vim, Tmux, Emacs with Stow
After moving off of Meta, Dotfiles has a greater responsibility to
manage configs. Vim, Tmux, and Emacs are now within Stow's purview.
2018-09-10 14:53:23 -04:00

112 lines
4.2 KiB
EmacsLisp
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

;;; nix-repl.el --- Nix repl -*- lexical-binding: t -*-
;; This file is NOT part of GNU Emacs.
;;; Commentary:
;;; Code:
(defvar nix-prompt-regexp "nix-repl> ")
(require 'comint)
(require 'nix)
(defgroup nix-repl nil
"nix-repl customizations"
:group 'nix)
(defcustom nix-repl-executable-args '("repl")
"Arguments to provide to nix-repl."
:type 'list)
(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))
(defmacro nix--with-temp-process-filter (proc &rest body)
"Use temp process PROC filter on 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))))
;;;###autoload
(defun nix-repl ()
"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)))
(defalias 'nix-repl-show 'nix-repl)
(defun nix--make-repl-in-buffer (buffer)
"Make Nix Repl in BUFFER."
(apply
'make-comint-in-buffer
(append `("Nix-REPL" ,buffer ,nix-executable nil)
nix-repl-executable-args)))
(defun nix-get-completions (proc prefix)
"Get Nix completions from Nix-repl process PROC and based off of 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"))
(let ((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)
"Send INPUT to PROCESS.
MUTE if true then dont alert user."
(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)
"Generate control character CHAR."
(char-to-string (logand #b10011111 char)))
(defun nix--process-filter (buf marker)
"Process filter for Nix-rel buffer BUF at 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