- (interactive)
- (require 'comint)
- (comint-mode)
- (setq major-mode 'inferior-prolog-mode
- mode-name "Inferior Prolog"
- comint-prompt-regexp "^| [ ?][- ] *")
- (prolog-mode-variables)
- (if inferior-prolog-mode-map nil
- (setq inferior-prolog-mode-map (copy-keymap comint-mode-map))
- (prolog-mode-commands inferior-prolog-mode-map))
- (use-local-map inferior-prolog-mode-map)
- (run-hooks 'prolog-mode-hook))
+ (setq comint-prompt-regexp "^| [ ?][- ] *")
+ (prolog-mode-variables))
+
+(defvar inferior-prolog-buffer nil)
+
+(defun inferior-prolog-run (&optional name)
+ (with-current-buffer (make-comint "prolog" (or name prolog-program-name))
+ (inferior-prolog-mode)
+ (setq-default inferior-prolog-buffer (current-buffer))
+ (make-local-variable 'inferior-prolog-buffer)
+ (when (and name (not (equal name prolog-program-name)))
+ (set (make-local-variable 'prolog-program-name) name))
+ (set (make-local-variable 'inferior-prolog-flavor)
+ ;; Force re-detection.
+ (let* ((proc (get-buffer-process (current-buffer)))
+ (pmark (and proc (marker-position (process-mark proc)))))
+ (cond
+ ((null pmark) (1- (point-min)))
+ ;; The use of insert-before-markers in comint.el together with
+ ;; the potential use of comint-truncate-buffer in the output
+ ;; filter, means that it's difficult to reliably keep track of
+ ;; the buffer position where the process's output started.
+ ;; If possible we use a marker at "start - 1", so that
+ ;; insert-before-marker at `start' won't shift it. And if not,
+ ;; we fall back on using a plain integer.
+ ((> pmark (point-min)) (copy-marker (1- pmark)))
+ (t (1- pmark)))))
+ (add-hook 'comint-output-filter-functions
+ 'inferior-prolog-guess-flavor nil t)))
+
+(defun inferior-prolog-process (&optional dontstart)
+ (or (and (buffer-live-p inferior-prolog-buffer)
+ (get-buffer-process inferior-prolog-buffer))
+ (unless dontstart
+ (inferior-prolog-run)
+ ;; Try again.
+ (inferior-prolog-process))))
+
+(defvar inferior-prolog-flavor 'unknown
+ "Either a symbol or a buffer position offset by one.
+If a buffer position, the flavor has not been determined yet and
+it is expected that the process's output has been or will
+be inserted at that position plus one.")
+
+(defun inferior-prolog-guess-flavor (&optional ignored)
+ (save-excursion
+ (goto-char (1+ inferior-prolog-flavor))
+ (setq inferior-prolog-flavor
+ (cond
+ ((looking-at "GNU Prolog") 'gnu)
+ ((looking-at "Welcome to SWI-Prolog") 'swi)
+ ((looking-at ".*\n") 'unknown) ;There's at least one line.
+ (t inferior-prolog-flavor))))
+ (when (symbolp inferior-prolog-flavor)
+ (remove-hook 'comint-output-filter-functions
+ 'inferior-prolog-guess-flavor t)
+ (if (eq inferior-prolog-flavor 'gnu)
+ (set (make-local-variable 'comint-process-echoes) t))))