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