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