comparison lisp/modes/prolog.el @ 0:376386a54a3c r19-14

Import from CVS: tag r19-14
author cvs
date Mon, 13 Aug 2007 08:45:50 +0200
parents
children ac2d302a0011
comparison
equal deleted inserted replaced
-1:000000000000 0:376386a54a3c
1 ;;; prolog.el --- major mode for editing and running Prolog under Emacs
2
3 ;; Copyright (C) 1986, 1987, 1993 Free Software Foundation, Inc.
4
5 ;; Author: Masanobu UMEDA <umerin@flab.flab.fujitsu.junet>
6 ;; Keywords: languages
7
8 ;; This file is part of XEmacs.
9
10 ;; XEmacs is free software; you can redistribute it and/or modify it
11 ;; under the terms of the GNU General Public License as published by
12 ;; the Free Software Foundation; either version 2, or (at your option)
13 ;; any later version.
14
15 ;; XEmacs is distributed in the hope that it will be useful, but
16 ;; WITHOUT ANY WARRANTY; without even the implied warranty of
17 ;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
18 ;; General Public License for more details.
19
20 ;; You should have received a copy of the GNU General Public License
21 ;; along with XEmacs; see the file COPYING. If not, write to the Free
22 ;; Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.
23
24 ;;; Synched up with: FSF 19.30.
25
26 ;;; Commentary:
27
28 ;; This package provides a major mode for editing Prolog. It knows
29 ;; about Prolog syntax and comments, and can send regions to an inferior
30 ;; Prolog interpreter process.
31
32 ;;; Code:
33
34 (defvar prolog-mode-syntax-table nil)
35 (defvar prolog-mode-abbrev-table nil)
36 (defvar prolog-mode-map nil)
37
38 (defvar prolog-program-name "prolog"
39 "*Program name for invoking an inferior Prolog with `run-prolog'.")
40
41 (defvar prolog-consult-string "reconsult(user).\n"
42 "*(Re)Consult mode (for C-Prolog and Quintus Prolog). ")
43
44 (defvar prolog-compile-string "compile(user).\n"
45 "*Compile mode (for Quintus Prolog).")
46
47 (defvar prolog-eof-string "end_of_file.\n"
48 "*String that represents end of file for prolog.
49 nil means send actual operating system end of file.")
50
51 (defvar prolog-indent-width 4)
52
53 (defconst prolog-font-lock-keywords (purecopy
54 (list
55 (cons (concat
56 "[( \t]\\("
57 (mapconcat 'identity
58 '("write" "writeq" "nl" "is" "call" "read" "get" "get0"
59 "tell" "told" "open" "close" "format" "put"
60 "assert" "asserta" "assertz"
61 "retract" "retractall" "clause"
62 "record" "recorda" "abolish"
63 "setof" "bagof" "findall" "sort" "compare"
64 "var" "nonvar" "integer" "float" "number" "ground"
65 "atom" "atomic" "simple" "callable" "compound"
66 "functor" "arg" "copy_term" "numbervars"
67 "atom_chars" "number_chars" "atom_to_chars"
68 "length" "unix" "halt"
69 "op" "dynamic" "meta_predicate" "raise_exception"
70 "module" "ensure_loaded" "use_module"
71 "fail" "true"
72 "module_interface" "begin_module" "define_struct"
73 "import" "export" "global" "tool" "external"
74 "define_macro" "local" "library" "from"
75 )
76 "\\|")
77 "\\)[ .,\t\n()]")
78 1)
79 '("^[a-z][a-zA-Z0-9_]+" 0 font-lock-function-name-face)
80 ; '("[@!$#]" 0 font-lock-function-name-face)
81 '("!" 0 font-lock-function-name-face)
82 '("@" 0 font-lock-function-name-face)
83 '("<=>" 0 font-lock-function-name-face)
84 '("==>" 0 font-lock-function-name-face)
85 '(";" 0 font-lock-function-name-face)
86 '(":-" 0 font-lock-function-name-face)
87 '("\\[" 0 font-lock-keyword-face)
88 '("\\]" 0 font-lock-keyword-face)
89 '("|" 0 font-lock-keyword-face)
90 ))
91 "Additional expressions to highlight in Prolog mode.")
92
93 (if prolog-mode-syntax-table
94 ()
95 (let ((table (make-syntax-table)))
96 (modify-syntax-entry ?/ ". 14" table)
97 (modify-syntax-entry ?* ". 23" table)
98 (modify-syntax-entry ?% "< b" table)
99 (modify-syntax-entry ?\n "> b" table)
100 (modify-syntax-entry ?_ "w" table)
101 (modify-syntax-entry ?\\ "\\" table)
102 (modify-syntax-entry ?\' "\"" table)
103 (modify-syntax-entry ?+ "." table)
104 (modify-syntax-entry ?- "." table)
105 (modify-syntax-entry ?= "." table)
106 (modify-syntax-entry ?< "." table)
107 (modify-syntax-entry ?> "." table)
108 (setq prolog-mode-syntax-table table)))
109
110 (define-abbrev-table 'prolog-mode-abbrev-table ())
111
112 (defun prolog-mode-variables ()
113 (set-syntax-table prolog-mode-syntax-table)
114 (setq local-abbrev-table prolog-mode-abbrev-table)
115 (make-local-variable 'paragraph-start)
116 (setq paragraph-start (concat "%%\\|$\\|" page-delimiter)) ;'%%..'
117 (make-local-variable 'paragraph-separate)
118 (setq paragraph-separate paragraph-start)
119 (make-local-variable 'paragraph-ignore-fill-prefix)
120 (setq paragraph-ignore-fill-prefix t)
121 (make-local-variable 'indent-line-function)
122 (setq indent-line-function 'prolog-indent-line)
123 (make-local-variable 'comment-start)
124 (setq comment-start "%")
125 (make-local-variable 'comment-start-skip)
126 (setq comment-start-skip "%+ *")
127 (make-local-variable 'comment-column)
128 (setq comment-column 48)
129 (make-local-variable 'comment-indent-function)
130 (setq comment-indent-function 'prolog-comment-indent))
131
132 (defun prolog-mode-commands (map)
133 (define-key map "\t" 'prolog-indent-line)
134 (define-key map "\e\C-x" 'prolog-consult-region))
135
136 (if prolog-mode-map
137 nil
138 (setq prolog-mode-map (make-sparse-keymap))
139 (prolog-mode-commands prolog-mode-map))
140
141 ;;;###autoload
142 (defun prolog-mode ()
143 "Major mode for editing Prolog code for Prologs.
144 Blank lines and `%%...' separate paragraphs. `%'s start comments.
145 Commands:
146 \\{prolog-mode-map}
147 Entry to this mode calls the value of `prolog-mode-hook'
148 if that value is non-nil."
149 (interactive)
150 (kill-all-local-variables)
151 (use-local-map prolog-mode-map)
152 (setq major-mode 'prolog-mode)
153 (setq mode-name "Prolog")
154 (prolog-mode-variables)
155 (run-hooks 'prolog-mode-hook))
156
157 (defun prolog-indent-line (&optional whole-exp)
158 "Indent current line as Prolog code.
159 With argument, indent any additional lines of the same clause
160 rigidly along with this one (not yet)."
161 (interactive "p")
162 (let ((indent (prolog-indent-level))
163 (pos (- (point-max) (point))) beg)
164 (beginning-of-line)
165 (setq beg (point))
166 (skip-chars-forward " \t")
167 (if (zerop (- indent (current-column)))
168 nil
169 (delete-region beg (point))
170 (indent-to indent))
171 (if (> (- (point-max) pos) (point))
172 (goto-char (- (point-max) pos)))
173 ))
174
175 (defun prolog-indent-level ()
176 "Compute prolog indentation level."
177 (save-excursion
178 (beginning-of-line)
179 (skip-chars-forward " \t")
180 (cond
181 ((looking-at "%%%") 0) ;Large comment starts
182 ((looking-at "%[^%]") comment-column) ;Small comment starts
183 ((bobp) 0) ;Beginning of buffer
184 (t
185 (let ((empty t) ind more less)
186 (if (looking-at ")")
187 (setq less t) ;Find close
188 (setq less nil))
189 ;; See previous indentation
190 (while empty
191 (forward-line -1)
192 (beginning-of-line)
193 (if (bobp)
194 (setq empty nil)
195 (skip-chars-forward " \t")
196 (if (not (or (looking-at "%[^%]") (looking-at "\n")))
197 (setq empty nil))))
198 (if (bobp)
199 (setq ind 0) ;Beginning of buffer
200 (setq ind (current-column))) ;Beginning of clause
201 ;; See its beginning
202 (if (looking-at "%%[^%]")
203 ind
204 ;; Real prolog code
205 (if (looking-at "(")
206 (setq more t) ;Find open
207 (setq more nil))
208 ;; See its tail
209 (end-of-prolog-clause)
210 (or (bobp) (forward-char -1))
211 (cond ((looking-at "[,(;>]")
212 (if (and more (looking-at "[^,]"))
213 (+ ind prolog-indent-width) ;More indentation
214 (max tab-width ind))) ;Same indentation
215 ((looking-at "-") tab-width) ;TAB
216 ((or less (looking-at "[^.]"))
217 (max (- ind prolog-indent-width) 0)) ;Less indentation
218 (t 0)) ;No indentation
219 )))
220 )))
221
222 (defun end-of-prolog-clause ()
223 "Go to end of clause in this line."
224 (beginning-of-line 1)
225 (let* ((eolpos (save-excursion (end-of-line) (point))))
226 (if (re-search-forward comment-start-skip eolpos 'move)
227 (goto-char (match-beginning 0)))
228 (skip-chars-backward " \t")))
229
230 (defun prolog-comment-indent ()
231 "Compute prolog comment indentation."
232 (cond ((looking-at "%%%") 0)
233 ((looking-at "%%") (prolog-indent-level))
234 (t
235 (save-excursion
236 (skip-chars-backward " \t")
237 ;; Insert one space at least, except at left margin.
238 (max (+ (current-column) (if (bolp) 0 1))
239 comment-column)))
240 ))
241
242
243 ;;;
244 ;;; Inferior prolog mode
245 ;;;
246 (defvar inferior-prolog-mode-map nil)
247
248 ;;;###autoload
249 (defun inferior-prolog-mode ()
250 "Major mode for interacting with an inferior Prolog process.
251
252 The following commands are available:
253 \\{inferior-prolog-mode-map}
254
255 Entry to this mode calls the value of `prolog-mode-hook' with no arguments,
256 if that value is non-nil. Likewise with the value of `comint-mode-hook'.
257 `prolog-mode-hook' is called after `comint-mode-hook'.
258
259 You can send text to the inferior Prolog from other buffers
260 using the commands `send-region', `send-string' and \\[prolog-consult-region].
261
262 Commands:
263 Tab indents for Prolog; with argument, shifts rest
264 of expression rigidly with the current line.
265 Paragraphs are separated only by blank lines and '%%'.
266 '%'s start comments.
267
268 Return at end of buffer sends line as input.
269 Return not at end copies rest of line to end and sends it.
270 \\[comint-kill-input] and \\[backward-kill-word] are kill commands, imitating normal Unix input editing.
271 \\[comint-interrupt-subjob] interrupts the shell or its current subjob if any.
272 \\[comint-stop-subjob] stops. \\[comint-quit-subjob] sends quit signal."
273 (interactive)
274 (require 'comint)
275 (comint-mode)
276 (setq major-mode 'inferior-prolog-mode
277 mode-name "Inferior Prolog"
278 comint-prompt-regexp "^| [ ?][- ] *")
279 (prolog-mode-variables)
280 (if inferior-prolog-mode-map nil
281 (setq inferior-prolog-mode-map (copy-keymap comint-mode-map))
282 (prolog-mode-commands inferior-prolog-mode-map))
283 (use-local-map inferior-prolog-mode-map)
284 (run-hooks 'prolog-mode-hook))
285
286 ;;;###autoload
287 (defun run-prolog ()
288 "Run an inferior Prolog process, input and output via buffer *prolog*."
289 (interactive)
290 (require 'comint)
291 (switch-to-buffer (make-comint "prolog" prolog-program-name))
292 (inferior-prolog-mode))
293
294 (defun prolog-consult-region (compile beg end)
295 "Send the region to the Prolog process made by \"M-x run-prolog\".
296 If COMPILE (prefix arg) is not nil, use compile mode rather than consult mode."
297 (interactive "P\nr")
298 (save-excursion
299 (if compile
300 (send-string "prolog" prolog-compile-string)
301 (send-string "prolog" prolog-consult-string))
302 (send-region "prolog" beg end)
303 (send-string "prolog" "\n") ;May be unnecessary
304 (if prolog-eof-string
305 (send-string "prolog" prolog-eof-string)
306 (process-send-eof "prolog")))) ;Send eof to prolog process.
307
308 (defun prolog-consult-region-and-go (compile beg end)
309 "Send the region to the inferior Prolog, and switch to *prolog* buffer.
310 If COMPILE (prefix arg) is not nil, use compile mode rather than consult mode."
311 (interactive "P\nr")
312 (prolog-consult-region compile beg end)
313 (switch-to-buffer "*prolog*"))
314
315 ;;; prolog.el ends here