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

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

[nongnu] elpa/rust-mode 947ebf9938 1/2: Support running interactive prog


From: ELPA Syncer
Subject: [nongnu] elpa/rust-mode 947ebf9938 1/2: Support running interactive programs
Date: Wed, 15 May 2024 01:01:57 -0400 (EDT)

branch: elpa/rust-mode
commit 947ebf993818f7135e12d4b0da6f5b05ba790c14
Author: Svilen Ivanov <isvilen@applicata.bg>
Commit: Svilen Ivanov <isvilen@applicata.bg>

    Support running interactive programs
---
 .gitignore               |  4 +++-
 Makefile                 |  1 +
 README.md                |  3 +++
 rust-cargo-tests.el      | 53 ++++++++++++++++++++++++++++++++++++++++++++++++
 rust-cargo.el            | 40 +++++++++++++++++++++---------------
 test-project/src/main.rs | 25 +++++++++++++++++++++++
 6 files changed, 109 insertions(+), 17 deletions(-)

diff --git a/.gitignore b/.gitignore
index 3d9cc85ce1..414084e4ec 100644
--- a/.gitignore
+++ b/.gitignore
@@ -2,4 +2,6 @@
 *-autoloads.el
 /rust-mode-pkg.el
  .eask
-/dist
\ No newline at end of file
+/dist
+test-project/Cargo.lock
+test-project/target/
diff --git a/Makefile b/Makefile
index 71ce201c91..d0c7308b89 100644
--- a/Makefile
+++ b/Makefile
@@ -28,6 +28,7 @@ compile:
 
 test:
        $(EASK) test ert rust-mode-tests.el
+       $(EASK) test ert rust-cargo-tests.el
 
 checkdoc:
        $(EASK) lint checkdoc
diff --git a/README.md b/README.md
index 2b77636efb..17aaa59e1f 100644
--- a/README.md
+++ b/README.md
@@ -173,6 +173,9 @@ By default these are bound to:
 - <kbd>C-c C-c C-t</kbd> `rust-test`
 - <kbd>C-c C-c C-r</kbd> `rust-run`
 
+To run programs requiring user input use universal argument when invoking
+ `rust-run` (<kbd>C-u C-c C-c C-r</kbd>).
+
 ### Clippy
 
 `rust-run-clippy` runs
