Sync to HEAD
[bpt/emacs.git] / lisp / progmodes / prolog.el
CommitLineData
6594deb0
ER
1;;; prolog.el --- major mode for editing and running Prolog under Emacs
2
6b61353c 3;; Copyright (C) 1986, 1987, 2003, 2004 Free Software Foundation, Inc.
9750e079 4
0acdb863 5;; Author: Masanobu UMEDA <umerin@mse.kyutech.ac.jp>
d7b4d18f 6;; Keywords: languages
e5167999 7
d8025917 8;; This file is part of GNU Emacs.
9
10;; GNU Emacs is free software; you can redistribute it and/or modify
11;; it under the terms of the GNU General Public License as published by
e5167999 12;; the Free Software Foundation; either version 2, or (at your option)
d8025917 13;; any later version.
14
15;; GNU Emacs is distributed in the hope that it will be useful,
16;; but WITHOUT ANY WARRANTY; without even the implied warranty of
17;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
18;; GNU General Public License for more details.
19
20;; You should have received a copy of the GNU General Public License
b578f267
EN
21;; along with GNU Emacs; see the file COPYING. If not, write to the
22;; Free Software Foundation, Inc., 59 Temple Place - Suite 330,
23;; Boston, MA 02111-1307, USA.
d8025917 24
edbd2f74
ER
25;;; Commentary:
26
27;; This package provides a major mode for editing Prolog. It knows
28;; about Prolog syntax and comments, and can send regions to an inferior
f614a1ae 29;; Prolog interpreter process. Font locking is tuned towards GNU Prolog.
edbd2f74 30
e5167999
ER
31;;; Code:
32
c5292bc8
RS
33(defgroup prolog nil
34 "Major mode for editing and running Prolog under Emacs"
35 :group 'languages)
36
f614a1ae 37
6b61353c
KH
38(defcustom prolog-program-name
39 (let ((names '("prolog" "gprolog")))
40 (while (and names
41 (not (executable-find (car names))))
42 (setq names (cdr names)))
43 (or (car names) "prolog"))
c5292bc8
RS
44 "*Program name for invoking an inferior Prolog with `run-prolog'."
45 :type 'string
46 :group 'prolog)
d8025917 47
c5292bc8
RS
48(defcustom prolog-consult-string "reconsult(user).\n"
49 "*(Re)Consult mode (for C-Prolog and Quintus Prolog). "
50 :type 'string
51 :group 'prolog)
d8025917 52
c5292bc8
RS
53(defcustom prolog-compile-string "compile(user).\n"
54 "*Compile mode (for Quintus Prolog)."
55 :type 'string
56 :group 'prolog)
d8025917 57
c5292bc8 58(defcustom prolog-eof-string "end_of_file.\n"
d8025917 59 "*String that represents end of file for prolog.
c5292bc8
RS
60nil means send actual operating system end of file."
61 :type 'string
62 :group 'prolog)
d8025917 63
c5292bc8
RS
64(defcustom prolog-indent-width 4
65 "Level of indentation in Prolog buffers."
66 :type 'integer
67 :group 'prolog)
d8025917 68
f614a1ae
TTN
69(defvar prolog-font-lock-keywords
70 '(("\\(#[<=]=>\\|:-\\)\\|\\(#=\\)\\|\\(#[#<>\\/][=\\/]*\\|!\\)"
71 0 font-lock-keyword-face)
72 ("\\<\\(is\\|write\\|nl\\|read_\\sw+\\)\\>"
73 1 font-lock-keyword-face)
74 ("^\\(\\sw+\\)\\s-*\\((\\(.+\\))\\)*"
75 (1 font-lock-function-name-face)
76 (3 font-lock-variable-name-face)))
77 "Font-lock keywords for Prolog mode.")
78
6b61353c 79(defvar prolog-mode-syntax-table
d8025917 80 (let ((table (make-syntax-table)))
81 (modify-syntax-entry ?_ "w" table)
82 (modify-syntax-entry ?\\ "\\" table)
f614a1ae
TTN
83 (modify-syntax-entry ?/ ". 14" table)
84 (modify-syntax-entry ?* ". 23" table)
d8025917 85 (modify-syntax-entry ?+ "." table)
86 (modify-syntax-entry ?- "." table)
87 (modify-syntax-entry ?= "." table)
88 (modify-syntax-entry ?% "<" table)
673f4fc6 89 (modify-syntax-entry ?\n ">" table)
d8025917 90 (modify-syntax-entry ?< "." table)
91 (modify-syntax-entry ?> "." table)
92 (modify-syntax-entry ?\' "\"" table)
6b61353c 93 table))
d8025917 94
6b61353c 95(defvar prolog-mode-abbrev-table nil)
d8025917 96(define-abbrev-table 'prolog-mode-abbrev-table ())
97
98(defun prolog-mode-variables ()
d8025917 99 (make-local-variable 'paragraph-separate)
6b61353c 100 (setq paragraph-separate (concat "%%\\|$\\|" page-delimiter)) ;'%%..'
d8025917 101 (make-local-variable 'paragraph-ignore-fill-prefix)
102 (setq paragraph-ignore-fill-prefix t)
2c239c80
KH
103 (make-local-variable 'imenu-generic-expression)
104 (setq imenu-generic-expression "^[a-z][a-zA-Z0-9_]+")
d8025917 105 (make-local-variable 'indent-line-function)
106 (setq indent-line-function 'prolog-indent-line)
107 (make-local-variable 'comment-start)
108 (setq comment-start "%")
109 (make-local-variable 'comment-start-skip)
6b61353c
KH
110 (setq comment-start-skip "\\(?:%+\\|/\\*+\\)[ \t]*")
111 (make-local-variable 'comment-end-skip)
112 (setq comment-end-skip "[ \t]*\\(\n\\|\\*+/\\)")
d8025917 113 (make-local-variable 'comment-column)
6b61353c 114 (setq comment-column 48))
d8025917 115
6b61353c
KH
116(defvar prolog-mode-map
117 (let ((map (make-sparse-keymap)))
118 (define-key map "\e\C-x" 'prolog-consult-region)
119 map))
d8025917 120
f9f9507e 121;;;###autoload
d8025917 122(defun prolog-mode ()
123 "Major mode for editing Prolog code for Prologs.
124Blank lines and `%%...' separate paragraphs. `%'s start comments.
125Commands:
126\\{prolog-mode-map}
573f9b32 127Entry to this mode calls the value of `prolog-mode-hook'
d8025917 128if that value is non-nil."
129 (interactive)
130 (kill-all-local-variables)
131 (use-local-map prolog-mode-map)
6b61353c 132 (set-syntax-table prolog-mode-syntax-table)
d8025917 133 (setq major-mode 'prolog-mode)
134 (setq mode-name "Prolog")
135 (prolog-mode-variables)
f614a1ae
TTN
136 ;; font lock
137 (setq font-lock-defaults '(prolog-font-lock-keywords
138 nil nil nil
139 beginning-of-line))
6b61353c 140 (run-mode-hooks 'prolog-mode-hook))
d8025917 141
142(defun prolog-indent-line (&optional whole-exp)
143 "Indent current line as Prolog code.
144With argument, indent any additional lines of the same clause
145rigidly along with this one (not yet)."
146 (interactive "p")
147 (let ((indent (prolog-indent-level))
148 (pos (- (point-max) (point))) beg)
149 (beginning-of-line)
150 (setq beg (point))
151 (skip-chars-forward " \t")
152 (if (zerop (- indent (current-column)))
153 nil
154 (delete-region beg (point))
155 (indent-to indent))
156 (if (> (- (point-max) pos) (point))
157 (goto-char (- (point-max) pos)))
158 ))
159
160(defun prolog-indent-level ()
161 "Compute prolog indentation level."
162 (save-excursion
163 (beginning-of-line)
164 (skip-chars-forward " \t")
165 (cond
166 ((looking-at "%%%") 0) ;Large comment starts
167 ((looking-at "%[^%]") comment-column) ;Small comment starts
168 ((bobp) 0) ;Beginning of buffer
169 (t
170 (let ((empty t) ind more less)
171 (if (looking-at ")")
172 (setq less t) ;Find close
173 (setq less nil))
174 ;; See previous indentation
175 (while empty
176 (forward-line -1)
177 (beginning-of-line)
178 (if (bobp)
179 (setq empty nil)
180 (skip-chars-forward " \t")
181 (if (not (or (looking-at "%[^%]") (looking-at "\n")))
182 (setq empty nil))))
183 (if (bobp)
184 (setq ind 0) ;Beginning of buffer
185 (setq ind (current-column))) ;Beginning of clause
186 ;; See its beginning
187 (if (looking-at "%%[^%]")
188 ind
189 ;; Real prolog code
190 (if (looking-at "(")
191 (setq more t) ;Find open
192 (setq more nil))
193 ;; See its tail
194 (end-of-prolog-clause)
195 (or (bobp) (forward-char -1))
196 (cond ((looking-at "[,(;>]")
197 (if (and more (looking-at "[^,]"))
198 (+ ind prolog-indent-width) ;More indentation
199 (max tab-width ind))) ;Same indentation
200 ((looking-at "-") tab-width) ;TAB
201 ((or less (looking-at "[^.]"))
202 (max (- ind prolog-indent-width) 0)) ;Less indentation
203 (t 0)) ;No indentation
204 )))
205 )))
206
207(defun end-of-prolog-clause ()
208 "Go to end of clause in this line."
209 (beginning-of-line 1)
210 (let* ((eolpos (save-excursion (end-of-line) (point))))
211 (if (re-search-forward comment-start-skip eolpos 'move)
212 (goto-char (match-beginning 0)))
213 (skip-chars-backward " \t")))
d8025917 214\f
215;;;
216;;; Inferior prolog mode
217;;;
6b61353c
KH
218(defvar inferior-prolog-mode-map
219 (let ((map (make-sparse-keymap)))
220 ;; This map will inherit from `comint-mode-map' when entering
221 ;; inferior-prolog-mode.
222 map))
223
224(defvar inferior-prolog-mode-syntax-table prolog-mode-syntax-table)
225(defvar inferior-prolog-mode-abbrev-table prolog-mode-abbrev-table)
d8025917 226
6b61353c 227(define-derived-mode inferior-prolog-mode comint-mode "Inferior Prolog"
d8025917 228 "Major mode for interacting with an inferior Prolog process.
229
230The following commands are available:
231\\{inferior-prolog-mode-map}
232
573f9b32
RS
233Entry to this mode calls the value of `prolog-mode-hook' with no arguments,
234if that value is non-nil. Likewise with the value of `comint-mode-hook'.
235`prolog-mode-hook' is called after `comint-mode-hook'.
d8025917 236
237You can send text to the inferior Prolog from other buffers
573f9b32 238using the commands `send-region', `send-string' and \\[prolog-consult-region].
d8025917 239
240Commands:
241Tab indents for Prolog; with argument, shifts rest
242 of expression rigidly with the current line.
573f9b32
RS
243Paragraphs are separated only by blank lines and '%%'.
244'%'s start comments.
d8025917 245
246Return at end of buffer sends line as input.
247Return not at end copies rest of line to end and sends it.
248\\[comint-kill-input] and \\[backward-kill-word] are kill commands, imitating normal Unix input editing.
249\\[comint-interrupt-subjob] interrupts the shell or its current subjob if any.
250\\[comint-stop-subjob] stops. \\[comint-quit-subjob] sends quit signal."
6b61353c
KH
251 (setq comint-prompt-regexp "^| [ ?][- ] *")
252 (prolog-mode-variables))
d8025917 253
f9f9507e 254;;;###autoload
d8025917 255(defun run-prolog ()
256 "Run an inferior Prolog process, input and output via buffer *prolog*."
257 (interactive)
258 (require 'comint)
6b61353c 259 (pop-to-buffer (make-comint "prolog" prolog-program-name))
d8025917 260 (inferior-prolog-mode))
261
262(defun prolog-consult-region (compile beg end)
573f9b32
RS
263 "Send the region to the Prolog process made by \"M-x run-prolog\".
264If COMPILE (prefix arg) is not nil, use compile mode rather than consult mode."
d8025917 265 (interactive "P\nr")
266 (save-excursion
267 (if compile
268 (send-string "prolog" prolog-compile-string)
269 (send-string "prolog" prolog-consult-string))
270 (send-region "prolog" beg end)
271 (send-string "prolog" "\n") ;May be unnecessary
272 (if prolog-eof-string
273 (send-string "prolog" prolog-eof-string)
274 (process-send-eof "prolog")))) ;Send eof to prolog process.
275
276(defun prolog-consult-region-and-go (compile beg end)
277 "Send the region to the inferior Prolog, and switch to *prolog* buffer.
573f9b32 278If COMPILE (prefix arg) is not nil, use compile mode rather than consult mode."
d8025917 279 (interactive "P\nr")
280 (prolog-consult-region compile beg end)
281 (switch-to-buffer "*prolog*"))
6594deb0 282
896546cd
RS
283(provide 'prolog)
284
6b61353c 285;;; arch-tag: f3ec6748-1272-4ab6-8826-c50cb1607636
6594deb0 286;;; prolog.el ends here