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