emacs-elpa-diffs
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

[elpa] externals/ulisp-repl 1464faec29 1/2: ulisp-repl.el: New package


From: Thomas Fitzsimmons
Subject: [elpa] externals/ulisp-repl 1464faec29 1/2: ulisp-repl.el: New package
Date: Thu, 1 Jun 2023 11:46:41 -0400 (EDT)

branch: externals/ulisp-repl
commit 1464faec29151e591ee171f7a7821bba5291595b
Author: Thomas Fitzsimmons <fitzsim@fitzsim.org>
Commit: Thomas Fitzsimmons <fitzsim@fitzsim.org>

    ulisp-repl.el: New package
    
    * ulisp-repl.el, .gitignore: New files.
---
 .gitignore    |   1 +
 ulisp-repl.el | 109 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
 2 files changed, 110 insertions(+)

diff --git a/.gitignore b/.gitignore
new file mode 100644
index 0000000000..f672b1daba
--- /dev/null
+++ b/.gitignore
@@ -0,0 +1 @@
+ulisp-repl.elc
diff --git a/ulisp-repl.el b/ulisp-repl.el
new file mode 100644
index 0000000000..0d97795b0f
--- /dev/null
+++ b/ulisp-repl.el
@@ -0,0 +1,109 @@
+;;; ulisp-repl.el --- uLisp REPL -*- lexical-binding: t -*-
+
+;; Copyright (C) 2023 Free Software Foundation, Inc.
+
+;; Author: Thomas Fitzsimmons <fitzsim@fitzsim.org>
+;; Version: 1.0.0
+;; Package-Requires: ((emacs "26.1") (paredit "26"))
+
+;; 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 <http://www.gnu.org/licenses/>.
+
+;;; Commentary:
+
+;; Interact with uLisp running on a target board over a serial connection.
+
+;; Usage:
+
+;; M-x ulisp-repl
+
+;;; Code:
+(require 'comint)
+(require 'lisp-mode)
+(require 'paredit)
+
+(defcustom ulisp-repl-serial-device-path nil
+  "The full path of the serial device this REPL should use."
+  :group 'comm
+  :type 'string)
+
+(define-derived-mode ulisp-repl--mode comint-mode "uLisp"
+  "Major mode for interacting with a uLisp target board."
+  :syntax lisp-mode-syntax-table
+  :interactive nil
+  :after-hook
+  (progn
+    ;; FIXME: make-serial-process and join the comint to that process.
+    (keymap-local-set "RET" 'comint-send-input)
+    (setq-local comint-process-echoes t)
+    (setq-local comint-prompt-regexp (concat "^[0-9]+> "))
+    (when (boundp 'comint-indirect-setup-function)
+      (setq-local comint-indirect-setup-function 'lisp-mode))
+    (when (fboundp 'comint-indirect-buffer)
+      (comint-indirect-buffer))
+    (when (fboundp 'comint-fontify-input-mode)
+      (comint-fontify-input-mode))
+    (make-local-variable 'kill-buffer-hook)
+    (when (fboundp 'comint--indirect-cleanup)
+      (add-hook 'kill-buffer-hook 'comint--indirect-cleanup))
+    (add-hook 'kill-buffer-hook
+              (lambda ()
+                (let ((network (get-process "*ulisp-repl*")))
+                  (when network (kill-process network)))))))
+
+(defun ulisp--filter-files (files)
+  "Return FILES but with . and .. entries removed."
+  (let (result)
+    (dolist (file files)
+      (when (not (or (string-match "/\\.$" file)
+                     (string-match "/\\.\\.$" file)))
+        (push file result)))
+    (nreverse result)))
+
+(defun ulisp--select-serial-device (prefix)
+  "Return the full path to a serial device.
+For the meaning of PREFIX, see `ulisp-repl'."
+  (if (or prefix (not ulisp-repl-serial-device-path))
+      (let ((base "/dev/serial/by-id/"))
+        (if (and (file-readable-p base) (file-executable-p base))
+            (let* ((files (ulisp--filter-files (directory-files base t)))
+                   (file (if (not (eq (length files) 1))
+                             (completing-read
+                              "uLisp serial port: " files nil nil base)
+                           (car files))))
+              (if (and (file-readable-p file) (file-readable-p file))
+                  (customize-set-value 'ulisp-repl-serial-device-path file)
+                (error "Failed to access %s" file)))
+          (error "Failed to access directory %s" base)))
+    ulisp-repl-serial-device-path))
+
+(defun ulisp-repl (prefix)
+  "Start a uLisp REPL.
+If PREFIX is non-nil, always query for the device path.  If
+PREFIX is nil, return the previously confiugred device path, or
+if that is nil, query."
+  (interactive "P")
+  (if (get-buffer-process "*ulisp-repl*")
+      (pop-to-buffer "*ulisp-repl*")
+    (with-current-buffer (get-buffer-create "*ulisp-repl*")
+      (let ((device (ulisp--select-serial-device prefix)))
+        (comint-exec
+         (current-buffer) "ulisp-serial" "cu" nil (list "-l" device))
+        (ulisp-repl--mode)
+        (paredit-mode)
+        (keymap-local-unset "RET" t)
+        (pop-to-buffer (current-buffer))))))
+
+(provide 'ulisp-repl)
+
+;;; ulisp-repl.el ends here



reply via email to

[Prev in Thread] Current Thread [Next in Thread]