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