;;; octave-wait.el --- Send commands to the Octave process without waiting. ;; The problem. ;; At the moment, the Emacs commands that send commands from octave ;; source buffers to the inferior octave process wait for the command ;; to finish before Emacs allows the user to do anything else. This ;; can be frustrating, since Emacs is effectively unsuable until ;; Octave finishes each command. e.g. If you have the command: ;; ;; sleep(100) ;; ;; in an .m file, and send that line to Octave process using ;; octave-send-line, Emacs cannot be used until that command finishes. ;; The following code provides two temporary functions, ;; sje-octave-send-line and sje-octave-send-region, so that Emacs ;; doesn't wait until the current Octave command has finished. The ;; only exception to this is that when there is no current Octave ;; process running. ;; Installation ;; ;; To use this code, just add: ;; (require 'octave-nowait) ;; to your .emacs file and it should work okay. ;; ;; The following hook will bind these two new functions to the numeric ;; keypad keys 1 and 2: ;; ;; (add-hook 'octave-mode-hook 'my-octave-hook) ;; ;; (defun my-octave-hook () ;; "My hook for Octave." ;; (interactive) ;; (local-set-key [kp-1] 'sje-octave-send-line) ;; (local-set-key [kp-2] 'sje-octave-send-region) ;; ) ;; ;; (Tested on Emacs 20.6 and XEmacs 21.1). ;; This file should be loaded after Octave mods have already been ;; loaded, since it overwrites a couple of functions from there. (require 'octave-mod) (require 'octave-inf) ;; This code works by lexically defining a new variable sje-ignore, ;; which if true, tells Emacs to not wait for the output from the ;; Octave process. This is useful most of the time, but sometime ;; Emacs must wait for the octave output, e.g. in initial startup, ;; when collecting completion information and when resync'ing ;; directory. ;;; Overwrite the previous definition of this defun in octave-inf.el (defun inferior-octave-send-list-and-digest (list) "Send LIST to the inferior Octave process and digest the output. The elements of LIST have to be strings and are sent one by one. All output is passed to the filter `inferior-octave-output-digest'." (let* ((proc inferior-octave-process) (filter (process-filter proc)) string) (set-process-filter proc 'inferior-octave-output-digest) (setq inferior-octave-output-list nil) (unwind-protect (while (setq string (car list)) (setq inferior-octave-output-string nil inferior-octave-receive-in-progress t) (comint-send-string proc string) ;; SJE -- check to see if we need to wait to process output. (if (not (and (boundp 'sje-ignore) (eq sje-ignore t))) (while inferior-octave-receive-in-progress (accept-process-output proc))) (setq list (cdr list))) (set-process-filter proc filter)))) (defun octave-send-region (beg end) "Send current region to the inferior Octave process." (interactive "r") (inferior-octave t) (let ((proc inferior-octave-process) (string (buffer-substring-no-properties beg end)) line) (save-excursion (set-buffer inferior-octave-buffer) (setq inferior-octave-output-list nil) (while (not (string-equal string "")) (if (string-match "\n" string) (setq line (substring string 0 (match-beginning 0)) string (substring string (match-end 0))) (setq line string string "")) (setq inferior-octave-receive-in-progress t) (inferior-octave-send-list-and-digest (list (concat line "\n"))) (if (not (and (boundp 'sje-ignore) (eq sje-ignore t))) (while inferior-octave-receive-in-progress (accept-process-output proc))) (insert-before-markers (mapconcat 'identity (append (if octave-send-echo-input (list line) (list "")) (mapcar 'inferior-octave-strip-ctrl-g inferior-octave-output-list) (list inferior-octave-output-string)) "\n"))))) (if octave-send-show-buffer (display-buffer inferior-octave-buffer))) (defun sje-octave-send-line (&optional arg) "Send current Octave code line to the inferior Octave process. With positive prefix ARG, send that many lines. If `octave-send-line-auto-forward' is non-nil, go to the next unsent code line." (interactive "P") (or arg (setq arg 1)) (if (> arg 0) (let (beg end) (beginning-of-line) (setq beg (point)) (octave-next-code-line (- arg 1)) (end-of-line) (setq end (point)) (if octave-send-line-auto-forward (octave-next-code-line 1)) (sje-octave-send-region beg end)))) (defun sje-octave-send-region (beg end) "SJE wrapper to send region and return immediately." (interactive "r") (let (sje-ignore) (setq sje-ignore ;; Cannot ignore if process is not yet running. (and (processp inferior-octave-process) (eq (process-status inferior-octave-process) 'run))) (octave-send-region beg end))) (provide 'octave-nowait)