mirror of
https://github.com/vale981/py-vterm-interaction.el
synced 2025-03-05 10:01:41 -05:00
191 lines
6.8 KiB
EmacsLisp
191 lines
6.8 KiB
EmacsLisp
;;; julia-repl-vterm.el --- A mode for Julia REPL using vterm -*- lexical-binding: t -*-
|
||
|
||
;; Copyright (C) 2020 Shigeaki Nishina
|
||
|
||
;; Author: Shigeaki Nishina
|
||
;; Maintainer: Shigeaki Nishina
|
||
;; Created: March 11, 2020
|
||
;; URL: https://github.com/shg/julia-repl-vterm.el
|
||
;; Version: 0.7a
|
||
;; Keywords: languages, julia
|
||
|
||
;; This file is not part of GNU Emacs.
|
||
|
||
;;; License:
|
||
|
||
;; 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 https://www.gnu.org/licenses/.
|
||
|
||
;;; Commentary:
|
||
|
||
;;; Code:
|
||
|
||
(require 'julia-mode)
|
||
(require 'vterm)
|
||
|
||
|
||
;;----------------------------------------------------------------------
|
||
(defgroup inferior-julia-repl-vterm nil
|
||
"A major mode for inferior Julia REPL"
|
||
:group 'julia)
|
||
|
||
(defvar inferior-julia-repl-vterm-buffer-name "*julia-repl*")
|
||
|
||
(defvar inferior-julia-repl-vterm-program "julia")
|
||
|
||
(defvar-local inferior-julia-repl-vterm-script-buffer nil)
|
||
|
||
(defvar inferior-julia-repl-vterm-mode-map
|
||
(let ((map (make-sparse-keymap)))
|
||
(define-key map (kbd "C-c C-z") #'inferior-julia-repl-vterm-switch-to-script-buffer)
|
||
(define-key map (kbd "C-l") #'recenter-top-bottom)
|
||
(define-key map (kbd "M-k") #'inferior-julia-repl-vterm-clear-buffer)
|
||
(define-key map (kbd "C-c C-t") #'inferior-julia-repl-vterm-copy-mode)
|
||
map))
|
||
|
||
(define-derived-mode inferior-julia-repl-vterm-mode vterm-mode "Inf-Julia"
|
||
"A major mode for inferior Julia REPL."
|
||
:group 'inferior-julia-repl-vterm)
|
||
|
||
(defun inferior-julia-repl-vterm-buffer ()
|
||
"Return the inferior Julia REPL buffer `*julia-repl*`. If the buffer doesn't exist,
|
||
create one and return it. If there's already the buffer and the inferior Julia REPL
|
||
is running, return the buffer. If the buffer exists but the process is not running,
|
||
kill the buffer and create a new one."
|
||
(if-let ((buffer (get-buffer inferior-julia-repl-vterm-buffer-name))
|
||
(proc (with-current-buffer buffer vterm--process)))
|
||
buffer
|
||
(if buffer (kill-buffer buffer))
|
||
(let ((buffer (generate-new-buffer inferior-julia-repl-vterm-buffer-name))
|
||
(vterm-shell inferior-julia-repl-vterm-program))
|
||
(with-current-buffer buffer
|
||
(inferior-julia-repl-vterm-mode))
|
||
buffer)))
|
||
|
||
(defun inferior-julia-repl-vterm ()
|
||
"Create an inferior Julia REPL buffer `*julia-repl*` and open it. If there's
|
||
already one with the process alive, just open it."
|
||
(interactive)
|
||
(pop-to-buffer-same-window (inferior-julia-repl-vterm-buffer)))
|
||
|
||
(defun inferior-julia-repl-vterm-switch-to-script-buffer ()
|
||
(interactive)
|
||
(if (and (boundp 'inferior-julia-repl-vterm-script-buffer) (buffer-live-p inferior-julia-repl-vterm-script-buffer))
|
||
(switch-to-buffer-other-window inferior-julia-repl-vterm-script-buffer)
|
||
(message "The script buffer does not exist.")))
|
||
|
||
(defun inferior-julia-repl-vterm-clear-buffer ()
|
||
(interactive)
|
||
(save-excursion
|
||
(goto-char (point-min))
|
||
(vterm-clear 1)))
|
||
|
||
(defvar inferior-julia-repl-vterm-copy-mode-map
|
||
(let ((map (make-sparse-keymap)))
|
||
(define-key map (kbd "C-c C-t") #'inferior-julia-repl-vterm-copy-mode)
|
||
(define-key map [return] #'inferior-julia-repl-vterm-copy-mode-done)
|
||
(define-key map (kbd "RET") #'inferior-julia-repl-vterm-copy-mode-done)
|
||
(define-key map (kbd "C-c C-r") #'vterm-reset-cursor-point)
|
||
map))
|
||
|
||
(define-minor-mode inferior-julia-repl-vterm-copy-mode
|
||
"Toggle copy mode."
|
||
:group 'inferior-julia-repl-vterm
|
||
:lighter " VTermCopy"
|
||
:keymap inferior-julia-repl-vterm-copy-mode-map
|
||
(when inferior-julia-repl-vterm-copy-mode
|
||
(message "Start copy mode")
|
||
(use-local-map nil)
|
||
(vterm-send-stop)))
|
||
|
||
(defun inferior-julia-repl-vterm-copy-mode-done ()
|
||
"Save the active region to the kill ring and exit `inferior-julia-repl-vterm-copy-mode'."
|
||
(interactive)
|
||
(if (region-active-p)
|
||
(kill-ring-save (region-beginning) (region-end))
|
||
(user-error "No active region"))
|
||
(inferior-julia-repl-vterm-copy-mode -1)
|
||
(vterm-reset-cursor-point)
|
||
(use-local-map inferior-julia-repl-vterm-mode-map)
|
||
(vterm-send-start)
|
||
(message "End copy mode"))
|
||
|
||
|
||
;;----------------------------------------------------------------------
|
||
(defgroup julia-with-repl-vterm nil
|
||
"A minor mode for a Julia script buffer that interacts with an inferior Julia REPL."
|
||
:group 'julia)
|
||
|
||
(defcustom julia-with-repl-vterm-hook nil
|
||
"Hook to run after starting a Julia script buffer that interacts with an inferior Julia REPL."
|
||
:type 'hook
|
||
:group 'julia-with-repl-vterm)
|
||
|
||
(defun julia-with-repl-vterm-switch-to-repl-buffer ()
|
||
(interactive)
|
||
(let ((current-script-buffer (current-buffer))
|
||
(inferior-buffer (inferior-julia-repl-vterm-buffer)))
|
||
(with-current-buffer inferior-buffer
|
||
(setq inferior-julia-repl-vterm-script-buffer current-script-buffer)
|
||
(switch-to-buffer-other-window inferior-buffer))))
|
||
|
||
(defun julia-with-repl-vterm-send-return-key ()
|
||
(with-current-buffer (inferior-julia-repl-vterm-buffer)
|
||
(vterm-send-return)))
|
||
|
||
(defun julia-with-repl-vterm-paste-string (string)
|
||
(with-current-buffer (inferior-julia-repl-vterm-buffer)
|
||
(vterm-send-string string t)))
|
||
|
||
(defun julia-with-repl-vterm-send-current-line ()
|
||
(interactive)
|
||
(save-excursion
|
||
(end-of-line)
|
||
(let ((clmn (current-column))
|
||
(char (char-after))
|
||
(line (string-trim (thing-at-point 'line t))))
|
||
(unless (and (zerop clmn) char)
|
||
(when (/= 0 clmn)
|
||
(julia-with-repl-vterm-paste-string line)
|
||
(julia-with-repl-vterm-send-return-key)
|
||
(if (not char)
|
||
(newline))))))
|
||
(forward-line))
|
||
|
||
(defun julia-with-repl-vterm-send-region-or-current-line ()
|
||
(interactive)
|
||
(if (use-region-p)
|
||
(progn
|
||
(julia-with-repl-vterm-paste-string
|
||
(buffer-substring-no-properties (region-beginning) (region-end)))
|
||
(deactivate-mark))
|
||
(julia-with-repl-vterm-send-current-line)))
|
||
|
||
(defun julia-with-repl-vterm-send-buffer ()
|
||
(interactive)
|
||
(save-excursion
|
||
(julia-with-repl-vterm-paste-string (buffer-string))))
|
||
|
||
;;;###autoload
|
||
(define-minor-mode julia-with-repl-vterm-mode
|
||
"A minor mode for a Julia script buffer that interacts with an inferior Julia REPL."
|
||
nil "⁂"
|
||
`((,(kbd "C-c C-z") . julia-with-repl-vterm-switch-to-repl-buffer)
|
||
(,(kbd "C-c C-b") . julia-with-repl-vterm-send-buffer)
|
||
(,(kbd "C-<return>") . julia-with-repl-vterm-send-region-or-current-line)))
|
||
|
||
(add-hook 'julia-mode-hook (lambda () (julia-with-repl-vterm-mode 1)))
|
||
|
||
(provide 'julia-repl-vterm)
|
||
|
||
;;; julia-repl-vterm.el ends here
|