From a2a923f84f40604ca66dda41b4d96b558495a49e Mon Sep 17 00:00:00 2001 From: jao Date: Sat, 2 Jan 2021 01:42:44 +0000 Subject: jao-vterm-repl --- prog/jao-vterm-repl.el | 125 +++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 125 insertions(+) create mode 100644 prog/jao-vterm-repl.el (limited to 'prog') diff --git a/prog/jao-vterm-repl.el b/prog/jao-vterm-repl.el new file mode 100644 index 0000000..306042c --- /dev/null +++ b/prog/jao-vterm-repl.el @@ -0,0 +1,125 @@ +;;; jao-vterm-repl.el --- vterm-based repls -*- lexical-binding: t; -*- + +;; Copyright (C) 2020 jao + +;; Author: jao +;; Keywords: terminals + +;; 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 . + +;;; Commentary: + +;; Helpers to launch reply things such as erlang shells inside a vterm. +;; For instance, to declare an erl repl for rebar projects, one would call: +;; +;; (jao-vterm-repl-register "rebar.config" "rebar3 shell" "^[0-9]+> ") + +;;; Code: + +(require 'jao-compilation) + +(declare-function 'vterm-copy-mode "vterm") +(declare-function 'vterm-send-string "vterm") +(declare-function 'vterm-send-return "vterm") + +(defun jao-vterm-repl--buffer-name (&optional dir) + (format "*vterm -- repl - %s*" (or dir (jao-compilation-root)))) + +(defvar jao-vterm-repl-repls nil) +(defvar jao-vterm-repl-prompts nil) +(defvar-local jao-vterm-repl--name nil) +(defvar-local jao-vterm-repl--last-buffer nil) +(defvar-local jao-vterm-repl--prompt-rx "^[0-9]+> ") + +(defun jao-vterm-repl--exec (cmd &optional name) + (vterm name) + (when name (vterm-send-string "unset PROMPT_COMMAND\n")) + (vterm-send-string cmd) + (vterm-send-return) + (when name (rename-buffer name))) + +;;;###autoload +(defun jao-vterm-repl-previous-prompt () + (interactive) + (when (derived-mode-p 'vterm-mode) + (vterm-copy-mode 1) + (forward-line 0) + (when (re-search-backward jao-vterm-repl--prompt-rx nil t) + (goto-char (match-end 0))))) + +;;;###autoload +(defun jao-vterm-repl-next-prompt () + (interactive) + (when (derived-mode-p 'vterm-mode) + (vterm-copy-mode 1) + (or (re-search-forward jao-vterm-repl--prompt-rx nil t) + (vterm-copy-mode -1)) + (unless (save-excursion + (re-search-forward jao-vterm-repl--prompt-rx nil t)) + (vterm-copy-mode -1)))) + +;;;###autoload +(define-minor-mode jao-vterm-repl-mode "repl-aware vterm" nil nil + '(("\C-c\C-p" . jao-vterm-repl-previous-prompt) + ("\C-c\C-n" . jao-vterm-repl-next-prompt) + ("\C-c\C-z" . jao-vterm-repl-pop-to-src))) + +;;;###autoload +(defun jao-vterm-repl () + (let* ((dir (jao-compilation-root)) + (vname (jao-vterm-repl--buffer-name dir)) + (root-name (jao-compilation-root-file)) + (buffer (seq-find `(lambda (b) + (string= + (buffer-local-value 'jao-vterm-repl--name + b) + ,vname)) + (buffer-list)))) + (or buffer + (let ((default-directory dir) + (prompt (cdr (assoc root-name jao-vterm-repl-prompts))) + (cmd (or (cdr (assoc root-name jao-vterm-repl-repls)) + (read-string "REPL command: ")))) + (jao-vterm-repl--exec cmd vname) + (jao-vterm-repl-mode) + (setq-local jao-vterm-repl--name vname) + (when prompt (setq-local jao-vterm-repl--prompt-rx prompt)) + (rename-buffer vname) + (current-buffer))))) + +;;;###autoload +(defun jao-vterm-repl-register (build-file repl-cmd prompt-rx) + (jao-compilation-add-dominating build-file) + (add-to-list 'jao-vterm-repl-repls (cons build-file repl-cmd)) + (add-to-list 'jao-vterm-repl-prompts (cons build-file prompt-rx))) + +;;;###autoload +(defun jao-vterm-repl-pop-to-repl () + (interactive) + (let ((bn (current-buffer))) + (pop-to-buffer (jao-vterm-repl)) + (setq-local jao-vterm-repl--last-buffer bn))) + +;;;###autoload +(defun jao-vterm-repl-pop-to-src () + (interactive) + (when (buffer-live-p jao-vterm-repl--last-buffer) + (pop-to-buffer jao-vterm-repl--last-buffer))) + +;;;###autoload +(defun jao-vterm-repl-send (cmd) + (with-current-buffer (jao-vterm-repl) (vterm-send-string cmd))) + +(provide 'jao-vterm-repl) +;;; jao-vterm-repl.el ends here -- cgit v1.2.3