Add elpa packages

This commit is contained in:
nemunaire 2026-01-24 09:39:42 +08:00
commit afd61b5209
197 changed files with 76816 additions and 0 deletions

View file

@ -0,0 +1,222 @@
;;; nix-repl.el --- Nix repl -*- lexical-binding: t -*-
;; This file is NOT part of GNU Emacs.
;; Homepage: https://github.com/NixOS/nix-mode
;; Package-Requires: ((emacs "24.4"))
;; 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 '(repeat string))
(defvar nix-repl-completion-redirect-buffer
" *nix-repl completions redirect*"
"Buffer to be used to redirect output of readline commands.")
(defcustom nix-repl-completion-output-timeout 1.0
"Time in seconds to wait for completion output before giving up."
:type 'float)
(defvar nix-repl-mode-map
(let ((map (make-sparse-keymap)))
(define-key map "\t" 'completion-at-point)
map))
(defun nix-repl-save-all-histories ()
"Call `comint-write-input-ring' for all `nix-repl-mode' buffers."
(dolist (buf (buffer-list))
(with-current-buffer buf
(when (eq major-mode 'nix-repl-mode)
(comint-write-input-ring)))))
(define-derived-mode nix-repl-mode comint-mode "Nix-REPL"
"Interactive prompt for Nix."
:interactive nil
(setq-local comint-prompt-regexp nix-prompt-regexp)
(setq-local comint-prompt-read-only t)
(let* ((is-remote (file-remote-p default-directory))
(maybe-xdg-data-home (if is-remote
(shell-command-to-string "echo -n $XDG_DATA_HOME")
(or (getenv "XDG_DATA_HOME")
"")))
(path-prefix (if (string-empty-p maybe-xdg-data-home)
"~/.local/share"
maybe-xdg-data-home))
(history-path (concat
is-remote
path-prefix
"/nix/repl-history")))
(setq-local comint-input-ring-file-name history-path))
(comint-read-input-ring t)
(add-hook 'kill-buffer-hook #'comint-write-input-ring nil 'local)
(add-hook 'kill-emacs-hook #'nix-repl-save-all-histories nil 'local)
(add-hook 'completion-at-point-functions
#'nix-repl-completion-at-point nil 'local))
(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 (process input)
"Get completions for INPUT using native readline for PROCESS."
(with-current-buffer (process-buffer process)
(let* ((original-filter-fn (process-filter process))
(redirect-buffer (get-buffer-create
nix-repl-completion-redirect-buffer))
(trigger "\t")
(new-input (concat input trigger))
(input-length
(save-excursion
(+ (- (point-max) (comint-bol)) (length new-input))))
(delete-line-command (make-string input-length ?\b))
(input-to-send (concat new-input delete-line-command)))
;; Ensure restoring the process filter, even if the user quits
;; or there's some other error.
(unwind-protect
(with-current-buffer redirect-buffer
;; Cleanup the redirect buffer
(erase-buffer)
;; Mimic `comint-redirect-send-command', unfortunately it
;; can't be used here because it expects a newline in the
;; command and that's exactly what we are trying to avoid.
(let ((comint-redirect-echo-input nil)
(comint-redirect-completed nil)
(comint-redirect-perform-sanity-check nil)
(comint-redirect-insert-matching-regexp t)
(comint-redirect-finished-regexp nix-prompt-regexp)
(comint-redirect-output-buffer redirect-buffer))
(set-process-filter
process (apply-partially
#'comint-redirect-filter original-filter-fn))
(process-send-string process input-to-send)
;; Grab output until our dummy completion used as
;; output end marker is found.
(when (nix--accept-process-output
process nix-repl-completion-output-timeout
comint-redirect-finished-regexp)
(beginning-of-line)
(if (eq (char-after) ?\r)
(cdr
(split-string
(buffer-substring-no-properties
(line-beginning-position) (point-min))
"[ \f\t\n\r\v]+" t))
(search-forward "" nil t)
(backward-char)
(if (eq (char-before) ?\a)
nil
(list (buffer-substring-no-properties (line-beginning-position) (point))))))))
(set-process-filter process original-filter-fn)))))
(defun nix--accept-process-output (process &optional timeout regexp)
"Accept PROCESS output with TIMEOUT until REGEXP is found.
Optional argument TIMEOUT is the timeout argument to
`accept-process-output' calls. Optional argument REGEXP
overrides the regexp to match the end of output, defaults to
`comint-prompt-regexp'. Returns non-nil when output was
properly captured.
This utility is useful in situations where the output may be
received in chunks, since `accept-process-output' gives no
guarantees they will be grabbed in a single call."
(let ((regexp (or regexp comint-prompt-regexp)))
(catch 'found
(while t
(when (not (accept-process-output process timeout))
(throw 'found nil))
(when (progn (re-search-backward regexp nil t))
(throw 'found t))))))
;;;###autoload
(defun nix-repl-completion-at-point ()
"Completion at point function for Nix using \"nix-repl\".
See `completion-at-point-functions'."
(save-excursion
(let* ((proc (get-buffer-process (current-buffer)))
(prefix (and (derived-mode-p 'nix-repl-mode)
proc
(executable-find nix-executable)
(nix--prefix-bounds))))
(pcase prefix
(`(,beg . ,end)
(list beg end
(nix-get-completions
proc
(buffer-substring beg end))
:exclusive 'no))))))
(defun nix--prefix-bounds ()
"Get bounds of Nix attribute path at point as a (BEG . END) pair, or nil."
(save-excursion
(when (< (skip-chars-backward "a-zA-Z0-9'\\-_\\.") 0)
(cons (point) (+ (point) (skip-chars-forward "a-zA-Z0-9'\\-_\\."))))))
(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