;; all the bells and whistles one would expect, including syntax
;; highlighting and auto indentation. It can also send regions to an
;; inferior Prolog process.
-;;
-;; The code requires the comint, easymenu, info, imenu, and font-lock
-;; libraries. These are normally distributed with GNU Emacs and
-;; XEmacs.
-;;; Installation:
-;;
-;; Insert the following lines in your init file:
-;;
-;; (setq load-path (cons "/usr/lib/xemacs/site-lisp" load-path))
-;; (autoload 'run-prolog "prolog" "Start a Prolog sub-process." t)
-;; (autoload 'prolog-mode "prolog" "Major mode for editing Prolog programs." t)
-;; (autoload 'mercury-mode "prolog" "Major mode for editing Mercury programs." t)
+;; Some settings you may wish to use:
+
;; (setq prolog-system 'swi) ; optional, the system you are using;
;; ; see `prolog-system' below for possible values
-;; (setq auto-mode-alist (append '(("\\.pl$" . prolog-mode)
-;; ("\\.m$" . mercury-mode))
+;; (setq auto-mode-alist (append '(("\\.pl\\'" . prolog-mode)
+;; ("\\.m\\'" . mercury-mode))
;; auto-mode-alist))
;;
-;; where the path in the first line is the file system path to this file.
-;; MSDOS paths can be written like "d:/programs/emacs-19.34/site-lisp".
-;; Note: In XEmacs, either `/usr/lib/xemacs/site-lisp' (RPM default in
-;; Red Hat-based distributions) or `/usr/local/lib/xemacs/site-lisp'
-;; (default when compiling from sources) are automatically added to
-;; `load-path', so the first line is not necessary provided that you
-;; put this file in the appropriate place.
-;;
-;; The last s-expression above makes sure that files ending with .pl
+;; The last expression above makes sure that files ending with .pl
;; are assumed to be Prolog files and not Perl, which is the default
;; Emacs setting. If this is not wanted, remove this line. It is then
;; necessary to either
;; If the command to start the prolog process ('sicstus', 'pl' or
;; 'swipl' for SWI prolog, etc.) is not available in the default path,
;; then it is necessary to set the value of the environment variable
-;; EPROLOG to a shell command to invoke the prolog process. In XEmacs
-;; and Emacs 20+ you can also customize the variable
+;; EPROLOG to a shell command to invoke the prolog process.
+;; You can also customize the variable
;; `prolog-program-name' (in the group `prolog-inferior') and provide
;; a full path for your Prolog system (swi, scitus, etc.).
;;
;; to keep the GNU Emacs compatibility. So if you work under Emacs
;; and see something that does not work do drop me a line, as I have
;; a smaller chance to notice this kind of bugs otherwise.
+; [The above comment dates from 2011.]
;; Changelog:
;; Version 0.1.35:
;; o Minor font-lock bug fixes.
-;;; TODO:
-
-;; Replace ":type 'sexp" with more precise Custom types.
\f
;;; Code:
(require 'easymenu)
(require 'align)
+(eval-when-compile
+ (or (fboundp 'use-region-p)
+ (defsubst use-region-p () (region-exists-p))))
(defgroup prolog nil
"Editing and running Prolog and Mercury files."
"Alist of Prolog keywords which is used for font locking of directives."
:version "24.1"
:group 'prolog-font-lock
- :type 'sexp
+ ;; Note that "(repeat string)" also allows "nil" (repeat-count 0).
+ ;; This gets processed by prolog-find-value-by-system, which
+ ;; allows both the car and the cdr to be a list to eval.
+ ;; Though the latter must have the form '(eval ...)'.
+ ;; Of course, none of this is documented...
+ :type '(repeat (list (choice symbol sexp) (choice (repeat string) sexp)))
:risky t)
(defcustom prolog-types
"Alist of Prolog types used by font locking."
:version "24.1"
:group 'prolog-font-lock
- :type 'sexp
+ :type '(repeat (list (choice symbol sexp) (choice (repeat string) sexp)))
:risky t)
(defcustom prolog-mode-specificators
"Alist of Prolog mode specificators used by font locking."
:version "24.1"
:group 'prolog-font-lock
- :type 'sexp
+ :type '(repeat (list (choice symbol sexp) (choice (repeat string) sexp)))
:risky t)
(defcustom prolog-determinism-specificators
"Alist of Prolog determinism specificators used by font locking."
:version "24.1"
:group 'prolog-font-lock
- :type 'sexp
+ :type '(repeat (list (choice symbol sexp) (choice (repeat string) sexp)))
:risky t)
(defcustom prolog-directives
"Alist of Prolog source code directives used by font locking."
:version "24.1"
:group 'prolog-font-lock
- :type 'sexp
+ :type '(repeat (list (choice symbol sexp) (choice (repeat string) sexp)))
:risky t)
(or (car names) "prolog"))))
"Alist of program names for invoking an inferior Prolog with `run-prolog'."
:group 'prolog-inferior
- :type 'sexp
+ :type '(alist :key-type (choice symbol sexp)
+ :value-type (group (choice string (const nil) sexp)))
:risky t)
(defun prolog-program-name ()
(prolog-find-value-by-system prolog-program-name))
"Alist of switches given to inferior Prolog run with `run-prolog'."
:version "24.1"
:group 'prolog-inferior
- :type 'sexp
+ :type '(repeat (list (choice symbol sexp) (choice (repeat string) sexp)))
:risky t)
(defun prolog-program-switches ()
(prolog-find-value-by-system prolog-program-switches))
region of a buffer, in which case it is the number of lines before
the region."
:group 'prolog-inferior
- :type 'sexp
+ :type '(alist :key-type (choice symbol sexp)
+ :value-type (group (choice string (const nil) sexp)))
:risky t)
(defun prolog-consult-string ()
If `prolog-program-name' is non-nil, it is a string sent to a Prolog process.
If `prolog-program-name' is nil, it is an argument to the `compile' function."
:group 'prolog-inferior
- :type 'sexp
+ :type '(alist :key-type (choice symbol sexp)
+ :value-type (group (choice string (const nil) sexp)))
:risky t)
(defun prolog-compile-string ()
(prolog-find-value-by-system prolog-compile-string))
(defcustom prolog-eof-string "end_of_file.\n"
- "Alist of strings that represent end of file for prolog.
-nil means send actual operating system end of file."
+ "String or alist of strings that represent end of file for prolog.
+If nil, send actual operating system end of file."
:group 'prolog-inferior
- :type 'sexp
+ :type '(choice string
+ (const nil)
+ (alist :key-type (choice symbol sexp)
+ :value-type (group (choice string (const nil) sexp))))
:risky t)
(defcustom prolog-prompt-regexp
"Alist of prompts of the prolog system command line."
:version "24.1"
:group 'prolog-inferior
- :type 'sexp
+ :type '(alist :key-type (choice symbol sexp)
+ :value-type (group (choice string (const nil) sexp)))
:risky t)
(defun prolog-prompt-regexp ()
;; (t "^|: +"))
;; "Alist of regexps matching the prompt when consulting `user'."
;; :group 'prolog-inferior
-;; :type 'sexp
+;; :type '(alist :key-type (choice symbol sexp)
+;; :value-type (group (choice string (const nil) sexp)))
;; :risky t)
(defcustom prolog-debug-on-string "debug.\n"
(define-abbrev-table 'prolog-mode-abbrev-table ())
-;; Becauses this can `eval' its arguments, any variable that gets
+;; Because this can `eval' its arguments, any variable that gets
;; processed by it should be marked as :risky.
(defun prolog-find-value-by-system (alist)
"Get value from ALIST according to `prolog-system'."
(comint-send-string proc (string last-command-event))
(call-interactively 'self-insert-command))))
-(declare-function 'compilation-shell-minor-mode "compile" (&optional arg))
+(declare-function compilation-shell-minor-mode "compile" (&optional arg))
(defvar compilation-error-regexp-alist)
(define-derived-mode prolog-inferior-mode comint-mode "Inferior Prolog"
()
(with-current-buffer (get-buffer-create "*prolog*")
(prolog-inferior-mode)
- (apply 'make-comint-in-buffer "prolog" (current-buffer)
- (prolog-program-name) nil (prolog-program-switches))
+
+ ;; The "INFERIOR=yes" hack is for SWI-Prolog 7.2.3 and earlier,
+ ;; which assumes it is running under Emacs if either INFERIOR=yes or
+ ;; if EMACS is set to a nonempty value. The EMACS setting is
+ ;; obsolescent, so set INFERIOR. Newer versions of SWI-Prolog should
+ ;; know about INSIDE_EMACS (which replaced EMACS) and should not need
+ ;; this hack.
+ (let ((process-environment
+ (if (getenv "INFERIOR")
+ process-environment
+ (cons "INFERIOR=yes" process-environment))))
+ (apply 'make-comint-in-buffer "prolog" (current-buffer)
+ (prolog-program-name) nil (prolog-program-switches)))
+
(unless prolog-system
;; Setup auto-detection.
(setq-local
;; prolog buffer)
;;-------------------------------------------------------------------
-(unless (fboundp 'region-exists-p)
- (defun region-exists-p ()
- "Non-nil if the mark is set. Lobotomized version for Emacsen that do not provide their own."
- (mark)))
-
-
;; GNU Emacs ignores `easy-menu-add' so the order in which the menus
;; are defined _is_ important!
:included (not (eq prolog-system 'mercury))]
["Consult buffer" prolog-consult-buffer
:included (not (eq prolog-system 'mercury))]
- ["Consult region" prolog-consult-region :active (region-exists-p)
+ ["Consult region" prolog-consult-region :active (use-region-p)
:included (not (eq prolog-system 'mercury))]
["Consult predicate" prolog-consult-predicate
:included (not (eq prolog-system 'mercury))]
:included (eq prolog-system 'sicstus)]
["Compile buffer" prolog-compile-buffer
:included (eq prolog-system 'sicstus)]
- ["Compile region" prolog-compile-region :active (region-exists-p)
+ ["Compile region" prolog-compile-region :active (use-region-p)
:included (eq prolog-system 'sicstus)]
["Compile predicate" prolog-compile-predicate
:included (eq prolog-system 'sicstus)]
prolog-edit-menu-insert-move prolog-mode-map
"Commands for Prolog code manipulation."
'("Prolog"
- ["Comment region" comment-region (region-exists-p)]
- ["Uncomment region" prolog-uncomment-region (region-exists-p)]
+ ["Comment region" comment-region (use-region-p)]
+ ["Uncomment region" prolog-uncomment-region (use-region-p)]
["Add comment/move to comment" indent-for-comment t]
["Convert variables in region to '_'" prolog-variables-to-anonymous
- :active (region-exists-p) :included (not (eq prolog-system 'mercury))]
+ :active (use-region-p) :included (not (eq prolog-system 'mercury))]
"---"
["Insert predicate template" prolog-insert-predicate-template t]
["Insert next clause head" prolog-insert-next-clause t]
["End of predicate" prolog-end-of-predicate t]
"---"
["Indent line" indent-according-to-mode t]
- ["Indent region" indent-region (region-exists-p)]
+ ["Indent region" indent-region (use-region-p)]
["Indent predicate" prolog-indent-predicate t]
["Indent buffer" prolog-indent-buffer t]
- ["Align region" align (region-exists-p)]
+ ["Align region" align (use-region-p)]
"---"
["Mark clause" prolog-mark-clause t]
["Mark predicate" prolog-mark-predicate t]