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