tvl-depot/configs/shared/emacs/.emacs.d/elpa/nix-mode-20180908.2240/nix-repl.el
William Carroll 9da3ffee41 Update Emacs packages
This is a massive diff that I had to do in a hurry - when leaving
Urbint. I'm pretty sure that most of these are updating Emacs packages,
but I'm not positive.
2018-10-02 09:54:39 -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