;;; File: winemacs-side-interaction.el
;;;
;;; John:Oct97. Adds interaction between KPML-PC and WinEmacs version of
;;; Emacs for PC. First cut; pretty basic. Uses the Editi package for
;;; use with WinEmacs as supplied by Franz. Eval-ed.el must therefore
;;; have already been loaded into WinEmacs for this to take affect.

;;; ----------------------------------------------------------------------
;;; (ACL->)Emacs
;;;
;;; Following function when started up (usually remotely from
;;; ACL-PC by means of acl::send-string-to-emacs, just opens
;;; up the named buffer and puts the form in there. This must
;;; then be compiled/evaluated by the editor explicitly.

(defun KPML-EDIT-FORM (buffer-name associated-file form message)
  (let ((def (prin1-to-string form)))
    (switch-to-buffer 
     (get-buffer-create buffer-name))
    (erase-buffer)
    (insert (substring def 1 (- (length def) 1)))
    (newline-and-indent)
    (newline-and-indent)
    (newline-and-indent)
    (insert (prin1-to-string message))
    (goto-char (point-min))
    (setq buffer-file-name associated-file)
    (lisp-mode)))

;;; ----------------------------------------------------------------------
;;; Emacs(->ACL)

;;; Define as compatible with Unix KPML... (this clobbers compile-region)

(define-key lisp-mode-map "\C-c\C-c"  'acl-eval-kpml-sexpr)

(defun acl-eval-kpml-sexpr ()
  "Compile the current KPML object in the external Lisp process."
  (interactive)
  (let ((start (top-level-region))
	end)
    (setq end (cdr start))
    (setq start (car start))
    (unless (and end start)
      (error "Unbalanced parentheses"))
    (acl-kpml-eval-region
     start end ':eval (acl-get-toplevel-form-name start))))

(defun acl-kpml-eval-region (start end operation &optional name callback)
  (or name
      (setq name (if (and (eq start (point-min))
			  (eq end (point-max)))
		     (format "buffer %s" (buffer-name))
		   (format "region [%d,%d) in buffer %s"
			   start end (buffer-name)))))
  (let* ((sexp-string
	  (if (or (integerp start) (markerp start))
	      (buffer-substring start end)
	    start))
	 (compile-p (eq operation ':compile))
	 (print-p   (eq operation ':eval-print))
	 (index (acl-next-queue-index (queue-file-ext compile-p)))
	 entry)
    ;; If printing output, move point to the end of the region or defun
    ;; so that any output will get printed there.
    (when (eq operation ':eval-print)
      (goto-char end)
      ;; Skip any immediately following comment block before inserting output
      (when (looking-at "[ \t]*;")
	(goto-char (find-eol))
	(while (looking-at "\n[ \t]*;")
	  (goto-char (find-eol nil 1))))
      (if (eq ?\n (preceding-char))
	  (goto-char (1- end))))
    ;; Wrap the form with code that decides whether the results
    ;; should be displayed anywhere within Emacs.
    (setq sexp-string
	  ;; Don't use format %s here, it stops at any nul char
	  (if (memq operation '(:eval-print :eval-popup))
	      (concat
	        "(acl::emacs-print-results\n (multiple-value-list\n  (progn "
		sexp-string ")))")
	    ;;
	    ;; this is where we decide what gets sent...
	    ;;(concat "(kpml::emacs2acl-hook\n " sexp-string ")")
	    ;; *************
	    sexp-string

	    ))
    (setq name (concat (symbol-name operation) "  " name))
    (setq entry (list index operation
		      (if (null end)
			  (buffer-name)
			(make-eval-region-extent start end
						 (and print-p index)))
		      callback))
    (setq acl-queue (nconc acl-queue (list entry)))

    ;; this is where it gets sent off to ACL...
    ;; Following has sexpressions sent to ACL and evaluated...
    ;; Appear to be done in the current package over there...
    ;; (acl-send-string "(setf x \"KPML\")" )

    (acl-send-string
      sexp-string
      (get-buffer-package (if end start (point)))
      compile-p
      index)))

;;; ----------------------------------------------------------------------

(setq editi-acl-init-code "(KPML::START-EMACS-SERVER)")


