Add arch taglines
[bpt/emacs.git] / lisp / progmodes / prolog.el
CommitLineData
6594deb0
ER
1;;; prolog.el --- major mode for editing and running Prolog under Emacs
2
9750e079
ER
3;; Copyright (C) 1986, 1987 Free Software Foundation, Inc.
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
d8025917 33(defvar prolog-mode-syntax-table nil)
34(defvar prolog-mode-abbrev-table nil)
35(defvar prolog-mode-map nil)
c5292bc8
RS
36
37(defgroup prolog nil
38 "Major mode for editing and running Prolog under Emacs"
39 :group 'languages)
40
f614a1ae 41
c5292bc8
RS
42(defcustom prolog-program-name "prolog"
43 "*Program name for invoking an inferior Prolog with `run-prolog'."
44 :type 'string
45 :group 'prolog)
d8025917 46
c5292bc8
RS
47(defcustom prolog-consult-string "reconsult(user).\n"
48 "*(Re)Consult mode (for C-Prolog and Quintus Prolog). "
49 :type 'string
50 :group 'prolog)
d8025917 51
c5292bc8
RS
52(defcustom prolog-compile-string "compile(user).\n"
53 "*Compile mode (for Quintus Prolog)."
54 :type 'string
55 :group 'prolog)
d8025917 56
c5292bc8 57(defcustom prolog-eof-string "end_of_file.\n"
d8025917 58 "*String that represents end of file for prolog.
c5292bc8
RS
59nil means send actual operating system end of file."
60 :type 'string
61 :group 'prolog)
d8025917 62
c5292bc8
RS
63(defcustom prolog-indent-width 4
64 "Level of indentation in Prolog buffers."
65 :type 'integer
66 :group 'prolog)
d8025917 67
f614a1ae
TTN
68(defvar prolog-font-lock-keywords
69 '(("\\(#[<=]=>\\|:-\\)\\|\\(#=\\)\\|\\(#[#<>\\/][=\\/]*\\|!\\)"
70 0 font-lock-keyword-face)
71 ("\\<\\(is\\|write\\|nl\\|read_\\sw+\\)\\>"
72 1 font-lock-keyword-face)
73 ("^\\(\\sw+\\)\\s-*\\((\\(.+\\))\\)*"
74 (1 font-lock-function-name-face)
75 (3 font-lock-variable-name-face)))
76 "Font-lock keywords for Prolog mode.")
77
d8025917 78(if prolog-mode-syntax-table
79 ()
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)
93 (setq prolog-mode-syntax-table table)))
94
95(define-abbrev-table 'prolog-mode-abbrev-table ())
96
97(defun prolog-mode-variables ()
98 (set-syntax-table prolog-mode-syntax-table)
99 (setq local-abbrev-table prolog-mode-abbrev-table)
100 (make-local-variable 'paragraph-start)
56414894 101 (setq paragraph-start (concat "%%\\|$\\|" page-delimiter)) ;'%%..'
d8025917 102 (make-local-variable 'paragraph-separate)
103 (setq paragraph-separate paragraph-start)
104 (make-local-variable 'paragraph-ignore-fill-prefix)
105 (setq paragraph-ignore-fill-prefix t)
2c239c80
KH
106 (make-local-variable 'imenu-generic-expression)
107 (setq imenu-generic-expression "^[a-z][a-zA-Z0-9_]+")
d8025917 108 (make-local-variable 'indent-line-function)
109 (setq indent-line-function 'prolog-indent-line)
110 (make-local-variable 'comment-start)
111 (setq comment-start "%")
112 (make-local-variable 'comment-start-skip)
113 (setq comment-start-skip "%+ *")
114 (make-local-variable 'comment-column)
115 (setq comment-column 48)
e41b2db1
ER
116 (make-local-variable 'comment-indent-function)
117 (setq comment-indent-function 'prolog-comment-indent))
d8025917 118
119(defun prolog-mode-commands (map)
120 (define-key map "\t" 'prolog-indent-line)
121 (define-key map "\e\C-x" 'prolog-consult-region))
122
123(if prolog-mode-map
124 nil
125 (setq prolog-mode-map (make-sparse-keymap))
126 (prolog-mode-commands prolog-mode-map))
127
f9f9507e 128;;;###autoload
d8025917 129(defun prolog-mode ()
130 "Major mode for editing Prolog code for Prologs.
131Blank lines and `%%...' separate paragraphs. `%'s start comments.
132Commands:
133\\{prolog-mode-map}
573f9b32 134Entry to this mode calls the value of `prolog-mode-hook'
d8025917 135if that value is non-nil."
136 (interactive)
137 (kill-all-local-variables)
138 (use-local-map prolog-mode-map)
139 (setq major-mode 'prolog-mode)
140 (setq mode-name "Prolog")
141 (prolog-mode-variables)
f614a1ae
TTN
142 ;; font lock
143 (setq font-lock-defaults '(prolog-font-lock-keywords
144 nil nil nil
145 beginning-of-line))
d8025917 146 (run-hooks 'prolog-mode-hook))
147
148(defun prolog-indent-line (&optional whole-exp)
149 "Indent current line as Prolog code.
150With argument, indent any additional lines of the same clause
151rigidly along with this one (not yet)."
152 (interactive "p")
153 (let ((indent (prolog-indent-level))
154 (pos (- (point-max) (point))) beg)
155 (beginning-of-line)
156 (setq beg (point))
157 (skip-chars-forward " \t")
158 (if (zerop (- indent (current-column)))
159 nil
160 (delete-region beg (point))
161 (indent-to indent))
162 (if (> (- (point-max) pos) (point))
163 (goto-char (- (point-max) pos)))
164 ))
165
166(defun prolog-indent-level ()
167 "Compute prolog indentation level."
168 (save-excursion
169 (beginning-of-line)
170 (skip-chars-forward " \t")
171 (cond
172 ((looking-at "%%%") 0) ;Large comment starts
173 ((looking-at "%[^%]") comment-column) ;Small comment starts
174 ((bobp) 0) ;Beginning of buffer
175 (t
176 (let ((empty t) ind more less)
177 (if (looking-at ")")
178 (setq less t) ;Find close
179 (setq less nil))
180 ;; See previous indentation
181 (while empty
182 (forward-line -1)
183 (beginning-of-line)
184 (if (bobp)
185 (setq empty nil)
186 (skip-chars-forward " \t")
187 (if (not (or (looking-at "%[^%]") (looking-at "\n")))
188 (setq empty nil))))
189 (if (bobp)
190 (setq ind 0) ;Beginning of buffer
191 (setq ind (current-column))) ;Beginning of clause
192 ;; See its beginning
193 (if (looking-at "%%[^%]")
194 ind
195 ;; Real prolog code
196 (if (looking-at "(")
197 (setq more t) ;Find open
198 (setq more nil))
199 ;; See its tail
200 (end-of-prolog-clause)
201 (or (bobp) (forward-char -1))
202 (cond ((looking-at "[,(;>]")
203 (if (and more (looking-at "[^,]"))
204 (+ ind prolog-indent-width) ;More indentation
205 (max tab-width ind))) ;Same indentation
206 ((looking-at "-") tab-width) ;TAB
207 ((or less (looking-at "[^.]"))
208 (max (- ind prolog-indent-width) 0)) ;Less indentation
209 (t 0)) ;No indentation
210 )))
211 )))
212
213(defun end-of-prolog-clause ()
214 "Go to end of clause in this line."
215 (beginning-of-line 1)
216 (let* ((eolpos (save-excursion (end-of-line) (point))))
217 (if (re-search-forward comment-start-skip eolpos 'move)
218 (goto-char (match-beginning 0)))
219 (skip-chars-backward " \t")))
220
221(defun prolog-comment-indent ()
222 "Compute prolog comment indentation."
223 (cond ((looking-at "%%%") 0)
224 ((looking-at "%%") (prolog-indent-level))
225 (t
226 (save-excursion
227 (skip-chars-backward " \t")
228 ;; Insert one space at least, except at left margin.
229 (max (+ (current-column) (if (bolp) 0 1))
230 comment-column)))
231 ))
232
233\f
234;;;
235;;; Inferior prolog mode
236;;;
237(defvar inferior-prolog-mode-map nil)
238
239(defun inferior-prolog-mode ()
240 "Major mode for interacting with an inferior Prolog process.
241
242The following commands are available:
243\\{inferior-prolog-mode-map}
244
573f9b32
RS
245Entry to this mode calls the value of `prolog-mode-hook' with no arguments,
246if that value is non-nil. Likewise with the value of `comint-mode-hook'.
247`prolog-mode-hook' is called after `comint-mode-hook'.
d8025917 248
249You can send text to the inferior Prolog from other buffers
573f9b32 250using the commands `send-region', `send-string' and \\[prolog-consult-region].
d8025917 251
252Commands:
253Tab indents for Prolog; with argument, shifts rest
254 of expression rigidly with the current line.
573f9b32
RS
255Paragraphs are separated only by blank lines and '%%'.
256'%'s start comments.
d8025917 257
258Return at end of buffer sends line as input.
259Return not at end copies rest of line to end and sends it.
260\\[comint-kill-input] and \\[backward-kill-word] are kill commands, imitating normal Unix input editing.
261\\[comint-interrupt-subjob] interrupts the shell or its current subjob if any.
262\\[comint-stop-subjob] stops. \\[comint-quit-subjob] sends quit signal."
263 (interactive)
264 (require 'comint)
265 (comint-mode)
266 (setq major-mode 'inferior-prolog-mode
267 mode-name "Inferior Prolog"
268 comint-prompt-regexp "^| [ ?][- ] *")
269 (prolog-mode-variables)
270 (if inferior-prolog-mode-map nil
271 (setq inferior-prolog-mode-map (copy-keymap comint-mode-map))
272 (prolog-mode-commands inferior-prolog-mode-map))
273 (use-local-map inferior-prolog-mode-map)
274 (run-hooks 'prolog-mode-hook))
275
f9f9507e 276;;;###autoload
d8025917 277(defun run-prolog ()
278 "Run an inferior Prolog process, input and output via buffer *prolog*."
279 (interactive)
280 (require 'comint)
281 (switch-to-buffer (make-comint "prolog" prolog-program-name))
282 (inferior-prolog-mode))
283
284(defun prolog-consult-region (compile beg end)
573f9b32
RS
285 "Send the region to the Prolog process made by \"M-x run-prolog\".
286If COMPILE (prefix arg) is not nil, use compile mode rather than consult mode."
d8025917 287 (interactive "P\nr")
288 (save-excursion
289 (if compile
290 (send-string "prolog" prolog-compile-string)
291 (send-string "prolog" prolog-consult-string))
292 (send-region "prolog" beg end)
293 (send-string "prolog" "\n") ;May be unnecessary
294 (if prolog-eof-string
295 (send-string "prolog" prolog-eof-string)
296 (process-send-eof "prolog")))) ;Send eof to prolog process.
297
298(defun prolog-consult-region-and-go (compile beg end)
299 "Send the region to the inferior Prolog, and switch to *prolog* buffer.
573f9b32 300If COMPILE (prefix arg) is not nil, use compile mode rather than consult mode."
d8025917 301 (interactive "P\nr")
302 (prolog-consult-region compile beg end)
303 (switch-to-buffer "*prolog*"))
6594deb0 304
896546cd
RS
305(provide 'prolog)
306
ab5796a9 307;;; arch-tag: f3ec6748-1272-4ab6-8826-c50cb1607636
6594deb0 308;;; prolog.el ends here