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