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