;; $Id: prolog-genind.el,v 1.27 1994/09/05 07:32:15 nickson Exp nickson $
;; special functions and bindings for Prolog mode (in Genind)

;(require 'quintus-manual)

(defvar prolog-genind-mode-map (make-sparse-keymap))

(define-key prolog-genind-mode-map "\C-C\C-E" 'prolog-end-of-term)
(define-key prolog-genind-mode-map "\C-C\C-P" 'run-prolog)
(define-key prolog-genind-mode-map "\C-C\C-M" 'prolog-this-manual)

(defvar prolog-genind-mode-hooks nil
  "*Hooks run after starting Prolog Genind mode.")

(defun prolog-genind-mode ()
  "Prolog mode using genind.
See the documentation for the variables `genind-current-list',
`genind-previous-list' and `genind-indent-triggers' for customizing
indentation.
\\{prolog-genind-mode-map}"
  (interactive)
  (make-variable-buffer-local 'comment-start)
  (make-variable-buffer-local 'comment-start-skip)
  (setq comment-start "%"
        comment-start-skip "%+ *")
  (modify-syntax-entry ?' ".")
  (setq major-mode 'prolog-genind-mode
        mode-name "Prolog Genind")
  (use-local-map prolog-genind-mode-map)
  (load-library "prolog.gel")
  (run-hooks 'prolog-genind-mode-hooks)
)

(fset 'prolog-mode 'prolog-genind-mode)

(defun prolog-end-of-term ()
  "Move point to the end of the smallest term point is on."
  (interactive)
  (if (not (looking-at "("))
      (forward-sexp 1))
  (if (looking-at "(")
      (forward-sexp 1)))

(defun prolog-args-of-term ()
  "How many args has the smallest term point is on?"
  (save-excursion
    (if (not (looking-at "("))
        (forward-sexp 1))
    (if (not (looking-at "("))
        0
      (forward-char 1)
      (let ((count 0))
        (while (not (looking-at " *[.)]"))
          (prolog-end-of-term)
          (inc count))
        count))))

(defun prolog-find-doc (pred arity file)
  "Return the documentation of PRED/ARITY in FILE."
  (save-excursion
    (set-buffer (find-file-noselect file))
    (save-restriction
      (widen)
      (goto-char 1)
      (if (and (re-search-forward (concat "^" pred (if (= arity 0) "" "("))
                                  nil t)
                (re-search-backward "^\n\\(^%%.*\n\\)+" nil t))
          (chop-string (replace-char-in-string (match-text 0) ?\n ?\C-a) 240)
        (error "Not found")))))

(defun prolog-display-doc (pred arity file)
  "Display the documentation of PRED/ARITY in FILE."
  (let ((buf (get-buffer-create "*Prolog Help*"))
        text)
    (save-excursion
      (set-buffer (find-file-noselect file))
      (save-restriction
        (widen)
        (goto-char 1)
        (if (and (re-search-forward (concat "^" pred (if (= arity 0) "" "("))
                                    nil t)
                 (re-search-backward "^\n\\(^%%.*\n\\)+" nil t))
            (setq text (chop-string (match-text 0) 240))
          (error "Not found")))
      (set-buffer buf)
      (erase-buffer)
      (insert text))
    (display-buffer buf)))
    
(defun prolog-find-def (pred file arity)
  "Display the definition of PRED in FILE with ARITY."
  (let ((buf))
    (save-window-excursion
      (set-buffer (setq buf (find-file-noselect file)))
      (widen)
      (goto-char 1)
      (or (re-search-forward (concat "^"
                                     (regexp-quote pred)
                                     (if (= arity 0) " "
                                       "(")) nil t)
          (error "Not found")))
  (display-buffer buf)))

(defun prolog-manual (pred &optional arity)
  (interactive "sProlog manual entry: ")
  (info)
  (Info-goto-node "(sicstus2.1)Built-In Index")
  (Info-menu (if arity (format "%s/%d" pred arity) pred))
  (re-search-forward (concat "^`" (regexp-quote pred) "[(']")))

(defun prolog-this-manual ()
  "Show the info node for the procedure whose name is around point."
  (interactive)
  (let (text)
    (save-excursion
      (or (looking-at "\\>") (forward-sexp 1))
      (forward-sexp -1)
      (setq text (buffer-substring (point) (point-at (forward-sexp 1)))))
    (prolog-manual text)))

