]> code.delx.au - gnu-emacs/blob - lisp/progmodes/prolog.el
(compilation-error-regexp-alist): Add regexp for Sun ada.
[gnu-emacs] / lisp / progmodes / prolog.el
1 ;;; prolog.el --- major mode for editing and running Prolog under Emacs
2
3 ;; Copyright (C) 1986, 1987 Free Software Foundation, Inc.
4
5 ;; Author: Masanobu UMEDA <umerin@flab.flab.fujitsu.junet>
6 ;; Keywords: languages
7
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
12 ;; the Free Software Foundation; either version 2, or (at your option)
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
21 ;; along with GNU Emacs; see the file COPYING. If not, write to
22 ;; the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.
23
24 ;;; Commentary:
25
26 ;; This package provides a major mode for editing Prolog. It knows
27 ;; about Prolog syntax and comments, and can send regions to an inferior
28 ;; Prolog interpreter process.
29
30 ;;; Code:
31
32 (defvar prolog-mode-syntax-table nil)
33 (defvar prolog-mode-abbrev-table nil)
34 (defvar prolog-mode-map nil)
35
36 (defvar prolog-program-name "prolog"
37 "*Program name for invoking an inferior Prolog with `run-prolog'.")
38
39 (defvar prolog-consult-string "reconsult(user).\n"
40 "*(Re)Consult mode (for C-Prolog and Quintus Prolog). ")
41
42 (defvar prolog-compile-string "compile(user).\n"
43 "*Compile mode (for Quintus Prolog).")
44
45 (defvar prolog-eof-string "end_of_file.\n"
46 "*String that represents end of file for prolog.
47 nil means send actual operating system end of file.")
48
49 (defvar prolog-indent-width 4)
50
51 (if prolog-mode-syntax-table
52 ()
53 (let ((table (make-syntax-table)))
54 (modify-syntax-entry ?_ "w" table)
55 (modify-syntax-entry ?\\ "\\" table)
56 (modify-syntax-entry ?/ "." table)
57 (modify-syntax-entry ?* "." table)
58 (modify-syntax-entry ?+ "." table)
59 (modify-syntax-entry ?- "." table)
60 (modify-syntax-entry ?= "." table)
61 (modify-syntax-entry ?% "<" table)
62 (modify-syntax-entry ?\n ">" table)
63 (modify-syntax-entry ?< "." table)
64 (modify-syntax-entry ?> "." table)
65 (modify-syntax-entry ?\' "\"" table)
66 (setq prolog-mode-syntax-table table)))
67
68 (define-abbrev-table 'prolog-mode-abbrev-table ())
69
70 (defun prolog-mode-variables ()
71 (set-syntax-table prolog-mode-syntax-table)
72 (setq local-abbrev-table prolog-mode-abbrev-table)
73 (make-local-variable 'paragraph-start)
74 (setq paragraph-start (concat "%%\\|$\\|" page-delimiter)) ;'%%..'
75 (make-local-variable 'paragraph-separate)
76 (setq paragraph-separate paragraph-start)
77 (make-local-variable 'paragraph-ignore-fill-prefix)
78 (setq paragraph-ignore-fill-prefix t)
79 (make-local-variable 'indent-line-function)
80 (setq indent-line-function 'prolog-indent-line)
81 (make-local-variable 'comment-start)
82 (setq comment-start "%")
83 (make-local-variable 'comment-start-skip)
84 (setq comment-start-skip "%+ *")
85 (make-local-variable 'comment-column)
86 (setq comment-column 48)
87 (make-local-variable 'comment-indent-function)
88 (setq comment-indent-function 'prolog-comment-indent))
89
90 (defun prolog-mode-commands (map)
91 (define-key map "\t" 'prolog-indent-line)
92 (define-key map "\e\C-x" 'prolog-consult-region))
93
94 (if prolog-mode-map
95 nil
96 (setq prolog-mode-map (make-sparse-keymap))
97 (prolog-mode-commands prolog-mode-map))
98
99 ;;;###autoload
100 (defun prolog-mode ()
101 "Major mode for editing Prolog code for Prologs.
102 Blank lines and `%%...' separate paragraphs. `%'s start comments.
103 Commands:
104 \\{prolog-mode-map}
105 Entry to this mode calls the value of `prolog-mode-hook'
106 if that value is non-nil."
107 (interactive)
108 (kill-all-local-variables)
109 (use-local-map prolog-mode-map)
110 (setq major-mode 'prolog-mode)
111 (setq mode-name "Prolog")
112 (prolog-mode-variables)
113 (run-hooks 'prolog-mode-hook))
114
115 (defun prolog-indent-line (&optional whole-exp)
116 "Indent current line as Prolog code.
117 With argument, indent any additional lines of the same clause
118 rigidly along with this one (not yet)."
119 (interactive "p")
120 (let ((indent (prolog-indent-level))
121 (pos (- (point-max) (point))) beg)
122 (beginning-of-line)
123 (setq beg (point))
124 (skip-chars-forward " \t")
125 (if (zerop (- indent (current-column)))
126 nil
127 (delete-region beg (point))
128 (indent-to indent))
129 (if (> (- (point-max) pos) (point))
130 (goto-char (- (point-max) pos)))
131 ))
132
133 (defun prolog-indent-level ()
134 "Compute prolog indentation level."
135 (save-excursion
136 (beginning-of-line)
137 (skip-chars-forward " \t")
138 (cond
139 ((looking-at "%%%") 0) ;Large comment starts
140 ((looking-at "%[^%]") comment-column) ;Small comment starts
141 ((bobp) 0) ;Beginning of buffer
142 (t
143 (let ((empty t) ind more less)
144 (if (looking-at ")")
145 (setq less t) ;Find close
146 (setq less nil))
147 ;; See previous indentation
148 (while empty
149 (forward-line -1)
150 (beginning-of-line)
151 (if (bobp)
152 (setq empty nil)
153 (skip-chars-forward " \t")
154 (if (not (or (looking-at "%[^%]") (looking-at "\n")))
155 (setq empty nil))))
156 (if (bobp)
157 (setq ind 0) ;Beginning of buffer
158 (setq ind (current-column))) ;Beginning of clause
159 ;; See its beginning
160 (if (looking-at "%%[^%]")
161 ind
162 ;; Real prolog code
163 (if (looking-at "(")
164 (setq more t) ;Find open
165 (setq more nil))
166 ;; See its tail
167 (end-of-prolog-clause)
168 (or (bobp) (forward-char -1))
169 (cond ((looking-at "[,(;>]")
170 (if (and more (looking-at "[^,]"))
171 (+ ind prolog-indent-width) ;More indentation
172 (max tab-width ind))) ;Same indentation
173 ((looking-at "-") tab-width) ;TAB
174 ((or less (looking-at "[^.]"))
175 (max (- ind prolog-indent-width) 0)) ;Less indentation
176 (t 0)) ;No indentation
177 )))
178 )))
179
180 (defun end-of-prolog-clause ()
181 "Go to end of clause in this line."
182 (beginning-of-line 1)
183 (let* ((eolpos (save-excursion (end-of-line) (point))))
184 (if (re-search-forward comment-start-skip eolpos 'move)
185 (goto-char (match-beginning 0)))
186 (skip-chars-backward " \t")))
187
188 (defun prolog-comment-indent ()
189 "Compute prolog comment indentation."
190 (cond ((looking-at "%%%") 0)
191 ((looking-at "%%") (prolog-indent-level))
192 (t
193 (save-excursion
194 (skip-chars-backward " \t")
195 ;; Insert one space at least, except at left margin.
196 (max (+ (current-column) (if (bolp) 0 1))
197 comment-column)))
198 ))
199
200 \f
201 ;;;
202 ;;; Inferior prolog mode
203 ;;;
204 (defvar inferior-prolog-mode-map nil)
205
206 (defun inferior-prolog-mode ()
207 "Major mode for interacting with an inferior Prolog process.
208
209 The following commands are available:
210 \\{inferior-prolog-mode-map}
211
212 Entry to this mode calls the value of `prolog-mode-hook' with no arguments,
213 if that value is non-nil. Likewise with the value of `comint-mode-hook'.
214 `prolog-mode-hook' is called after `comint-mode-hook'.
215
216 You can send text to the inferior Prolog from other buffers
217 using the commands `send-region', `send-string' and \\[prolog-consult-region].
218
219 Commands:
220 Tab indents for Prolog; with argument, shifts rest
221 of expression rigidly with the current line.
222 Paragraphs are separated only by blank lines and '%%'.
223 '%'s start comments.
224
225 Return at end of buffer sends line as input.
226 Return not at end copies rest of line to end and sends it.
227 \\[comint-kill-input] and \\[backward-kill-word] are kill commands, imitating normal Unix input editing.
228 \\[comint-interrupt-subjob] interrupts the shell or its current subjob if any.
229 \\[comint-stop-subjob] stops. \\[comint-quit-subjob] sends quit signal."
230 (interactive)
231 (require 'comint)
232 (comint-mode)
233 (setq major-mode 'inferior-prolog-mode
234 mode-name "Inferior Prolog"
235 comint-prompt-regexp "^| [ ?][- ] *")
236 (prolog-mode-variables)
237 (if inferior-prolog-mode-map nil
238 (setq inferior-prolog-mode-map (copy-keymap comint-mode-map))
239 (prolog-mode-commands inferior-prolog-mode-map))
240 (use-local-map inferior-prolog-mode-map)
241 (run-hooks 'prolog-mode-hook))
242
243 ;;;###autoload
244 (defun run-prolog ()
245 "Run an inferior Prolog process, input and output via buffer *prolog*."
246 (interactive)
247 (require 'comint)
248 (switch-to-buffer (make-comint "prolog" prolog-program-name))
249 (inferior-prolog-mode))
250
251 (defun prolog-consult-region (compile beg end)
252 "Send the region to the Prolog process made by \"M-x run-prolog\".
253 If COMPILE (prefix arg) is not nil, use compile mode rather than consult mode."
254 (interactive "P\nr")
255 (save-excursion
256 (if compile
257 (send-string "prolog" prolog-compile-string)
258 (send-string "prolog" prolog-consult-string))
259 (send-region "prolog" beg end)
260 (send-string "prolog" "\n") ;May be unnecessary
261 (if prolog-eof-string
262 (send-string "prolog" prolog-eof-string)
263 (process-send-eof "prolog")))) ;Send eof to prolog process.
264
265 (defun prolog-consult-region-and-go (compile beg end)
266 "Send the region to the inferior Prolog, and switch to *prolog* buffer.
267 If COMPILE (prefix arg) is not nil, use compile mode rather than consult mode."
268 (interactive "P\nr")
269 (prolog-consult-region compile beg end)
270 (switch-to-buffer "*prolog*"))
271
272 ;;; prolog.el ends here