home *** CD-ROM | disk | FTP | other *** search
- ;;; Interface to SWI-Prolog
- ;;; Author: Jan Wielemaker, SWI, University of Amsterdam
- ;;; E-mail: jan@swi.psy.uva.nl
-
- ;;; This package forms a layer around the Quintus-Prolog interface. It
- ;;; should be used together with the Prolog library 'emacs_interface.pl'.
-
- ;;; It implements hooks that allow SWI-Prolog to give compilation-warnings
- ;;; back to EMACS, so the user can step through them using the normal
- ;;; ^X` command
-
- ;;; Usage:
- ;;;
- ;;; Put the following lines in your ~/.emacs:
- ;;;
- ;;; (autoload 'run-prolog "swi-prolog" "Run an inferior prolog process" t)
- ;;; (autoload 'prolog-mode "swi-prolog" "SWI-Prolog mode" t)
-
- ;;; Notes:
- ;;;
- ;;; As far as I was able to figure out, the Quintus Prolog GNU-Emacs lisp
- ;;; interface can be distributed under the normal GNU general public licence
- ;;;
- ;;; This file is distributed confirm the GNU general public licence.
-
-
- (defconst qplisp-directory "/usr/local/Emacs19/lib/emacs/site-lisp/qplisp"
- "Directory with all the quintus interface files")
- (defvar run-prolog-command "pl"
- "Command to start SWI-Prolog")
- (defconst prolog-warning-buffer "*compilation*"
- "SWI-Prolog buffer for warnings")
-
- ;;; Get the Quintus EMACS library in your load path
-
- (setq load-path (cons qplisp-directory load-path))
- (load-library "qprolog-mode")
-
- ;;; "compile.el" that comes with Emacs19 does not seem to work very well.
- ;;; Especially, error messages are not parsed correctly. It might be the
- ;;; case that errors are treated somewhat differently in Emacs19. Jan?
- ;;;
- (load-library "compile18")
-
- (setq prolog-prompt-pattern "^[0-9]+ \\?- ")
-
-
- ;;; Prolog Mode popup windows (Manfred Aben)
- ;;;
-
- (require 'easymenu)
-
- (defvar prolog-menu nil
- "Popup menu with the available commands for SWI-prolog mode")
-
- (setq prolog-menu
- '("Prolog"
- ["Start SWI-Prolog" run-prolog t]
- ["Interrupt Prolog" interrupt-prolog t]
- " "
- ["Consult this file" prolog-compile-buffer-only t]
- ["Reconsult modified files" prolog-recompile t]
- " "
- ["Go to next error" next-error t]
- " "
- ["Previous query" prolog-previous-command t]
- ["Next query" prolog-next-command t]
- " "
- ["Find source file of this term" find-definition t]
- ["Find other source files" find-more-definition t]
- " "
- ["Select clause" mark-clause t]
- ["Delete clause" kill-clause t]
- ["Indent clause" prolog-indent-clause t]
- ))
-
-
- (or (fboundp 'old-prolog-mode)
- (fset 'old-prolog-mode
- (symbol-function 'prolog-mode)))
-
- (defun prolog-mode ()
- "Major mode for editing files of prolog code.
- The following commands are available:
- \\{prolog-mode-map}."
- (interactive)
- ;;; HACK; Q-prolog-mode complains about "mark not active"
- (set-mark (beginning-of-buffer))
- (old-prolog-mode)
- (easy-menu-define menu-bar-swi-prolog1-commands
- prolog-mode-map
- "SWI-Prolog mode commands"
- prolog-menu))
-
- (defun prolog-compilation-start (dir)
- "Clear *compilation* buffer"
- (save-excursion
- (set-buffer (get-buffer-create prolog-warning-buffer))
- (erase-buffer)
- (setq default-directory dir)
- (compilation-forget-errors)
- (setq compilation-error-list t)
- (setq compilation-error-message "No more SWI-Prolog errors")
- (insert "cd " dir)
- (newline)
- (insert "SWI-Prolog warnings")
- (newline)))
-
-
- (defun prolog-compilation-finish ()
- "Finish prolog-compilation"
- (save-excursion
- (set-buffer prolog-warning-buffer)
- (end-of-buffer)
- (newline 2)
- (insert "Compilation finished at " (current-time-string))
- (newline)
- (setq compilation-parsing-end 1)))
-
-
- (defun prolog-compilation-warning (file line msg)
- "Put a prolog error-message in *compilation*"
- (save-excursion
- (set-buffer prolog-warning-buffer)
- (end-of-buffer)
- (display-buffer (current-buffer))
- (insert file ":" line ": " msg)
- (newline)))
-
-
- ;;; STARTING PROLOG
- ;;; This function is a modified version of run-prolog in qprolog-mode.el
-
- (defun run-prolog (command)
- "Run an inferior SWI-Prolog process, input and output via buffer
- *prolog*."
- (interactive (list (read-string "Run prolog: " run-prolog-command)))
- (setq run-prolog-command command)
- (ensure-prolog-syntax)
- (qprequire 'shell)
- (get-prolog-exec-and-flags (concat command startup-jcl))
- (switch-to-buffer-other-window (apply 'make-comint "prolog"
- *prolog-executable* nil
- *prolog-flags*))
- (set-process-filter (get-process "prolog") 'prolog-process-filter)
- (sleep-for 2)
- (inferior-prolog-mode)
- (local-set-key "\t" 'prolog-dabbrev-atom)
- (local-set-key "\C-d" 'prolog-complete-atom)
- (local-set-key "\C-c\C-n" 'prolog-next-command)
- (local-set-key "\C-c\C-p" 'prolog-previous-command)
-
- (easy-menu-define menu-bar-swi-prolog2-commands
- inferior-prolog-mode-map
- "SWI-Prolog mode commands"
- prolog-menu))
-
- ;;; ATOM COMPLETION
-
- (defvar *prolog-start-completion* nil
- "Start of prolog completion")
- (defvar *prolog-end-completion* nil
- "End of prolog completion")
- (defvar *prolog-atom-completions* nil
- "Collect-list for prolog completions")
- (defvar *prolog-completion-process-mark* nil
- "Process mark when starting completion")
-
- (defun prolog-completion-backward-word ()
- (interactive)
- (backward-word 1)
- (backward-char 1)
- (if (looking-at "_")
- (prolog-completion-backward-word)
- (forward-char 1)))
-
-
- (defun prolog-completion-sofar ()
- (setq *prolog-end-completion* (point))
- (let ((end (point)))
- (save-excursion
- (backward-char 1)
- (cond ((looking-at "[a-zA-Z0-9_]\\b")
- (prolog-completion-backward-word)
- (setq *prolog-start-completion* (point))
- (setq *prolog-completion-process-mark*
- (marker-position (process-mark
- (get-buffer-process "*prolog*"))))
- (buffer-substring (point) end))
- (t nil)))))
-
- (defun prolog-complete-atom-with (extended unique)
- (cond ((eq *prolog-end-completion* (point))
- (kill-region *prolog-start-completion* *prolog-end-completion*)
- (insert extended)
- (setq *saved-prolog-process-mark* *prolog-completion-process-mark*)
- (if (not unique) (message "[incomplete]")))
- (t
- (prolog-completion-error-message "Mismatch of dabbrev-point"))))
-
- (defun prolog-completion-error-message (string)
- (message string)
- (setq *saved-prolog-process-mark* *prolog-completion-process-mark*))
-
- ;;; DABBREV
-
- (defun prolog-dabbrev-atom ()
- (interactive)
- (let (sofar)
- (cond ((setq sofar (prolog-completion-sofar))
- (send-prolog (concat
- "'$silent'(emacs_dabbrev_atom(\""
- sofar
- "\"))")))
- (t
- (message "Point not at end of atom")))))
-
- ;;; COMPLETION
-
- (defun prolog-complete-atom ()
- (interactive)
- (let (sofar)
- (cond ((setq sofar (prolog-completion-sofar))
- (send-prolog (concat
- "'$silent'(emacs_complete_atom(\""
- sofar
- "\"))")))
- (t
- (message "Point not at end of atom")))))
-
- (defun prolog-completions-start-collect ()
- (setq *prolog-atom-completions* nil))
-
- (defun prolog-transfer-completion (atom number)
- (setq *prolog-atom-completions*
- (cons (list atom number)
- *prolog-atom-completions*)))
-
- (defun prolog-completions-run (sofar)
- (prolog-complete-atom-with
- (completing-read "Complete atom: "
- *prolog-atom-completions*
- nil
- nil
- sofar)
- t))
-
- ;;; HISTORY
-
- (defun prolog-previous-command ()
- (interactive)
- (end-of-buffer)
- (setq *prolog-completion-process-mark*
- (marker-position (process-mark (get-buffer-process "*prolog*"))))
- (send-prolog "'$silent'(emacs_previous_command)"))
-
-
- (defun prolog-next-command ()
- (interactive)
- (end-of-buffer)
- (setq *prolog-completion-process-mark*
- (marker-position (process-mark (get-buffer-process "*prolog*"))))
- (send-prolog "'$silent'(emacs_next_command)"))
-
-
- (defun prolog-insert-history-command (cmd)
- (kill-region *prolog-completion-process-mark* (point))
- (insert cmd ".")
- (setq *saved-prolog-process-mark* *prolog-completion-process-mark*))
-
-
- ;;; COMPILATION
-
- (defun prolog-recompile ()
- (interactive)
- (save-some-buffers)
- (if (not (eq (current-buffer) (get-buffer "*prolog*")))
- (pop-to-buffer (get-buffer "*prolog*") nil))
- (end-of-buffer)
- (insert "make.\n")
- (send-prolog "make"))
-
- (defun prolog-compile-buffer-only ()
- "to avoid complications with compile-region and compile-predicate"
- (interactive)
- (let* ((file-name (buffer-file-name))
- (command (concat "['" file-name "']")))
- (if (eq (current-buffer) (get-buffer "*prolog*"))
- (error "Cannot compile *prolog* buffer!")
- (save-some-buffers)
- (pop-to-buffer (get-buffer "*prolog*") nil)
- (end-of-buffer)
- (insert command)
- (insert ".\n")
- (send-prolog command))))
-
- ;;; Show SWI prolog help info in separate window
- (defun prolog-help (filename from to)
- (find-file-other-window filename)
- (widen)
- (narrow-to-region from to))
-