diff --git a/rust-cargo-tests.el b/rust-cargo-tests.el
new file mode 100644
index 0000000000..f49cba034a
--- /dev/null
+++ b/rust-cargo-tests.el
@@ -0,0 +1,53 @@
+;;; rust-cargo-tests.el --- ERT tests for rust-cargo.el  -*- lexical-binding: 
t; -*-
+(require 'rust-cargo)
+(require 'ert)
+
+(defun rust-test--wait-process-exit ()
+  "Wait for comint process for current buffer to exit."
+  (let ((proc (get-buffer-process (current-buffer))))
+    (while (not (eq (process-status proc) 'exit))
+      (sit-for 0.2))))
+
+(defun rust-test--send-process-string (string)
+  "Send STRING to comint process for current buffer."
+  (let ((proc (get-buffer-process (current-buffer))))
+    (comint-send-string proc string)))
+
+(defmacro rust-test--with-main-file-buffer (expr)
+  `(let* ((test-dir (expand-file-name "test-project/" default-directory))
+          (main-file (expand-file-name "src/main.rs" test-dir)))
+     (save-current-buffer
+       (find-file main-file)
+       ,expr)))
+
+(defun rust-test--find-string (string)
+  "Find STRING in current buffer."
+  (goto-char (point-min))
+  (not (null (search-forward string nil t))))
+
+
+(ert-deftest rust-test-compile ()
+  (skip-unless (executable-find rust-cargo-bin))
+  (setq rust-cargo-default-arguments "")
+  (rust-test--with-main-file-buffer
+     (with-current-buffer (rust-compile)
+       (rust-test--wait-process-exit)
+       (should (rust-test--find-string "Compilation finished")))))
+
+(ert-deftest rust-test-run ()
+  (skip-unless (executable-find rust-cargo-bin))
+  (setq rust-cargo-default-arguments "")
+  (rust-test--with-main-file-buffer
+     (with-current-buffer (rust-run)
+       (rust-test--wait-process-exit)
+       (should (rust-test--find-string "***run not interactive")))))
+
+(ert-deftest rust-test-run-interactive ()
+  (skip-unless (executable-find rust-cargo-bin))
+  (setq rust-cargo-default-arguments "interactive")
+  (rust-test--with-main-file-buffer
+   ;; '(4) is default value when called interactively with universal argument
+   (with-current-buffer (rust-run '(4))
+     (rust-test--send-process-string "1234\n")
+     (rust-test--wait-process-exit)
+     (should (rust-test--find-string "***run interactive: 1234")))))
diff --git a/rust-cargo.el b/rust-cargo.el
index bda23d8e0a..cd2214aef5 100644
--- a/rust-cargo.el
+++ b/rust-cargo.el
@@ -67,46 +67,54 @@
 
 ;;; Internal
 
-(defun rust--compile (format-string &rest args)
+(defun rust--compile (comint format-string &rest args)
   (when (null rust-buffer-project)
     (rust-update-buffer-project))
   (let ((default-directory
           (or (and rust-buffer-project
                    (file-name-directory rust-buffer-project))
-              default-directory)))
-    (compile (apply #'format format-string args))))
+              default-directory))
+        ;; make sure comint is a boolean value
+        (comint (not (not comint))))
+    (compile (apply #'format format-string args) comint)))
 
 ;;; Commands
 
 (defun rust-check ()
   "Compile using `cargo check`"
   (interactive)
-  (rust--compile "%s check %s" rust-cargo-bin rust-cargo-default-arguments))
+  (rust--compile nil "%s check %s" rust-cargo-bin 
rust-cargo-default-arguments))
 
 (defun rust-compile ()
   "Compile using `cargo build`"
   (interactive)
-  (rust--compile "%s build %s" rust-cargo-bin rust-cargo-default-arguments))
+  (rust--compile nil "%s build %s" rust-cargo-bin 
rust-cargo-default-arguments))
 
 (defun rust-compile-release ()
   "Compile using `cargo build --release`"
   (interactive)
-  (rust--compile "%s build --release" rust-cargo-bin))
+  (rust--compile nil "%s build --release" rust-cargo-bin))
 
-(defun rust-run ()
-  "Run using `cargo run`"
-  (interactive)
-  (rust--compile "%s run %s" rust-cargo-bin rust-cargo-default-arguments))
+(defun rust-run (&optional comint)
+  "Run using `cargo run`
 
-(defun rust-run-release ()
-  "Run using `cargo run --release`"
-  (interactive)
-  (rust--compile "%s run --release" rust-cargo-bin))
+If optional arg COMINT is t or invoked with universal prefix arg,
+output buffer will be in comint mode, i.e. interactive."
+  (interactive "P")
+  (rust--compile comint "%s run %s" rust-cargo-bin 
rust-cargo-default-arguments))
+
+(defun rust-run-release (&optional comint)
+  "Run using `cargo run --release`
+
+If optional arg COMINT is t or invoked with universal prefix arg,
+output buffer will be in comint mode, i.e. interactive."
+  (interactive "P")
+  (rust--compile comint "%s run --release" rust-cargo-bin))
 
 (defun rust-test ()
   "Test using `cargo test`"
   (interactive)
-  (rust--compile "%s test %s" rust-cargo-bin rust-cargo-default-arguments))
+  (rust--compile nil "%s test %s" rust-cargo-bin rust-cargo-default-arguments))
 
 (defun rust-run-clippy ()
   "Run `cargo clippy'."
@@ -118,7 +126,7 @@
          ;; set `compile-command' temporarily so `compile' doesn't
          ;; clobber the existing value
          (compile-command (mapconcat #'shell-quote-argument args " ")))
-    (rust--compile compile-command)))
+    (rust--compile nil compile-command)))
 
 ;;; _
 (provide 'rust-cargo)
diff --git a/test-project/src/main.rs b/test-project/src/main.rs
new file mode 100644
index 0000000000..4d22e983a4
--- /dev/null
+++ b/test-project/src/main.rs
@@ -0,0 +1,25 @@
+use std::{env, io};
+
+fn main() {
+    let mut args = env::args();
+
+    if args.len() == 1 {
+        println!("***run not interactive");
+    } else {
+        match args.nth(1).unwrap().as_str() {
+            "interactive" => {
+                let mut line = String::new();
+
+                io::stdin()
+                    .read_line(&mut line)
+                    .expect("Failed to read line");
+
+                println!("***run interactive: {line}");
+            }
+
+            _ => {
+                panic!("unexpected argument");
+            }
+        }
+    }
+}



reply via email to

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