aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorPaul Eggert2011-01-11 21:57:19 -0800
committerPaul Eggert2011-01-11 21:57:19 -0800
commit7ea547574105f338c900d0c59390287c750a18c0 (patch)
treeebe2282d83447c9ecf34177320a2915e2201271d
parente8c53d3abf2f23dc40ed2bc748678025d5b5a5bc (diff)
parent529ee9edf2fd51f3e53f1fc4f7a9ba1859b0af99 (diff)
downloademacs-7ea547574105f338c900d0c59390287c750a18c0.tar.gz
emacs-7ea547574105f338c900d0c59390287c750a18c0.zip
Merge from mainline.
-rw-r--r--admin/bzrmerge.el10
-rw-r--r--doc/lispref/ChangeLog6
-rw-r--r--doc/lispref/files.texi2
-rw-r--r--doc/lispref/loading.texi3
-rw-r--r--doc/misc/ChangeLog5
-rw-r--r--doc/misc/dbus.texi86
-rw-r--r--etc/ChangeLog11
-rw-r--r--etc/NEWS18
-rw-r--r--etc/themes/tango-dark-theme.el180
-rw-r--r--etc/themes/tango-theme.el173
-rw-r--r--etc/themes/tsdh-dark-theme.el1
-rw-r--r--etc/themes/tsdh-light-theme.el1
-rw-r--r--lisp/ChangeLog137
-rw-r--r--lisp/allout.el17
-rw-r--r--lisp/calendar/diary-lib.el5
-rw-r--r--lisp/comint.el4
-rw-r--r--lisp/cus-edit.el20
-rw-r--r--lisp/custom.el138
-rw-r--r--lisp/doc-view.el3
-rw-r--r--lisp/emacs-lisp/unsafep.el3
-rw-r--r--lisp/files.el2
-rw-r--r--lisp/gnus/ChangeLog19
-rw-r--r--lisp/gnus/gnus-int.el6
-rw-r--r--lisp/gnus/gnus-sum.el3
-rw-r--r--lisp/gnus/mm-decode.el21
-rw-r--r--lisp/gnus/nnimap.el2
-rw-r--r--lisp/gnus/proto-stream.el21
-rw-r--r--lisp/info.el11
-rw-r--r--lisp/net/dbus.el43
-rw-r--r--lisp/net/ldap.el12
-rw-r--r--lisp/org/ChangeLog5
-rw-r--r--lisp/org/org-faces.el6
-rw-r--r--lisp/progmodes/compile.el10
-rw-r--r--lisp/progmodes/idlw-help.el5
-rw-r--r--lisp/progmodes/prolog.el4284
-rw-r--r--lisp/subr.el44
-rw-r--r--lisp/tool-bar.el25
-rw-r--r--lisp/vc/vc-dir.el53
-rw-r--r--lisp/wid-edit.el44
-rw-r--r--src/ChangeLog42
-rw-r--r--src/dbusbind.c164
-rw-r--r--src/fns.c11
-rw-r--r--src/gtkutil.c2
-rw-r--r--src/image.c11
44 files changed, 4921 insertions, 748 deletions
diff --git a/admin/bzrmerge.el b/admin/bzrmerge.el
index a33d666e143..d725f8a559a 100644
--- a/admin/bzrmerge.el
+++ b/admin/bzrmerge.el
@@ -1,22 +1,22 @@
1;;; bzrmerge.el --- 1;;; bzrmerge.el ---
2 2
3;; Copyright (C) 2010 Stefan Monnier 3;; Copyright (C) 2010, 2011 Free Software Foundation, Inc.
4 4
5;; Author: Stefan Monnier <monnier@iro.umontreal.ca> 5;; Author: Stefan Monnier <monnier@iro.umontreal.ca>
6;; Keywords: 6;; Keywords:
7 7
8;; This program is free software; you can redistribute it and/or modify 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 9;; it under the terms of the GNU General Public License as published by
10;; the Free Software Foundation, either version 3 of the License, or 10;; the Free Software Foundation, either version 3 of the License, or
11;; (at your option) any later version. 11;; (at your option) any later version.
12 12
13;; This program is distributed in the hope that it will be useful, 13;; GNU Emacs is distributed in the hope that it will be useful,
14;; but WITHOUT ANY WARRANTY; without even the implied warranty of 14;; but WITHOUT ANY WARRANTY; without even the implied warranty of
15;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 15;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16;; GNU General Public License for more details. 16;; GNU General Public License for more details.
17 17
18;; You should have received a copy of the GNU General Public License 18;; You should have received a copy of the GNU General Public License
19;; along with this program. If not, see <http://www.gnu.org/licenses/>. 19;; along with GNU Emacs. If not, see <http://www.gnu.org/licenses/>.
20 20
21;;; Commentary: 21;;; Commentary:
22 22
@@ -202,7 +202,7 @@ Does not make other difference."
202 "merge" "-r" (format "%s" endrevno) from) 202 "merge" "-r" (format "%s" endrevno) from)
203 (call-process "bzr" nil t nil "revert" ".") 203 (call-process "bzr" nil t nil "revert" ".")
204 (call-process "bzr" nil t nil "unshelve"))) 204 (call-process "bzr" nil t nil "unshelve")))
205 205
206(defvar bzrmerge-already-done nil) 206(defvar bzrmerge-already-done nil)
207 207
208(defun bzrmerge-apply (missing from) 208(defun bzrmerge-apply (missing from)
diff --git a/doc/lispref/ChangeLog b/doc/lispref/ChangeLog
index 7307d7fab4f..6a51b3f506b 100644
--- a/doc/lispref/ChangeLog
+++ b/doc/lispref/ChangeLog
@@ -1,3 +1,7 @@
12011-01-11 Stefan Monnier <monnier@iro.umontreal.ca>
2
3 * loading.texi (Hooks for Loading): Adjust doc of eval-after-load.
4
12011-01-02 Eli Zaretskii <eliz@gnu.org> 52011-01-02 Eli Zaretskii <eliz@gnu.org>
2 6
3 * modes.texi (Emulating Mode Line): Fix last change. 7 * modes.texi (Emulating Mode Line): Fix last change.
@@ -8884,7 +8888,7 @@
8884;; End: 8888;; End:
8885 8889
8886 Copyright (C) 1998, 1999, 2000, 2001, 2002, 2003, 2004, 2005, 2006, 8890 Copyright (C) 1998, 1999, 2000, 2001, 2002, 2003, 2004, 2005, 2006,
8887 2007, 2008, 2009, 2010 Free Software Foundation, Inc. 8891 2007, 2008, 2009, 2010, 2011 Free Software Foundation, Inc.
8888 8892
8889 This file is part of GNU Emacs. 8893 This file is part of GNU Emacs.
8890 8894
diff --git a/doc/lispref/files.texi b/doc/lispref/files.texi
index 2b539f00975..850cfd98220 100644
--- a/doc/lispref/files.texi
+++ b/doc/lispref/files.texi
@@ -1919,7 +1919,7 @@ The variable @code{directory-abbrev-alist} contains an alist of
1919abbreviations to use for file directories. Each element has the form 1919abbreviations to use for file directories. Each element has the form
1920@code{(@var{from} . @var{to})}, and says to replace @var{from} with 1920@code{(@var{from} . @var{to})}, and says to replace @var{from} with
1921@var{to} when it appears in a directory name. The @var{from} string is 1921@var{to} when it appears in a directory name. The @var{from} string is
1922actually a regular expression; it should always start with @samp{\`}. 1922actually a regular expression; it ought to always start with @samp{\`}.
1923The @var{to} string should be an ordinary absolute directory name. Do 1923The @var{to} string should be an ordinary absolute directory name. Do
1924not use @samp{~} to stand for a home directory in that string. The 1924not use @samp{~} to stand for a home directory in that string. The
1925function @code{abbreviate-file-name} performs these substitutions. 1925function @code{abbreviate-file-name} performs these substitutions.
diff --git a/doc/lispref/loading.texi b/doc/lispref/loading.texi
index 05d836140c7..11bd48f8a01 100644
--- a/doc/lispref/loading.texi
+++ b/doc/lispref/loading.texi
@@ -962,7 +962,8 @@ example, @file{my_inst.elc} or @file{my_inst.elc.gz} in some directory
962@end example 962@end example
963 963
964@var{library} can also be a feature (i.e.@: a symbol), in which case 964@var{library} can also be a feature (i.e.@: a symbol), in which case
965@var{form} is evaluated when @code{(provide @var{library})} is called. 965@var{form} is evaluated at the end of any file where
966@code{(provide @var{library})} is called.
966 967
967An error in @var{form} does not undo the load, but does prevent 968An error in @var{form} does not undo the load, but does prevent
968execution of the rest of @var{form}. 969execution of the rest of @var{form}.
diff --git a/doc/misc/ChangeLog b/doc/misc/ChangeLog
index 1acf8b0bbda..ca43b7e06df 100644
--- a/doc/misc/ChangeLog
+++ b/doc/misc/ChangeLog
@@ -1,3 +1,8 @@
12011-01-10 Jan Moringen <jan.moringen@uni-bielefeld.de>
2
3 * dbus.texi (Receiving Method Calls): New function
4 dbus-register-service. Rearrange node.
5
12011-01-07 Paul Eggert <eggert@cs.ucla.edu> 62011-01-07 Paul Eggert <eggert@cs.ucla.edu>
2 7
3 * texinfo.tex: Update to version 2010-12-23.17 from gnulib, 8 * texinfo.tex: Update to version 2010-12-23.17 from gnulib,
diff --git a/doc/misc/dbus.texi b/doc/misc/dbus.texi
index 39f6221e2f2..fe7918038e2 100644
--- a/doc/misc/dbus.texi
+++ b/doc/misc/dbus.texi
@@ -1244,9 +1244,73 @@ message has been arrived, and @var{handler} is called. Example:
1244@cindex method calls, returning 1244@cindex method calls, returning
1245@cindex returning method calls 1245@cindex returning method calls
1246 1246
1247Emacs can also offer own methods, which can be called by other 1247In order to register methods on the D-Bus, Emacs has to request a well
1248applications. These methods could be an implementation of an 1248known name on the D-Bus under which it will be available for other
1249interface of a well known service, like @samp{org.freedesktop.TextEditor}. 1249clients. Names on the D-Bus can be registered and unregistered using
1250the following functions:
1251
1252@defun dbus-register-service bus service &rest flags
1253Register the known name @var{service} on D-Bus @var{bus}.
1254
1255@var{bus} is either the symbol @code{:system} or the symbol
1256@code{:session}.
1257
1258@var{service} is the service name to be registered on the D-Bus. It
1259must be a known name.
1260
1261@var{flags} is a subset of the following keywords:
1262
1263@itemize
1264@item @code{:allow-replacement}: Allow another service to become the primary
1265owner if requested.
1266
1267@item @code{:replace-existing}: Request to replace the current primary owner.
1268
1269@item @code{:do-not-queue}: If we can not become the primary owner do not
1270place us in the queue.
1271@end itemize
1272
1273One of the following keywords is returned:
1274
1275@itemize
1276
1277@item @code{:primary-owner}: We have become the primary owner of the name
1278@var{service}.
1279
1280@item @code{:in-queue}: We could not become the primary owner and
1281have been placed in the queue.
1282
1283@item @code{:exists}: We already are in the queue.
1284
1285@item @code{:already-owner}: We already are the primary
1286owner.
1287@end itemize
1288@end defun
1289
1290@defun dbus-unregister-service bus service
1291Unregister all objects from D-Bus @var{bus}, registered by Emacs for
1292@var{service}.
1293
1294@var{bus} is either the symbol @code{:system} or the symbol
1295@code{:session}.
1296
1297@var{service} is the D-Bus service name of the D-Bus. It must be a
1298known name. Emacs releases its association to @var{service} from
1299D-Bus.
1300
1301One of the following keywords is returned:
1302
1303@itemize
1304@item @code{:released}: We successfully released the name @var{service}.
1305@item @code{:non-existent}: The name @var{service} does not exist on the bus.
1306@item @code{:not-owner}: We are not an owner of the name @var{service}.
1307@end itemize
1308@end defun
1309
1310When a name has been chosen, Emacs can offer own methods, which can be
1311called by other applications. These methods could be an
1312implementation of an interface of a well known service, like
1313@samp{org.freedesktop.TextEditor}.
1250 1314
1251It could be also an implementation of an own interface. In this case, 1315It could be also an implementation of an own interface. In this case,
1252the service name must be @samp{org.gnu.Emacs}. The object path shall 1316the service name must be @samp{org.gnu.Emacs}. The object path shall
@@ -1300,7 +1364,7 @@ When @var{dont-register-service} is non-@code{nil}, the known name
1300@var{service} is not registered. This means that other D-Bus clients 1364@var{service} is not registered. This means that other D-Bus clients
1301have no way of noticing the newly registered method. When interfaces 1365have no way of noticing the newly registered method. When interfaces
1302are constructed incrementally by adding single methods or properties 1366are constructed incrementally by adding single methods or properties
1303at a time, @var{dont-register-service} can be use to prevent other 1367at a time, @var{dont-register-service} can be used to prevent other
1304clients from discovering the still incomplete interface. 1368clients from discovering the still incomplete interface.
1305 1369
1306The default D-Bus timeout when waiting for a message reply is 25 1370The default D-Bus timeout when waiting for a message reply is 25
@@ -1414,7 +1478,7 @@ When @var{dont-register-service} is non-@code{nil}, the known name
1414@var{service} is not registered. This means that other D-Bus clients 1478@var{service} is not registered. This means that other D-Bus clients
1415have no way of noticing the newly registered method. When interfaces 1479have no way of noticing the newly registered method. When interfaces
1416are constructed incrementally by adding single methods or properties 1480are constructed incrementally by adding single methods or properties
1417at a time, @var{dont-register-service} can be use to prevent other 1481at a time, @var{dont-register-service} can be used to prevent other
1418clients from discovering the still incomplete interface. 1482clients from discovering the still incomplete interface.
1419 1483
1420@noindent Example: 1484@noindent Example:
@@ -1491,18 +1555,6 @@ registered for the respective service, Emacs releases its association
1491to the service from D-Bus. 1555to the service from D-Bus.
1492@end defun 1556@end defun
1493 1557
1494@defun dbus-unregister-service bus service
1495Unregister all objects from D-Bus @var{bus}, registered by Emacs for
1496@var{service}.
1497
1498@var{bus} is either the symbol @code{:system} or the symbol
1499@code{:session}.
1500
1501@var{service} is the D-Bus service name of the D-Bus. It must be a
1502known name. Emacs releases its association to @var{service} from
1503D-Bus.
1504@end defun
1505
1506 1558
1507@node Signals 1559@node Signals
1508@chapter Sending and receiving signals. 1560@chapter Sending and receiving signals.
diff --git a/etc/ChangeLog b/etc/ChangeLog
index 9d8a3b8aafd..d690c963fba 100644
--- a/etc/ChangeLog
+++ b/etc/ChangeLog
@@ -1,3 +1,14 @@
12011-01-10 Jan Moringen <jan.moringen@uni-bielefeld.de>
2
3 * NEWS: Add new function dbus-register-service.
4
52011-01-09 Chong Yidong <cyd@stupidchicken.com>
6
7 * themes/tango-theme.el, themes/tango-dark-theme.el: Let-bind
8 tango palette colors. Only define faces for color displays.
9 Customize the ansi-color-names-vector variable. Add Ediff,
10 Flyspell, and Semantic faces as suggested by Jan Moringen.
11
12011-01-08 Andreas Schwab <schwab@linux-m68k.org> 122011-01-08 Andreas Schwab <schwab@linux-m68k.org>
2 13
3 * compilation.txt: Add column to gcc-include sample. 14 * compilation.txt: Add column to gcc-include sample.
diff --git a/etc/NEWS b/etc/NEWS
index 0fd74252601..92d96fd1806 100644
--- a/etc/NEWS
+++ b/etc/NEWS
@@ -219,9 +219,10 @@ Emacs no longer looks for custom themes in `load-path'. The default
219is to search in `custom-theme-directory', followed by a built-in theme 219is to search in `custom-theme-directory', followed by a built-in theme
220directory named "themes/" in `data-directory'. 220directory named "themes/" in `data-directory'.
221 221
222*** New option `custom-safe-theme-files' lists known-safe theme files. 222*** New option `custom-safe-themes' records known-safe theme files.
223If a theme is not in this list, Emacs queries before loading it. 223If a theme is not in this list, Emacs queries before loading it, and
224The default value treats all themes included in Emacs as safe. 224offers to save the theme to `custom-safe-themes' automatically. By
225default, all themes included in Emacs are treated as safe.
225 226
226** The user option `remote-file-name-inhibit-cache' controls whether 227** The user option `remote-file-name-inhibit-cache' controls whether
227the remote file-name cache is used for read access. 228the remote file-name cache is used for read access.
@@ -322,6 +323,10 @@ prompts for a number to count from and for a format string.
322 323
323* Changes in Specialized Modes and Packages in Emacs 24.1 324* Changes in Specialized Modes and Packages in Emacs 24.1
324 325
326** Prolog mode has been completely revamped, with lots of additional
327functionality such as more intelligent indentation, electricty, support for
328more variants, including Mercury, and a lot more.
329
325** shell-mode can track your cwd by reading it from your prompt. 330** shell-mode can track your cwd by reading it from your prompt.
326Just set shell-dir-cookie-re to an appropriate regexp. 331Just set shell-dir-cookie-re to an appropriate regexp.
327 332
@@ -564,7 +569,12 @@ threads simultaneously.
564*** It is possible now, to access alternative buses than the default 569*** It is possible now, to access alternative buses than the default
565system or session bus. 570system or session bus.
566 571
567*** dbus-register-{method,property} do not necessarily register names anymore. 572*** dbus-register-{service,method,property}
573The -method and -property functions do not automatically register
574names anymore.
575
576The new function dbus-register-service registers a service known name
577on a D-Bus without simultaneously registering a property or a method.
568 578
569** Tramp 579** Tramp
570 580
diff --git a/etc/themes/tango-dark-theme.el b/etc/themes/tango-dark-theme.el
index f63440b4ea7..06f209a03db 100644
--- a/etc/themes/tango-dark-theme.el
+++ b/etc/themes/tango-dark-theme.el
@@ -1,6 +1,9 @@
1;;; tango-dark-theme.el --- Tango-based custom theme for faces 1;;; tango-dark-theme.el --- Tango-based custom theme for faces
2 2
3;; Copyright (C) 2010 Free Software Foundation, Inc. 3;; Copyright (C) 2010, 2011 Free Software Foundation, Inc.
4
5;; Authors: Chong Yidong <cyd@stupidchicken>
6;; Jan Moringen <jan.moringen@uni-bielefeld.de>
4 7
5;; This file is part of GNU Emacs. 8;; This file is part of GNU Emacs.
6 9
@@ -25,63 +28,124 @@
25;;; Code: 28;;; Code:
26 29
27(deftheme tango-dark 30(deftheme tango-dark
28 "Theme for faces, based on the Tango palette on a dark background. 31 "Theme for faces, based on the Tango palette with a dark background.
29Basic, Font Lock, Isearch, Gnus, and Message faces are included.") 32Basic, Font Lock, Isearch, Gnus, Message, Ediff, Flyspell,
30 33Semantic, and Ansi-Color faces are included.")
31(custom-theme-set-faces 34
32 'tango-dark 35(let ((class '((class color) (min-colors 89)))
33 '(default ((t (:foreground "#eeeeec" :background "#2e3436")))) 36 ;; Tango palette colors.
34 '(cursor ((t (:foreground "#2e3436" :background "#fce94f")))) 37 (butter-1 "#fce94f") (butter-2 "#edd400") (butter-3 "#c4a000")
35 '(highlight ((t (:foreground "#2e3436" :background "#edd400")))) 38 (orange-1 "#fcaf3e") (orange-2 "#f57900") (orange-3 "#ce5c00")
36 '(region ((t (:background "#555753")))) 39 (choc-1 "#e9b96e") (choc-2 "#c17d11") (choc-3 "#8f5902")
37 '(font-lock-builtin-face ((t (:foreground "#ad7fa8")))) 40 (cham-1 "#8ae234") (cham-2 "#73d216") (cham-3 "#4e9a06")
38 '(font-lock-comment-face ((t (:foreground "#73d216")))) 41 (blue-1 "#729fcf") (blue-2 "#3465a4") (blue-3 "#204a87")
39 '(font-lock-constant-face ((t (:foreground "#e6a8df")))) 42 (plum-1 "#ad7fa8") (plum-2 "#75507b") (plum-3 "#5c3566")
40 '(font-lock-function-name-face ((t (:foreground "#fce94f")))) 43 (red-1 "#ef2929") (red-2 "#cc0000") (red-3 "#a40000")
41 '(font-lock-keyword-face ((t (:foreground "#8cc4ff")))) 44 (alum-1 "#eeeeec") (alum-2 "#d3d7cf") (alum-3 "#babdb6")
42 '(font-lock-string-face ((t (:foreground "#e9b96e")))) 45 (alum-4 "#888a85") (alum-5 "#555753") (alum-6 "#2e3436")
43 '(font-lock-type-face ((t (:foreground "#a5ff4d")))) 46 ;; Not in Tango palette; used for better contrast.
44 '(font-lock-variable-name-face ((t (:foreground "#fcaf3e")))) 47 (cham-0 "#b4fa70") (blue-0 "#8cc4ff") (plum-0 "#e6a8df")
45 '(font-lock-warning-face ((t (:foreground "#ef2929")))) 48 (red-0 "#ff4b4b") (alum-5.5 "#41423f") (alum-7 "#212526"))
46 '(button ((t (:underline t :foreground "#729fcf")))) 49
47 '(link ((t (:underline t :foreground "#729fcf")))) 50 (custom-theme-set-faces
48 '(link-visited ((t (:underline t :foreground "#3465a4")))) 51 'tango-dark
49 '(mode-line ((t (:box (:line-width -1 :style released-button) 52 `(default ((,class (:foreground ,alum-1 :background ,alum-6))))
50 :background "#d3d7cf" :foreground "black")))) 53 `(cursor ((,class (:foreground ,alum-6 :background ,butter-1))))
51 '(mode-line-inactive ((t (:box (:line-width -1 :style released-button) 54 ;; Highlighting faces
52 :background "#555753" :foreground "white")))) 55 `(fringe ((,class (:background ,alum-7))))
53 '(isearch ((t (:foreground "#ffffff" :background "#ce5c00")))) 56 `(highlight ((,class (:foreground ,alum-6 :background ,butter-2))))
54 '(lazy-highlight ((t (:background "#8f5902")))) 57 `(region ((,class (:background ,alum-5))))
55 '(gnus-group-news-1 ((t (:foreground "#ad7fa8")))) 58 `(secondary-selection ((,class (:background ,blue-3))))
56 '(gnus-group-news-1-low ((t (:foreground "#75507b")))) 59 `(isearch ((,class (:foreground ,alum-1 :background ,orange-3))))
57 '(gnus-group-news-2 ((t (:foreground "#729fcf")))) 60 `(lazy-highlight ((,class (:background ,choc-3))))
58 '(gnus-group-news-2-low ((t (:foreground "#3465a4")))) 61 `(trailing-whitespace ((,class (:background ,red-3))))
59 '(gnus-group-news-3 ((t (:foreground "#8ae234")))) 62 ;; Mode line faces
60 '(gnus-group-news-3-low ((t (:foreground "#73d216")))) 63 `(mode-line ((,class
61 '(gnus-group-news-4 ((t (:foreground "#e9b9e6")))) 64 (:box (:line-width -1 :style released-button)
62 '(gnus-group-news-4-low ((t (:foreground "#c17d11")))) 65 :background ,alum-2 :foreground ,alum-6))))
63 '(gnus-group-news-5 ((t (:foreground "#fcaf3e")))) 66 `(mode-line-inactive ((,class
64 '(gnus-group-news-5-low ((t (:foreground "#f57900")))) 67 (:box (:line-width -1 :style released-button)
65 '(gnus-group-news-low ((t (:foreground "#edd400")))) 68 :background ,alum-5 :foreground ,alum-1))))
66 '(gnus-group-mail-1 ((t (:foreground "#ad7fa8")))) 69 ;; Escape and prompt faces
67 '(gnus-group-mail-1-low ((t (:foreground "#75507b")))) 70 `(minibuffer-prompt ((,class (:foreground ,cham-0))))
68 '(gnus-group-mail-2 ((t (:foreground "#729fcf")))) 71 `(escape-glyph ((,class (:foreground ,butter-3))))
69 '(gnus-group-mail-2-low ((t (:foreground "#3465a4")))) 72 ;; Font lock faces
70 '(gnus-group-mail-3 ((t (:foreground "#8ae234")))) 73 `(font-lock-builtin-face ((,class (:foreground ,plum-1))))
71 '(gnus-group-mail-3-low ((t (:foreground "#73d216")))) 74 `(font-lock-comment-face ((,class (:foreground ,cham-2))))
72 '(gnus-group-mail-low ((t (:foreground "#edd400")))) 75 `(font-lock-constant-face ((,class (:foreground ,plum-0))))
73 '(gnus-header-content ((t (:weight normal :foreground "#c4a000")))) 76 `(font-lock-function-name-face ((,class (:foreground ,butter-1))))
74 '(gnus-header-from ((t (:foreground "#edd400")))) 77 `(font-lock-keyword-face ((,class (:foreground ,cham-0))))
75 '(gnus-header-subject ((t (:foreground "#8ae234")))) 78 `(font-lock-string-face ((,class (:foreground ,choc-1))))
76 '(gnus-header-name ((t (:foreground "#729fcf")))) 79 `(font-lock-type-face ((,class (:foreground ,blue-0))))
77 '(gnus-header-newsgroups ((t (:foreground "#c17d11")))) 80 `(font-lock-variable-name-face ((,class (:foreground ,orange-1))))
78 '(message-header-name ((t (:foreground "#729fcf")))) 81 `(font-lock-warning-face ((,class (:foreground ,red-0))))
79 '(message-header-cc ((t (:foreground "#c4a000")))) 82 ;; Button and link faces
80 '(message-header-other ((t (:foreground "#c17d11")))) 83 `(button ((,class (:underline t :foreground ,blue-1))))
81 '(message-header-subject ((t (:foreground "#8ae234")))) 84 `(link ((,class (:underline t :foreground ,blue-1))))
82 '(message-header-to ((t (:foreground "#edd400")))) 85 `(link-visited ((,class (:underline t :foreground ,blue-2))))
83 '(message-cited-text ((t (:foreground "#8ae234")))) 86 ;; Gnus faces
84 '(message-separator ((t (:foreground "#ad7fa8"))))) 87 `(gnus-group-news-1 ((,class (:foreground ,plum-1))))
88 `(gnus-group-news-1-low ((,class (:foreground ,plum-2))))
89 `(gnus-group-news-2 ((,class (:foreground ,blue-1))))
90 `(gnus-group-news-2-low ((,class (:foreground ,blue-2))))
91 `(gnus-group-news-3 ((,class (:foreground ,cham-1))))
92 `(gnus-group-news-3-low ((,class (:foreground ,cham-2))))
93 `(gnus-group-news-4 ((,class (:foreground ,plum-0))))
94 `(gnus-group-news-4-low ((,class (:foreground ,choc-2))))
95 `(gnus-group-news-5 ((,class (:foreground ,orange-1))))
96 `(gnus-group-news-5-low ((,class (:foreground ,orange-2))))
97 `(gnus-group-news-low ((,class (:foreground ,butter-2))))
98 `(gnus-group-mail-1 ((,class (:foreground ,plum-1))))
99 `(gnus-group-mail-1-low ((,class (:foreground ,plum-2))))
100 `(gnus-group-mail-2 ((,class (:foreground ,blue-1))))
101 `(gnus-group-mail-2-low ((,class (:foreground ,blue-2))))
102 `(gnus-group-mail-3 ((,class (:foreground ,cham-1))))
103 `(gnus-group-mail-3-low ((,class (:foreground ,cham-2))))
104 `(gnus-group-mail-low ((,class (:foreground ,butter-2))))
105 `(gnus-header-content ((,class (:weight normal :foreground ,butter-3))))
106 `(gnus-header-from ((,class (:foreground ,butter-2))))
107 `(gnus-header-subject ((,class (:foreground ,cham-1))))
108 `(gnus-header-name ((,class (:foreground ,blue-1))))
109 `(gnus-header-newsgroups ((,class (:foreground ,choc-2))))
110 ;; Message faces
111 `(message-header-name ((,class (:foreground ,blue-1))))
112 `(message-header-cc ((,class (:foreground ,butter-3))))
113 `(message-header-other ((,class (:foreground ,choc-2))))
114 `(message-header-subject ((,class (:foreground ,cham-1))))
115 `(message-header-to ((,class (:foreground ,butter-2))))
116 `(message-cited-text ((,class (:foreground ,cham-1))))
117 `(message-separator ((,class (:foreground ,plum-1))))
118 ;; SMerge faces
119 `(smerge-refined-change ((,class (:background ,blue-3))))
120 ;; Ediff faces
121 `(ediff-current-diff-A ((,class (:background ,alum-5))))
122 `(ediff-fine-diff-A ((,class (:background ,blue-3))))
123 `(ediff-even-diff-A ((,class (:background ,alum-5.5))))
124 `(ediff-odd-diff-A ((,class (:background ,alum-5.5))))
125 `(ediff-current-diff-B ((,class (:background ,alum-5))))
126 `(ediff-fine-diff-B ((,class (:background ,choc-3))))
127 `(ediff-even-diff-B ((,class (:background ,alum-5.5))))
128 `(ediff-odd-diff-B ((,class (:background ,alum-5.5))))
129 ;; Flyspell faces
130 `(flyspell-duplicate ((,class (:underline ,orange-1))))
131 `(flyspell-incorrect ((,class (:underline ,red-1))))
132 ;; Semantic faces
133 `(semantic-decoration-on-includes ((,class (:underline ,alum-4))))
134 `(semantic-decoration-on-private-members-face
135 ((,class (:background ,plum-3))))
136 `(semantic-decoration-on-protected-members-face
137 ((,class (:background ,choc-3))))
138 `(semantic-decoration-on-unknown-includes
139 ((,class (:background ,red-3))))
140 `(semantic-decoration-on-unparsed-includes
141 ((,class (:background ,alum-5.5))))
142 `(semantic-tag-boundary-face ((,class (:overline ,blue-1))))
143 `(semantic-unmatched-syntax-face ((,class (:underline ,red-1)))))
144
145 (custom-theme-set-variables
146 'tango-dark
147 `(ansi-color-names-vector [,alum-7 ,red-0 ,cham-0 ,butter-1
148 ,blue-1 ,plum-1 ,blue-0 ,alum-1])))
85 149
86(provide-theme 'tango-dark) 150(provide-theme 'tango-dark)
87 151
diff --git a/etc/themes/tango-theme.el b/etc/themes/tango-theme.el
index f0492c048af..29fc6a6b4d5 100644
--- a/etc/themes/tango-theme.el
+++ b/etc/themes/tango-theme.el
@@ -1,6 +1,9 @@
1;;; tango-theme.el --- Tango-based custom theme for faces 1;;; tango-theme.el --- Tango-based custom theme for faces
2 2
3;; Copyright (C) 2010 Free Software Foundation, Inc. 3;; Copyright (C) 2010, 2011 Free Software Foundation, Inc.
4
5;; Authors: Chong Yidong <cyd@stupidchicken>
6;; Jan Moringen <jan.moringen@uni-bielefeld.de>
4 7
5;; This file is part of GNU Emacs. 8;; This file is part of GNU Emacs.
6 9
@@ -25,63 +28,117 @@
25;;; Code: 28;;; Code:
26 29
27(deftheme tango 30(deftheme tango
28 "Theme for faces, based on the Tango palette on a light background. 31 "Theme for faces, based on the Tango palette with a light background.
29Basic, Font Lock, Isearch, Gnus, and Message faces are included.") 32Basic, Font Lock, Isearch, Gnus, Message, Ediff, Flyspell,
30 33Semantic, and Ansi-Color faces are included.")
31(custom-theme-set-faces 34
32 'tango 35(let ((class '((class color) (min-colors 89)))
33 '(default ((t (:foreground "#16191a" :background "#eeeeec")))) 36 ;; Tango palette colors.
34 '(cursor ((t (:foreground "#eeeeec" :background "#204a87")))) 37 (butter-1 "#fce94f") (butter-2 "#edd400") (butter-3 "#c4a000")
35 '(highlight ((t (:background "#babdb6")))) 38 (orange-1 "#fcaf3e") (orange-2 "#f57900") (orange-3 "#ce5c00")
36 '(region ((t (:background "#babdb6")))) 39 (choc-1 "#e9b96e") (choc-2 "#c17d11") (choc-3 "#8f5902")
37 '(font-lock-builtin-face ((t (:weight bold :foreground "#204a87")))) 40 (cham-1 "#8ae234") (cham-2 "#73d216") (cham-3 "#4e9a06")
38 '(font-lock-comment-face ((t (:foreground "#204a87")))) 41 (blue-1 "#729fcf") (blue-2 "#3465a4") (blue-3 "#204a87")
39 '(font-lock-constant-face ((t (:weight bold :foreground "#5c3566")))) 42 (plum-1 "#ad7fa8") (plum-2 "#75507b") (plum-3 "#5c3566")
40 '(font-lock-function-name-face ((t (:weight bold :foreground "#ce5c00")))) 43 (red-1 "#ef2929") (red-2 "#cc0000") (red-3 "#a40000")
41 '(font-lock-keyword-face ((t (:foreground "#a40000")))) 44 (alum-1 "#eeeeec") (alum-2 "#d3d7cf") (alum-3 "#babdb6")
42 '(font-lock-string-face ((t (:foreground "#5c3566")))) 45 (alum-4 "#888a85") (alum-5 "#555753") (alum-6 "#2e3436")
43 '(font-lock-type-face ((t (:weight bold :foreground "#4e9a06")))) 46 ;; Not in Tango palette; used for better contrast.
44 '(font-lock-variable-name-face ((t (:weight bold :foreground "#c17d11")))) 47 (cham-4 "#346604") (blue-0 "#8cc4ff"))
45 '(font-lock-warning-face ((t (:foreground "#cc0000")))) 48
46 '(button ((t (:underline t :foreground "#204a87")))) 49 (custom-theme-set-faces
47 '(link ((t (:underline t :foreground "#204a87")))) 50 'tango
48 '(link-visited ((t (:underline t :foreground "#3465a4")))) 51 `(default ((,class (:foreground ,"#16191a" :background ,alum-1))))
49 '(mode-line ((t (:box (:line-width -1 :style released-button) 52 `(cursor ((,class (:foreground ,alum-1 :background ,blue-3))))
50 :background "#d3d7cf" :foreground "black")))) 53 ;; Highlighting faces
51 '(mode-line-inactive ((t (:box (:line-width -1 :style released-button) 54 `(fringe ((,class (:background ,alum-2))))
52 :background "#babdb6" :foreground "black")))) 55 `(highlight ((,class (:background ,alum-3))))
53 '(isearch ((t (:foreground "#ffffff" :background "#ce5c00")))) 56 `(region ((,class (:background ,alum-3))))
54 '(lazy-highlight ((t (:background "#e9b96e")))) 57 `(secondary-selection ((,class (:background ,blue-0))))
55 '(gnus-group-news-1 ((t (:weight bold :foreground "#5c3566")))) 58 `(isearch ((,class (:foreground ,"#ffffff" :background ,orange-3))))
56 '(gnus-group-news-1-low ((t (:foreground "#5c3566")))) 59 `(lazy-highlight ((,class (:background ,choc-1))))
57 '(gnus-group-news-2 ((t (:weight bold :foreground "#204a87")))) 60 `(trailing-whitespace ((,class (:background ,red-1))))
58 '(gnus-group-news-2-low ((t (:foreground "#204a87")))) 61 ;; Mode line faces
59 '(gnus-group-news-3 ((t (:weight bold :foreground "#4e0a06")))) 62 `(mode-line ((,class (:box (:line-width -1 :style released-button)
60 '(gnus-group-news-3-low ((t (:foreground "#4e0a06")))) 63 :background ,alum-2 :foreground ,alum-6))))
61 '(gnus-group-news-4 ((t (:weight bold :foreground "#7a4c02")))) 64 `(mode-line-inactive ((,class (:box (:line-width -1 :style released-button)
62 '(gnus-group-news-4-low ((t (:foreground "#7a4c02")))) 65 :background ,alum-4 :foreground ,alum-6))))
63 '(gnus-group-news-5 ((t (:weight bold :foreground "#ce5c00")))) 66 ;; Escape and prompt faces
64 '(gnus-group-news-5-low ((t (:foreground "#ce5c00")))) 67 `(minibuffer-prompt ((,class (:weight bold :foreground ,blue-3))))
65 '(gnus-group-news-low ((t (:foreground "#888a85")))) 68 `(escape-glyph ((,class (:foreground ,red-3))))
66 '(gnus-group-mail-1 ((t (:weight bold :foreground "#5c3566")))) 69 ;; Font lock faces
67 '(gnus-group-mail-1-low ((t (:foreground "#5c3566")))) 70 `(font-lock-builtin-face ((,class (:weight bold :foreground ,plum-3))))
68 '(gnus-group-mail-2 ((t (:weight bold :foreground "#204a87")))) 71 `(font-lock-comment-face ((,class (:foreground ,cham-4))))
69 '(gnus-group-mail-2-low ((t (:foreground "#204a87")))) 72 `(font-lock-constant-face ((,class (:weight bold :foreground ,blue-3))))
70 '(gnus-group-mail-3 ((t (:weight bold :foreground "#4e0a06")))) 73 `(font-lock-function-name-face ((,class (:foreground ,red-3))))
71 '(gnus-group-mail-3-low ((t (:foreground "#4e0a06")))) 74 `(font-lock-keyword-face ((,class (:weight bold :foreground ,choc-2))))
72 '(gnus-group-mail-low ((t (:foreground "#888a85")))) 75 `(font-lock-string-face ((,class (:foreground ,plum-3))))
73 '(gnus-header-content ((t (:foreground "#4e9a06")))) 76 `(font-lock-type-face ((,class (:foreground ,blue-3))))
74 '(gnus-header-from ((t (:weight bold :foreground "#c4a000")))) 77 `(font-lock-variable-name-face ((,class (:weight bold :foreground ,orange-3))))
75 '(gnus-header-subject ((t (:foreground "#4e0a06")))) 78 `(font-lock-warning-face ((,class (:foreground ,red-2))))
76 '(gnus-header-name ((t (:foreground "#204a87")))) 79 ;; Button and link faces
77 '(gnus-header-newsgroups ((t (:foreground "#888a85")))) 80 `(button ((,class (:underline t :foreground ,blue-3))))
78 '(message-header-name ((t (:foreground "#204a87")))) 81 `(link ((,class (:underline t :foreground ,blue-3))))
79 '(message-header-cc ((t (:foreground "#c4a000")))) 82 `(link-visited ((,class (:underline t :foreground ,blue-2))))
80 '(message-header-other ((t (:foreground "#c17d11")))) 83 ;; Gnus faces
81 '(message-header-subject ((t (:foreground "#4e0a06")))) 84 `(gnus-group-news-1 ((,class (:weight bold :foreground ,plum-3))))
82 '(message-header-to ((t (:weight bold :foreground "#c4a000")))) 85 `(gnus-group-news-1-low ((,class (:foreground ,plum-3))))
83 '(message-cited-text ((t (:foreground "#888a85")))) 86 `(gnus-group-news-2 ((,class (:weight bold :foreground ,blue-3))))
84 '(message-separator ((t (:weight bold :foreground "#4e9a06"))))) 87 `(gnus-group-news-2-low ((,class (:foreground ,blue-3))))
88 `(gnus-group-news-3 ((,class (:weight bold :foreground ,"#4e0a06"))))
89 `(gnus-group-news-3-low ((,class (:foreground ,"#4e0a06"))))
90 `(gnus-group-news-4 ((,class (:weight bold :foreground ,"#7a4c02"))))
91 `(gnus-group-news-4-low ((,class (:foreground ,"#7a4c02"))))
92 `(gnus-group-news-5 ((,class (:weight bold :foreground ,orange-3))))
93 `(gnus-group-news-5-low ((,class (:foreground ,orange-3))))
94 `(gnus-group-news-low ((,class (:foreground ,"#888a85"))))
95 `(gnus-group-mail-1 ((,class (:weight bold :foreground ,plum-3))))
96 `(gnus-group-mail-1-low ((,class (:foreground ,plum-3))))
97 `(gnus-group-mail-2 ((,class (:weight bold :foreground ,blue-3))))
98 `(gnus-group-mail-2-low ((,class (:foreground ,blue-3))))
99 `(gnus-group-mail-3 ((,class (:weight bold :foreground ,"#4e0a06"))))
100 `(gnus-group-mail-3-low ((,class (:foreground ,"#4e0a06"))))
101 `(gnus-group-mail-low ((,class (:foreground ,"#888a85"))))
102 `(gnus-header-content ((,class (:foreground ,cham-3))))
103 `(gnus-header-from ((,class (:weight bold :foreground ,butter-3))))
104 `(gnus-header-subject ((,class (:foreground ,"#4e0a06"))))
105 `(gnus-header-name ((,class (:foreground ,blue-3))))
106 `(gnus-header-newsgroups ((,class (:foreground ,"#888a85"))))
107 ;; Message faces
108 `(message-header-name ((,class (:foreground ,blue-3))))
109 `(message-header-cc ((,class (:foreground ,butter-3))))
110 `(message-header-other ((,class (:foreground ,choc-2))))
111 `(message-header-subject ((,class (:foreground ,"#4e0a06"))))
112 `(message-header-to ((,class (:weight bold :foreground ,butter-3))))
113 `(message-cited-text ((,class (:foreground ,"#888a85"))))
114 `(message-separator ((,class (:weight bold :foreground ,cham-3))))
115 ;; SMerge
116 `(smerge-refined-change ((,class (:background ,plum-1))))
117 ;; Ediff
118 `(ediff-current-diff-A ((,class (:background ,blue-1))))
119 `(ediff-fine-diff-A ((,class (:background ,plum-1))))
120 `(ediff-current-diff-B ((,class (:background ,butter-1))))
121 `(ediff-fine-diff-B ((,class (:background ,orange-1))))
122 ;; Flyspell
123 `(flyspell-duplicate ((,class (:underline ,orange-1))))
124 `(flyspell-incorrect ((,class (:underline ,red-1))))
125 ;; Semantic faces
126 `(semantic-decoration-on-includes ((,class (:underline ,cham-4))))
127 `(semantic-decoration-on-private-members-face
128 ((,class (:background ,alum-2))))
129 `(semantic-decoration-on-protected-members-face
130 ((,class (:background ,alum-2))))
131 `(semantic-decoration-on-unknown-includes
132 ((,class (:background ,choc-3))))
133 `(semantic-decoration-on-unparsed-includes
134 ((,class (:underline ,orange-3))))
135 `(semantic-tag-boundary-face ((,class (:overline ,blue-1))))
136 `(semantic-unmatched-syntax-face ((,class (:underline ,red-1)))))
137
138 (custom-theme-set-variables
139 'tango
140 `(ansi-color-names-vector [,alum-6 ,red-3 ,cham-3 ,butter-3
141 ,blue-3 ,plum-3 ,blue-1 ,alum-1])))
85 142
86(provide-theme 'tango) 143(provide-theme 'tango)
87 144
diff --git a/etc/themes/tsdh-dark-theme.el b/etc/themes/tsdh-dark-theme.el
index f7761d0489e..4fe86987d87 100644
--- a/etc/themes/tsdh-dark-theme.el
+++ b/etc/themes/tsdh-dark-theme.el
@@ -31,6 +31,7 @@
31 '(diff-indicator-changed ((t (:weight bold)))) 31 '(diff-indicator-changed ((t (:weight bold))))
32 '(diff-indicator-removed ((t (:inherit diff-indicator-changed)))) 32 '(diff-indicator-removed ((t (:inherit diff-indicator-changed))))
33 '(diff-removed ((t (:inherit diff-changed :background "sandy brown")))) 33 '(diff-removed ((t (:inherit diff-changed :background "sandy brown"))))
34 '(dired-directory ((t (:inherit font-lock-function-name-face :weight bold))))
34 '(hl-line ((t (:background "grey28")))) 35 '(hl-line ((t (:background "grey28"))))
35 '(message-header-subject ((t (:foreground "SkyBlue")))) 36 '(message-header-subject ((t (:foreground "SkyBlue"))))
36 '(minibuffer-prompt ((t (:background "yellow" :foreground "medium blue" :box (:line-width -1 :color "red" :style released-button) :weight bold)))) 37 '(minibuffer-prompt ((t (:background "yellow" :foreground "medium blue" :box (:line-width -1 :color "red" :style released-button) :weight bold))))
diff --git a/etc/themes/tsdh-light-theme.el b/etc/themes/tsdh-light-theme.el
index b66acccaa83..5fb6ba84d70 100644
--- a/etc/themes/tsdh-light-theme.el
+++ b/etc/themes/tsdh-light-theme.el
@@ -31,6 +31,7 @@
31 '(diff-indicator-changed ((t (:weight bold)))) 31 '(diff-indicator-changed ((t (:weight bold))))
32 '(diff-indicator-removed ((t (:inherit diff-indicator-changed)))) 32 '(diff-indicator-removed ((t (:inherit diff-indicator-changed))))
33 '(diff-removed ((t (:inherit diff-changed :background "sandy brown")))) 33 '(diff-removed ((t (:inherit diff-changed :background "sandy brown"))))
34 '(dired-directory ((t (:inherit font-lock-function-name-face :weight bold))))
34 '(hl-line ((t (:background "grey95")))) 35 '(hl-line ((t (:background "grey95"))))
35 '(minibuffer-prompt ((t (:background "yellow" :foreground "medium blue" :box (:line-width -1 :color "red" :style released-button) :weight bold)))) 36 '(minibuffer-prompt ((t (:background "yellow" :foreground "medium blue" :box (:line-width -1 :color "red" :style released-button) :weight bold))))
36 '(mode-line ((t (:box (:line-width -1 :color "red" :style released-button) :family "DejaVu Sans")))) 37 '(mode-line ((t (:box (:line-width -1 :color "red" :style released-button) :family "DejaVu Sans"))))
diff --git a/lisp/ChangeLog b/lisp/ChangeLog
index 86f9e8fa0b9..0c3f09e157b 100644
--- a/lisp/ChangeLog
+++ b/lisp/ChangeLog
@@ -1,5 +1,128 @@
12011-01-11 Johan Bockgård <bojohan@gnu.org>
2
3 * emacs-lisp/unsafep.el (unsafep): Handle backquoted forms.
4
52011-01-11 Stefan Monnier <monnier@iro.umontreal.ca>
6
7 * progmodes/prolog.el: Fix up coding convention and such.
8 (prolog-indent-width): Use the same default as in
9 previous prolog.el rather than tab-width which depends on which buffer
10 is current when the file is loaded.
11 (prolog-electric-newline-flag): Only enable if electric-indent-mode
12 is not available.
13 (prolog-emacs): Remove. Use (featurep 'xemacs) instead.
14 (prolog-known-systems): Remove.
15 (prolog-mode-syntax-table, prolog-inferior-mode-map):
16 Move initialization into declaration.
17 (prolog-mode-map): Move initialization into declaration.
18 Remove system-specific mode-map vars, since they referred to the same
19 keymap anyway.
20 (prolog-mode-variables): Obey the user's preference w.r.t
21 adaptive-fill-mode. Prefer symbol-value to `eval'.
22 (prolog-mode-keybindings-edit): Add compatibility bindings.
23 (prolog-mode): Use define-derived-mode. Don't handle mercury here.
24 (mercury-mode-map): New var.
25 (mercury-mode, prolog-inferior-mode): Use define-derived-mode.
26 (prolog-ensure-process, prolog-process-insert-string)
27 (prolog-consult-compile): Use with-current-buffer.
28 (prolog-guess-fill-prefix): Simplify data flow.
29 (prolog-replace-in-string): New function to use instead of
30 replace-in-string.
31 (prolog-enable-sicstus-sd): Don't abuse `eval'.
32 (prolog-uncomment-region): Use `uncomment-region' when available.
33 (prolog-electric-colon, prolog-electric-dash): Use `eolp'.
34 (prolog-int-to-char, prolog-char-to-int): New functions to use instead
35 of int-to-char and char-to-int.
36 (prolog-mode-hook, prolog-inferior-mode-hook): Don't force font-lock.
37
382011-01-11 Stefan Bruda <stefan@bruda.ca>
39
40 * progmodes/prolog.el: Replace by a whole new file.
41
422011-01-11 Stefan Monnier <monnier@iro.umontreal.ca>
43
44 * subr.el (eval-after-load): Fix timing for features (bug#7769).
45 (declare-function, undefined, insert-for-yank)
46 (replace-regexp-in-string): Follow checkdoc's recommendations.
47
482011-01-10 Stefan Monnier <monnier@iro.umontreal.ca>
49
50 * calendar/diary-lib.el (diary-mode): Refresh *Calendar* after
51 refreshing the diary buffer.
52
532011-01-10 Ken Manheimer <ken.manheimer@gmail.com>
54
55 * allout.el: Add 2011 to the file copyright.
56 (allout-encrypt-string): Prevent encryption from adding an extra
57 newline at the end of the topic body.
58 (allout-version): Increment to 2.3.
59
602011-01-10 Michael Albinus <michael.albinus@gmx.de>
61
62 * net/dbus.el (dbus-unregister-service): Complete doc.
63 Fix call of dbus-error signal.
64 (dbus-register-property): Use `dont-register' keyword.
65
662011-01-10 Jan Moringen <jan.moringen@uni-bielefeld.de>
67
68 * net/dbus.el (dbus-unregister-service): Translate returned
69 integer into a symbol.
70 (dbus-register-property): Use `dbus-register-service' to do the
71 name registration.
72
732011-01-09 Chong Yidong <cyd@stupidchicken.com>
74
75 * progmodes/idlw-help.el (idlwave-help-link): Inherit from link face.
76 Suggested by Joakim Verona.
77
78 * comint.el (comint-highlight-prompt): Inherit minibuffer-prompt.
79
80 * wid-edit.el (visibility): Replace :on-image and :off-image
81 widget properties with :on-glyph and :off-glyph, for consistency
82 with the `visibility' widget.
83 (widget-toggle-value-create, widget-visibility-value-create):
84 Merge into a single function `widget-toggle-value-create'.
85
86 * cus-edit.el (custom-variable-value-create, custom-visibility)
87 (custom-face-edit-value-create, custom-face-value-create):
88 Replace :on-image and :off-image widget properties with :on-glyph and
89 :off-glyph, for consistency with the `visibility' widget.
90
912011-01-09 Andreas Schwab <schwab@linux-m68k.org>
92
93 * net/ldap.el (ldap-search-internal): Don't use eval.
94
952011-01-09 Chong Yidong <cyd@stupidchicken.com>
96
97 * subr.el (read-char-choice): Use read-key.
98
99 * custom.el (custom-safe-themes): Rename from
100 custom-safe-theme-files. Add :risky tag.
101 (load-theme, custom-theme-load-confirm): Save sha1 hashes to
102 custom-safe-themes, not filenames. Suggested by Stefan Monnier.
103
1042011-01-09 Chong Yidong <cyd@stupidchicken.com>
105
106 * tool-bar.el (tool-bar-setup): Remove Help button. Remove label
107 from Search and add a label to Undo.
108
109 * vc/vc-dir.el (vc-dir-tool-bar-map): Rearrange, removing
110 inappropriate buttons and adding :vert-only tags.
111
112 * progmodes/compile.el (compilation-mode-tool-bar-map): Adjust to
113 removal of Help tool-bar button. Remove Undo button for space.
114
115 * info.el (info-tool-bar-map): Add :vert-only tags.
116
1172011-01-08 Tassilo Horn <tassilo@member.fsf.org>
118
119 * doc-view.el (doc-view-mode-p): Check for png or imagemagick
120 image backend support. Either of them is fine.
121
12011-01-08 Chong Yidong <cyd@stupidchicken.com> 1222011-01-08 Chong Yidong <cyd@stupidchicken.com>
2 123
124 * subr.el (y-or-n-p): Doc fix.
125
3 * custom.el (custom-safe-theme-files): New defcustom. 126 * custom.el (custom-safe-theme-files): New defcustom.
4 (custom-theme-load-confirm): New function. 127 (custom-theme-load-confirm): New function.
5 (load-theme): Load theme using `load', confirming with 128 (load-theme): Load theme using `load', confirming with
@@ -97,7 +220,7 @@
97 220
982011-01-04 Jan Moringen <jan.moringen@uni-bielefeld.de> 2212011-01-04 Jan Moringen <jan.moringen@uni-bielefeld.de>
99 222
100 * net/dbus.el (dbus-register-property): Added optional parameter 223 * net/dbus.el (dbus-register-property): Add optional parameter
101 dont-register-service. Updated docstring accordingly. 224 dont-register-service. Updated docstring accordingly.
102 225
1032011-01-04 Andreas Schwab <schwab@linux-m68k.org> 2262011-01-04 Andreas Schwab <schwab@linux-m68k.org>
@@ -266,8 +389,8 @@
266 389
2672010-12-30 Tassilo Horn <tassilo@member.fsf.org> 3902010-12-30 Tassilo Horn <tassilo@member.fsf.org>
268 391
269 * doc-view.el (doc-view-mode, doc-view-toggle-display): Use 392 * doc-view.el (doc-view-mode, doc-view-toggle-display):
270 normal-mode without doc-view-mode bindings in auto-mode-alist as 393 Use normal-mode without doc-view-mode bindings in auto-mode-alist as
271 fallback instead of hard coding fundamental mode. 394 fallback instead of hard coding fundamental mode.
272 395
2732010-12-30 Tassilo Horn <tassilo@member.fsf.org> 3962010-12-30 Tassilo Horn <tassilo@member.fsf.org>
@@ -462,8 +585,8 @@
462 585
4632010-12-16 Leo <sdl.web@gmail.com> 5862010-12-16 Leo <sdl.web@gmail.com>
464 587
465 * eshell/eshell.el (eshell-directory-name): Use 588 * eshell/eshell.el (eshell-directory-name):
466 locate-user-emacs-file (Bug#7578). 589 Use locate-user-emacs-file (Bug#7578).
467 590
4682010-12-15 Glenn Morris <rgm@gnu.org> 5912010-12-15 Glenn Morris <rgm@gnu.org>
469 592
@@ -488,8 +611,8 @@
488 (tramp-handle-insert-file-contents): Do not set permanent-local 611 (tramp-handle-insert-file-contents): Do not set permanent-local
489 property. 612 property.
490 613
491 * net/tramp-cache.el (tramp-persistency-file-name): Use 614 * net/tramp-cache.el (tramp-persistency-file-name):
492 `locate-user-emacs-file' if fboundp. 615 Use `locate-user-emacs-file' if fboundp.
493 616
494 * net/tramp-sh.el (tramp-methods): Add "ksu". 617 * net/tramp-sh.el (tramp-methods): Add "ksu".
495 (tramp-default-user-alist): Add "ksu". Use `regexp-opt' for 618 (tramp-default-user-alist): Add "ksu". Use `regexp-opt' for
diff --git a/lisp/allout.el b/lisp/allout.el
index 0df2d2bb153..63af7457d93 100644
--- a/lisp/allout.el
+++ b/lisp/allout.el
@@ -1,12 +1,12 @@
1;;; allout.el --- extensive outline mode for use alone and with other modes 1;;; allout.el --- extensive outline mode for use alone and with other modes
2 2
3;; Copyright (C) 1992, 1993, 1994, 2001, 2002, 2003, 2004, 2005, 2006, 3;; Copyright (C) 1992, 1993, 1994, 2001, 2002, 2003, 2004, 2005, 2006,
4;; 2007, 2008, 2009, 2010 Free Software Foundation, Inc. 4;; 2007, 2008, 2009, 2010, 2011 Free Software Foundation, Inc.
5 5
6;; Author: Ken Manheimer <ken dot manheimer at gmail dot com> 6;; Author: Ken Manheimer <ken dot manheimer at gmail dot com>
7;; Maintainer: Ken Manheimer <ken dot manheimer at gmail dot com> 7;; Maintainer: Ken Manheimer <ken dot manheimer at gmail dot com>
8;; Created: Dec 1991 -- first release to usenet 8;; Created: Dec 1991 -- first release to usenet
9;; Version: 2.2.2 9;; Version: 2.3
10;; Keywords: outlines wp languages 10;; Keywords: outlines wp languages
11;; Website: http://myriadicity.net/Sundry/EmacsAllout 11;; Website: http://myriadicity.net/Sundry/EmacsAllout
12 12
@@ -569,7 +569,7 @@ themselves:
569 `!' - exclamation point/bang -- emphatic 569 `!' - exclamation point/bang -- emphatic
570 `[' - open square bracket -- meta-note, about item instead of item's subject 570 `[' - open square bracket -- meta-note, about item instead of item's subject
571 `\"' - double quote -- a quotation or other citation 571 `\"' - double quote -- a quotation or other citation
572 `=' - equal sign -- an assignement, equating a name with some connotation 572 `=' - equal sign -- an assignment, some kind of definition
573 `^' - carat -- relates to something above 573 `^' - carat -- relates to something above
574 574
575Some are more elusive, but their rationale may be recognizable: 575Some are more elusive, but their rationale may be recognizable:
@@ -891,7 +891,7 @@ For details, see `allout-toggle-current-subtree-encryption's docstring."
891;;;_ #1 Internal Outline Formatting and Configuration 891;;;_ #1 Internal Outline Formatting and Configuration
892;;;_ : Version 892;;;_ : Version
893;;;_ = allout-version 893;;;_ = allout-version
894(defvar allout-version "2.2.2" 894(defvar allout-version "2.3"
895 "Version of currently loaded outline package. (allout.el)") 895 "Version of currently loaded outline package. (allout.el)")
896;;;_ > allout-version 896;;;_ > allout-version
897(defun allout-version (&optional here) 897(defun allout-version (&optional here)
@@ -6226,10 +6226,11 @@ signal."
6226 (epg-decrypt-string epg-context 6226 (epg-decrypt-string epg-context
6227 (encode-coding-string massaged-text 6227 (encode-coding-string massaged-text
6228 (or encoding 'utf-8))) 6228 (or encoding 'utf-8)))
6229 (epg-encrypt-string epg-context 6229 (replace-regexp-in-string "\n$" ""
6230 (encode-coding-string massaged-text 6230 (epg-encrypt-string epg-context
6231 (or encoding 'utf-8)) 6231 (encode-coding-string massaged-text
6232 recipients))) 6232 (or encoding 'utf-8))
6233 recipients))))
6233 6234
6234 ;; validate result -- non-empty 6235 ;; validate result -- non-empty
6235 (if (not result-text) 6236 (if (not result-text)
diff --git a/lisp/calendar/diary-lib.el b/lisp/calendar/diary-lib.el
index 869d69fd8b7..ee4de475079 100644
--- a/lisp/calendar/diary-lib.el
+++ b/lisp/calendar/diary-lib.el
@@ -1,7 +1,7 @@
1;;; diary-lib.el --- diary functions 1;;; diary-lib.el --- diary functions
2 2
3;; Copyright (C) 1989, 1990, 1992, 1993, 1994, 1995, 2001, 2002, 2003, 3;; Copyright (C) 1989, 1990, 1992, 1993, 1994, 1995, 2001, 2002, 2003,
4;; 2004, 2005, 2006, 2007, 2008, 2009, 2010 4;; 2004, 2005, 2006, 2007, 2008, 2009, 2010, 2011
5;; Free Software Foundation, Inc. 5;; Free Software Foundation, Inc.
6 6
7;; Author: Edward M. Reingold <reingold@cs.uiuc.edu> 7;; Author: Edward M. Reingold <reingold@cs.uiuc.edu>
@@ -2346,6 +2346,9 @@ return a font-lock pattern matching array of MONTHS and marking SYMBOL."
2346 '(diary-font-lock-keywords t)) 2346 '(diary-font-lock-keywords t))
2347 (add-to-invisibility-spec '(diary . nil)) 2347 (add-to-invisibility-spec '(diary . nil))
2348 (add-hook 'after-save-hook 'diary-redraw-calendar nil t) 2348 (add-hook 'after-save-hook 'diary-redraw-calendar nil t)
2349 ;; In case the file was modified externally, refresh the calendar
2350 ;; after refreshing the diary buffer.
2351 (add-hook 'after-revert-hook 'diary-redraw-calendar nil t)
2349 (if diary-header-line-flag 2352 (if diary-header-line-flag
2350 (setq header-line-format diary-header-line-format))) 2353 (setq header-line-format diary-header-line-format)))
2351 2354
diff --git a/lisp/comint.el b/lisp/comint.el
index bd563ee4592..bfee8e35c9c 100644
--- a/lisp/comint.el
+++ b/lisp/comint.el
@@ -227,9 +227,7 @@ This variable is buffer-local."
227 :group 'comint) 227 :group 'comint)
228 228
229(defface comint-highlight-prompt 229(defface comint-highlight-prompt
230 '((((min-colors 88) (background dark)) (:foreground "cyan1")) 230 '((t :inherit minibuffer-prompt))
231 (((background dark)) (:foreground "cyan"))
232 (t (:foreground "dark blue")))
233 "Face to use to highlight prompts." 231 "Face to use to highlight prompts."
234 :group 'comint) 232 :group 'comint)
235 233
diff --git a/lisp/cus-edit.el b/lisp/cus-edit.el
index edb299f86ed..8d42e497450 100644
--- a/lisp/cus-edit.el
+++ b/lisp/cus-edit.el
@@ -2551,9 +2551,9 @@ try matching its doc string against `custom-guess-doc-alist'."
2551 (push (widget-create-child-and-convert 2551 (push (widget-create-child-and-convert
2552 widget 'custom-visibility 2552 widget 'custom-visibility
2553 :help-echo "Show the value of this option." 2553 :help-echo "Show the value of this option."
2554 :on-image "down" 2554 :on-glyph "down"
2555 :on "Hide" 2555 :on "Hide"
2556 :off-image "right" 2556 :off-glyph "right"
2557 :off "Show Value" 2557 :off "Show Value"
2558 :action 'custom-toggle-hide-variable 2558 :action 'custom-toggle-hide-variable
2559 nil) 2559 nil)
@@ -2573,8 +2573,8 @@ try matching its doc string against `custom-guess-doc-alist'."
2573 :help-echo "Hide the value of this option." 2573 :help-echo "Hide the value of this option."
2574 :on "Hide" 2574 :on "Hide"
2575 :off "Show" 2575 :off "Show"
2576 :on-image "down" 2576 :on-glyph "down"
2577 :off-image "right" 2577 :off-glyph "right"
2578 :action 'custom-toggle-hide-variable 2578 :action 'custom-toggle-hide-variable
2579 t) 2579 t)
2580 buttons) 2580 buttons)
@@ -2603,8 +2603,8 @@ try matching its doc string against `custom-guess-doc-alist'."
2603 :help-echo "Hide or show this option." 2603 :help-echo "Hide or show this option."
2604 :on "Hide" 2604 :on "Hide"
2605 :off "Show" 2605 :off "Show"
2606 :on-image "down" 2606 :on-glyph "down"
2607 :off-image "right" 2607 :off-glyph "right"
2608 :action 'custom-toggle-hide-variable 2608 :action 'custom-toggle-hide-variable
2609 t) 2609 t)
2610 buttons) 2610 buttons)
@@ -3056,8 +3056,8 @@ to switch between two values."
3056 :pressed-face 'custom-visibility 3056 :pressed-face 'custom-visibility
3057 :mouse-face 'highlight 3057 :mouse-face 'highlight
3058 :pressed-face 'highlight 3058 :pressed-face 'highlight
3059 :on-image nil 3059 :on-glyph nil
3060 :off-image nil) 3060 :off-glyph nil)
3061 3061
3062(defface custom-visibility 3062(defface custom-visibility
3063 '((t :height 0.8 :inherit link)) 3063 '((t :height 0.8 :inherit link))
@@ -3120,7 +3120,7 @@ face attributes (as specified by a `default' defface entry)."
3120 :pressed-face 'custom-visibility 3120 :pressed-face 'custom-visibility
3121 :mouse-face 'highlight 3121 :mouse-face 'highlight
3122 :on "Hide Unused Attributes" :off "Show All Attributes" 3122 :on "Hide Unused Attributes" :off "Show All Attributes"
3123 :on-image nil :off-image nil 3123 :on-glyph nil :off-glyph nil
3124 :always-active t 3124 :always-active t
3125 :action 'custom-face-edit-value-visibility-action 3125 :action 'custom-face-edit-value-visibility-action
3126 show-all) 3126 show-all)
@@ -3475,7 +3475,7 @@ the present value is saved to its :shown-value property instead."
3475 widget 'custom-visibility 3475 widget 'custom-visibility
3476 :help-echo "Hide or show this face." 3476 :help-echo "Hide or show this face."
3477 :on "Hide" :off "Show" 3477 :on "Hide" :off "Show"
3478 :on-image "down" :off-image "right" 3478 :on-glyph "down" :off-glyph "right"
3479 :action 'custom-toggle-hide-face 3479 :action 'custom-toggle-hide-face
3480 (not hiddenp)) 3480 (not hiddenp))
3481 buttons) 3481 buttons)
diff --git a/lisp/custom.el b/lisp/custom.el
index f984d132dd1..6a0beae749e 100644
--- a/lisp/custom.el
+++ b/lisp/custom.el
@@ -1105,14 +1105,16 @@ property `theme-feature' (which is usually a symbol created by
1105 (let ((custom-enabling-themes t)) 1105 (let ((custom-enabling-themes t))
1106 (enable-theme 'user)))) 1106 (enable-theme 'user))))
1107 1107
1108(defcustom custom-safe-theme-files '(default) 1108(defcustom custom-safe-themes '(default)
1109 "List of theme files that are considered safe to load. 1109 "List of themes that are considered safe to load.
1110Each list element should be either an absolute file name, or the 1110Each list element should be the `sha1' hash of a theme file, or
1111symbol `default', which stands for the built-in Emacs theme 1111the symbol `default', which stands for any theme in the built-in
1112directory (a directory named \"themes\" in `data-directory'." 1112Emacs theme directory (a directory named \"themes\" in
1113`data-directory')."
1113 :type '(repeat 1114 :type '(repeat
1114 (choice file (const :tag "Built-in theme directory" default))) 1115 (choice string (const :tag "Built-in themes" default)))
1115 :group 'customize 1116 :group 'customize
1117 :risky t
1116 :version "24.1") 1118 :version "24.1")
1117 1119
1118(defvar safe-functions) ; From unsafep.el 1120(defvar safe-functions) ; From unsafep.el
@@ -1140,74 +1142,74 @@ in one of the directories specified by `custom-theme-load-path'."
1140 (put theme 'theme-documentation nil)) 1142 (put theme 'theme-documentation nil))
1141 (let ((fn (locate-file (concat (symbol-name theme) "-theme.el") 1143 (let ((fn (locate-file (concat (symbol-name theme) "-theme.el")
1142 (custom-theme--load-path) 1144 (custom-theme--load-path)
1143 '("" "c")))) 1145 '("" "c")))
1146 hash)
1144 (unless fn 1147 (unless fn
1145 (error "Unable to find theme file for `%s'." theme)) 1148 (error "Unable to find theme file for `%s'." theme))
1146 ;; Check file safety. 1149 (with-temp-buffer
1147 (when (or (and (memq 'default custom-safe-theme-files) 1150 (insert-file-contents fn)
1148 (equal (file-name-directory fn) 1151 (setq hash (sha1 (current-buffer)))
1149 (expand-file-name "themes/" data-directory))) 1152 ;; Check file safety.
1150 (member fn custom-safe-theme-files) 1153 (when (or (and (memq 'default custom-safe-themes)
1151 ;; If the file is not in the builtin theme directory or 1154 (equal (file-name-directory fn)
1152 ;; in `custom-safe-theme-files', check it with unsafep. 1155 (expand-file-name "themes/" data-directory)))
1153 (with-temp-buffer 1156 (member hash custom-safe-themes)
1154 (require 'unsafep) 1157 ;; If the theme is not in `custom-safe-themes', check
1155 (insert-file-contents fn) 1158 ;; it with unsafep.
1156 (let ((safe-functions (append '(provide-theme deftheme 1159 (progn
1157 custom-theme-set-variables 1160 (require 'unsafep)
1158 custom-theme-set-faces) 1161 (let ((safe-functions
1159 safe-functions)) 1162 (append '(provide-theme deftheme
1160 unsafep form) 1163 custom-theme-set-variables
1161 (while (and (setq form (condition-case nil 1164 custom-theme-set-faces)
1162 (let ((read-circle nil)) 1165 safe-functions))
1163 (read (current-buffer))) 1166 unsafep form)
1164 (end-of-file nil))) 1167 (while (and (setq form (condition-case nil
1165 (null (setq unsafep (unsafep form))))) 1168 (let ((read-circle nil))
1166 (or (null unsafep) 1169 (read (current-buffer)))
1167 (custom-theme-load-confirm fn))))) 1170 (end-of-file nil)))
1168 (let ((custom--inhibit-theme-enable no-enable)) 1171 (null (setq unsafep (unsafep form)))))
1169 (load fn))))) 1172 (or (null unsafep)
1170 1173 (custom-theme-load-confirm hash)))))
1171(defun custom-theme-load-confirm (filename) 1174 (let ((custom--inhibit-theme-enable no-enable))
1175 (eval-buffer))))))
1176
1177(defun custom-theme-load-confirm (hash)
1178 "Query the user about loading a Custom theme that may not be safe.
1179The theme should be in the current buffer. If the user agrees,
1180query also about adding HASH to `custom-safe-themes'."
1172 (if noninteractive 1181 (if noninteractive
1173 nil 1182 nil
1174 (let ((existing-buffer (find-buffer-visiting filename)) 1183 (let ((exit-chars '(?y ?n ?\s))
1175 (exit-chars '(?y ?n ?\s ?\C-g))
1176 prompt char) 1184 prompt char)
1177 (save-window-excursion 1185 (save-window-excursion
1178 (if existing-buffer 1186 (rename-buffer "*Custom Theme*" t)
1179 (pop-to-buffer existing-buffer) 1187 (emacs-lisp-mode)
1180 (find-file filename)) 1188 (display-buffer (current-buffer))
1181 (unwind-protect 1189 (setq prompt
1182 (progn 1190 (format "This theme is not guaranteed to be safe. Really load? %s"
1183 (setq prompt 1191 (if (< (line-number-at-pos (point-max))
1184 (format "This theme is not guaranteed to be safe. Really load? %s" 1192 (window-body-height))
1185 (if (< (line-number-at-pos (point-max)) 1193 "(y or n) "
1186 (window-body-height)) 1194 (push ?\C-v exit-chars)
1187 "(y or n) " 1195 "Type y or n, or C-v to scroll: ")))
1188 (push ?\C-v exit-chars) 1196 (goto-char (point-min))
1189 "Type y or n, or C-v to scroll: "))) 1197 (while (null char)
1190 (goto-char (point-min)) 1198 (setq char (read-char-choice prompt exit-chars))
1191 (while (null char) 1199 (when (eq char ?\C-v)
1192 (setq char (read-char-choice prompt exit-chars t)) 1200 (condition-case nil
1193 (when (eq char ?\C-v) 1201 (scroll-up)
1194 (condition-case nil 1202 (error (goto-char (point-min))))
1195 (scroll-up) 1203 (setq char nil)))
1196 (error (goto-char (point-min)))) 1204 (when (memq char '(?\s ?y))
1197 (setq char nil))) 1205 (push hash custom-safe-themes)
1198 (when (memq char '(?\s ?y)) 1206 ;; Offer to save to `custom-safe-themes'.
1199 (push filename custom-safe-theme-files) 1207 (and (or custom-file user-init-file)
1200 ;; Offer to save to `custom-safe-theme-files'. 1208 (y-or-n-p "Treat this theme as safe for future loads? ")
1201 (and (or custom-file user-init-file) 1209 (let ((coding-system-for-read nil))
1202 (y-or-n-p "Treat %s as safe for future loads? " 1210 (customize-save-variable 'custom-safe-themes
1203 (file-name-nondirectory filename)) 1211 custom-safe-themes)))
1204 (let ((coding-system-for-read nil)) 1212 t)))))
1205 (customize-save-variable
1206 'custom-safe-theme-files
1207 custom-safe-theme-files)))
1208 t))
1209 ;; Unwind form.
1210 (unless existing-buffer (kill-buffer)))))))
1211 1213
1212(defun custom-theme-name-valid-p (name) 1214(defun custom-theme-name-valid-p (name)
1213 "Return t if NAME is a valid name for a Custom theme, nil otherwise. 1215 "Return t if NAME is a valid name for a Custom theme, nil otherwise.
diff --git a/lisp/doc-view.el b/lisp/doc-view.el
index fce3597409c..636f78031fa 100644
--- a/lisp/doc-view.el
+++ b/lisp/doc-view.el
@@ -621,7 +621,8 @@ It's a subdirectory of `doc-view-cache-directory'."
621Document types are symbols like `dvi', `ps', `pdf', or `odf' (any 621Document types are symbols like `dvi', `ps', `pdf', or `odf' (any
622OpenDocument format)." 622OpenDocument format)."
623 (and (display-graphic-p) 623 (and (display-graphic-p)
624 (image-type-available-p 'png) 624 (or (image-type-available-p 'imagemagick)
625 (image-type-available-p 'png))
625 (cond 626 (cond
626 ((eq type 'dvi) 627 ((eq type 'dvi)
627 (and (doc-view-mode-p 'pdf) 628 (and (doc-view-mode-p 'pdf)
diff --git a/lisp/emacs-lisp/unsafep.el b/lisp/emacs-lisp/unsafep.el
index a62f8de4010..6484969541f 100644
--- a/lisp/emacs-lisp/unsafep.el
+++ b/lisp/emacs-lisp/unsafep.el
@@ -202,6 +202,9 @@ UNSAFEP-VARS is a list of symbols with local bindings."
202 (dolist (x (nthcdr 3 form)) 202 (dolist (x (nthcdr 3 form))
203 (setq reason (unsafep-progn (cdr x))) 203 (setq reason (unsafep-progn (cdr x)))
204 (if reason (throw 'unsafep reason)))))) 204 (if reason (throw 'unsafep reason))))))
205 ((eq fun '\`)
206 ;; Backquoted form - safe if its expansion is.
207 (unsafep (cdr (backquote-process (cadr form)))))
205 (t 208 (t
206 ;;First unsafep-function call above wasn't nil, no special case applies 209 ;;First unsafep-function call above wasn't nil, no special case applies
207 reason))))) 210 reason)))))
diff --git a/lisp/files.el b/lisp/files.el
index 6ff8af98dc1..1e03ba1920f 100644
--- a/lisp/files.el
+++ b/lisp/files.el
@@ -57,7 +57,7 @@ when it has unsaved changes."
57A list of elements of the form (FROM . TO), each meaning to replace 57A list of elements of the form (FROM . TO), each meaning to replace
58FROM with TO when it appears in a directory name. This replacement is 58FROM with TO when it appears in a directory name. This replacement is
59done when setting up the default directory of a newly visited file. 59done when setting up the default directory of a newly visited file.
60*Every* FROM string should start with \"\\\\`\". 60*Every* FROM string ought to start with \"\\\\`\".
61 61
62FROM and TO should be equivalent names, which refer to the 62FROM and TO should be equivalent names, which refer to the
63same directory. Do not use `~' in the TO strings; 63same directory. Do not use `~' in the TO strings;
diff --git a/lisp/gnus/ChangeLog b/lisp/gnus/ChangeLog
index abbddcc49cc..c0c6533d531 100644
--- a/lisp/gnus/ChangeLog
+++ b/lisp/gnus/ChangeLog
@@ -1,3 +1,22 @@
12011-01-11 Lars Magne Ingebrigtsen <larsi@gnus.org>
2
3 * nnimap.el (nnimap-convert-partial-article): Protect against
4 zero-length body parts.
5
6 * mm-decode.el (mm-preferred-alternative-precedence): Discourage
7 showing empty parts.
8
9 * gnus-int.el (gnus-request-accept-article): Don't try to update marks
10 and stuff if the backend didn't return the article number. This fixes
11 an Exchange-related nnimap bug.
12
13 * gnus-sum.el (gnus-summary-next-article): Remove hack to reselect
14 group window, because it does the wrong thing when a separate frame
15 displays the group buffer.
16
17 * proto-stream.el (open-protocol-stream): Protect against the low-level
18 transport functions returning nil.
19
12011-01-07 Daiki Ueno <ueno@unixuser.org> 202011-01-07 Daiki Ueno <ueno@unixuser.org>
2 21
3 * mml2015.el (epg-sub-key-fingerprint): Autoload. 22 * mml2015.el (epg-sub-key-fingerprint): Autoload.
diff --git a/lisp/gnus/gnus-int.el b/lisp/gnus/gnus-int.el
index 71a9aa9e618..b805167149f 100644
--- a/lisp/gnus/gnus-int.el
+++ b/lisp/gnus/gnus-int.el
@@ -1,7 +1,7 @@
1;;; gnus-int.el --- backend interface functions for Gnus 1;;; gnus-int.el --- backend interface functions for Gnus
2 2
3;; Copyright (C) 1996, 1997, 1998, 1999, 2000, 2001, 2002, 2003, 2004 3;; Copyright (C) 1996, 1997, 1998, 1999, 2000, 2001, 2002, 2003, 2004
4;; 2005, 2006, 2007, 2008, 2009, 2010 Free Software Foundation, Inc. 4;; 2005, 2006, 2007, 2008, 2009, 2010, 2011 Free Software Foundation, Inc.
5 5
6;; Author: Lars Magne Ingebrigtsen <larsi@gnus.org> 6;; Author: Lars Magne Ingebrigtsen <larsi@gnus.org>
7;; Keywords: news 7;; Keywords: news
@@ -711,7 +711,9 @@ If GROUP is nil, all groups on GNUS-COMMAND-METHOD are scanned."
711 (if (stringp group) (gnus-group-real-name group) group) 711 (if (stringp group) (gnus-group-real-name group) group)
712 (cadr gnus-command-method) 712 (cadr gnus-command-method)
713 last))) 713 last)))
714 (when (and gnus-agent (gnus-agent-method-p gnus-command-method)) 714 (when (and gnus-agent
715 (gnus-agent-method-p gnus-command-method)
716 (cdr result))
715 (gnus-agent-regenerate-group group (list (cdr result)))) 717 (gnus-agent-regenerate-group group (list (cdr result))))
716 result)) 718 result))
717 719
diff --git a/lisp/gnus/gnus-sum.el b/lisp/gnus/gnus-sum.el
index 9a21a9c7f68..20a1141cc25 100644
--- a/lisp/gnus/gnus-sum.el
+++ b/lisp/gnus/gnus-sum.el
@@ -7687,9 +7687,6 @@ If BACKWARD, the previous article is selected instead of the next."
7687 (if (eq gnus-keep-same-level 'best) 7687 (if (eq gnus-keep-same-level 'best)
7688 (gnus-summary-best-group gnus-newsgroup-name) 7688 (gnus-summary-best-group gnus-newsgroup-name)
7689 (gnus-summary-search-group backward gnus-keep-same-level)))) 7689 (gnus-summary-search-group backward gnus-keep-same-level))))
7690 ;; For some reason, the group window gets selected. We change
7691 ;; it back.
7692 (select-window (get-buffer-window (current-buffer)))
7693 ;; Select next unread newsgroup automagically. 7690 ;; Select next unread newsgroup automagically.
7694 (cond 7691 (cond
7695 ((or (not gnus-auto-select-next) 7692 ((or (not gnus-auto-select-next)
diff --git a/lisp/gnus/mm-decode.el b/lisp/gnus/mm-decode.el
index 216ed6624d9..62755347142 100644
--- a/lisp/gnus/mm-decode.el
+++ b/lisp/gnus/mm-decode.el
@@ -1,7 +1,7 @@
1;;; mm-decode.el --- Functions for decoding MIME things 1;;; mm-decode.el --- Functions for decoding MIME things
2 2
3;; Copyright (C) 1998, 1999, 2000, 2001, 2002, 2003, 2004, 2005, 2006, 3;; Copyright (C) 1998, 1999, 2000, 2001, 2002, 2003, 2004, 2005, 2006,
4;; 2007, 2008, 2009, 2010 Free Software Foundation, Inc. 4;; 2007, 2008, 2009, 2010, 2011 Free Software Foundation, Inc.
5 5
6;; Author: Lars Magne Ingebrigtsen <larsi@gnus.org> 6;; Author: Lars Magne Ingebrigtsen <larsi@gnus.org>
7;; MORIOKA Tomohiko <morioka@jaist.ac.jp> 7;; MORIOKA Tomohiko <morioka@jaist.ac.jp>
@@ -1367,13 +1367,18 @@ Use CMD as the process."
1367 1367
1368(defun mm-preferred-alternative-precedence (handles) 1368(defun mm-preferred-alternative-precedence (handles)
1369 "Return the precedence based on HANDLES and `mm-discouraged-alternatives'." 1369 "Return the precedence based on HANDLES and `mm-discouraged-alternatives'."
1370 (let ((seq (nreverse (mapcar #'mm-handle-media-type 1370 (setq handles (reverse handles))
1371 handles)))) 1371 (dolist (disc (reverse mm-discouraged-alternatives))
1372 (dolist (disc (reverse mm-discouraged-alternatives)) 1372 (dolist (handle (copy-sequence handles))
1373 (dolist (elem (copy-sequence seq)) 1373 (when (string-match disc (mm-handle-media-type handle))
1374 (when (string-match disc elem) 1374 (setq handles (nconc (delete handle handles) (list handle))))))
1375 (setq seq (nconc (delete elem seq) (list elem)))))) 1375 ;; Remove empty parts.
1376 seq)) 1376 (dolist (handle (copy-sequence handles))
1377 (unless (with-current-buffer (mm-handle-buffer handle)
1378 (goto-char (point-min))
1379 (re-search-forward "[^ \t\n]" nil t))
1380 (setq handles (nconc (delete handle handles) (list handle)))))
1381 (mapcar #'mm-handle-media-type handles))
1377 1382
1378(defun mm-get-content-id (id) 1383(defun mm-get-content-id (id)
1379 "Return the handle(s) referred to by ID." 1384 "Return the handle(s) referred to by ID."
diff --git a/lisp/gnus/nnimap.el b/lisp/gnus/nnimap.el
index 51fa532a371..0c711701e96 100644
--- a/lisp/gnus/nnimap.el
+++ b/lisp/gnus/nnimap.el
@@ -582,7 +582,7 @@ textual parts.")
582 ;; Collect all the body parts. 582 ;; Collect all the body parts.
583 (while (looking-at ".*BODY\\[\\([.0-9]+\\)\\]") 583 (while (looking-at ".*BODY\\[\\([.0-9]+\\)\\]")
584 (setq id (match-string 1) 584 (setq id (match-string 1)
585 bytes (nnimap-get-length)) 585 bytes (or (nnimap-get-length) 0))
586 (beginning-of-line) 586 (beginning-of-line)
587 (delete-region (point) (progn (forward-line 1) (point))) 587 (delete-region (point) (progn (forward-line 1) (point)))
588 (push (list id (buffer-substring (point) (+ (point) bytes))) 588 (push (list id (buffer-substring (point) (+ (point) bytes)))
diff --git a/lisp/gnus/proto-stream.el b/lisp/gnus/proto-stream.el
index d1266cb5461..546461a67b3 100644
--- a/lisp/gnus/proto-stream.el
+++ b/lisp/gnus/proto-stream.el
@@ -1,6 +1,6 @@
1;;; proto-stream.el --- negotiating TLS, STARTTLS and other connections 1;;; proto-stream.el --- negotiating TLS, STARTTLS and other connections
2 2
3;; Copyright (C) 2010 Free Software Foundation, Inc. 3;; Copyright (C) 2010, 2011 Free Software Foundation, Inc.
4 4
5;; Author: Lars Magne Ingebrigtsen <larsi@gnus.org> 5;; Author: Lars Magne Ingebrigtsen <larsi@gnus.org>
6;; Keywords: network 6;; Keywords: network
@@ -101,14 +101,17 @@ command to switch on STARTTLS otherwise."
101 (setq type 'network)) 101 (setq type 'network))
102 ((eq type 'ssl) 102 ((eq type 'ssl)
103 (setq type 'tls))) 103 (setq type 'tls)))
104 (destructuring-bind (stream greeting capabilities) 104 (let ((open-result
105 (funcall (intern (format "proto-stream-open-%s" type) obarray) 105 (funcall (intern (format "proto-stream-open-%s" type) obarray)
106 name buffer host service parameters) 106 name buffer host service parameters)))
107 (list (and stream 107 (if (null open-result)
108 (memq (process-status stream) 108 (list nil nil nil)
109 '(open run)) 109 (destructuring-bind (stream greeting capabilities) open-result
110 stream) 110 (list (and stream
111 greeting capabilities)))) 111 (memq (process-status stream)
112 '(open run))
113 stream)
114 greeting capabilities))))))
112 115
113(defun proto-stream-open-network-only (name buffer host service parameters) 116(defun proto-stream-open-network-only (name buffer host service parameters)
114 (let ((start (with-current-buffer buffer (point))) 117 (let ((start (with-current-buffer buffer (point)))
diff --git a/lisp/info.el b/lisp/info.el
index ad92914a54d..7391dfad39e 100644
--- a/lisp/info.el
+++ b/lisp/info.el
@@ -3777,13 +3777,16 @@ If FORK is non-nil, it is passed to `Info-goto-node'."
3777 (tool-bar-local-item-from-menu 'Info-up "up-node" map Info-mode-map 3777 (tool-bar-local-item-from-menu 'Info-up "up-node" map Info-mode-map
3778 :vert-only t) 3778 :vert-only t)
3779 (define-key-after map [separator-2] menu-bar-separator) 3779 (define-key-after map [separator-2] menu-bar-separator)
3780 (tool-bar-local-item-from-menu 'Info-top-node "home" map Info-mode-map) 3780 (tool-bar-local-item-from-menu 'Info-top-node "home" map Info-mode-map
3781 :vert-only t)
3781 (tool-bar-local-item-from-menu 'Info-goto-node "jump-to" map Info-mode-map) 3782 (tool-bar-local-item-from-menu 'Info-goto-node "jump-to" map Info-mode-map)
3782 (define-key-after map [separator-3] menu-bar-separator) 3783 (define-key-after map [separator-3] menu-bar-separator)
3783 (tool-bar-local-item-from-menu 'Info-index "index" map Info-mode-map 3784 (tool-bar-local-item-from-menu 'Info-index "index" map Info-mode-map
3784 :label "Index Search") 3785 :label "Index")
3785 (tool-bar-local-item-from-menu 'Info-search "search" map Info-mode-map) 3786 (tool-bar-local-item-from-menu 'Info-search "search" map Info-mode-map
3786 (tool-bar-local-item-from-menu 'Info-exit "exit" map Info-mode-map) 3787 :vert-only t)
3788 (tool-bar-local-item-from-menu 'Info-exit "exit" map Info-mode-map
3789 :vert-only t)
3787 map)) 3790 map))
3788 3791
3789(defvar Info-menu-last-node nil) 3792(defvar Info-menu-last-node nil)
diff --git a/lisp/net/dbus.el b/lisp/net/dbus.el
index 7903644029e..ca1a1743231 100644
--- a/lisp/net/dbus.el
+++ b/lisp/net/dbus.el
@@ -183,7 +183,18 @@ association to the service from D-Bus."
183(defun dbus-unregister-service (bus service) 183(defun dbus-unregister-service (bus service)
184 "Unregister all objects related to SERVICE from D-Bus BUS. 184 "Unregister all objects related to SERVICE from D-Bus BUS.
185BUS is either a Lisp symbol, `:system' or `:session', or a string 185BUS is either a Lisp symbol, `:system' or `:session', or a string
186denoting the bus address. SERVICE must be a known service name." 186denoting the bus address. SERVICE must be a known service name.
187
188The function returns a keyword, indicating the result of the
189operation. One of the following keywords is returned:
190
191`:released': Service has become the primary owner of the name.
192
193`:non-existent': Service name does not exist on this bus.
194
195`:not-owner': We are neither the primary owner nor waiting in the
196queue of this service."
197
187 (maphash 198 (maphash
188 (lambda (key value) 199 (lambda (key value)
189 (dolist (elt value) 200 (dolist (elt value)
@@ -193,9 +204,14 @@ denoting the bus address. SERVICE must be a known service name."
193 (puthash key (delete elt value) dbus-registered-objects-table) 204 (puthash key (delete elt value) dbus-registered-objects-table)
194 (remhash key dbus-registered-objects-table)))))) 205 (remhash key dbus-registered-objects-table))))))
195 dbus-registered-objects-table) 206 dbus-registered-objects-table)
196 (dbus-call-method 207 (let ((reply (dbus-call-method
197 bus dbus-service-dbus dbus-path-dbus dbus-interface-dbus 208 bus dbus-service-dbus dbus-path-dbus dbus-interface-dbus
198 "ReleaseName" service)) 209 "ReleaseName" service)))
210 (case reply
211 (1 :released)
212 (2 :non-existent)
213 (3 :not-owner)
214 (t (signal 'dbus-error (list "Could not unregister service" service))))))
199 215
200(defun dbus-call-method-non-blocking-handler (&rest args) 216(defun dbus-call-method-non-blocking-handler (&rest args)
201 "Handler for reply messages of asynchronous D-Bus message calls. 217 "Handler for reply messages of asynchronous D-Bus message calls.
@@ -914,17 +930,20 @@ clients from discovering the still incomplete interface."
914 bus dbus-service-dbus dbus-path-dbus dbus-interface-dbus 930 bus dbus-service-dbus dbus-path-dbus dbus-interface-dbus
915 "RequestName" service 0)) 931 "RequestName" service 0))
916 932
917 ;; Add the handler. We use `dbus-service-emacs' as service name, in 933 ;; Add handlers for the three property-related methods.
918 ;; order to let unregister SERVICE despite of this default handler.
919 (dbus-register-method 934 (dbus-register-method
920 bus service path dbus-interface-properties "Get" 'dbus-property-handler 935 bus service path dbus-interface-properties "Get"
921 dont-register-service) 936 'dbus-property-handler 'dont-register)
922 (dbus-register-method 937 (dbus-register-method
923 bus service path dbus-interface-properties "GetAll" 'dbus-property-handler 938 bus service path dbus-interface-properties "GetAll"
924 dont-register-service) 939 'dbus-property-handler 'dont-register)
925 (dbus-register-method 940 (dbus-register-method
926 bus service path dbus-interface-properties "Set" 'dbus-property-handler 941 bus service path dbus-interface-properties "Set"
927 dont-register-service) 942 'dbus-property-handler 'dont-register)
943
944 ;; Register the name SERVICE with BUS.
945 (unless dont-register-service
946 (dbus-register-service bus service))
928 947
929 ;; Send the PropertiesChanged signal. 948 ;; Send the PropertiesChanged signal.
930 (when emits-signal 949 (when emits-signal
diff --git a/lisp/net/ldap.el b/lisp/net/ldap.el
index 066dbd8bea0..88284af06f0 100644
--- a/lisp/net/ldap.el
+++ b/lisp/net/ldap.el
@@ -1,7 +1,7 @@
1;;; ldap.el --- client interface to LDAP for Emacs 1;;; ldap.el --- client interface to LDAP for Emacs
2 2
3;; Copyright (C) 1998, 1999, 2000, 2001, 2002, 2003, 2004, 2005, 2006, 3;; Copyright (C) 1998, 1999, 2000, 2001, 2002, 2003, 2004, 2005, 2006,
4;; 2007, 2008, 2009, 2010 Free Software Foundation, Inc. 4;; 2007, 2008, 2009, 2010, 2011 Free Software Foundation, Inc.
5 5
6;; Author: Oscar Figueiredo <oscar@cpe.fr> 6;; Author: Oscar Figueiredo <oscar@cpe.fr>
7;; Maintainer: FSF 7;; Maintainer: FSF
@@ -556,13 +556,9 @@ an alist of attribute/value pairs."
556 (if (and sizelimit 556 (if (and sizelimit
557 (not (equal "" sizelimit))) 557 (not (equal "" sizelimit)))
558 (setq arglist (nconc arglist (list (format "-z%s" sizelimit))))) 558 (setq arglist (nconc arglist (list (format "-z%s" sizelimit)))))
559 (eval `(call-process ldap-ldapsearch-prog 559 (apply #'call-process ldap-ldapsearch-prog
560 nil 560 nil buf nil
561 buf 561 (append arglist ldap-ldapsearch-args filter))
562 nil
563 ,@arglist
564 ,@ldap-ldapsearch-args
565 ,@filter))
566 (insert "\n") 562 (insert "\n")
567 (goto-char (point-min)) 563 (goto-char (point-min))
568 564
diff --git a/lisp/org/ChangeLog b/lisp/org/ChangeLog
index 9bf07deeffe..e8531be05f8 100644
--- a/lisp/org/ChangeLog
+++ b/lisp/org/ChangeLog
@@ -1,3 +1,8 @@
12011-01-09 Chong Yidong <cyd@stupidchicken.com>
2
3 * org-faces.el (org-link): Inherit from link face.
4 Suggested by Joakim Verona.
5
12010-12-11 Tassilo Horn <tassilo@member.fsf.org> 62010-12-11 Tassilo Horn <tassilo@member.fsf.org>
2 7
3 * org-footnote.el (org-footnote-create-definition): Place 8 * org-footnote.el (org-footnote-create-definition): Place
diff --git a/lisp/org/org-faces.el b/lisp/org/org-faces.el
index 3f8245758f7..d4f458232ce 100644
--- a/lisp/org/org-faces.el
+++ b/lisp/org/org-faces.el
@@ -1,6 +1,6 @@
1;;; org-faces.el --- Face definitions for Org-mode. 1;;; org-faces.el --- Face definitions for Org-mode.
2 2
3;; Copyright (C) 2004, 2005, 2006, 2007, 2008, 2009, 2010 3;; Copyright (C) 2004, 2005, 2006, 2007, 2008, 2009, 2010, 2011
4;; Free Software Foundation, Inc. 4;; Free Software Foundation, Inc.
5 5
6;; Author: Carsten Dominik <carsten at orgmode dot org> 6;; Author: Carsten Dominik <carsten at orgmode dot org>
@@ -247,9 +247,7 @@ column view defines special faces for each outline level. See the file
247 :group 'org-faces) 247 :group 'org-faces)
248 248
249(defface org-link 249(defface org-link
250 '((((class color) (background light)) (:foreground "Purple" :underline t)) 250 '((t :inherit link))
251 (((class color) (background dark)) (:foreground "Cyan" :underline t))
252 (t (:underline t)))
253 "Face for links." 251 "Face for links."
254 :group 'org-faces) 252 :group 'org-faces)
255 253
diff --git a/lisp/progmodes/compile.el b/lisp/progmodes/compile.el
index 710b5d0858b..f86dd7e1bec 100644
--- a/lisp/progmodes/compile.el
+++ b/lisp/progmodes/compile.el
@@ -1569,9 +1569,11 @@ Returns the compilation buffer created."
1569(defvar compilation-mode-tool-bar-map 1569(defvar compilation-mode-tool-bar-map
1570 ;; When bootstrapping, tool-bar-map is not properly initialized yet, 1570 ;; When bootstrapping, tool-bar-map is not properly initialized yet,
1571 ;; so don't do anything. 1571 ;; so don't do anything.
1572 (when (keymapp (butlast tool-bar-map)) 1572 (when (keymapp tool-bar-map)
1573 (let ((map (butlast (copy-keymap tool-bar-map))) 1573 (let ((map (copy-keymap tool-bar-map)))
1574 (help (last tool-bar-map))) ;; Keep Help last in tool bar 1574 (define-key map [undo] nil)
1575 (define-key map [separator-2] nil)
1576 (define-key-after map [separator-compile] menu-bar-separator)
1575 (tool-bar-local-item 1577 (tool-bar-local-item
1576 "left-arrow" 'previous-error-no-select 'previous-error-no-select map 1578 "left-arrow" 'previous-error-no-select 'previous-error-no-select map
1577 :rtl "right-arrow" 1579 :rtl "right-arrow"
@@ -1588,7 +1590,7 @@ Returns the compilation buffer created."
1588 (tool-bar-local-item 1590 (tool-bar-local-item
1589 "refresh" 'recompile 'recompile map 1591 "refresh" 'recompile 'recompile map
1590 :help "Restart compilation") 1592 :help "Restart compilation")
1591 (append map help)))) 1593 map)))
1592 1594
1593(put 'compilation-mode 'mode-class 'special) 1595(put 'compilation-mode 'mode-class 'special)
1594 1596
diff --git a/lisp/progmodes/idlw-help.el b/lisp/progmodes/idlw-help.el
index 0674ccf730a..f8121beb231 100644
--- a/lisp/progmodes/idlw-help.el
+++ b/lisp/progmodes/idlw-help.el
@@ -1,7 +1,7 @@
1;;; idlw-help.el --- HTML Help code for IDLWAVE 1;;; idlw-help.el --- HTML Help code for IDLWAVE
2 2
3;; Copyright (C) 2000, 2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008, 3;; Copyright (C) 2000, 2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008,
4;; 2009, 2010 Free Software Foundation, Inc. 4;; 2009, 2010, 2011 Free Software Foundation, Inc.
5;; 5;;
6;; Authors: J.D. Smith <jdsmith@as.arizona.edu> 6;; Authors: J.D. Smith <jdsmith@as.arizona.edu>
7;; Carsten Dominik <dominik@science.uva.nl> 7;; Carsten Dominik <dominik@science.uva.nl>
@@ -195,8 +195,7 @@ support."
195 :type 'string) 195 :type 'string)
196 196
197(defface idlwave-help-link 197(defface idlwave-help-link
198 '((((class color)) (:foreground "Blue")) 198 '((t :inherit link))
199 (t (:weight bold)))
200 "Face for highlighting links into IDLWAVE online help." 199 "Face for highlighting links into IDLWAVE online help."
201 :group 'idlwave-online-help) 200 :group 'idlwave-online-help)
202 201
diff --git a/lisp/progmodes/prolog.el b/lisp/progmodes/prolog.el
index 822e6d9b6f8..16450ee3b69 100644
--- a/lisp/progmodes/prolog.el
+++ b/lisp/progmodes/prolog.el
@@ -1,10 +1,15 @@
1;;; prolog.el --- major mode for editing and running Prolog under Emacs 1;;; prolog.el --- major mode for editing and running Prolog (and Mercury) code
2 2
3;; Copyright (C) 1986, 1987, 2001, 2002, 2003, 2004, 2005, 2006, 2007, 3;; Copyright (C) 1986, 1987, 1997, 1998, 1999, 2002, 2003, 2011 Free Software Foundation, Inc.
4;; 2008, 2009, 2010 Free Software Foundation, Inc.
5 4
6;; Author: Masanobu UMEDA <umerin@mse.kyutech.ac.jp> 5;; Authors: Emil Åström <emil_astrom(at)hotmail(dot)com>
7;; Keywords: languages 6;; Milan Zamazal <pdm(at)freesoft(dot)cz>
7;; Stefan Bruda <stefan(at)bruda(dot)ca> (current maintainer)
8;; * See below for more details
9;; Keywords: prolog major mode sicstus swi mercury
10
11(defvar prolog-mode-version "1.22"
12 "Prolog mode version number.")
8 13
9;; This file is part of GNU Emacs. 14;; This file is part of GNU Emacs.
10 15
@@ -21,409 +26,4020 @@
21;; You should have received a copy of the GNU General Public License 26;; You should have received a copy of the GNU General Public License
22;; along with GNU Emacs. If not, see <http://www.gnu.org/licenses/>. 27;; along with GNU Emacs. If not, see <http://www.gnu.org/licenses/>.
23 28
29;; Original author: Masanobu UMEDA <umerin(at)mse(dot)kyutech(dot)ac(dot)jp>
30;; Parts of this file was taken from a modified version of the original
31;; by Johan Andersson, Peter Olin, Mats Carlsson, Johan Bevemyr, Stefan
32;; Andersson, and Per Danielsson (all SICS people), and Henrik Båkman
33;; at Uppsala University, Sweden.
34;;
35;; Some ideas and also a few lines of code have been borrowed (not stolen ;-)
36;; from Oz.el, the Emacs major mode for the Oz programming language,
37;; Copyright (C) 1993 DFKI GmbH, Germany, with permission.
38;; Authors: Ralf Scheidhauer and Michael Mehl ([scheidhr|mehl](at)dfki(dot)uni-sb(dot)de)
39;;
40;; More ideas and code have been taken from the SICStus debugger mode
41;; (http://www.csd.uu.se/~perm/source_debug/index.shtml -- broken link
42;; as of Mon May 5 08:23:48 EDT 2003) by Per Mildner.
43;;
44;; Additions for ECLiPSe and other helpful suggestions: Stephan Heuel
45;; <heuel(at)ipb(dot)uni-bonn(dot)de>
46
24;;; Commentary: 47;;; Commentary:
48;;
49;; This package provides a major mode for editing Prolog code, with
50;; all the bells and whistles one would expect, including syntax
51;; highlighting and auto indentation. It can also send regions to an
52;; inferior Prolog process.
53;;
54;; The code requires the comint, easymenu, info, imenu, and font-lock
55;; libraries. These are normally distributed with GNU Emacs and
56;; XEmacs.
57
58;;; Installation:
59;;
60;; Insert the following lines in your init file--typically ~/.emacs
61;; (GNU Emacs and XEmacs <21.4), or ~/.xemacs/init.el (XEmacs
62;; 21.4)--to use this mode when editing Prolog files under Emacs:
63;;
64;; (setq load-path (cons "/usr/lib/xemacs/site-lisp" load-path))
65;; (autoload 'run-prolog "prolog" "Start a Prolog sub-process." t)
66;; (autoload 'prolog-mode "prolog" "Major mode for editing Prolog programs." t)
67;; (autoload 'mercury-mode "prolog" "Major mode for editing Mercury programs." t)
68;; (setq prolog-system 'swi) ; optional, the system you are using;
69;; ; see `prolog-system' below for possible values
70;; (setq auto-mode-alist (append '(("\\.pl$" . prolog-mode)
71;; ("\\.m$" . mercury-mode))
72;; auto-mode-alist))
73;;
74;; where the path in the first line is the file system path to this file.
75;; MSDOS paths can be written like "d:/programs/emacs-19.34/site-lisp".
76;; Note: In XEmacs, either `/usr/lib/xemacs/site-lisp' (RPM default in
77;; Red Hat-based distributions) or `/usr/local/lib/xemacs/site-lisp'
78;; (default when compiling from sources) are automatically added to
79;; `load-path', so the first line is not necessary provided that you
80;; put this file in the appropriate place.
81;;
82;; The last s-expression above makes sure that files ending with .pl
83;; are assumed to be Prolog files and not Perl, which is the default
84;; Emacs setting. If this is not wanted, remove this line. It is then
85;; necessary to either
86;;
87;; o insert in your Prolog files the following comment as the first line:
88;;
89;; % -*- Mode: Prolog -*-
90;;
91;; and then the file will be open in Prolog mode no matter its
92;; extension, or
93;;
94;; o manually switch to prolog mode after opening a Prolog file, by typing
95;; M-x prolog-mode.
96;;
97;; If the command to start the prolog process ('sicstus', 'pl' or
98;; 'swipl' for SWI prolog, etc.) is not available in the default path,
99;; then it is necessary to set the value of the environment variable
100;; EPROLOG to a shell command to invoke the prolog process. In XEmacs
101;; and Emacs 20+ you can also customize the variable
102;; `prolog-program-name' (in the group `prolog-inferior') and provide
103;; a full path for your Prolog system (swi, scitus, etc.).
104;;
105;; Note: I (Stefan, the current maintainer) work under XEmacs. Future
106;; developments will thus be biased towards XEmacs (OK, I admit it,
107;; I am biased towards XEmacs in general), though I will do my best
108;; to keep the GNU Emacs compatibility. So if you work under Emacs
109;; and see something that does not work do drop me a line, as I have
110;; a smaller chance to notice this kind of bugs otherwise.
111
112;; Changelog:
25 113
26;; This package provides a major mode for editing Prolog. It knows 114;; Version 1.22:
27;; about Prolog syntax and comments, and can send regions to an inferior 115;; o Allowed both 'swipl' and 'pl' as names for the SWI Prolog
28;; Prolog interpreter process. Font locking is tuned towards GNU Prolog. 116;; interpreter.
117;; o Atoms that start a line are not blindly coloured as
118;; predicates. Instead we check that they are followed by ( or
119;; :- first. Patch suggested by Guy Wiener.
120;; Version 1.21:
121;; o Cleaned up the code that defines faces. The missing face
122;; warnings on some Emacsen should disappear.
123;; Version 1.20:
124;; o Improved the handling of clause start detection and multi-line
125;; comments: `prolog-clause-start' no longer finds non-predicate
126;; (e.g., capitalized strings) beginning of clauses.
127;; `prolog-tokenize' recognizes when the end point is within a
128;; multi-line comment.
129;; Version 1.19:
130;; o Minimal changes for Aquamacs inclusion and in general for
131;; better coping with finding the Prolog executable. Patch
132;; provided by David Reitter
133;; Version 1.18:
134;; o Fixed syntax highlighting for clause heads that do not begin at
135;; the beginning of the line.
136;; o Fixed compilation warnings under Emacs.
137;; o Updated the email address of the current maintainer.
138;; Version 1.17:
139;; o Minor indentation fix (patch by Markus Triska)
140;; o `prolog-underscore-wordchar-flag' defaults now to nil (more
141;; consistent to other Emacs modes)
142;; Version 1.16:
143;; o Eliminated a possible compilation warning.
144;; Version 1.15:
145;; o Introduced three new customizable variables: electric colon
146;; (`prolog-electric-colon-flag', default nil), electric dash
147;; (`prolog-electric-dash-flag', default nil), and a possibility
148;; to prevent the predicate template insertion from adding commata
149;; (`prolog-electric-dot-full-predicate-template', defaults to t
150;; since it seems quicker to me to just type those commata). A
151;; trivial adaptation of a patch by Markus Triska.
152;; o Improved the behaviour of electric if-then-else to only skip
153;; forward if the parenthesis/semicolon is preceded by
154;; whitespace. Once more a trivial adaptation of a patch by
155;; Markus Triska.
156;; Version 1.14:
157;; o Cleaned up align code. `prolog-align-flag' is eliminated (since
158;; on a second thought it does not do anything useful). Added key
159;; binding (C-c C-a) and menu entry for alignment.
160;; o Condensed regular expressions for lower and upper case
161;; characters (GNU Emacs seems to go over the regexp length limit
162;; with the original form). My code on the matter was improved
163;; considerably by Markus Triska.
164;; o Fixed `prolog-insert-spaces-after-paren' (which used an
165;; unitialized variable).
166;; o Minor changes to clean up the code and avoid some implicit
167;; package requirements.
168;; Version 1.13:
169;; o Removed the use of `map-char-table' in `prolog-build-case-strings'
170;; which appears to cause prblems in (at least) Emacs 23.0.0.1.
171;; o Added if-then-else indentation + corresponding electric
172;; characters. New customization: `prolog-electric-if-then-else-flag'
173;; o Align support (requires `align'). New customization:
174;; `prolog-align-flag'.
175;; o Temporary consult files have now the same name throughout the
176;; session. This prevents issues with reconsulting a buffer
177;; (this event is no longer passed to Prolog as a request to
178;; consult a new file).
179;; o Adaptive fill mode is now turned on. Comment indentation is
180;; still worse than it could be though, I am working on it.
181;; o Improved filling and auto-filling capabilities. Now block
182;; comments should be [auto-]filled correctly most of the time;
183;; the following pattern in particular is worth noting as being
184;; filled correctly:
185;; <some code here> % some comment here that goes beyond the
186;; % rightmost column, possibly combined with
187;; % subsequent comment lines
188;; o `prolog-char-quote-workaround' now defaults to nil.
189;; o Note: Many of the above improvements have been suggested by
190;; Markus Triska, who also provided useful patches on the matter
191;; when he realized that I was slow in responding. Many thanks.
192;; Version 1.11 / 1.12
193;; o GNU Emacs compatibility fix for paragraph filling (fixed
194;; incorrectly in 1.11, fix fixed in 1.12).
195;; Version 1.10
196;; o Added paragraph filling in comment blocks and also correct auto
197;; filling for comments.
198;; o Fixed the possible "Regular expression too big" error in
199;; `prolog-electric-dot'.
200;; Version 1.9
201;; o Parenthesis expressions are now indented by default so that
202;; components go one underneath the other, just as for compound
203;; terms. You can use the old style (the second and subsequent
204;; lines being indented to the right in a parenthesis expression)
205;; by setting the customizable variable `prolog-paren-indent-p'
206;; (group "Prolog Indentation") to t.
207;; o (Somehow awkward) handling of the 0' character escape
208;; sequence. I am looking into a better way of doing it but
209;; prospects look bleak. If this breaks things for you please let
210;; me know and also set the `prolog-char-quote-workaround' (group
211;; "Prolog Other") to nil.
212;; Version 1.8
213;; o Key binding fix.
214;; Version 1.7
215;; o Fixed a number of issues with the syntax of single quotes,
216;; including Debian bug #324520.
217;; Version 1.6
218;; o Fixed mercury mode menu initialization (Debian bug #226121).
219;; o Fixed (i.e., eliminated) Delete remapping (Debian bug #229636).
220;; o Corrected indentation for clauses defining quoted atoms.
221;; Version 1.5:
222;; o Keywords fontifying should work in console mode so this is
223;; enabled everywhere.
224;; Version 1.4:
225;; o Now supports GNU Prolog--minor adaptation of a patch by Stefan
226;; Moeding.
227;; Version 1.3:
228;; o Info-follow-nearest-node now called correctly under Emacs too
229;; (thanks to Nicolas Pelletier). Should be implemented more
230;; elegantly (i.e., without compilation warnings) in the future.
231;; Version 1.2:
232;; o Another prompt fix, still in SWI mode (people seem to have
233;; changed the prompt of SWI Prolog).
234;; Version 1.1:
235;; o Fixed dots in the end of line comments causing indentation
236;; problems. The following code is now correctly indented (note
237;; the dot terminating the comment):
238;; a(X) :- b(X),
239;; c(X). % comment here.
240;; a(X).
241;; and so is this (and variants):
242;; a(X) :- b(X),
243;; c(X). /* comment here. */
244;; a(X).
245;; Version 1.0:
246;; o Revamped the menu system.
247;; o Yet another prompt recognition fix (SWI mode).
248;; o This is more of a renumbering than a new edition. I promoted
249;; the mode to version 1.0 to emphasize the fact that it is now
250;; mature and stable enough to be considered production (in my
251;; opinion anyway).
252;; Version 0.1.41:
253;; o GNU Emacs compatibility fixes.
254;; Version 0.1.40:
255;; o prolog-get-predspec is now suitable to be called as
256;; imenu-extract-index-name-function. The predicate index works.
257;; o Since imenu works now as advertised, prolog-imenu-flag is t
258;; by default.
259;; o Eliminated prolog-create-predicate-index since the imenu
260;; utilities now work well. Actually, this function is also
261;; buggy, and I see no reason to fix it since we do not need it
262;; anyway.
263;; o Fixed prolog-pred-start, prolog-clause-start, prolog-clause-info.
264;; o Fix for prolog-build-case-strings; now prolog-upper-case-string
265;; and prolog-lower-case-string are correctly initialized,
266;; o Various font-lock changes; most importantly, block comments (/*
267;; ... */) are now correctly fontified in XEmacs even when they
268;; extend on multiple lines.
269;; Version 0.1.36:
270;; o The debug prompt of SWI Prolog is now correctly recognized.
271;; Version 0.1.35:
272;; o Minor font-lock bug fixes.
29 273
274
30;;; Code: 275;;; Code:
31 276
32(defvar comint-prompt-regexp) 277(eval-when-compile
33(defvar comint-process-echoes) 278 (require 'compile)
34(require 'smie) 279 (require 'font-lock)
280 ;; We need imenu everywhere because of the predicate index!
281 (require 'imenu)
282 ;)
283 (require 'info)
284 (require 'shell)
285 )
286
287(require 'comint)
288(require 'easymenu)
289(require 'align)
290
35 291
36(defgroup prolog nil 292(defgroup prolog nil
37 "Major mode for editing and running Prolog under Emacs." 293 "Major modes for editing and running Prolog and Mercury files."
38 :link '(custom-group-link :tag "Font Lock Faces group" font-lock-faces)
39 :group 'languages) 294 :group 'languages)
40 295
296(defgroup prolog-faces nil
297 "Prolog mode specific faces."
298 :group 'font-lock)
41 299
42(defcustom prolog-program-name 300(defgroup prolog-indentation nil
43 (let ((names '("prolog" "gprolog" "swipl"))) 301 "Prolog mode indentation configuration."
44 (while (and names
45 (not (executable-find (car names))))
46 (setq names (cdr names)))
47 (or (car names) "prolog"))
48 "Program name for invoking an inferior Prolog with `run-prolog'."
49 :type 'string
50 :group 'prolog) 302 :group 'prolog)
51 303
52(defcustom prolog-consult-string "reconsult(user).\n" 304(defgroup prolog-font-lock nil
53 "(Re)Consult mode (for C-Prolog and Quintus Prolog). " 305 "Prolog mode font locking patterns."
54 :type 'string
55 :group 'prolog) 306 :group 'prolog)
56 307
57(defcustom prolog-compile-string "compile(user).\n" 308(defgroup prolog-keyboard nil
58 "Compile mode (for Quintus Prolog)." 309 "Prolog mode keyboard flags."
59 :type 'string
60 :group 'prolog) 310 :group 'prolog)
61 311
62(defcustom prolog-eof-string "end_of_file.\n" 312(defgroup prolog-inferior nil
63 "String that represents end of file for Prolog. 313 "Inferior Prolog mode options."
64When nil, send actual operating system end of file."
65 :type 'string
66 :group 'prolog) 314 :group 'prolog)
67 315
68(defcustom prolog-indent-width 4 316(defgroup prolog-other nil
69 "Level of indentation in Prolog buffers." 317 "Other Prolog mode options."
70 :type 'integer 318 :group 'prolog)
319
320
321;;-------------------------------------------------------------------
322;; User configurable variables
323;;-------------------------------------------------------------------
324
325;; General configuration
326
327(defcustom prolog-system nil
328 "*Prolog interpreter/compiler used.
329The value of this variable is nil or a symbol.
330If it is a symbol, it determines default values of other configuration
331variables with respect to properties of the specified Prolog
332interpreter/compiler.
333
334Currently recognized symbol values are:
335eclipse - Eclipse Prolog
336mercury - Mercury
337sicstus - SICStus Prolog
338swi - SWI Prolog
339gnu - GNU Prolog"
340 :group 'prolog
341 :type '(choice (const :tag "SICStus" :value sicstus)
342 (const :tag "SWI Prolog" :value swi)
343 (const :tag "Default" :value nil)))
344(make-variable-buffer-local 'prolog-system)
345
346;; NB: This alist can not be processed in prolog-mode-variables to
347;; create a prolog-system-version-i variable since it is needed
348;; prior to the call to prolog-mode-variables.
349(defcustom prolog-system-version
350 '((sicstus (3 . 6))
351 (swi (0 . 0))
352 (mercury (0 . 0))
353 (eclipse (3 . 7))
354 (gnu (0 . 0)))
355 "*Alist of Prolog system versions.
356The version numbers are of the format (Major . Minor)."
71 :group 'prolog) 357 :group 'prolog)
72 358
73(defvar prolog-font-lock-keywords 359;; Indentation
74 '(("\\(#[<=]=>\\|:-\\)\\|\\(#=\\)\\|\\(#[#<>\\/][=\\/]*\\|!\\)" 360
75 0 font-lock-keyword-face) 361(defcustom prolog-indent-width 4
76 ("\\<\\(is\\|write\\|nl\\|read_\\sw+\\)\\>" 362 "*The indentation width used by the editing buffer."
77 1 font-lock-keyword-face) 363 :group 'prolog-indentation
78 ("^\\(\\sw+\\)\\s-*\\((\\(.+\\))\\)*" 364 :type 'integer)
79 (1 font-lock-function-name-face) 365
80 (3 font-lock-variable-name-face))) 366(defcustom prolog-align-comments-flag t
81 "Font-lock keywords for Prolog mode.") 367 "*Non-nil means automatically align comments when indenting."
368 :group 'prolog-indentation
369 :type 'boolean)
370
371(defcustom prolog-indent-mline-comments-flag t
372 "*Non-nil means indent contents of /* */ comments.
373Otherwise leave such lines as they are."
374 :group 'prolog-indentation
375 :type 'boolean)
376
377(defcustom prolog-object-end-to-0-flag t
378 "*Non-nil means indent closing '}' in SICStus object definitions to level 0.
379Otherwise indent to `prolog-indent-width'."
380 :group 'prolog-indentation
381 :type 'boolean)
382
383(defcustom prolog-left-indent-regexp "\\(;\\|\\*?->\\)"
384 "*Regexp for character sequences after which next line is indented.
385Next line after such a regexp is indented to the opening paranthesis level."
386 :group 'prolog-indentation
387 :type 'regexp)
388
389(defcustom prolog-paren-indent-p nil
390 "*If non-nil, increase indentation for parenthesis expressions.
391The second and subsequent line in a parenthesis expression other than
392a compound term can either be indented `prolog-paren-indent' to the
393right (if this variable is non-nil) or in the same way as for compound
394terms (if this variable is nil, default)."
395 :group 'prolog-indentation
396 :type 'boolean)
397
398(defcustom prolog-paren-indent 4
399 "*The indentation increase for parenthesis expressions.
400Only used in ( If -> Then ; Else) and ( Disj1 ; Disj2 ) style expressions."
401 :group 'prolog-indentation
402 :type 'integer)
403
404(defcustom prolog-parse-mode 'beg-of-clause
405 "*The parse mode used (decides from which point parsing is done).
406Legal values:
407'beg-of-line - starts parsing at the beginning of a line, unless the
408 previous line ends with a backslash. Fast, but has
409 problems detecting multiline /* */ comments.
410'beg-of-clause - starts parsing at the beginning of the current clause.
411 Slow, but copes better with /* */ comments."
412 :group 'prolog-indentation
413 :type '(choice (const :value beg-of-line)
414 (const :value beg-of-clause)))
415
416;; Font locking
417
418(defcustom prolog-keywords
419 '((eclipse
420 ("use_module" "begin_module" "module_interface" "dynamic"
421 "external" "export" "dbgcomp" "nodbgcomp" "compile"))
422 (mercury
423 ("all" "else" "end_module" "equality" "external" "fail" "func" "if"
424 "implementation" "import_module" "include_module" "inst" "instance"
425 "interface" "mode" "module" "not" "pragma" "pred" "some" "then" "true"
426 "type" "typeclass" "use_module" "where"))
427 (sicstus
428 ("block" "dynamic" "mode" "module" "multifile" "meta_predicate"
429 "parallel" "public" "sequential" "volatile"))
430 (swi
431 ("discontiguous" "dynamic" "ensure_loaded" "export" "export_list" "import"
432 "meta_predicate" "module" "module_transparent" "multifile" "require"
433 "use_module" "volatile"))
434 (gnu
435 ("built_in" "char_conversion" "discontiguous" "dynamic" "ensure_linked"
436 "ensure_loaded" "foreign" "include" "initialization" "multifile" "op"
437 "public" "set_prolog_flag"))
438 (t
439 ("dynamic" "module")))
440 "*Alist of Prolog keywords which is used for font locking of directives."
441 :group 'prolog-font-lock
442 :type 'sexp)
443
444(defcustom prolog-types
445 '((mercury
446 ("char" "float" "int" "io__state" "string" "univ"))
447 (t nil))
448 "*Alist of Prolog types used by font locking."
449 :group 'prolog-font-lock
450 :type 'sexp)
451
452(defcustom prolog-mode-specificators
453 '((mercury
454 ("bound" "di" "free" "ground" "in" "mdi" "mui" "muo" "out" "ui" "uo"))
455 (t nil))
456 "*Alist of Prolog mode specificators used by font locking."
457 :group 'prolog-font-lock
458 :type 'sexp)
459
460(defcustom prolog-determinism-specificators
461 '((mercury
462 ("cc_multi" "cc_nondet" "det" "erroneous" "failure" "multi" "nondet"
463 "semidet"))
464 (t nil))
465 "*Alist of Prolog determinism specificators used by font locking."
466 :group 'prolog-font-lock
467 :type 'sexp)
468
469(defcustom prolog-directives
470 '((mercury
471 ("^#[0-9]+"))
472 (t nil))
473 "*Alist of Prolog source code directives used by font locking."
474 :group 'prolog-font-lock
475 :type 'sexp)
476
477
478;; Keyboard
479
480(defcustom prolog-electric-newline-flag (not (fboundp 'electric-indent-mode))
481 "*Non-nil means automatically indent the next line when the user types RET."
482 :group 'prolog-keyboard
483 :type 'boolean)
484
485(defcustom prolog-hungry-delete-key-flag nil
486 "*Non-nil means delete key consumes all preceding spaces."
487 :group 'prolog-keyboard
488 :type 'boolean)
489
490(defcustom prolog-electric-dot-flag nil
491 "*Non-nil means make dot key electric.
492Electric dot appends newline or inserts head of a new clause.
493If dot is pressed at the end of a line where at least one white space
494precedes the point, it inserts a recursive call to the current predicate.
495If dot is pressed at the beginning of an empty line, it inserts the head
496of a new clause for the current predicate. It does not apply in strings
497and comments.
498It does not apply in strings and comments."
499 :group 'prolog-keyboard
500 :type 'boolean)
501
502(defcustom prolog-electric-dot-full-predicate-template nil
503 "*If nil, electric dot inserts only the current predicate's name and `('
504for recursive calls or new clause heads. Non-nil means to also
505insert enough commata to cover the predicate's arity and `)',
506and dot and newline for recursive calls."
507 :group 'prolog-keyboard
508 :type 'boolean)
509
510(defcustom prolog-electric-underscore-flag nil
511 "*Non-nil means make underscore key electric.
512Electric underscore replaces the current variable with underscore.
513If underscore is pressed not on a variable then it behaves as usual."
514 :group 'prolog-keyboard
515 :type 'boolean)
516
517(defcustom prolog-electric-tab-flag nil
518 "*Non-nil means make TAB key electric.
519Electric TAB inserts spaces after parentheses, ->, and ;
520in ( If -> Then ; Else) and ( Disj1 ; Disj2 ) style expressions."
521 :group 'prolog-keyboard
522 :type 'boolean)
523
524(defcustom prolog-electric-if-then-else-flag nil
525 "*Non-nil makes `(', `>' and `;' electric
526to automatically indent if-then-else constructs."
527 :group 'prolog-keyboard
528 :type 'boolean)
529
530(defcustom prolog-electric-colon-flag nil
531 "*Makes `:' electric (inserts `:-' on a new line).
532If non-nil, pressing `:' at the end of a line that starts in
533the first column (i.e., clause heads) inserts ` :-' and newline."
534 :group 'prolog-keyboard
535 :type 'boolean)
536
537(defcustom prolog-electric-dash-flag nil
538 "*Makes `-' electric (inserts a `-->' on a new line).
539If non-nil, pressing `-' at the end of a line that starts in
540the first column (i.e., DCG heads) inserts ` -->' and newline."
541 :group 'prolog-keyboard
542 :type 'boolean)
543
544(defcustom prolog-old-sicstus-keys-flag nil
545 "*Non-nil means old SICStus Prolog mode keybindings are used."
546 :group 'prolog-keyboard
547 :type 'boolean)
548
549;; Inferior mode
550
551(defcustom prolog-program-name
552 `(((getenv "EPROLOG") (eval (getenv "EPROLOG")))
553 (eclipse "eclipse")
554 (mercury nil)
555 (sicstus "sicstus")
556 (swi ,(if (not (executable-find "swipl")) "pl" "swipl"))
557 (gnu "gprolog")
558 (t ,(let ((names '("prolog" "gprolog" "swipl" "pl")))
559 (while (and names
560 (not (executable-find (car names))))
561 (setq names (cdr names)))
562 (or (car names) "prolog"))))
563 "*Alist of program names for invoking an inferior Prolog with `run-prolog'."
564 :group 'prolog-inferior
565 :type 'sexp)
566
567(defcustom prolog-program-switches
568 '((sicstus ("-i"))
569 (t nil))
570 "*Alist of switches given to inferior Prolog run with `run-prolog'."
571 :group 'prolog-inferior
572 :type 'sexp)
573
574(defcustom prolog-consult-string
575 '((eclipse "[%f].")
576 (mercury nil)
577 (sicstus (eval (if (prolog-atleast-version '(3 . 7))
578 "prolog:zap_file(%m,%b,consult,%l)."
579 "prolog:zap_file(%m,%b,consult).")))
580 (swi "[%f].")
581 (gnu "[%f].")
582 (t "reconsult(%f)."))
583 "*Alist of strings defining predicate for reconsulting.
584
585Some parts of the string are replaced:
586`%f' by the name of the consulted file (can be a temporary file)
587`%b' by the file name of the buffer to consult
588`%m' by the module name and name of the consulted file separated by colon
589`%l' by the line offset into the file. This is 0 unless consulting a
590 region of a buffer, in which case it is the number of lines before
591 the region."
592 :group 'prolog-inferior
593 :type 'sexp)
594
595(defcustom prolog-compile-string
596 '((eclipse "[%f].")
597 (mercury "mmake ")
598 (sicstus (eval (if (prolog-atleast-version '(3 . 7))
599 "prolog:zap_file(%m,%b,compile,%l)."
600 "prolog:zap_file(%m,%b,compile).")))
601 (swi "[%f].")
602 (t "compile(%f)."))
603 "*Alist of strings and lists defining predicate for recompilation.
604
605Some parts of the string are replaced:
606`%f' by the name of the compiled file (can be a temporary file)
607`%b' by the file name of the buffer to compile
608`%m' by the module name and name of the compiled file separated by colon
609`%l' by the line offset into the file. This is 0 unless compiling a
610 region of a buffer, in which case it is the number of lines before
611 the region.
612
613If `prolog-program-name' is non-nil, it is a string sent to a Prolog process.
614If `prolog-program-name' is nil, it is an argument to the `compile' function."
615 :group 'prolog-inferior
616 :type 'sexp)
617
618(defcustom prolog-eof-string "end_of_file.\n"
619 "*Alist of strings that represent end of file for prolog.
620nil means send actual operating system end of file."
621 :group 'prolog-inferior
622 :type 'sexp)
623
624(defcustom prolog-prompt-regexp
625 '((eclipse "^[a-zA-Z0-9()]* *\\?- \\|^\\[[a-zA-Z]* [0-9]*\\]:")
626 (sicstus "| [ ?][- ] *")
627 (swi "^\\(\\[[a-zA-Z]*\\] \\)?[1-9]?[0-9]*[ ]?\\?- \\|^| +")
628 (t "^ *\\?-"))
629 "*Alist of prompts of the prolog system command line."
630 :group 'prolog-inferior
631 :type 'sexp)
632
633(defcustom prolog-continued-prompt-regexp
634 '((sicstus "^\\(| +\\| +\\)")
635 (t "^|: +"))
636 "*Alist of regexps matching the prompt when consulting `user'."
637 :group 'prolog-inferior
638 :type 'sexp)
639
640(defcustom prolog-debug-on-string "debug.\n"
641 "*Predicate for enabling debug mode."
642 :group 'prolog-inferior
643 :type 'string)
644
645(defcustom prolog-debug-off-string "nodebug.\n"
646 "*Predicate for disabling debug mode."
647 :group 'prolog-inferior
648 :type 'string)
649
650(defcustom prolog-trace-on-string "trace.\n"
651 "*Predicate for enabling tracing."
652 :group 'prolog-inferior
653 :type 'string)
654
655(defcustom prolog-trace-off-string "notrace.\n"
656 "*Predicate for disabling tracing."
657 :group 'prolog-inferior
658 :type 'string)
659
660(defcustom prolog-zip-on-string "zip.\n"
661 "*Predicate for enabling zip mode for SICStus."
662 :group 'prolog-inferior
663 :type 'string)
664
665(defcustom prolog-zip-off-string "nozip.\n"
666 "*Predicate for disabling zip mode for SICStus."
667 :group 'prolog-inferior
668 :type 'string)
669
670(defcustom prolog-use-standard-consult-compile-method-flag t
671 "*Non-nil means use the standard compilation method.
672Otherwise the new compilation method will be used. This
673utilises a special compilation buffer with the associated
674features such as parsing of error messages and automatically
675jumping to the source code responsible for the error.
676
677Warning: the new method is so far only experimental and
678does contain bugs. The recommended setting for the novice user
679is non-nil for this variable."
680 :group 'prolog-inferior
681 :type 'boolean)
682
683
684;; Miscellaneous
685
686(defcustom prolog-use-prolog-tokenizer-flag t
687 "*Non-nil means use the internal prolog tokenizer for indentation etc.
688Otherwise use `parse-partial-sexp' which is faster but sometimes incorrect."
689 :group 'prolog-other
690 :type 'boolean)
691
692(defcustom prolog-imenu-flag t
693 "*Non-nil means add a clause index menu for all prolog files."
694 :group 'prolog-other
695 :type 'boolean)
696
697(defcustom prolog-imenu-max-lines 3000
698 "*The maximum number of lines of the file for imenu to be enabled.
699Relevant only when `prolog-imenu-flag' is non-nil."
700 :group 'prolog-other
701 :type 'integer)
702
703(defcustom prolog-info-predicate-index
704 "(sicstus)Predicate Index"
705 "*The info node for the SICStus predicate index."
706 :group 'prolog-other
707 :type 'string)
708
709(defcustom prolog-underscore-wordchar-flag nil
710 "*Non-nil means underscore (_) is a word-constituent character."
711 :group 'prolog-other
712 :type 'boolean)
713
714(defcustom prolog-use-sicstus-sd nil
715 "*If non-nil, use the source level debugger of SICStus 3#7 and later."
716 :group 'prolog-other
717 :type 'boolean)
718
719(defcustom prolog-char-quote-workaround nil
720 ;; FIXME: Use syntax-propertize-function to fix it right.
721 "*If non-nil, declare 0 as a quote character so that 0'<char> does not break syntax highlighting.
722This is really kludgy but I have not found any better way of handling it."
723 :group 'prolog-other
724 :type 'boolean)
725
726
727;;-------------------------------------------------------------------
728;; Internal variables
729;;-------------------------------------------------------------------
730
731;;(defvar prolog-temp-filename "") ; Later set by `prolog-temporary-file'
82 732
83(defvar prolog-mode-syntax-table 733(defvar prolog-mode-syntax-table
84 (let ((table (make-syntax-table))) 734 (let ((table (make-syntax-table)))
85 (modify-syntax-entry ?_ "w" table) 735 (if prolog-underscore-wordchar-flag
86 (modify-syntax-entry ?\\ "\\" table) 736 (modify-syntax-entry ?_ "w" table)
87 (modify-syntax-entry ?/ ". 14" table) 737 (modify-syntax-entry ?_ "_" table))
88 (modify-syntax-entry ?* ". 23" table) 738
89 (modify-syntax-entry ?+ "." table) 739 (modify-syntax-entry ?+ "." table)
90 (modify-syntax-entry ?- "." table) 740 (modify-syntax-entry ?- "." table)
91 (modify-syntax-entry ?= "." table) 741 (modify-syntax-entry ?= "." table)
92 (modify-syntax-entry ?% "<" table)
93 (modify-syntax-entry ?\n ">" table)
94 (modify-syntax-entry ?< "." table) 742 (modify-syntax-entry ?< "." table)
95 (modify-syntax-entry ?> "." table) 743 (modify-syntax-entry ?> "." table)
744 (modify-syntax-entry ?| "." table)
96 (modify-syntax-entry ?\' "\"" table) 745 (modify-syntax-entry ?\' "\"" table)
97 table))
98 746
747 ;; Any better way to handle the 0'<char> construct?!?
748 (when prolog-char-quote-workaround
749 (modify-syntax-entry ?0 "\\" table))
750
751 (modify-syntax-entry ?% "<" table)
752 (modify-syntax-entry ?\n ">" table)
753 (if (featurep 'xemacs)
754 (progn
755 (modify-syntax-entry ?* ". 67" table)
756 (modify-syntax-entry ?/ ". 58" table)
757 )
758 ;; Emacs wants to see this it seems:
759 (modify-syntax-entry ?* ". 23b" table)
760 (modify-syntax-entry ?/ ". 14" table)
761 )
762 table))
99(defvar prolog-mode-abbrev-table nil) 763(defvar prolog-mode-abbrev-table nil)
764(defvar prolog-upper-case-string ""
765 "A string containing all upper case characters.
766Set by prolog-build-case-strings.")
767(defvar prolog-lower-case-string ""
768 "A string containing all lower case characters.
769Set by prolog-build-case-strings.")
770
771(defvar prolog-atom-char-regexp ""
772 "Set by prolog-set-atom-regexps.")
773;; "Regexp specifying characters which constitute atoms without quoting.")
774(defvar prolog-atom-regexp ""
775 "Set by prolog-set-atom-regexps.")
776
777(defconst prolog-left-paren "[[({]"
778 "The characters used as left parentheses for the indentation code.")
779(defconst prolog-right-paren "[])}]"
780 "The characters used as right parentheses for the indentation code.")
781
782(defconst prolog-quoted-atom-regexp
783 "\\(^\\|[^0-9]\\)\\('\\([^\n']\\|\\\\'\\)*'\\)"
784 "Regexp matching a quoted atom.")
785(defconst prolog-string-regexp
786 "\\(\"\\([^\n\"]\\|\\\\\"\\)*\"\\)"
787 "Regexp matching a string.")
788(defconst prolog-head-delimiter "\\(:-\\|\\+:\\|-:\\|\\+\\?\\|-\\?\\|-->\\)"
789 "A regexp for matching on the end delimiter of a head (e.g. \":-\").")
790
791(defvar prolog-compilation-buffer "*prolog-compilation*"
792 "Name of the output buffer for Prolog compilation/consulting.")
793
794(defvar prolog-temporary-file-name nil)
795(defvar prolog-keywords-i nil)
796(defvar prolog-types-i nil)
797(defvar prolog-mode-specificators-i nil)
798(defvar prolog-determinism-specificators-i nil)
799(defvar prolog-directives-i nil)
800(defvar prolog-program-name-i nil)
801(defvar prolog-program-switches-i nil)
802(defvar prolog-consult-string-i nil)
803(defvar prolog-compile-string-i nil)
804(defvar prolog-eof-string-i nil)
805(defvar prolog-prompt-regexp-i nil)
806(defvar prolog-continued-prompt-regexp-i nil)
807(defvar prolog-help-function-i nil)
808
809(defvar prolog-align-rules
810 (eval-when-compile
811 (mapcar
812 (lambda (x)
813 (let ((name (car x))
814 (sym (cdr x)))
815 `(,(intern (format "prolog-%s" name))
816 (regexp . ,(format "\\(\\s-*\\)%s\\(\\s-*\\)" sym))
817 (tab-stop . nil)
818 (modes . '(prolog-mode))
819 (group . (1 2)))))
820 '(("dcg" . "-->") ("rule" . ":-") ("simplification" . "<=>")
821 ("propagation" . "==>")))))
822
823
824
825;;-------------------------------------------------------------------
826;; Prolog mode
827;;-------------------------------------------------------------------
828
829;; Example: (prolog-atleast-version '(3 . 6))
830(defun prolog-atleast-version (version)
831 "Return t if the version of the current prolog system is VERSION or later.
832VERSION is of the format (Major . Minor)"
833 ;; Version.major < major or
834 ;; Version.major = major and Version.minor <= minor
835 (let* ((thisversion (prolog-find-value-by-system prolog-system-version))
836 (thismajor (car thisversion))
837 (thisminor (cdr thisversion)))
838 (or (< (car version) thismajor)
839 (and (= (car version) thismajor)
840 (<= (cdr version) thisminor)))
841 ))
842
100(define-abbrev-table 'prolog-mode-abbrev-table ()) 843(define-abbrev-table 'prolog-mode-abbrev-table ())
101 844
102(defun prolog-smie-forward-token () 845(defun prolog-find-value-by-system (alist)
103 (forward-comment (point-max)) 846 "Get value from ALIST according to `prolog-system'."
104 (buffer-substring-no-properties 847 (if (listp alist)
105 (point) 848 (let (result
106 (progn (cond 849 id)
107 ((looking-at "[!;]") (forward-char 1)) 850 (while alist
108 ((not (zerop (skip-chars-forward "#&*+-./:<=>?@\\^`~")))) 851 (setq id (car (car alist)))
109 ((not (zerop (skip-syntax-forward "w_'")))) 852 (if (or (eq id prolog-system)
110 ;; In case of non-ASCII punctuation. 853 (eq id t)
111 ((not (zerop (skip-syntax-forward "."))))) 854 (and (listp id)
112 (point)))) 855 (eval id)))
113 856 (progn
114(defun prolog-smie-backward-token () 857 (setq result (car (cdr (car alist))))
115 (forward-comment (- (point-max))) 858 (if (and (listp result)
116 (buffer-substring-no-properties 859 (eq (car result) 'eval))
117 (point) 860 (setq result (eval (car (cdr result)))))
118 (progn (cond 861 (setq alist nil))
119 ((memq (char-before) '(?! ?\;)) (forward-char -1)) 862 (setq alist (cdr alist))))
120 ((not (zerop (skip-chars-backward "#&*+-./:<=>?@\\^`~")))) 863 result)
121 ((not (zerop (skip-syntax-backward "w_'")))) 864 alist))
122 ;; In case of non-ASCII punctuation.
123 ((not (zerop (skip-syntax-backward ".")))))
124 (point))))
125
126(defconst prolog-smie-grammar
127 ;; Rather than construct the operator levels table from the BNF,
128 ;; we directly provide the operator precedences from GNU Prolog's
129 ;; manual (7.14.10 op/3). The only problem is that GNU Prolog's
130 ;; manual uses precedence levels in the opposite sense (higher
131 ;; numbers bind less tightly) than SMIE, so we use negative numbers.
132 '(("." -10000 -10000)
133 (":-" -1200 -1200)
134 ("-->" -1200 -1200)
135 (";" -1100 -1100)
136 ("->" -1050 -1050)
137 ("," -1000 -1000)
138 ("\\+" -900 -900)
139 ("=" -700 -700)
140 ("\\=" -700 -700)
141 ("=.." -700 -700)
142 ("==" -700 -700)
143 ("\\==" -700 -700)
144 ("@<" -700 -700)
145 ("@=<" -700 -700)
146 ("@>" -700 -700)
147 ("@>=" -700 -700)
148 ("is" -700 -700)
149 ("=:=" -700 -700)
150 ("=\\=" -700 -700)
151 ("<" -700 -700)
152 ("=<" -700 -700)
153 (">" -700 -700)
154 (">=" -700 -700)
155 (":" -600 -600)
156 ("+" -500 -500)
157 ("-" -500 -500)
158 ("/\\" -500 -500)
159 ("\\/" -500 -500)
160 ("*" -400 -400)
161 ("/" -400 -400)
162 ("//" -400 -400)
163 ("rem" -400 -400)
164 ("mod" -400 -400)
165 ("<<" -400 -400)
166 (">>" -400 -400)
167 ("**" -200 -200)
168 ("^" -200 -200)
169 ;; Prefix
170 ;; ("+" 200 200)
171 ;; ("-" 200 200)
172 ;; ("\\" 200 200)
173 )
174 "Precedence levels of infix operators.")
175
176(defun prolog-smie-rules (kind token)
177 (pcase (cons kind token)
178 (`(:elem . basic) prolog-indent-width)
179 (`(:after . ".") 0) ;; To work around smie-closer-alist.
180 (`(:after . ,(or `":-" `"->")) prolog-indent-width)))
181 865
182(defun prolog-mode-variables () 866(defun prolog-mode-variables ()
183 (set (make-local-variable 'paragraph-separate) (concat "%%\\|$\\|" page-delimiter)) ;'%%..' 867 "Set some common variables to Prolog code specific values."
184 (set (make-local-variable 'paragraph-ignore-fill-prefix) t) 868 (setq local-abbrev-table prolog-mode-abbrev-table)
185 (set (make-local-variable 'imenu-generic-expression) '((nil "^\\sw+" 0))) 869 (make-local-variable 'paragraph-start)
186 870 (setq paragraph-start (concat "[ \t]*$\\|" page-delimiter)) ;'%%..'
187 ;; Setup SMIE. 871 (make-local-variable 'paragraph-separate)
188 (smie-setup prolog-smie-grammar #'prolog-smie-rules 872 (setq paragraph-separate paragraph-start)
189 :forward-token #'prolog-smie-forward-token 873 (make-local-variable 'paragraph-ignore-fill-prefix)
190 :backward-token #'prolog-smie-backward-token) 874 (setq paragraph-ignore-fill-prefix t)
191 (set (make-local-variable 'smie-blink-matching-triggers) '(?.)) 875 (make-local-variable 'normal-auto-fill-function)
192 (set (make-local-variable 'smie-closer-alist) '((t . "."))) 876 (setq normal-auto-fill-function 'prolog-do-auto-fill)
193 (add-hook 'post-self-insert-hook #'smie-blink-matching-open 'append 'local) 877 (make-local-variable 'indent-line-function)
194 ;; There's no real closer in Prolog anyway. 878 (setq indent-line-function 'prolog-indent-line)
195 (set (make-local-variable 'smie-blink-matching-inners) t) 879 (make-local-variable 'comment-start)
196 880 (setq comment-start "%")
197 (set (make-local-variable 'comment-start) "%") 881 (make-local-variable 'comment-end)
198 (set (make-local-variable 'comment-start-skip) "\\(?:%+\\|/\\*+\\)[ \t]*") 882 (setq comment-end "")
199 (set (make-local-variable 'comment-end-skip) "[ \t]*\\(\n\\|\\*+/\\)") 883 (make-local-variable 'comment-start-skip)
200 (set (make-local-variable 'comment-column) 48)) 884 ;; This complex regexp makes sure that comments cannot start
885 ;; inside quoted atoms or strings
886 (setq comment-start-skip
887 (format "^\\(\\(%s\\|%s\\|[^\n\'\"%%]\\)*\\)\\(/\\*+ *\\|%%+ *\\)"
888 prolog-quoted-atom-regexp prolog-string-regexp))
889 (make-local-variable 'comment-column)
890 (make-local-variable 'comment-indent-function)
891 (setq comment-indent-function 'prolog-comment-indent)
892 (make-local-variable 'parens-require-spaces)
893 (setq parens-require-spaces nil)
894 ;; Initialize Prolog system specific variables
895 (let ((vars '(prolog-keywords prolog-types prolog-mode-specificators
896 prolog-determinism-specificators prolog-directives
897 prolog-program-name prolog-program-switches
898 prolog-consult-string prolog-compile-string prolog-eof-string
899 prolog-prompt-regexp prolog-continued-prompt-regexp
900 prolog-help-function)))
901 (while vars
902 (set (intern (concat (symbol-name (car vars)) "-i"))
903 (prolog-find-value-by-system (symbol-value (car vars))))
904 (setq vars (cdr vars))))
905 (when (null prolog-program-name-i)
906 (make-local-variable 'compile-command)
907 (setq compile-command prolog-compile-string-i))
908 (make-local-variable 'font-lock-defaults)
909 (setq font-lock-defaults
910 '(prolog-font-lock-keywords nil nil ((?_ . "w"))))
911)
912
913(defun prolog-mode-keybindings-common (map)
914 "Define keybindings common to both Prolog modes in MAP."
915 (define-key map "\C-c?" 'prolog-help-on-predicate)
916 (define-key map "\C-c/" 'prolog-help-apropos)
917 (define-key map "\C-c\C-d" 'prolog-debug-on)
918 (define-key map "\C-c\C-t" 'prolog-trace-on)
919 (if (and (eq prolog-system 'sicstus)
920 (prolog-atleast-version '(3 . 7)))
921 (define-key map "\C-c\C-z" 'prolog-zip-on))
922 (define-key map "\C-c\r" 'run-prolog))
923
924(defun prolog-mode-keybindings-edit (map)
925 "Define keybindings for Prolog mode in MAP."
926 (define-key map "\M-a" 'prolog-beginning-of-clause)
927 (define-key map "\M-e" 'prolog-end-of-clause)
928 (define-key map "\M-q" 'prolog-fill-paragraph)
929 (define-key map "\C-c\C-a" 'align)
930 (define-key map "\C-\M-a" 'prolog-beginning-of-predicate)
931 (define-key map "\C-\M-e" 'prolog-end-of-predicate)
932 (define-key map "\M-\C-c" 'prolog-mark-clause)
933 (define-key map "\M-\C-h" 'prolog-mark-predicate)
934 (define-key map "\M-\C-n" 'prolog-forward-list)
935 (define-key map "\M-\C-p" 'prolog-backward-list)
936 (define-key map "\C-c\C-n" 'prolog-insert-predicate-template)
937 (define-key map "\C-c\C-s" 'prolog-insert-predspec)
938 (define-key map "\M-\r" 'prolog-insert-next-clause)
939 (define-key map "\C-c\C-va" 'prolog-variables-to-anonymous)
940 (define-key map "\C-c\C-v\C-s" 'prolog-view-predspec)
941
942 (define-key map [Backspace] 'prolog-electric-delete)
943 (define-key map "." 'prolog-electric-dot)
944 (define-key map "_" 'prolog-electric-underscore)
945 (define-key map "(" 'prolog-electric-if-then-else)
946 (define-key map ";" 'prolog-electric-if-then-else)
947 (define-key map ">" 'prolog-electric-if-then-else)
948 (define-key map ":" 'prolog-electric-colon)
949 (define-key map "-" 'prolog-electric-dash)
950 (if prolog-electric-newline-flag
951 (define-key map "\r" 'newline-and-indent))
952
953 ;; If we're running SICStus, then map C-c C-c e/d to enabling
954 ;; and disabling of the source-level debugging facilities.
955 ;(if (and (eq prolog-system 'sicstus)
956 ; (prolog-atleast-version '(3 . 7)))
957 ; (progn
958 ; (define-key map "\C-c\C-ce" 'prolog-enable-sicstus-sd)
959 ; (define-key map "\C-c\C-cd" 'prolog-disable-sicstus-sd)
960 ; ))
961
962 (if prolog-old-sicstus-keys-flag
963 (progn
964 (define-key map "\C-c\C-c" 'prolog-consult-predicate)
965 (define-key map "\C-cc" 'prolog-consult-region)
966 (define-key map "\C-cC" 'prolog-consult-buffer)
967 (define-key map "\C-c\C-k" 'prolog-compile-predicate)
968 (define-key map "\C-ck" 'prolog-compile-region)
969 (define-key map "\C-cK" 'prolog-compile-buffer))
970 (define-key map "\C-c\C-p" 'prolog-consult-predicate)
971 (define-key map "\C-c\C-r" 'prolog-consult-region)
972 (define-key map "\C-c\C-b" 'prolog-consult-buffer)
973 (define-key map "\C-c\C-f" 'prolog-consult-file)
974 (define-key map "\C-c\C-cp" 'prolog-compile-predicate)
975 (define-key map "\C-c\C-cr" 'prolog-compile-region)
976 (define-key map "\C-c\C-cb" 'prolog-compile-buffer)
977 (define-key map "\C-c\C-cf" 'prolog-compile-file))
978
979 ;; Inherited from the old prolog.el.
980 (define-key map "\e\C-x" 'prolog-consult-region)
981 (define-key map "\C-c\C-l" 'prolog-consult-file)
982 (define-key map "\C-c\C-z" 'switch-to-prolog))
983
984(defun prolog-mode-keybindings-inferior (map)
985 "Define keybindings for inferior Prolog mode in MAP."
986 ;; No inferior mode specific keybindings now.
987 )
201 988
202(defvar prolog-mode-map 989(defvar prolog-mode-map
203 (let ((map (make-sparse-keymap))) 990 (let ((map (make-sparse-keymap)))
204 (define-key map "\e\C-x" 'prolog-consult-region) 991 (prolog-mode-keybindings-common map)
205 (define-key map "\C-c\C-l" 'inferior-prolog-load-file) 992 (prolog-mode-keybindings-edit map)
206 (define-key map "\C-c\C-z" 'switch-to-prolog)
207 map)) 993 map))
994
208 995
209(easy-menu-define prolog-mode-menu prolog-mode-map "Menu for Prolog mode." 996(defvar prolog-mode-hook nil
210 ;; Mostly copied from scheme-mode's menu. 997 "List of functions to call after the prolog mode has initialised.")
211 ;; Not tremendously useful, but it's a start.
212 '("Prolog"
213 ["Indent line" indent-according-to-mode t]
214 ["Indent region" indent-region t]
215 ["Comment region" comment-region t]
216 ["Uncomment region" uncomment-region t]
217 "--"
218 ["Run interactive Prolog session" run-prolog t]
219 ))
220 998
999(unless (fboundp 'prog-mode)
1000 (defalias 'prog-mode 'fundamental-mode))
221;;;###autoload 1001;;;###autoload
222(define-derived-mode prolog-mode prog-mode "Prolog" 1002(define-derived-mode prolog-mode prog-mode "Prolog"
223 "Major mode for editing Prolog code for Prologs. 1003 "Major mode for editing Prolog code.
224Blank lines and `%%...' separate paragraphs. `%'s start comments. 1004
1005Blank lines and `%%...' separate paragraphs. `%'s starts a comment
1006line and comments can also be enclosed in /* ... */.
1007
1008If an optional argument SYSTEM is non-nil, set up mode for the given system.
1009
1010To find out what version of Prolog mode you are running, enter
1011`\\[prolog-mode-version]'.
1012
225Commands: 1013Commands:
226\\{prolog-mode-map} 1014\\{prolog-mode-map}
227Entry to this mode calls the value of `prolog-mode-hook' 1015Entry to this mode calls the value of `prolog-mode-hook'
228if that value is non-nil." 1016if that value is non-nil."
1017 (setq mode-name (concat "Prolog"
1018 (cond
1019 ((eq prolog-system 'eclipse) "[ECLiPSe]")
1020 ((eq prolog-system 'sicstus) "[SICStus]")
1021 ((eq prolog-system 'swi) "[SWI]")
1022 ((eq prolog-system 'gnu) "[GNU]")
1023 (t ""))))
229 (prolog-mode-variables) 1024 (prolog-mode-variables)
230 (set (make-local-variable 'comment-add) 1) 1025 (prolog-build-case-strings)
231 (setq font-lock-defaults '(prolog-font-lock-keywords 1026 (prolog-set-atom-regexps)
232 nil nil nil 1027 (dolist (ar prolog-align-rules) (add-to-list 'align-rules-list ar))
233 beginning-of-line))) 1028
234 1029 ;; imenu entry moved to the appropriate hook for consistency
235(defun end-of-prolog-clause () 1030
236 "Go to end of clause in this line." 1031 ;; Load SICStus debugger if suitable
237 (beginning-of-line 1) 1032 (if (and (eq prolog-system 'sicstus)
238 (let* ((eolpos (line-end-position))) 1033 (prolog-atleast-version '(3 . 7))
239 (if (re-search-forward comment-start-skip eolpos 'move) 1034 prolog-use-sicstus-sd)
240 (goto-char (match-beginning 0))) 1035 (prolog-enable-sicstus-sd)))
241 (skip-chars-backward " \t"))) 1036
242 1037(defvar mercury-mode-map
243;;;
244;;; Inferior prolog mode
245;;;
246(defvar inferior-prolog-mode-map
247 (let ((map (make-sparse-keymap))) 1038 (let ((map (make-sparse-keymap)))
248 ;; This map will inherit from `comint-mode-map' when entering 1039 (set-keymap-parent map prolog-mode-map)
249 ;; inferior-prolog-mode.
250 (define-key map [remap self-insert-command]
251 'inferior-prolog-self-insert-command)
252 map)) 1040 map))
253 1041
254(defvar inferior-prolog-mode-syntax-table prolog-mode-syntax-table) 1042;;;###autoload
255(defvar inferior-prolog-mode-abbrev-table prolog-mode-abbrev-table) 1043(define-derived-mode mercury-mode prolog-mode "Prolog[Mercury]"
1044 "Major mode for editing Mercury programs.
1045Actually this is just customized `prolog-mode'."
1046 (set (make-local-variable 'prolog-system) 'mercury))
256 1047
257(defvar inferior-prolog-error-regexp-alist 1048
258 ;; GNU Prolog used to not follow the GNU standard format. 1049;;-------------------------------------------------------------------
259 '(("^\\(.*?\\):\\([0-9]+\\) error: .*(char:\\([0-9]+\\)" 1 2 3) 1050;; Inferior prolog mode
260 gnu)) 1051;;-------------------------------------------------------------------
261 1052
262(declare-function comint-mode "comint") 1053(defvar prolog-inferior-mode-map
263(declare-function comint-send-string "comint" (process string)) 1054 (let ((map (make-sparse-keymap)))
264(declare-function comint-send-region "comint" (process start end)) 1055 (prolog-mode-keybindings-common map)
265(declare-function comint-send-eof "comint" ()) 1056 (prolog-mode-keybindings-inferior map)
266(defvar compilation-error-regexp-alist) 1057 map))
1058
1059(defvar prolog-inferior-mode-hook nil
1060 "List of functions to call after the inferior prolog mode has initialised.")
267 1061
268(define-derived-mode inferior-prolog-mode comint-mode "Inferior Prolog" 1062(define-derived-mode prolog-inferior-mode comint-mode "Inferior Prolog"
269 "Major mode for interacting with an inferior Prolog process. 1063 "Major mode for interacting with an inferior Prolog process.
270 1064
271The following commands are available: 1065The following commands are available:
272\\{inferior-prolog-mode-map} 1066\\{prolog-inferior-mode-map}
273 1067
274Entry to this mode calls the value of `prolog-mode-hook' with no arguments, 1068Entry to this mode calls the value of `prolog-mode-hook' with no arguments,
275if that value is non-nil. Likewise with the value of `comint-mode-hook'. 1069if that value is non-nil. Likewise with the value of `comint-mode-hook'.
276`prolog-mode-hook' is called after `comint-mode-hook'. 1070`prolog-mode-hook' is called after `comint-mode-hook'.
277 1071
278You can send text to the inferior Prolog from other buffers using the commands 1072You can send text to the inferior Prolog from other buffers
279`process-send-region', `process-send-string' and \\[prolog-consult-region]. 1073using the commands `send-region', `send-string' and \\[prolog-consult-region].
280 1074
281Commands: 1075Commands:
282Tab indents for Prolog; with argument, shifts rest 1076Tab indents for Prolog; with argument, shifts rest
283 of expression rigidly with the current line. 1077 of expression rigidly with the current line.
284Paragraphs are separated only by blank lines and '%%'. 1078Paragraphs are separated only by blank lines and '%%'. '%'s start comments.
285'%'s start comments.
286 1079
287Return at end of buffer sends line as input. 1080Return at end of buffer sends line as input.
288Return not at end copies rest of line to end and sends it. 1081Return not at end copies rest of line to end and sends it.
289\\[comint-kill-input] and \\[backward-kill-word] are kill commands, imitating normal Unix input editing. 1082\\[comint-delchar-or-maybe-eof] sends end-of-file as input.
1083\\[comint-kill-input] and \\[backward-kill-word] are kill commands,
1084imitating normal Unix input editing.
290\\[comint-interrupt-subjob] interrupts the shell or its current subjob if any. 1085\\[comint-interrupt-subjob] interrupts the shell or its current subjob if any.
291\\[comint-stop-subjob] stops. \\[comint-quit-subjob] sends quit signal." 1086\\[comint-stop-subjob] stops, likewise.
292 (setq comint-prompt-regexp "^| [ ?][- ] *") 1087\\[comint-quit-subjob] sends quit signal, likewise.
293 (set (make-local-variable 'compilation-error-regexp-alist) 1088
294 inferior-prolog-error-regexp-alist) 1089To find out what version of Prolog mode you are running, enter
295 (compilation-shell-minor-mode) 1090`\\[prolog-mode-version]'."
296 (prolog-mode-variables)) 1091 (setq comint-input-filter 'prolog-input-filter)
297 1092 (setq mode-line-process '(": %s"))
298(defvar inferior-prolog-buffer nil) 1093 (prolog-mode-variables)
299 1094 (setq comint-prompt-regexp prolog-prompt-regexp-i)
300(defvar inferior-prolog-flavor 'unknown 1095 (set (make-local-variable 'shell-dirstack-query) "pwd."))
301 "Either a symbol or a buffer position offset by one. 1096
302If a buffer position, the flavor has not been determined yet and 1097(defun prolog-input-filter (str)
303it is expected that the process's output has been or will 1098 (cond ((string-match "\\`\\s *\\'" str) nil) ;whitespace
304be inserted at that position plus one.") 1099 ((not (eq major-mode 'prolog-inferior-mode)) t)
305 1100 ((= (length str) 1) nil) ;one character
306(defun inferior-prolog-run (&optional name) 1101 ((string-match "\\`[rf] *[0-9]*\\'" str) nil) ;r(edo) or f(ail)
307 (with-current-buffer (make-comint "prolog" (or name prolog-program-name)) 1102 (t t)))
308 (inferior-prolog-mode)
309 (setq-default inferior-prolog-buffer (current-buffer))
310 (make-local-variable 'inferior-prolog-buffer)
311 (when (and name (not (equal name prolog-program-name)))
312 (set (make-local-variable 'prolog-program-name) name))
313 (set (make-local-variable 'inferior-prolog-flavor)
314 ;; Force re-detection.
315 (let* ((proc (get-buffer-process (current-buffer)))
316 (pmark (and proc (marker-position (process-mark proc)))))
317 (cond
318 ((null pmark) (1- (point-min)))
319 ;; The use of insert-before-markers in comint.el together with
320 ;; the potential use of comint-truncate-buffer in the output
321 ;; filter, means that it's difficult to reliably keep track of
322 ;; the buffer position where the process's output started.
323 ;; If possible we use a marker at "start - 1", so that
324 ;; insert-before-marker at `start' won't shift it. And if not,
325 ;; we fall back on using a plain integer.
326 ((> pmark (point-min)) (copy-marker (1- pmark)))
327 (t (1- pmark)))))
328 (add-hook 'comint-output-filter-functions
329 'inferior-prolog-guess-flavor nil t)))
330
331(defun inferior-prolog-process (&optional dontstart)
332 (or (and (buffer-live-p inferior-prolog-buffer)
333 (get-buffer-process inferior-prolog-buffer))
334 (unless dontstart
335 (inferior-prolog-run)
336 ;; Try again.
337 (inferior-prolog-process))))
338
339(defun inferior-prolog-guess-flavor (&optional ignored)
340 (save-excursion
341 (goto-char (1+ inferior-prolog-flavor))
342 (setq inferior-prolog-flavor
343 (cond
344 ((looking-at "GNU Prolog") 'gnu)
345 ((looking-at "Welcome to SWI-Prolog") 'swi)
346 ((looking-at ".*\n") 'unknown) ;There's at least one line.
347 (t inferior-prolog-flavor))))
348 (when (symbolp inferior-prolog-flavor)
349 (remove-hook 'comint-output-filter-functions
350 'inferior-prolog-guess-flavor t)
351 (if (eq inferior-prolog-flavor 'gnu)
352 (set (make-local-variable 'comint-process-echoes) t))))
353 1103
354;;;###autoload 1104;;;###autoload
355(defalias 'run-prolog 'switch-to-prolog) 1105(defun run-prolog (arg)
356;;;###autoload
357(defun switch-to-prolog (&optional name)
358 "Run an inferior Prolog process, input and output via buffer *prolog*. 1106 "Run an inferior Prolog process, input and output via buffer *prolog*.
359With prefix argument \\[universal-prefix], prompt for the program to use." 1107With prefix argument ARG, restart the Prolog process if running before."
360 (interactive 1108 (interactive "P")
361 (list (when current-prefix-arg 1109 (if (and arg (get-process "prolog"))
362 (let ((proc (inferior-prolog-process 'dontstart))) 1110 (progn
363 (if proc 1111 (process-send-string "prolog" "halt.\n")
364 (if (yes-or-no-p "Kill current process before starting new one? ") 1112 (while (get-process "prolog") (sit-for 0.1))))
365 (kill-process proc) 1113 (let ((buff (buffer-name)))
366 (error "Abort"))) 1114 (if (not (string= buff "*prolog*"))
367 (read-string "Run Prolog: " prolog-program-name))))) 1115 (prolog-goto-prolog-process-buffer))
368 (unless (inferior-prolog-process 'dontstart) 1116 ;; Load SICStus debugger if suitable
369 (inferior-prolog-run name)) 1117 (if (and (eq prolog-system 'sicstus)
370 (pop-to-buffer inferior-prolog-buffer)) 1118 (prolog-atleast-version '(3 . 7))
371 1119 prolog-use-sicstus-sd)
372(defun inferior-prolog-self-insert-command () 1120 (prolog-enable-sicstus-sd))
373 "Insert the char in the buffer or pass it directly to the process." 1121 (prolog-mode-variables)
374 (interactive) 1122 (prolog-ensure-process)
375 (let* ((proc (get-buffer-process (current-buffer))) 1123 ))
376 (pmark (and proc (marker-position (process-mark proc))))) 1124
377 (if (and (eq inferior-prolog-flavor 'gnu) 1125(defun prolog-ensure-process (&optional wait)
378 pmark 1126 "If Prolog process is not running, run it.
379 (null current-prefix-arg) 1127If the optional argument WAIT is non-nil, wait for Prolog prompt specified by
380 (eobp) 1128the variable `prolog-prompt-regexp'."
381 (eq (point) pmark) 1129 (if (null prolog-program-name-i)
1130 (error "This Prolog system has defined no interpreter."))
1131 (if (comint-check-proc "*prolog*")
1132 ()
1133 (apply 'make-comint "prolog" prolog-program-name-i nil
1134 prolog-program-switches-i)
1135 (with-current-buffer "*prolog*"
1136 (prolog-inferior-mode)
1137 (if wait
1138 (progn
1139 (goto-char (point-max))
1140 (while
1141 (save-excursion
1142 (not
1143 (re-search-backward
1144 (concat "\\(" prolog-prompt-regexp-i "\\)" "\\=")
1145 nil t)))
1146 (sit-for 0.1)))))))
1147
1148(defun prolog-process-insert-string (process string)
1149 "Insert STRING into inferior Prolog buffer running PROCESS."
1150 ;; Copied from elisp manual, greek to me
1151 (with-current-buffer (process-buffer process)
1152 ;; FIXME: Use window-point-insertion-type instead.
1153 (let ((moving (= (point) (process-mark process))))
1154 (save-excursion
1155 ;; Insert the text, moving the process-marker.
1156 (goto-char (process-mark process))
1157 (insert string)
1158 (set-marker (process-mark process) (point)))
1159 (if moving (goto-char (process-mark process))))))
1160
1161;;------------------------------------------------------------
1162;; Old consulting and compiling functions
1163;;------------------------------------------------------------
1164
1165(defun prolog-old-process-region (compilep start end)
1166 "Process the region limited by START and END positions.
1167If COMPILEP is non-nil then use compilation, otherwise consulting."
1168 (prolog-ensure-process)
1169 ;(let ((tmpfile prolog-temp-filename)
1170 (let ((tmpfile (prolog-bsts (prolog-temporary-file)))
1171 ;(process (get-process "prolog"))
1172 (first-line (1+ (count-lines
1173 (point-min)
1174 (save-excursion
1175 (goto-char start)
1176 (point))))))
1177 (write-region start end tmpfile)
1178 (process-send-string
1179 "prolog" (prolog-build-prolog-command
1180 compilep tmpfile (prolog-bsts buffer-file-name)
1181 first-line))
1182 (prolog-goto-prolog-process-buffer)))
1183
1184(defun prolog-old-process-predicate (compilep)
1185 "Process the predicate around point.
1186If COMPILEP is non-nil then use compilation, otherwise consulting."
1187 (prolog-old-process-region
1188 compilep (prolog-pred-start) (prolog-pred-end)))
1189
1190(defun prolog-old-process-buffer (compilep)
1191 "Process the entire buffer.
1192If COMPILEP is non-nil then use compilation, otherwise consulting."
1193 (prolog-old-process-region compilep (point-min) (point-max)))
1194
1195(defun prolog-old-process-file (compilep)
1196 "Process the file of the current buffer.
1197If COMPILEP is non-nil then use compilation, otherwise consulting."
1198 (save-some-buffers)
1199 (prolog-ensure-process)
1200 (let ((filename (prolog-bsts buffer-file-name)))
1201 (process-send-string
1202 "prolog" (prolog-build-prolog-command
1203 compilep filename filename))
1204 (prolog-goto-prolog-process-buffer)))
1205
1206
1207;;------------------------------------------------------------
1208;; Consulting and compiling
1209;;------------------------------------------------------------
1210
1211;;; Interactive interface functions, used by both the standard
1212;;; and the experimental consultation and compilation functions
1213(defun prolog-consult-file ()
1214 "Consult file of current buffer."
1215 (interactive)
1216 (if prolog-use-standard-consult-compile-method-flag
1217 (prolog-old-process-file nil)
1218 (prolog-consult-compile-file nil)))
1219
1220(defun prolog-consult-buffer ()
1221 "Consult buffer."
1222 (interactive)
1223 (if prolog-use-standard-consult-compile-method-flag
1224 (prolog-old-process-buffer nil)
1225 (prolog-consult-compile-buffer nil)))
1226
1227(defun prolog-consult-region (beg end)
1228 "Consult region between BEG and END."
1229 (interactive "r")
1230 (if prolog-use-standard-consult-compile-method-flag
1231 (prolog-old-process-region nil beg end)
1232 (prolog-consult-compile-region nil beg end)))
1233
1234(defun prolog-consult-predicate ()
1235 "Consult the predicate around current point."
1236 (interactive)
1237 (if prolog-use-standard-consult-compile-method-flag
1238 (prolog-old-process-predicate nil)
1239 (prolog-consult-compile-predicate nil)))
1240
1241(defun prolog-compile-file ()
1242 "Compile file of current buffer."
1243 (interactive)
1244 (if prolog-use-standard-consult-compile-method-flag
1245 (prolog-old-process-file t)
1246 (prolog-consult-compile-file t)))
1247
1248(defun prolog-compile-buffer ()
1249 "Compile buffer."
1250 (interactive)
1251 (if prolog-use-standard-consult-compile-method-flag
1252 (prolog-old-process-buffer t)
1253 (prolog-consult-compile-buffer t)))
1254
1255(defun prolog-compile-region (beg end)
1256 "Compile region between BEG and END."
1257 (interactive "r")
1258 (if prolog-use-standard-consult-compile-method-flag
1259 (prolog-old-process-region t beg end)
1260 (prolog-consult-compile-region t beg end)))
1261
1262(defun prolog-compile-predicate ()
1263 "Compile the predicate around current point."
1264 (interactive)
1265 (if prolog-use-standard-consult-compile-method-flag
1266 (prolog-old-process-predicate t)
1267 (prolog-consult-compile-predicate t)))
1268
1269(defun prolog-buffer-module ()
1270 "Select Prolog module name appropriate for current buffer.
1271Bases decision on buffer contents (-*- line)."
1272 ;; Look for -*- ... module: MODULENAME; ... -*-
1273 (let (beg end)
1274 (save-excursion
1275 (goto-char (point-min))
1276 (skip-chars-forward " \t")
1277 (and (search-forward "-*-" (save-excursion (end-of-line) (point)) t)
1278 (progn
1279 (skip-chars-forward " \t")
1280 (setq beg (point))
1281 (search-forward "-*-" (save-excursion (end-of-line) (point)) t))
1282 (progn
1283 (forward-char -3)
1284 (skip-chars-backward " \t")
1285 (setq end (point))
1286 (goto-char beg)
1287 (and (let ((case-fold-search t))
1288 (search-forward "module:" end t))
1289 (progn
1290 (skip-chars-forward " \t")
1291 (setq beg (point))
1292 (if (search-forward ";" end t)
1293 (forward-char -1)
1294 (goto-char end))
1295 (skip-chars-backward " \t")
1296 (buffer-substring beg (point)))))))))
1297
1298(defun prolog-build-prolog-command (compilep file buffername
1299 &optional first-line)
1300 "Make Prolog command for FILE compilation/consulting.
1301If COMPILEP is non-nil, consider compilation, otherwise consulting."
1302 (let* ((compile-string
1303 (if compilep prolog-compile-string-i prolog-consult-string-i))
1304 (module (prolog-buffer-module))
1305 (file-name (concat "'" file "'"))
1306 (module-name (if module (concat "'" module "'")))
1307 (module-file (if module
1308 (concat module-name ":" file-name)
1309 file-name))
1310 strbeg strend
1311 (lineoffset (if first-line
1312 (- first-line 1)
1313 0)))
1314
1315 ;; Assure that there is a buffer name
1316 (if (not buffername)
1317 (error "The buffer is not saved"))
1318
1319 (if (not (string-match "^'.*'$" buffername)) ; Add quotes
1320 (setq buffername (concat "'" buffername "'")))
1321 (while (string-match "%m" compile-string)
1322 (setq strbeg (substring compile-string 0 (match-beginning 0)))
1323 (setq strend (substring compile-string (match-end 0)))
1324 (setq compile-string (concat strbeg module-file strend)))
1325 (while (string-match "%f" compile-string)
1326 (setq strbeg (substring compile-string 0 (match-beginning 0)))
1327 (setq strend (substring compile-string (match-end 0)))
1328 (setq compile-string (concat strbeg file-name strend)))
1329 (while (string-match "%b" compile-string)
1330 (setq strbeg (substring compile-string 0 (match-beginning 0)))
1331 (setq strend (substring compile-string (match-end 0)))
1332 (setq compile-string (concat strbeg buffername strend)))
1333 (while (string-match "%l" compile-string)
1334 (setq strbeg (substring compile-string 0 (match-beginning 0)))
1335 (setq strend (substring compile-string (match-end 0)))
1336 (setq compile-string (concat strbeg (format "%d" lineoffset) strend)))
1337 (concat compile-string "\n")))
1338
1339;;; The rest of this page is experimental code!
1340
1341;; Global variables for process filter function
1342(defvar prolog-process-flag nil
1343 "Non-nil means that a prolog task (i.e. a consultation or compilation job)
1344is running.")
1345(defvar prolog-consult-compile-output ""
1346 "Hold the unprocessed output from the current prolog task.")
1347(defvar prolog-consult-compile-first-line 1
1348 "The number of the first line of the file to consult/compile.
1349Used for temporary files.")
1350(defvar prolog-consult-compile-file nil
1351 "The file to compile/consult (can be a temporary file).")
1352(defvar prolog-consult-compile-real-file nil
1353 "The file name of the buffer to compile/consult.")
1354
1355(defun prolog-consult-compile (compilep file &optional first-line)
1356 "Consult/compile FILE.
1357If COMPILEP is non-nil, perform compilation, otherwise perform CONSULTING.
1358COMMAND is a string described by the variables `prolog-consult-string'
1359and `prolog-compile-string'.
1360Optional argument FIRST-LINE is the number of the first line in the compiled
1361region.
1362
1363This function must be called from the source code buffer."
1364 (if prolog-process-flag
1365 (error "Another Prolog task is running."))
1366 (prolog-ensure-process t)
1367 (let* ((buffer (get-buffer-create prolog-compilation-buffer))
1368 (real-file buffer-file-name)
1369 (command-string (prolog-build-prolog-command compilep file
1370 real-file first-line))
1371 (process (get-process "prolog"))
1372 (old-filter (process-filter process)))
1373 (with-current-buffer buffer
1374 (delete-region (point-min) (point-max))
1375 (compilation-mode)
1376 ;; Setting up font-locking for this buffer
1377 (make-local-variable 'font-lock-defaults)
1378 (setq font-lock-defaults
1379 '(prolog-font-lock-keywords nil nil ((?_ . "w"))))
1380 (if (eq prolog-system 'sicstus)
1381 (progn
1382 (make-local-variable 'compilation-parse-errors-function)
1383 (setq compilation-parse-errors-function
1384 'prolog-parse-sicstus-compilation-errors)))
1385 (toggle-read-only 0)
1386 (insert command-string "\n"))
1387 (save-selected-window
1388 (pop-to-buffer buffer))
1389 (setq prolog-process-flag t
1390 prolog-consult-compile-output ""
1391 prolog-consult-compile-first-line (if first-line (1- first-line) 0)
1392 prolog-consult-compile-file file
1393 prolog-consult-compile-real-file (if (string=
1394 file buffer-file-name)
1395 nil
1396 real-file))
1397 (with-current-buffer buffer
1398 (goto-char (point-max))
1399 (set-process-filter process 'prolog-consult-compile-filter)
1400 (process-send-string "prolog" command-string)
1401 ;; (prolog-build-prolog-command compilep file real-file first-line))
1402 (while (and prolog-process-flag
1403 (accept-process-output process 10)) ; 10 secs is ok?
1404 (sit-for 0.1)
1405 (unless (get-process "prolog")
1406 (setq prolog-process-flag nil)))
1407 (insert (if compilep
1408 "\nCompilation finished.\n"
1409 "\nConsulted.\n"))
1410 (set-process-filter process old-filter))))
1411
1412(defun prolog-parse-sicstus-compilation-errors (limit)
1413 "Parse the prolog compilation buffer for errors.
1414Argument LIMIT is a buffer position limiting searching.
1415For use with the `compilation-parse-errors-function' variable."
1416 (setq compilation-error-list nil)
1417 (message "Parsing SICStus error messages...")
1418 (let (filepath dir file errorline)
1419 (while
1420 (re-search-backward
1421 "{\\([a-zA-Z ]* ERROR\\|Warning\\):.* in line[s ]*\\([0-9]+\\)"
1422 limit t)
1423 (setq errorline (string-to-number (match-string 2)))
1424 (save-excursion
1425 (re-search-backward
1426 "{\\(consulting\\|compiling\\|processing\\) \\(.*\\)\\.\\.\\.}"
1427 limit t)
1428 (setq filepath (match-string 2)))
1429
1430 ;; ###### Does this work with SICStus under Windows (i.e. backslahes and stuff?)
1431 (if (string-match "\\(.*/\\)\\([^/]*\\)$" filepath)
1432 (progn
1433 (setq dir (match-string 1 filepath))
1434 (setq file (match-string 2 filepath))))
1435
1436 (setq compilation-error-list
1437 (cons
1438 (cons (save-excursion
1439 (beginning-of-line)
1440 (point-marker))
1441 (list (list file dir) errorline))
1442 compilation-error-list)
1443 ))
1444 ))
1445
1446(defun prolog-consult-compile-filter (process output)
1447 "Filter function for Prolog compilation PROCESS.
1448Argument OUTPUT is a name of the output file."
1449 ;;(message "start")
1450 (setq prolog-consult-compile-output
1451 (concat prolog-consult-compile-output output))
1452 ;;(message "pccf1: %s" prolog-consult-compile-output)
1453 ;; Iterate through the lines of prolog-consult-compile-output
1454 (let (outputtype)
1455 (while (and prolog-process-flag
1456 (or
1457 ;; Trace question
1458 (progn
1459 (setq outputtype 'trace)
1460 (and (eq prolog-system 'sicstus)
1461 (string-match
1462 "^[ \t]*[0-9]+[ \t]*[0-9]+[ \t]*Call:.*? "
1463 prolog-consult-compile-output)))
1464
1465 ;; Match anything
1466 (progn
1467 (setq outputtype 'normal)
1468 (string-match "^.*\n" prolog-consult-compile-output))
1469 ))
1470 ;;(message "outputtype: %s" outputtype)
1471
1472 (setq output (match-string 0 prolog-consult-compile-output))
1473 ;; remove the text in output from prolog-consult-compile-output
1474 (setq prolog-consult-compile-output
1475 (substring prolog-consult-compile-output (length output)))
1476 ;;(message "pccf2: %s" prolog-consult-compile-output)
1477
1478 ;; If temporary files were used, then we change the error
1479 ;; messages to point to the original source file.
1480 (cond
1481
1482 ;; If the prolog process was in trace mode then it requires
1483 ;; user input
1484 ((and (eq prolog-system 'sicstus)
1485 (eq outputtype 'trace))
1486 (let (input)
1487 (setq input (concat (read-string output) "\n"))
1488 (process-send-string process input)
1489 (setq output (concat output input))))
1490
1491 ((eq prolog-system 'sicstus)
1492 (if (and prolog-consult-compile-real-file
1493 (string-match
1494 "\\({.*:.* in line[s ]*\\)\\([0-9]+\\)-\\([0-9]+\\)" output))
1495 (setq output (replace-match
1496 ;; Adds a {processing ...} line so that
1497 ;; `prolog-parse-sicstus-compilation-errors'
1498 ;; finds the real file instead of the temporary one.
1499 ;; Also fixes the line numbers.
1500 (format "Added by Emacs: {processing %s...}\n%s%d-%d"
1501 prolog-consult-compile-real-file
1502 (match-string 1 output)
1503 (+ prolog-consult-compile-first-line
1504 (string-to-number
1505 (match-string 2 output)))
1506 (+ prolog-consult-compile-first-line
1507 (string-to-number
1508 (match-string 3 output))))
1509 t t output)))
1510 )
1511
1512 ((eq prolog-system 'swi)
1513 (if (and prolog-consult-compile-real-file
1514 (string-match (format
1515 "%s\\([ \t]*:[ \t]*\\)\\([0-9]+\\)"
1516 prolog-consult-compile-file)
1517 output))
1518 (setq output (replace-match
1519 ;; Real filename + text + fixed linenum
1520 (format "%s%s%d"
1521 prolog-consult-compile-real-file
1522 (match-string 1 output)
1523 (+ prolog-consult-compile-first-line
1524 (string-to-number
1525 (match-string 2 output))))
1526 t t output)))
1527 )
1528
1529 (t ())
1530 )
1531 ;; Write the output in the *prolog-compilation* buffer
1532 (insert output)))
1533
1534 ;; If the prompt is visible, then the task is finished
1535 (if (string-match prolog-prompt-regexp-i prolog-consult-compile-output)
1536 (setq prolog-process-flag nil)))
1537
1538(defun prolog-consult-compile-file (compilep)
1539 "Consult/compile file of current buffer.
1540If COMPILEP is non-nil, compile, otherwise consult."
1541 (let ((file buffer-file-name))
1542 (if file
1543 (progn
1544 (save-some-buffers)
1545 (prolog-consult-compile compilep file))
1546 (prolog-consult-compile-region compilep (point-min) (point-max)))))
1547
1548(defun prolog-consult-compile-buffer (compilep)
1549 "Consult/compile current buffer.
1550If COMPILEP is non-nil, compile, otherwise consult."
1551 (prolog-consult-compile-region compilep (point-min) (point-max)))
1552
1553(defun prolog-consult-compile-region (compilep beg end)
1554 "Consult/compile region between BEG and END.
1555If COMPILEP is non-nil, compile, otherwise consult."
1556 ;(let ((file prolog-temp-filename)
1557 (let ((file (prolog-bsts (prolog-temporary-file)))
1558 (lines (count-lines 1 beg)))
1559 (write-region beg end file nil 'no-message)
1560 (write-region "\n" nil file t 'no-message)
1561 (prolog-consult-compile compilep file
1562 (if (looking-at "^") (1+ lines) lines))
1563 (delete-file file)))
1564
1565(defun prolog-consult-compile-predicate (compilep)
1566 "Consult/compile the predicate around current point.
1567If COMPILEP is non-nil, compile, otherwise consult."
1568 (prolog-consult-compile-region
1569 compilep (prolog-pred-start) (prolog-pred-end)))
1570
1571
1572;;-------------------------------------------------------------------
1573;; Font-lock stuff
1574;;-------------------------------------------------------------------
1575
1576;; Auxilliary functions
1577(defun prolog-make-keywords-regexp (keywords &optional protect)
1578 "Create regexp from the list of strings KEYWORDS.
1579If PROTECT is non-nil, surround the result regexp by word breaks."
1580 (let ((regexp
1581 (if (fboundp 'regexp-opt)
1582 ;; Emacs 20
1583 ;; Avoid compile warnings under earlier versions by using eval
1584 (eval '(regexp-opt keywords))
1585 ;; Older Emacsen
1586 (concat (mapconcat 'regexp-quote keywords "\\|")))
1587 ))
1588 (if protect
1589 (concat "\\<\\(" regexp "\\)\\>")
1590 regexp)))
1591
1592(defun prolog-font-lock-object-matcher (bound)
1593 "Find SICStus objects method name for font lock.
1594Argument BOUND is a buffer position limiting searching."
1595 (let (point
1596 (case-fold-search nil))
1597 (while (and (not point)
1598 (re-search-forward "\\(::[ \t\n]*{\\|&\\)[ \t]*"
1599 bound t))
1600 (while (or (re-search-forward "\\=\n[ \t]*" bound t)
1601 (re-search-forward "\\=%.*" bound t)
1602 (and (re-search-forward "\\=/\\*" bound t)
1603 (re-search-forward "\\*/[ \t]*" bound t))))
1604 (setq point (re-search-forward
1605 (format "\\=\\(%s\\)" prolog-atom-regexp)
1606 bound t)))
1607 point))
1608
1609(defsubst prolog-face-name-p (facename)
1610 ;; Return t if FACENAME is the name of a face. This method is
1611 ;; necessary since facep in XEmacs only returns t for the actual
1612 ;; face objects (while it's only their names that are used just
1613 ;; about anywhere else) without providing a predicate that tests
1614 ;; face names. This function (including the above commentary) is
1615 ;; borrowed from cc-mode.
1616 (memq facename (face-list)))
1617
1618;; Set everything up
1619(defun prolog-font-lock-keywords ()
1620 "Set up font lock keywords for the current Prolog system."
1621 ;(when window-system
1622 (require 'font-lock)
1623
1624 ;; Define Prolog faces
1625 (defface prolog-redo-face
1626 '((((class grayscale)) (:italic t))
1627 (((class color)) (:foreground "darkorchid"))
1628 (t (:italic t)))
1629 "Prolog mode face for highlighting redo trace lines."
1630 :group 'prolog-faces)
1631 (defface prolog-exit-face
1632 '((((class grayscale)) (:underline t))
1633 (((class color) (background dark)) (:foreground "green"))
1634 (((class color) (background light)) (:foreground "ForestGreen"))
1635 (t (:underline t)))
1636 "Prolog mode face for highlighting exit trace lines."
1637 :group 'prolog-faces)
1638 (defface prolog-exception-face
1639 '((((class grayscale)) (:bold t :italic t :underline t))
1640 (((class color)) (:bold t :foreground "black" :background "Khaki"))
1641 (t (:bold t :italic t :underline t)))
1642 "Prolog mode face for highlighting exception trace lines."
1643 :group 'prolog-faces)
1644 (defface prolog-warning-face
1645 '((((class grayscale)) (:underline t))
1646 (((class color) (background dark)) (:foreground "blue"))
1647 (((class color) (background light)) (:foreground "MidnightBlue"))
1648 (t (:underline t)))
1649 "Face name to use for compiler warnings."
1650 :group 'prolog-faces)
1651 (defface prolog-builtin-face
1652 '((((class color) (background light)) (:foreground "Purple"))
1653 (((class color) (background dark)) (:foreground "Cyan"))
1654 (((class grayscale) (background light)) (:foreground "LightGray" :bold t))
1655 (((class grayscale) (background dark)) (:foreground "DimGray" :bold t))
1656 (t (:bold t)))
1657 "Face name to use for compiler warnings."
1658 :group 'prolog-faces)
1659 (defvar prolog-warning-face
1660 (if (prolog-face-name-p 'font-lock-warning-face)
1661 'font-lock-warning-face
1662 'prolog-warning-face)
1663 "Face name to use for built in predicates.")
1664 (defvar prolog-builtin-face
1665 (if (prolog-face-name-p 'font-lock-builtin-face)
1666 'font-lock-builtin-face
1667 'prolog-builtin-face)
1668 "Face name to use for built in predicates.")
1669 (defvar prolog-redo-face 'prolog-redo-face
1670 "Face name to use for redo trace lines.")
1671 (defvar prolog-exit-face 'prolog-exit-face
1672 "Face name to use for exit trace lines.")
1673 (defvar prolog-exception-face 'prolog-exception-face
1674 "Face name to use for exception trace lines.")
1675
1676 ;; Font Lock Patterns
1677 (let (
1678 ;; "Native" Prolog patterns
1679 (head-predicates
1680 (list (format "^\\(%s\\)\\((\\|[ \t]*:-\\)" prolog-atom-regexp)
1681 1 font-lock-function-name-face))
1682 ;(list (format "^%s" prolog-atom-regexp)
1683 ; 0 font-lock-function-name-face))
1684 (head-predicates-1
1685 (list (format "\\.[ \t]*\\(%s\\)" prolog-atom-regexp)
1686 1 font-lock-function-name-face) )
1687 (variables
1688 '("\\<\\([_A-Z][a-zA-Z0-9_]*\\)"
1689 1 font-lock-variable-name-face))
1690 (important-elements
1691 (list (if (eq prolog-system 'mercury)
1692 "[][}{;|]\\|\\\\[+=]\\|<?=>?"
1693 "[][}{!;|]\\|\\*->")
1694 0 'font-lock-keyword-face))
1695 (important-elements-1
1696 '("[^-*]\\(->\\)" 1 font-lock-keyword-face))
1697 (predspecs ; module:predicate/cardinality
1698 (list (format "\\<\\(%s:\\|\\)%s/[0-9]+"
1699 prolog-atom-regexp prolog-atom-regexp)
1700 0 font-lock-function-name-face 'prepend))
1701 (keywords ; directives (queries)
1702 (list
1703 (if (eq prolog-system 'mercury)
1704 (concat
1705 "\\<\\("
1706 (prolog-make-keywords-regexp prolog-keywords-i)
1707 "\\|"
1708 (prolog-make-keywords-regexp
1709 prolog-determinism-specificators-i)
1710 "\\)\\>")
1711 (concat
1712 "^[?:]- *\\("
1713 (prolog-make-keywords-regexp prolog-keywords-i)
1714 "\\)\\>"))
1715 1 prolog-builtin-face))
1716 (quoted_atom (list prolog-quoted-atom-regexp
1717 2 'font-lock-string-face 'append))
1718 (string (list prolog-string-regexp
1719 1 'font-lock-string-face 'append))
1720 ;; SICStus specific patterns
1721 (sicstus-object-methods
1722 (if (eq prolog-system 'sicstus)
1723 '(prolog-font-lock-object-matcher
1724 1 font-lock-function-name-face)))
1725 ;; Mercury specific patterns
1726 (types
1727 (if (eq prolog-system 'mercury)
1728 (list
1729 (prolog-make-keywords-regexp prolog-types-i t)
1730 0 'font-lock-type-face)))
1731 (modes
1732 (if (eq prolog-system 'mercury)
1733 (list
1734 (prolog-make-keywords-regexp prolog-mode-specificators-i t)
1735 0 'font-lock-reference-face)))
1736 (directives
1737 (if (eq prolog-system 'mercury)
1738 (list
1739 (prolog-make-keywords-regexp prolog-directives-i t)
1740 0 'prolog-warning-face)))
1741 ;; Inferior mode specific patterns
1742 (prompt
1743 (list prolog-prompt-regexp-i 0 'font-lock-keyword-face))
1744 (trace-exit
1745 (cond
1746 ((eq prolog-system 'sicstus)
1747 '("[ \t]*[0-9]+[ \t]+[0-9]+[ \t]*\\(Exit\\):"
1748 1 prolog-exit-face))
1749 ((eq prolog-system 'swi)
1750 '("[ \t]*\\(Exit\\):[ \t]*([ \t0-9]*)" 1 prolog-exit-face))
1751 (t nil)))
1752 (trace-fail
1753 (cond
1754 ((eq prolog-system 'sicstus)
1755 '("[ \t]*[0-9]+[ \t]+[0-9]+[ \t]*\\(Fail\\):"
1756 1 prolog-warning-face))
1757 ((eq prolog-system 'swi)
1758 '("[ \t]*\\(Fail\\):[ \t]*([ \t0-9]*)" 1 prolog-warning-face))
1759 (t nil)))
1760 (trace-redo
1761 (cond
1762 ((eq prolog-system 'sicstus)
1763 '("[ \t]*[0-9]+[ \t]+[0-9]+[ \t]*\\(Redo\\):"
1764 1 prolog-redo-face))
1765 ((eq prolog-system 'swi)
1766 '("[ \t]*\\(Redo\\):[ \t]*([ \t0-9]*)" 1 prolog-redo-face))
1767 (t nil)))
1768 (trace-call
1769 (cond
1770 ((eq prolog-system 'sicstus)
1771 '("[ \t]*[0-9]+[ \t]+[0-9]+[ \t]*\\(Call\\):"
1772 1 font-lock-function-name-face))
1773 ((eq prolog-system 'swi)
1774 '("[ \t]*\\(Call\\):[ \t]*([ \t0-9]*)"
1775 1 font-lock-function-name-face))
1776 (t nil)))
1777 (trace-exception
1778 (cond
1779 ((eq prolog-system 'sicstus)
1780 '("[ \t]*[0-9]+[ \t]+[0-9]+[ \t]*\\(Exception\\):"
1781 1 prolog-exception-face))
1782 ((eq prolog-system 'swi)
1783 '("[ \t]*\\(Exception\\):[ \t]*([ \t0-9]*)"
1784 1 prolog-exception-face))
1785 (t nil)))
1786 (error-message-identifier
1787 (cond
1788 ((eq prolog-system 'sicstus)
1789 '("{\\([A-Z]* ?ERROR:\\)" 1 prolog-exception-face prepend))
1790 ((eq prolog-system 'swi)
1791 '("^[[]\\(WARNING:\\)" 1 prolog-builtin-face prepend))
1792 (t nil)))
1793 (error-whole-messages
1794 (cond
1795 ((eq prolog-system 'sicstus)
1796 '("{\\([A-Z]* ?ERROR:.*\\)}[ \t]*$"
1797 1 font-lock-comment-face append))
1798 ((eq prolog-system 'swi)
1799 '("^[[]WARNING:[^]]*[]]$" 0 font-lock-comment-face append))
1800 (t nil)))
1801 (error-warning-messages
1802 ;; Mostly errors that SICStus asks the user about how to solve,
1803 ;; such as "NAME CLASH:" for example.
1804 (cond
1805 ((eq prolog-system 'sicstus)
1806 '("^[A-Z ]*[A-Z]+:" 0 prolog-warning-face))
1807 (t nil)))
1808 (warning-messages
1809 (cond
1810 ((eq prolog-system 'sicstus)
1811 '("\\({ ?\\(Warning\\|WARNING\\) ?:.*}\\)[ \t]*$"
1812 2 prolog-warning-face prepend))
1813 (t nil))))
1814
1815 ;; Make font lock list
1816 (delq
1817 nil
1818 (cond
1819 ((eq major-mode 'prolog-mode)
1820 (list
1821 head-predicates
1822 head-predicates-1
1823 quoted_atom
1824 string
1825 variables
1826 important-elements
1827 important-elements-1
1828 predspecs
1829 keywords
1830 sicstus-object-methods
1831 types
1832 modes
1833 directives))
1834 ((eq major-mode 'prolog-inferior-mode)
1835 (list
1836 prompt
1837 error-message-identifier
1838 error-whole-messages
1839 error-warning-messages
1840 warning-messages
1841 predspecs
1842 trace-exit
1843 trace-fail
1844 trace-redo
1845 trace-call
1846 trace-exception))
1847 ((eq major-mode 'compilation-mode)
1848 (list
1849 error-message-identifier
1850 error-whole-messages
1851 error-warning-messages
1852 warning-messages
1853 predspecs))))
1854 ))
1855
1856
1857;;-------------------------------------------------------------------
1858;; Indentation stuff
1859;;-------------------------------------------------------------------
1860
1861;; NB: This function *MUST* have this optional argument since XEmacs
1862;; assumes it. This does not mean we have to use it...
1863(defun prolog-indent-line (&optional whole-exp)
1864 "Indent current line as Prolog code.
1865With argument, indent any additional lines of the same clause
1866rigidly along with this one (not yet)."
1867 (interactive "p")
1868 (let ((indent (prolog-indent-level))
1869 (pos (- (point-max) (point))) beg)
1870 (beginning-of-line)
1871 (setq beg (point))
1872 (skip-chars-forward " \t")
1873 (if (zerop (- indent (current-column)))
1874 nil
1875 (delete-region beg (point))
1876 (indent-to indent))
1877 (if (> (- (point-max) pos) (point))
1878 (goto-char (- (point-max) pos)))
1879
1880 ;; Align comments
1881 (if prolog-align-comments-flag
1882 (save-excursion
1883 (prolog-goto-comment-column t)))
1884
1885 ;; Insert spaces if needed
1886 (if (or prolog-electric-tab-flag prolog-electric-if-then-else-flag)
1887 (prolog-insert-spaces-after-paren))
1888 ))
1889
1890(defun prolog-comment-indent ()
1891 "Compute prolog comment indentation."
1892 (cond ((looking-at "%%%") (prolog-indentation-level-of-line))
1893 ((looking-at "%%") (prolog-indent-level))
1894 (t
1895 (save-excursion
1896 (skip-chars-backward " \t")
1897 ;; Insert one space at least, except at left margin.
1898 (max (+ (current-column) (if (bolp) 0 1))
1899 comment-column)))
1900 ))
1901
1902(defun prolog-indent-level ()
1903 "Compute prolog indentation level."
1904 (save-excursion
1905 (beginning-of-line)
1906 (let ((totbal (prolog-region-paren-balance
1907 (prolog-clause-start t) (point)))
1908 (oldpoint (point)))
1909 (skip-chars-forward " \t")
1910 (cond
1911 ((looking-at "%%%") (prolog-indentation-level-of-line))
1912 ;Large comment starts
1913 ((looking-at "%[^%]") comment-column) ;Small comment starts
1914 ((bobp) 0) ;Beginning of buffer
1915
1916 ;; If we found '}' then we must check if it's the
1917 ;; end of an object declaration or something else.
1918 ((and (looking-at "}")
382 (save-excursion 1919 (save-excursion
383 (goto-char (- pmark 3)) 1920 (forward-char 1)
384 (looking-at " \\? "))) 1921 ;; Goto to matching {
385 ;; This is GNU prolog waiting to know whether you want more answers 1922 (if prolog-use-prolog-tokenizer-flag
386 ;; or not (or abort, etc...). The answer is a single char, not 1923 (prolog-backward-list)
387 ;; a line, so pass this char directly rather than wait for RET to 1924 (backward-list))
388 ;; send a whole line. 1925 (skip-chars-backward " \t")
389 (comint-send-string proc (string last-command-event)) 1926 (backward-char 2)
390 (call-interactively 'self-insert-command)))) 1927 (looking-at "::")))
391 1928 ;; It was an object
392(defun prolog-consult-region (compile beg end) 1929 (if prolog-object-end-to-0-flag
393 "Send the region to the Prolog process made by \"M-x run-prolog\". 1930 0
394If COMPILE (prefix arg) is not nil, use compile mode rather than consult mode." 1931 prolog-indent-width))
395 (interactive "P\nr") 1932
396 (let ((proc (inferior-prolog-process))) 1933 ;;End of /* */ comment
397 (comint-send-string proc 1934 ((looking-at "\\*/")
398 (if compile prolog-compile-string 1935 (save-excursion
399 prolog-consult-string)) 1936 (prolog-find-start-of-mline-comment)
400 (comint-send-region proc beg end) 1937 (skip-chars-backward " \t")
401 (comint-send-string proc "\n") ;May be unnecessary 1938 (- (current-column) 2)))
402 (if prolog-eof-string 1939
403 (comint-send-string proc prolog-eof-string) 1940 ;; Here we check if the current line is within a /* */ pair
404 (with-current-buffer (process-buffer proc) 1941 ((and (looking-at "[^%/]")
405 (comint-send-eof))))) ;Send eof to prolog process. 1942 (eq (prolog-in-string-or-comment) 'cmt))
406 1943 (if prolog-indent-mline-comments-flag
407(defun prolog-consult-region-and-go (compile beg end) 1944 (prolog-find-start-of-mline-comment)
408 "Send the region to the inferior Prolog, and switch to *prolog* buffer. 1945 ;; Same as before
409If COMPILE (prefix arg) is not nil, use compile mode rather than consult mode." 1946 (prolog-indentation-level-of-line)))
410 (interactive "P\nr") 1947
411 (prolog-consult-region compile beg end) 1948 (t
412 (pop-to-buffer inferior-prolog-buffer)) 1949 (let ((empty t) ind linebal)
413 1950 ;; See previous indentation
414;; inferior-prolog-mode uses the autoloaded compilation-shell-minor-mode. 1951 (while empty
415(declare-function compilation-forget-errors "compile" ()) 1952 (forward-line -1)
416 1953 (beginning-of-line)
417(defun inferior-prolog-load-file () 1954 (if (= (point) (point-min))
418 "Pass the current buffer's file to the inferior prolog process." 1955 (setq empty nil)
419 (interactive) 1956 (skip-chars-forward " \t")
420 (save-buffer) 1957 (if (not (or (not (member (prolog-in-string-or-comment) '(nil txt)))
421 (let ((file buffer-file-name) 1958 (looking-at "%")
422 (proc (inferior-prolog-process))) 1959 (looking-at "\n")))
423 (with-current-buffer (process-buffer proc) 1960 (setq empty nil))))
424 (compilation-forget-errors) 1961
425 (comint-send-string proc (concat "['" (file-relative-name file) "'].\n")) 1962 ;; Store this line's indentation
426 (pop-to-buffer (current-buffer))))) 1963 (if (= (point) (point-min))
1964 (setq ind 0) ;Beginning of buffer
1965 (setq ind (current-column))) ;Beginning of clause
1966
1967 ;; Compute the balance of the line
1968 (setq linebal (prolog-paren-balance))
1969 ;;(message "bal of previous line %d totbal %d" linebal totbal)
1970 (if (< linebal 0)
1971 (progn
1972 ;; Add 'indent-level' mode to find-unmatched-paren instead?
1973 (end-of-line)
1974 (setq ind (prolog-find-indent-of-matching-paren))))
1975
1976 ;;(message "ind %d" ind)
1977 (beginning-of-line)
1978
1979 ;; Check if the line ends with ":-", ".", ":: {", "}" (might be
1980 ;; unnecessary), "&" or ")" (The last four concerns SICStus objects)
1981 (cond
1982 ;; If the last char of the line is a '&' then set the indent level
1983 ;; to prolog-indent-width (used in SICStus objects)
1984 ((and (eq prolog-system 'sicstus)
1985 (looking-at ".+&[ \t]*\\(%.*\\|\\)$"))
1986 (setq ind prolog-indent-width))
1987
1988 ;; Increase indentation if the previous line was the head of a rule
1989 ;; and does not contain a '.'
1990 ((and (looking-at (format ".*%s[^\\.]*[ \t]*\\(%%.*\\|\\)$"
1991 prolog-head-delimiter))
1992 ;; We must check that the match is at a paren balance of 0.
1993 (save-excursion
1994 (let ((p (point)))
1995 (re-search-forward prolog-head-delimiter)
1996 (>= 0 (prolog-region-paren-balance p (point))))))
1997 (let (headindent)
1998 (if (< (prolog-paren-balance) 0)
1999 (save-excursion
2000 (end-of-line)
2001 (setq headindent (prolog-find-indent-of-matching-paren)))
2002 (setq headindent (prolog-indentation-level-of-line)))
2003 (setq ind (+ headindent prolog-indent-width))))
2004
2005 ;; The previous line was the head of an object
2006 ((looking-at ".+ *::.*{[ \t]*$")
2007 (setq ind prolog-indent-width))
2008
2009 ;; If a '.' is found at the end of the previous line, then
2010 ;; decrease the indentation. (The \\(%.*\\|\\) part of the
2011 ;; regexp is for comments at the end of the line)
2012 ((and (looking-at "^.+\\.[ \t]*\\(%.*\\|\\)$")
2013 ;; Make sure that the '.' found is not in a comment or string
2014 (save-excursion
2015 (end-of-line)
2016 (re-search-backward "\\.[ \t]*\\(%.*\\|\\)$" (point-min))
2017 ;; Guard against the real '.' being followed by a
2018 ;; commented '.'.
2019 (if (eq (prolog-in-string-or-comment) 'cmt) ;; commented out '.'
2020 (let ((here (save-excursion
2021 (beginning-of-line)
2022 (point))))
2023 (end-of-line)
2024 (re-search-backward "\\.[ \t]*%.*$" here t))
2025 (not (prolog-in-string-or-comment))
2026 )
2027 ))
2028 (setq ind 0))
2029
2030 ;; If a '.' is found at the end of the previous line, then
2031 ;; decrease the indentation. (The /\\*.*\\*/ part of the
2032 ;; regexp is for C-like comments at the end of the
2033 ;; line--can we merge with the case above?).
2034 ((and (looking-at "^.+\\.[ \t]*\\(/\\*.*\\|\\)$")
2035 ;; Make sure that the '.' found is not in a comment or string
2036 (save-excursion
2037 (end-of-line)
2038 (re-search-backward "\\.[ \t]*\\(/\\*.*\\|\\)$" (point-min))
2039 ;; Guard against the real '.' being followed by a
2040 ;; commented '.'.
2041 (if (eq (prolog-in-string-or-comment) 'cmt) ;; commented out '.'
2042 (let ((here (save-excursion
2043 (beginning-of-line)
2044 (point))))
2045 (end-of-line)
2046 (re-search-backward "\\.[ \t]*/\\*.*$" here t))
2047 (not (prolog-in-string-or-comment))
2048 )
2049 ))
2050 (setq ind 0))
2051
2052 )
2053
2054 ;; If the last non comment char is a ',' or left paren or a left-
2055 ;; indent-regexp then indent to open parenthesis level
2056 (if (and
2057 (> totbal 0)
2058 ;; SICStus objects have special syntax rules if point is
2059 ;; not inside additional parens (objects are defined
2060 ;; within {...})
2061 (not (and (eq prolog-system 'sicstus)
2062 (= totbal 1)
2063 (prolog-in-object))))
2064 (if (looking-at
2065 (format "\\(%s\\|%s\\|0'.\\|[0-9]+'[0-9a-zA-Z]+\\|[^\n\'\"%%]\\)*\\(,\\|%s\\|%s\\)\[ \t]*\\(%%.*\\|\\)$"
2066 prolog-quoted-atom-regexp prolog-string-regexp
2067 prolog-left-paren prolog-left-indent-regexp))
2068 (progn
2069 (goto-char oldpoint)
2070 (setq ind (prolog-find-unmatched-paren (if prolog-paren-indent-p
2071 'termdependent
2072 'skipwhite)))
2073 ;;(setq ind (prolog-find-unmatched-paren 'termdependent))
2074 )
2075 (goto-char oldpoint)
2076 (setq ind (prolog-find-unmatched-paren nil))
2077 ))
2078
2079
2080 ;; Return the indentation level
2081 ind
2082 ))))))
2083
2084(defun prolog-find-indent-of-matching-paren ()
2085 "Find the indentation level based on the matching parenthesis.
2086Indentation level is set to the one the point is after when the function is
2087called."
2088 (save-excursion
2089 ;; Go to the matching paren
2090 (if prolog-use-prolog-tokenizer-flag
2091 (prolog-backward-list)
2092 (backward-list))
2093
2094 ;; If this was the first paren on the line then return this line's
2095 ;; indentation level
2096 (if (prolog-paren-is-the-first-on-line-p)
2097 (prolog-indentation-level-of-line)
2098 ;; It was not the first one
2099 (progn
2100 ;; Find the next paren
2101 (prolog-goto-next-paren 0)
2102
2103 ;; If this paren is a left one then use its column as indent level,
2104 ;; if not then recurse this function
2105 (if (looking-at prolog-left-paren)
2106 (+ (current-column) 1)
2107 (progn
2108 (forward-char 1)
2109 (prolog-find-indent-of-matching-paren)))
2110 ))
2111 ))
2112
2113(defun prolog-indentation-level-of-line ()
2114 "Return the indentation level of the current line."
2115 (save-excursion
2116 (beginning-of-line)
2117 (skip-chars-forward " \t")
2118 (current-column)))
2119
2120(defun prolog-first-pos-on-line ()
2121 "Return the first position on the current line."
2122 (save-excursion
2123 (beginning-of-line)
2124 (point)))
2125
2126(defun prolog-paren-is-the-first-on-line-p ()
2127 "Return t if the parenthesis under the point is the first one on the line.
2128Return nil otherwise.
2129Note: does not check if the point is actually at a parenthesis!"
2130 (save-excursion
2131 (let ((begofline (prolog-first-pos-on-line)))
2132 (if (= begofline (point))
2133 t
2134 (if (prolog-goto-next-paren begofline)
2135 nil
2136 t)))))
2137
2138(defun prolog-find-unmatched-paren (&optional mode)
2139 "Return the column of the last unmatched left parenthesis.
2140If MODE is `skipwhite' then any white space after the parenthesis is added to
2141the answer.
2142If MODE is `plusone' then the parenthesis' column +1 is returned.
2143If MODE is `termdependent' then if the unmatched parenthesis is part of
2144a compound term the function will work as `skipwhite', otherwise
2145it will return the column paren plus the value of `prolog-paren-indent'.
2146If MODE is nil or not set then the parenthesis' exact column is returned."
2147 (save-excursion
2148 ;; If the next paren we find is a left one we're finished, if it's
2149 ;; a right one then we go back one step and recurse
2150 (prolog-goto-next-paren 0)
2151
2152 (let ((roundparen (looking-at "(")))
2153 (if (looking-at prolog-left-paren)
2154 (let ((not-part-of-term
2155 (save-excursion
2156 (backward-char 1)
2157 (looking-at "[ \t]"))))
2158 (if (eq mode nil)
2159 (current-column)
2160 (if (and roundparen
2161 (eq mode 'termdependent)
2162 not-part-of-term)
2163 (+ (current-column)
2164 (if prolog-electric-tab-flag
2165 ;; Electric TAB
2166 prolog-paren-indent
2167 ;; Not electric TAB
2168 (if (looking-at ".[ \t]*$")
2169 2
2170 prolog-paren-indent))
2171 )
2172
2173 (forward-char 1)
2174 (if (or (eq mode 'skipwhite) (eq mode 'termdependent) )
2175 (skip-chars-forward " \t"))
2176 (current-column))))
2177 ;; Not looking at left paren
2178 (progn
2179 (forward-char 1)
2180 ;; Go to the matching paren. When we get there we have a total
2181 ;; balance of 0.
2182 (if prolog-use-prolog-tokenizer-flag
2183 (prolog-backward-list)
2184 (backward-list))
2185 (prolog-find-unmatched-paren mode)))
2186 )))
2187
2188
2189(defun prolog-paren-balance ()
2190 "Return the parenthesis balance of the current line.
2191A return value of n means n more left parentheses than right ones."
2192 (save-excursion
2193 (end-of-line)
2194 (prolog-region-paren-balance (prolog-first-pos-on-line) (point))))
2195
2196(defun prolog-region-paren-balance (beg end)
2197 "Return the summed parenthesis balance in the region.
2198The region is limited by BEG and END positions."
2199 (save-excursion
2200 (let ((state (if prolog-use-prolog-tokenizer-flag
2201 (prolog-tokenize beg end)
2202 (parse-partial-sexp beg end))))
2203 (nth 0 state))))
2204
2205(defun prolog-goto-next-paren (limit-pos)
2206 "Move the point to the next parenthesis earlier in the buffer.
2207Return t if a match was found before LIMIT-POS. Return nil otherwise."
2208 (let (retval)
2209 (setq retval (re-search-backward
2210 (concat prolog-left-paren "\\|" prolog-right-paren)
2211 limit-pos t))
2212
2213 ;; If a match was found but it was in a string or comment, then recurse
2214 (if (and retval (prolog-in-string-or-comment))
2215 (prolog-goto-next-paren limit-pos)
2216 retval)
2217 ))
2218
2219(defun prolog-in-string-or-comment ()
2220 "Check whether string, atom, or comment is under current point.
2221Return:
2222 `txt' if the point is in a string, atom, or character code expression
2223 `cmt' if the point is in a comment
2224 nil otherwise."
2225 (save-excursion
2226 (let* ((start
2227 (if (eq prolog-parse-mode 'beg-of-line)
2228 ;; 'beg-of-line
2229 (save-excursion
2230 (let (safepoint)
2231 (beginning-of-line)
2232 (setq safepoint (point))
2233 (while (and (> (point) (point-min))
2234 (progn
2235 (forward-line -1)
2236 (end-of-line)
2237 (if (not (bobp))
2238 (backward-char 1))
2239 (looking-at "\\\\"))
2240 )
2241 (beginning-of-line)
2242 (setq safepoint (point)))
2243 safepoint))
2244 ;; 'beg-of-clause
2245 (prolog-clause-start)))
2246 (end (point))
2247 (state (if prolog-use-prolog-tokenizer-flag
2248 (prolog-tokenize start end)
2249 (parse-partial-sexp start end))))
2250 (cond
2251 ((nth 3 state) 'txt) ; String
2252 ((nth 4 state) 'cmt) ; Comment
2253 (t
2254 (cond
2255 ((looking-at "%") 'cmt) ; Start of a comment
2256 ((looking-at "/\\*") 'cmt) ; Start of a comment
2257 ((looking-at "\'") 'txt) ; Start of an atom
2258 ((looking-at "\"") 'txt) ; Start of a string
2259 (t nil)
2260 ))))
2261 ))
2262
2263(defun prolog-find-start-of-mline-comment ()
2264 "Return the start column of a /* */ comment.
2265This assumes that the point is inside a comment."
2266 (re-search-backward "/\\*" (point-min) t)
2267 (forward-char 2)
2268 (skip-chars-forward " \t")
2269 (current-column))
2270
2271(defun prolog-insert-spaces-after-paren ()
2272 "Insert spaces after the opening parenthesis, \"then\" (->) and \"else\" (;) branches.
2273Spaces are inserted if all preceding objects on the line are
2274whitespace characters, parentheses, or then/else branches."
2275 (save-excursion
2276 (let ((regexp (concat "(\\|" prolog-left-indent-regexp))
2277 level)
2278 (beginning-of-line)
2279 (skip-chars-forward " \t")
2280 (when (looking-at regexp)
2281 ;; Treat "( If -> " lines specially.
2282 ;;(if (looking-at "(.*->")
2283 ;; (setq incr 2)
2284 ;; (setq incr prolog-paren-indent))
2285
2286 ;; work on all subsequent "->", "(", ";"
2287 (while (looking-at regexp)
2288 (goto-char (match-end 0))
2289 (setq level (+ (prolog-find-unmatched-paren) prolog-paren-indent))
2290
2291 ;; Remove old white space
2292 (let ((start (point)))
2293 (skip-chars-forward " \t")
2294 (delete-region start (point)))
2295 (indent-to level)
2296 (skip-chars-forward " \t"))
2297 )))
2298 (when (save-excursion
2299 (backward-char 2)
2300 (looking-at "\\s ;\\|\\s (\\|->")) ; (looking-at "\\s \\((\\|;\\)"))
2301 (skip-chars-forward " \t"))
2302 )
2303
2304;;;; Comment filling
2305
2306(defun prolog-comment-limits ()
2307 "Return the current comment limits plus the comment type (block or line).
2308The comment limits are the range of a block comment or the range that
2309contains all adjacent line comments (i.e. all comments that starts in
2310the same column with no empty lines or non-whitespace characters
2311between them)."
2312 (let ((here (point))
2313 lit-limits-b lit-limits-e lit-type beg end
2314 )
2315 (save-restriction
2316 ;; Widen to catch comment limits correctly.
2317 (widen)
2318 (setq end (save-excursion (end-of-line) (point))
2319 beg (save-excursion (beginning-of-line) (point)))
2320 (save-excursion
2321 (beginning-of-line)
2322 (setq lit-type (if (search-forward-regexp "%" end t) 'line 'block))
2323 ; (setq lit-type 'line)
2324 ;(if (search-forward-regexp "^[ \t]*%" end t)
2325 ; (setq lit-type 'line)
2326 ; (if (not (search-forward-regexp "%" end t))
2327 ; (setq lit-type 'block)
2328 ; (if (not (= (forward-line 1) 0))
2329 ; (setq lit-type 'block)
2330 ; (setq done t
2331 ; ret (prolog-comment-limits)))
2332 ; ))
2333 (if (eq lit-type 'block)
2334 (progn
2335 (goto-char here)
2336 (when (looking-at "/\\*") (forward-char 2))
2337 (when (and (looking-at "\\*") (> (point) (point-min))
2338 (forward-char -1) (looking-at "/"))
2339 (forward-char 1))
2340 (when (save-excursion (search-backward "/*" nil t))
2341 (list (save-excursion (search-backward "/*") (point))
2342 (or (search-forward "*/" nil t) (point-max)) lit-type)))
2343 ;; line comment
2344 (setq lit-limits-b (- (point) 1)
2345 lit-limits-e end)
2346 (condition-case nil
2347 (if (progn (goto-char lit-limits-b)
2348 (looking-at "%"))
2349 (let ((col (current-column)) done)
2350 (setq beg (point)
2351 end lit-limits-e)
2352 ;; Always at the beginning of the comment
2353 ;; Go backward now
2354 (beginning-of-line)
2355 (while (and (zerop (setq done (forward-line -1)))
2356 (search-forward-regexp "^[ \t]*%" (save-excursion (end-of-line) (point)) t)
2357 (= (+ 1 col) (current-column)))
2358 (setq beg (- (point) 1)))
2359 (when (= done 0)
2360 (forward-line 1))
2361 ;; We may have a line with code above...
2362 (when (and (zerop (setq done (forward-line -1)))
2363 (search-forward "%" (save-excursion (end-of-line) (point)) t)
2364 (= (+ 1 col) (current-column)))
2365 (setq beg (- (point) 1)))
2366 (when (= done 0)
2367 (forward-line 1))
2368 ;; Go forward
2369 (goto-char lit-limits-b)
2370 (beginning-of-line)
2371 (while (and (zerop (forward-line 1))
2372 (search-forward-regexp "^[ \t]*%" (save-excursion (end-of-line) (point)) t)
2373 (= (+ 1 col) (current-column)))
2374 (setq end (save-excursion (end-of-line) (point))))
2375 (list beg end lit-type))
2376 (list lit-limits-b lit-limits-e lit-type)
2377 )
2378 (error (list lit-limits-b lit-limits-e lit-type))))
2379 ))))
2380
2381(defun prolog-guess-fill-prefix ()
2382 ;; fill 'txt entities?
2383 (when (save-excursion
2384 (end-of-line)
2385 (equal (prolog-in-string-or-comment) 'cmt))
2386 (let* ((bounds (prolog-comment-limits))
2387 (cbeg (car bounds))
2388 (type (nth 2 bounds))
2389 beg end)
2390 (save-excursion
2391 (end-of-line)
2392 (setq end (point))
2393 (beginning-of-line)
2394 (setq beg (point))
2395 (if (and (eq type 'line)
2396 (> cbeg beg)
2397 (save-excursion (not (search-forward-regexp "^[ \t]*%"
2398 cbeg t))))
2399 (progn
2400 (goto-char cbeg)
2401 (search-forward-regexp "%+[ \t]*" end t)
2402 (prolog-replace-in-string (buffer-substring beg (point))
2403 "[^ \t%]" " "))
2404 ;(goto-char beg)
2405 (if (search-forward-regexp "^[ \t]*\\(%+\\|\\*+\\|/\\*+\\)[ \t]*"
2406 end t)
2407 (prolog-replace-in-string (buffer-substring beg (point)) "/" " ")
2408 (beginning-of-line)
2409 (when (search-forward-regexp "^[ \t]+" end t)
2410 (buffer-substring beg (point)))))))))
2411
2412(defun prolog-fill-paragraph ()
2413 "Fill paragraph comment at or after point."
2414 (interactive)
2415 (let* ((bounds (prolog-comment-limits))
2416 (type (nth 2 bounds)))
2417 (if (eq type 'line)
2418 (let ((fill-prefix (prolog-guess-fill-prefix)))
2419 (fill-paragraph nil))
2420 (save-excursion
2421 (save-restriction
2422 ;; exclude surrounding lines that delimit a multiline comment
2423 ;; and don't contain alphabetic characters, like "/*******",
2424 ;; "- - - */" etc.
2425 (save-excursion
2426 (backward-paragraph)
2427 (unless (bobp) (forward-line))
2428 (if (string-match "^/\\*[^a-zA-Z]*$" (thing-at-point 'line))
2429 (narrow-to-region (point-at-eol) (point-max))))
2430 (save-excursion
2431 (forward-paragraph)
2432 (forward-line -1)
2433 (if (string-match "^[^a-zA-Z]*\\*/$" (thing-at-point 'line))
2434 (narrow-to-region (point-min) (point-at-bol))))
2435 (let ((fill-prefix (prolog-guess-fill-prefix)))
2436 (fill-paragraph nil))))
2437 )))
2438
2439(defun prolog-do-auto-fill ()
2440 "Carry out Auto Fill for Prolog mode.
2441In effect it sets the `fill-prefix' when inside comments and then calls
2442`do-auto-fill'."
2443 (let ((fill-prefix (prolog-guess-fill-prefix)))
2444 (do-auto-fill)
2445 ))
2446
2447(defalias 'prolog-replace-in-string
2448 (if (fboundp 'replace-in-string)
2449 #'replace-in-string
2450 (lambda (str regexp newtext &optional literal)
2451 (replace-regexp-in-string regexp newtext str nil literal))))
2452
2453;;-------------------------------------------------------------------
2454;; The tokenizer
2455;;-------------------------------------------------------------------
2456
2457(defconst prolog-tokenize-searchkey
2458 (concat "[0-9]+'"
2459 "\\|"
2460 "['\"]"
2461 "\\|"
2462 prolog-left-paren
2463 "\\|"
2464 prolog-right-paren
2465 "\\|"
2466 "%"
2467 "\\|"
2468 "/\\*"
2469 ))
2470
2471(defun prolog-tokenize (beg end &optional stopcond)
2472 "Tokenize a region of prolog code between BEG and END.
2473STOPCOND decides the stop condition of the parsing. Valid values
2474are 'zerodepth which stops the parsing at the first right parenthesis
2475where the parenthesis depth is zero, 'skipover which skips over
2476the current entity (e.g. a list, a string, etc.) and nil.
2477
2478The function returns a list with the following information:
2479 0. parenthesis depth
2480 3. 'atm if END is inside an atom
2481 'str if END is inside a string
2482 'chr if END is in a character code expression (0'x)
2483 nil otherwise
2484 4. non-nil if END is inside a comment
2485 5. end position (always equal to END if STOPCOND is nil)
2486The rest of the elements are undefined."
2487 (save-excursion
2488 (let* ((end2 (1+ end))
2489 oldp
2490 (depth 0)
2491 (quoted nil)
2492 inside_cmt
2493 (endpos end2)
2494 skiptype ; The type of entity we'll skip over
2495 )
2496 (goto-char beg)
2497
2498 (if (and (eq stopcond 'skipover)
2499 (looking-at "[^[({'\"]"))
2500 (setq endpos (point)) ; Stay where we are
2501 (while (and
2502 (re-search-forward prolog-tokenize-searchkey end2 t)
2503 (< (point) end2))
2504 (progn
2505 (setq oldp (point))
2506 (goto-char (match-beginning 0))
2507 (cond
2508 ;; Atoms and strings
2509 ((looking-at "'")
2510 ;; Find end of atom
2511 (if (re-search-forward "[^\\]'" end2 'limit)
2512 ;; Found end of atom
2513 (progn
2514 (setq oldp end2)
2515 (if (and (eq stopcond 'skipover)
2516 (not skiptype))
2517 (setq endpos (point))
2518 (setq oldp (point)))) ; Continue tokenizing
2519 (setq quoted 'atm)))
2520
2521 ((looking-at "\"")
2522 ;; Find end of string
2523 (if (re-search-forward "[^\\]\"" end2 'limit)
2524 ;; Found end of string
2525 (progn
2526 (setq oldp end2)
2527 (if (and (eq stopcond 'skipover)
2528 (not skiptype))
2529 (setq endpos (point))
2530 (setq oldp (point)))) ; Continue tokenizing
2531 (setq quoted 'str)))
2532
2533 ;; Paren stuff
2534 ((looking-at prolog-left-paren)
2535 (setq depth (1+ depth))
2536 (setq skiptype 'paren))
2537
2538 ((looking-at prolog-right-paren)
2539 (setq depth (1- depth))
2540 (if (and
2541 (or (eq stopcond 'zerodepth)
2542 (and (eq stopcond 'skipover)
2543 (eq skiptype 'paren)))
2544 (= depth 0))
2545 (progn
2546 (setq endpos (1+ (point)))
2547 (setq oldp end2))))
2548
2549 ;; Comment stuff
2550 ((looking-at comment-start)
2551 (end-of-line)
2552 ;; (if (>= (point) end2)
2553 (if (>= (point) end)
2554 (progn
2555 (setq inside_cmt t)
2556 (setq oldp end2))
2557 (setq oldp (point))))
2558
2559 ((looking-at "/\\*")
2560 (if (re-search-forward "\\*/" end2 'limit)
2561 (setq oldp (point))
2562 (setq inside_cmt t)
2563 (setq oldp end2)))
2564
2565 ;; 0'char
2566 ((looking-at "0'")
2567 (setq oldp (1+ (match-end 0)))
2568 (if (> oldp end)
2569 (setq quoted 'chr)))
2570
2571 ;; base'number
2572 ((looking-at "[0-9]+'")
2573 (goto-char (match-end 0))
2574 (skip-chars-forward "0-9a-zA-Z")
2575 (setq oldp (point)))
2576
2577
2578 )
2579 (goto-char oldp)
2580 )) ; End of while
2581 )
2582
2583 ;; Deal with multi-line comments
2584 (and (prolog-inside-mline-comment end)
2585 (setq inside_cmt t))
2586
2587 ;; Create return list
2588 (list depth nil nil quoted inside_cmt endpos)
2589 )))
2590
2591(defun prolog-inside-mline-comment (here)
2592 (save-excursion
2593 (goto-char here)
2594 (let* ((next-close (save-excursion (search-forward "*/" nil t)))
2595 (next-open (save-excursion (search-forward "/*" nil t)))
2596 (prev-open (save-excursion (search-backward "/*" nil t)))
2597 (prev-close (save-excursion (search-backward "*/" nil t)))
2598 (unmatched-next-close (and next-close
2599 (or (not next-open)
2600 (> next-open next-close))))
2601 (unmatched-prev-open (and prev-open
2602 (or (not prev-close)
2603 (> prev-open prev-close))))
2604 )
2605 (or unmatched-next-close unmatched-prev-open)
2606 )))
2607
2608
2609;;-------------------------------------------------------------------
2610;; Online help
2611;;-------------------------------------------------------------------
2612
2613(defvar prolog-help-function
2614 '((mercury nil)
2615 (eclipse prolog-help-online)
2616 ;; (sicstus prolog-help-info)
2617 (sicstus prolog-find-documentation)
2618 (swi prolog-help-online)
2619 (t prolog-help-online))
2620 "Alist for the name of the function for finding help on a predicate.")
2621
2622(defun prolog-help-on-predicate ()
2623 "Invoke online help on the atom under cursor."
2624 (interactive)
2625
2626 (cond
2627 ;; Redirect help for SICStus to `prolog-find-documentation'.
2628 ((eq prolog-help-function-i 'prolog-find-documentation)
2629 (prolog-find-documentation))
2630
2631 ;; Otherwise, ask for the predicate name and then call the function
2632 ;; in prolog-help-function-i
2633 (t
2634 (let* (word
2635 predicate
2636 ;point
2637 )
2638 (setq word (prolog-atom-under-point))
2639 (setq predicate (read-from-minibuffer
2640 (format "Help on predicate%s: "
2641 (if word
2642 (concat " (default " word ")")
2643 ""))))
2644 (if (string= predicate "")
2645 (setq predicate word))
2646 (if prolog-help-function-i
2647 (funcall prolog-help-function-i predicate)
2648 (error "Sorry, no help method defined for this Prolog system."))))
2649 ))
2650
2651(defun prolog-help-info (predicate)
2652 (let ((buffer (current-buffer))
2653 oldp
2654 (str (concat "^\\* " (regexp-quote predicate) " */")))
2655 (require 'info)
2656 (pop-to-buffer nil)
2657 (Info-goto-node prolog-info-predicate-index)
2658 (if (not (re-search-forward str nil t))
2659 (error (format "Help on predicate `%s' not found." predicate)))
2660
2661 (setq oldp (point))
2662 (if (re-search-forward str nil t)
2663 ;; Multiple matches, ask user
2664 (let ((max 2)
2665 n)
2666 ;; Count matches
2667 (while (re-search-forward str nil t)
2668 (setq max (1+ max)))
2669
2670 (goto-char oldp)
2671 (re-search-backward "[^ /]" nil t)
2672 (recenter 0)
2673 (setq n (read-string ;; was read-input, which is obsolete
2674 (format "Several matches, choose (1-%d): " max) "1"))
2675 (forward-line (- (string-to-number n) 1)))
2676 ;; Single match
2677 (re-search-backward "[^ /]" nil t))
2678
2679 ;; (Info-follow-nearest-node (point))
2680 (prolog-Info-follow-nearest-node)
2681 (re-search-forward (concat "^`" (regexp-quote predicate)) nil t)
2682 (beginning-of-line)
2683 (recenter 0)
2684 (pop-to-buffer buffer)))
2685
2686(defun prolog-Info-follow-nearest-node ()
2687 (if (featurep 'xemacs)
2688 (Info-follow-nearest-node (point))
2689 (Info-follow-nearest-node)))
2690
2691(defun prolog-help-online (predicate)
2692 (prolog-ensure-process)
2693 (process-send-string "prolog" (concat "help(" predicate ").\n"))
2694 (display-buffer "*prolog*"))
2695
2696(defun prolog-help-apropos (string)
2697 "Find Prolog apropos on given STRING.
2698This function is only available when `prolog-system' is set to `swi'."
2699 (interactive "sApropos: ")
2700 (cond
2701 ((eq prolog-system 'swi)
2702 (prolog-ensure-process)
2703 (process-send-string "prolog" (concat "apropos(" string ").\n"))
2704 (display-buffer "*prolog*"))
2705 (t
2706 (error "Sorry, no Prolog apropos available for this Prolog system."))))
2707
2708(defun prolog-atom-under-point ()
2709 "Return the atom under or left to the point."
2710 (save-excursion
2711 (let ((nonatom_chars "[](){},\. \t\n")
2712 start)
2713 (skip-chars-forward (concat "^" nonatom_chars))
2714 (skip-chars-backward nonatom_chars)
2715 (skip-chars-backward (concat "^" nonatom_chars))
2716 (setq start (point))
2717 (skip-chars-forward (concat "^" nonatom_chars))
2718 (buffer-substring-no-properties start (point))
2719 )))
2720
2721
2722;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
2723;; Help function with completion
2724;; Stolen from Per Mildner's SICStus debugger mode and modified
2725
2726(defun prolog-find-documentation ()
2727 "Go to the Info node for a predicate in the SICStus Info manual."
2728 (interactive)
2729 (let ((pred (prolog-read-predicate)))
2730 (prolog-goto-predicate-info pred)))
2731
2732(defvar prolog-info-alist nil
2733 "Alist with all builtin predicates.
2734Only for internal use by `prolog-find-documentation'")
2735
2736;; Very similar to prolog-help-info except that that function cannot
2737;; cope with arity and that it asks the user if there are several
2738;; functors with different arity. This function also uses
2739;; prolog-info-alist for finding the info node, rather than parsing
2740;; the predicate index.
2741(defun prolog-goto-predicate-info (predicate)
2742 "Go to the info page for PREDICATE, which is a PredSpec."
2743 (interactive)
2744 (require 'info)
2745 (string-match "\\(.*\\)/\\([0-9]+\\).*$" predicate)
2746 (let ((buffer (current-buffer))
2747 (name (match-string 1 predicate))
2748 (arity (match-string 2 predicate))
2749 ;oldp
2750 ;(str (regexp-quote predicate))
2751 )
2752 (setq arity (string-to-number arity))
2753 (pop-to-buffer nil)
2754
2755 (Info-goto-node
2756 prolog-info-predicate-index) ;; We must be in the SICStus pages
2757 (Info-goto-node (car (cdr (assoc predicate prolog-info-alist))))
2758
2759 (prolog-find-term (regexp-quote name) arity "^`")
2760
2761 (recenter 0)
2762 (pop-to-buffer buffer))
2763)
2764
2765(defun prolog-read-predicate ()
2766 "Read a PredSpec from the user.
2767Returned value is a string \"FUNCTOR/ARITY\".
2768Interaction supports completion."
2769 (let ((initial (prolog-atom-under-point))
2770 answer)
2771 ;; If the predicate index is not yet built, do it now
2772 (if (not prolog-info-alist)
2773 (prolog-build-info-alist))
2774 ;; Test if the initial string could be the base for completion.
2775 ;; Discard it if not.
2776 (if (eq (try-completion initial prolog-info-alist) nil)
2777 (setq initial ""))
2778 ;; Read the PredSpec from the user
2779 (setq answer (completing-read
2780 "Help on predicate: "
2781 prolog-info-alist nil t initial))
2782 (if (equal answer "")
2783 initial
2784 answer)))
2785
2786(defun prolog-build-info-alist (&optional verbose)
2787 "Build an alist of all builtins and library predicates.
2788Each element is of the form (\"NAME/ARITY\" . (INFO-NODE1 INFO-NODE2 ...)).
2789Typically there is just one Info node associated with each name
2790If an optional argument VERBOSE is non-nil, print messages at the beginning
2791and end of list building."
2792 (if verbose
2793 (message "Building info alist..."))
2794 (setq prolog-info-alist
2795 (let ((l ())
2796 (last-entry (cons "" ())))
2797 (save-excursion
2798 (save-window-excursion
2799 ;; select any window but the minibuffer (as we cannot switch
2800 ;; buffers in minibuffer window.
2801 ;; I am not sure this is the right/best way
2802 (if (active-minibuffer-window) ; nil if none active
2803 (select-window (next-window)))
2804 ;; Do this after going away from minibuffer window
2805 (save-window-excursion
2806 (info))
2807 (Info-goto-node prolog-info-predicate-index)
2808 (goto-char (point-min))
2809 (while (re-search-forward
2810 "^\\* \\(.+\\)/\\([0-9]+\\)\\([^\n:*]*\\):" nil t)
2811 (let* ((name (match-string 1))
2812 (arity (string-to-number (match-string 2)))
2813 (comment (match-string 3))
2814 (fa (format "%s/%d%s" name arity comment))
2815 info-node)
2816 (beginning-of-line)
2817 ;; Extract the info node name
2818 (setq info-node (progn
2819 (re-search-forward ":[ \t]*\\([^:]+\\).$")
2820 (match-string 1)
2821 ))
2822 ;; ###### Easier? (from Milan version 0.1.28)
2823 ;; (setq info-node (Info-extract-menu-node-name))
2824 (if (equal fa (car last-entry))
2825 (setcdr last-entry (cons info-node (cdr last-entry)))
2826 (setq last-entry (cons fa (list info-node))
2827 l (cons last-entry l)))))
2828 (nreverse l)
2829 ))))
2830 (if verbose
2831 (message "Building info alist... done.")))
2832
2833
2834;;-------------------------------------------------------------------
2835;; Miscellaneous functions
2836;;-------------------------------------------------------------------
2837
2838;; For Windows. Change backslash to slash. SICStus handles either
2839;; path separator but backslash must be doubled, therefore use slash.
2840(defun prolog-bsts (string)
2841 "Change backslashes to slashes in STRING."
2842 (let ((str1 (copy-sequence string))
2843 (len (length string))
2844 (i 0))
2845 (while (< i len)
2846 (if (char-equal (aref str1 i) ?\\)
2847 (aset str1 i ?/))
2848 (setq i (1+ i)))
2849 str1))
2850
2851;(defun prolog-temporary-file ()
2852; "Make temporary file name for compilation."
2853; (make-temp-name
2854; (concat
2855; (or
2856; (getenv "TMPDIR")
2857; (getenv "TEMP")
2858; (getenv "TMP")
2859; (getenv "SYSTEMP")
2860; "/tmp")
2861; "/prolcomp")))
2862;(setq prolog-temp-filename (prolog-bsts (prolog-temporary-file)))
2863
2864(defun prolog-temporary-file ()
2865 "Make temporary file name for compilation."
2866 (if prolog-temporary-file-name
2867 ;; We already have a file, erase content and continue
2868 (progn
2869 (write-region "" nil prolog-temporary-file-name nil 'silent)
2870 prolog-temporary-file-name)
2871 ;; Actually create the file and set `prolog-temporary-file-name' accordingly
2872 (let* ((umask (default-file-modes))
2873 (temporary-file-directory (or
2874 (getenv "TMPDIR")
2875 (getenv "TEMP")
2876 (getenv "TMP")
2877 (getenv "SYSTEMP")
2878 "/tmp"))
2879 (prefix (expand-file-name "prolcomp" temporary-file-directory))
2880 (suffix ".pl")
2881 file)
2882 (unwind-protect
2883 (progn
2884 ;; Create temp files with strict access rights.
2885 (set-default-file-modes #o700)
2886 (while (condition-case ()
2887 (progn
2888 (setq file (concat (make-temp-name prefix) suffix))
2889 ;; (concat (make-temp-name "/tmp/prolcomp") ".pl")
2890 (unless (file-exists-p file)
2891 (write-region "" nil file nil 'silent))
2892 nil)
2893 (file-already-exists t))
2894 ;; the file was somehow created by someone else between
2895 ;; `make-temp-name' and `write-region', let's try again.
2896 nil)
2897 (setq prolog-temporary-file-name file))
2898 ;; Reset the umask.
2899 (set-default-file-modes umask)))
2900 ))
2901
2902(defun prolog-goto-prolog-process-buffer ()
2903 "Switch to the prolog process buffer and go to its end."
2904 (switch-to-buffer-other-window "*prolog*")
2905 (goto-char (point-max))
2906)
2907
2908(defun prolog-enable-sicstus-sd ()
2909 "Enable the source level debugging facilities of SICStus 3.7 and later."
2910 (interactive)
2911 (require 'pltrace) ; Load the SICStus debugger code
2912 ;; Turn on the source level debugging by default
2913 (add-hook 'prolog-inferior-mode-hook 'pltrace-on)
2914 (if (not prolog-use-sicstus-sd)
2915 (progn
2916 ;; If there is a *prolog* buffer, then call pltrace-on
2917 (if (get-buffer "*prolog*")
2918 ;; Avoid compilation warnings by using eval
2919 (eval '(pltrace-on)))
2920 (setq prolog-use-sicstus-sd t)
2921 )))
2922
2923(defun prolog-disable-sicstus-sd ()
2924 "Disable the source level debugging facilities of SICStus 3.7 and later."
2925 (interactive)
2926 (setq prolog-use-sicstus-sd nil)
2927 ;; Remove the hook
2928 (remove-hook 'prolog-inferior-mode-hook 'pltrace-on)
2929 ;; If there is a *prolog* buffer, then call pltrace-off
2930 (if (get-buffer "*prolog*")
2931 ;; Avoid compile warnings by using eval
2932 (eval '(pltrace-off))))
2933
2934(defun prolog-debug-on (&optional arg)
2935 "Enable debugging.
2936When called with prefix argument ARG, disable debugging instead."
2937 (interactive "P")
2938 (if arg
2939 (prolog-debug-off)
2940 (prolog-process-insert-string (get-process "prolog")
2941 prolog-debug-on-string)
2942 (process-send-string "prolog" prolog-debug-on-string)))
2943
2944(defun prolog-debug-off ()
2945 "Disable debugging."
2946 (interactive)
2947 (prolog-process-insert-string (get-process "prolog")
2948 prolog-debug-off-string)
2949 (process-send-string "prolog" prolog-debug-off-string))
2950
2951(defun prolog-trace-on (&optional arg)
2952 "Enable tracing.
2953When called with prefix argument ARG, disable tracing instead."
2954 (interactive "P")
2955 (if arg
2956 (prolog-trace-off)
2957 (prolog-process-insert-string (get-process "prolog")
2958 prolog-trace-on-string)
2959 (process-send-string "prolog" prolog-trace-on-string)))
2960
2961(defun prolog-trace-off ()
2962 "Disable tracing."
2963 (interactive)
2964 (prolog-process-insert-string (get-process "prolog")
2965 prolog-trace-off-string)
2966 (process-send-string "prolog" prolog-trace-off-string))
2967
2968(defun prolog-zip-on (&optional arg)
2969 "Enable zipping (for SICStus 3.7 and later).
2970When called with prefix argument ARG, disable zipping instead."
2971 (interactive "P")
2972 (if arg
2973 (prolog-zip-off)
2974 (prolog-process-insert-string (get-process "prolog")
2975 prolog-zip-on-string)
2976 (process-send-string "prolog" prolog-zip-on-string)))
2977
2978(defun prolog-zip-off ()
2979 "Disable zipping (for SICStus 3.7 and later)."
2980 (interactive)
2981 (prolog-process-insert-string (get-process "prolog")
2982 prolog-zip-off-string)
2983 (process-send-string "prolog" prolog-zip-off-string))
2984
2985;; (defun prolog-create-predicate-index ()
2986;; "Create an index for all predicates in the buffer."
2987;; (let ((predlist '())
2988;; clauseinfo
2989;; object
2990;; pos
2991;; )
2992;; (goto-char (point-min))
2993;; ;; Replace with prolog-clause-start!
2994;; (while (re-search-forward "^.+:-" nil t)
2995;; (setq pos (match-beginning 0))
2996;; (setq clauseinfo (prolog-clause-info))
2997;; (setq object (prolog-in-object))
2998;; (setq predlist (append
2999;; predlist
3000;; (list (cons
3001;; (if (and (eq prolog-system 'sicstus)
3002;; (prolog-in-object))
3003;; (format "%s::%s/%d"
3004;; object
3005;; (nth 0 clauseinfo)
3006;; (nth 1 clauseinfo))
3007;; (format "%s/%d"
3008;; (nth 0 clauseinfo)
3009;; (nth 1 clauseinfo)))
3010;; pos
3011;; ))))
3012;; (prolog-end-of-predicate))
3013;; predlist))
3014
3015(defun prolog-get-predspec ()
3016 (save-excursion
3017 (let ((state (prolog-clause-info))
3018 (object (prolog-in-object)))
3019 (if (or (equal (nth 0 state) "") (equal (prolog-in-string-or-comment) 'cmt))
3020 nil
3021 (if (and (eq prolog-system 'sicstus)
3022 object)
3023 (format "%s::%s/%d"
3024 object
3025 (nth 0 state)
3026 (nth 1 state))
3027 (format "%s/%d"
3028 (nth 0 state)
3029 (nth 1 state)))
3030 ))))
3031
3032;; For backward compatibility. Stolen from custom.el.
3033(or (fboundp 'match-string)
3034 ;; Introduced in Emacs 19.29.
3035 (defun match-string (num &optional string)
3036 "Return string of text matched by last search.
3037NUM specifies which parenthesized expression in the last regexp.
3038 Value is nil if NUMth pair didn't match, or there were less than NUM pairs.
3039Zero means the entire text matched by the whole regexp or whole string.
3040STRING should be given if the last search was by `string-match' on STRING."
3041 (if (match-beginning num)
3042 (if string
3043 (substring string (match-beginning num) (match-end num))
3044 (buffer-substring (match-beginning num) (match-end num))))))
3045
3046(defun prolog-pred-start ()
3047 "Return the starting point of the first clause of the current predicate."
3048 (save-excursion
3049 (goto-char (prolog-clause-start))
3050 ;; Find first clause, unless it was a directive
3051 (if (and (not (looking-at "[:?]-"))
3052 (not (looking-at "[ \t]*[%/]")) ; Comment
3053
3054 )
3055 (let* ((pinfo (prolog-clause-info))
3056 (predname (nth 0 pinfo))
3057 (arity (nth 1 pinfo))
3058 (op (point)))
3059 (while (and (re-search-backward
3060 (format "^%s\\([(\\.]\\| *%s\\)"
3061 predname prolog-head-delimiter) nil t)
3062 (= arity (nth 1 (prolog-clause-info)))
3063 )
3064 (setq op (point)))
3065 (if (eq prolog-system 'mercury)
3066 ;; Skip to the beginning of declarations of the predicate
3067 (progn
3068 (goto-char (prolog-beginning-of-clause))
3069 (while (and (not (eq (point) op))
3070 (looking-at
3071 (format ":-[ \t]*\\(pred\\|mode\\)[ \t]+%s"
3072 predname)))
3073 (setq op (point))
3074 (goto-char (prolog-beginning-of-clause)))))
3075 op)
3076 (point))))
3077
3078(defun prolog-pred-end ()
3079 "Return the position at the end of the last clause of the current predicate."
3080 (save-excursion
3081 (goto-char (prolog-clause-end)) ; if we are before the first predicate
3082 (goto-char (prolog-clause-start))
3083 (let* ((pinfo (prolog-clause-info))
3084 (predname (nth 0 pinfo))
3085 (arity (nth 1 pinfo))
3086 oldp
3087 (notdone t)
3088 (op (point)))
3089 (if (looking-at "[:?]-")
3090 ;; This was a directive
3091 (progn
3092 (if (and (eq prolog-system 'mercury)
3093 (looking-at
3094 (format ":-[ \t]*\\(pred\\|mode\\)[ \t]+\\(%s+\\)"
3095 prolog-atom-regexp)))
3096 ;; Skip predicate declarations
3097 (progn
3098 (setq predname (buffer-substring-no-properties
3099 (match-beginning 2) (match-end 2)))
3100 (while (re-search-forward
3101 (format
3102 "\n*\\(:-[ \t]*\\(pred\\|mode\\)[ \t]+\\)?%s[( \t]"
3103 predname)
3104 nil t))))
3105 (goto-char (prolog-clause-end))
3106 (setq op (point)))
3107 ;; It was not a directive, find the last clause
3108 (while (and notdone
3109 (re-search-forward
3110 (format "^%s\\([(\\.]\\| *%s\\)"
3111 predname prolog-head-delimiter) nil t)
3112 (= arity (nth 1 (prolog-clause-info))))
3113 (setq oldp (point))
3114 (setq op (prolog-clause-end))
3115 (if (>= oldp op)
3116 ;; End of clause not found.
3117 (setq notdone nil)
3118 ;; Continue while loop
3119 (goto-char op))))
3120 op)))
3121
3122(defun prolog-clause-start (&optional not-allow-methods)
3123 "Return the position at the start of the head of the current clause.
3124If NOTALLOWMETHODS is non-nil then do not match on methods in
3125objects (relevent only if 'prolog-system' is set to 'sicstus)."
3126 (save-excursion
3127 (let ((notdone t)
3128 (retval (point-min)))
3129 (end-of-line)
3130
3131 ;; SICStus object?
3132 (if (and (not not-allow-methods)
3133 (eq prolog-system 'sicstus)
3134 (prolog-in-object))
3135 (while (and
3136 notdone
3137 ;; Search for a head or a fact
3138 (re-search-backward
3139 ;; If in object, then find method start.
3140 ;; "^[ \t]+[a-z$].*\\(:-\\|&\\|:: {\\|,\\)"
3141 "^[ \t]+[a-z$].*\\(:-\\|&\\|:: {\\)" ; The comma causes
3142 ; problems since we cannot assume
3143 ; that the line starts at column 0,
3144 ; thus we don't know if the line
3145 ; is a head or a subgoal
3146 (point-min) t))
3147 (if (>= (prolog-paren-balance) 0) ; To no match on " a) :-"
3148 ;; Start of method found
3149 (progn
3150 (setq retval (point))
3151 (setq notdone nil)))
3152 ) ; End of while
3153
3154 ;; Not in object
3155 (while (and
3156 notdone
3157 ;; Search for a text at beginning of a line
3158 ;; ######
3159 ;; (re-search-backward "^[a-z$']" nil t))
3160 (let ((case-fold-search nil))
3161 (re-search-backward
3162 ;; (format "^[%s$']" prolog-lower-case-string)
3163 ;; FIXME: Use [:lower:]
3164 (format "^\\([%s$']\\|[:?]-\\)" prolog-lower-case-string)
3165 nil t)))
3166 (let ((bal (prolog-paren-balance)))
3167 (cond
3168 ((> bal 0)
3169 ;; Start of clause found
3170 (progn
3171 (setq retval (point))
3172 (setq notdone nil)))
3173 ((and (= bal 0)
3174 (looking-at
3175 (format ".*\\(\\.\\|%s\\|!,\\)[ \t]*\\(%%.*\\|\\)$"
3176 prolog-head-delimiter)))
3177 ;; Start of clause found if the line ends with a '.' or
3178 ;; a prolog-head-delimiter
3179 (progn
3180 (setq retval (point))
3181 (setq notdone nil))
3182 )
3183 (t nil) ; Do nothing
3184 ))))
3185
3186 retval)))
3187
3188(defun prolog-clause-end (&optional not-allow-methods)
3189 "Return the position at the end of the current clause.
3190If NOTALLOWMETHODS is non-nil then do not match on methods in
3191objects (relevent only if 'prolog-system' is set to 'sicstus)."
3192 (save-excursion
3193 (beginning-of-line) ; Necessary since we use "^...." for the search
3194 (if (re-search-forward
3195 (if (and (not not-allow-methods)
3196 (eq prolog-system 'sicstus)
3197 (prolog-in-object))
3198 (format
3199 "^\\(%s\\|%s\\|[^\n\'\"%%]\\)*&[ \t]*\\(\\|%%.*\\)$\\|[ \t]*}"
3200 prolog-quoted-atom-regexp prolog-string-regexp)
3201 (format
3202 "^\\(%s\\|%s\\|[^\n\'\"%%]\\)*\\.[ \t]*\\(\\|%%.*\\)$"
3203 prolog-quoted-atom-regexp prolog-string-regexp))
3204 nil t)
3205 (if (and (prolog-in-string-or-comment)
3206 (not (eobp)))
3207 (progn
3208 (forward-char)
3209 (prolog-clause-end))
3210 (point))
3211 (point))))
3212
3213(defun prolog-clause-info ()
3214 "Return a (name arity) list for the current clause."
3215 (let (predname (arity 0))
3216 (save-excursion
3217 (goto-char (prolog-clause-start))
3218 (let ((op (point)))
3219 (if (looking-at prolog-atom-char-regexp)
3220 (progn
3221 (skip-chars-forward "^ (\\.")
3222 (setq predname (buffer-substring op (point))))
3223 (setq predname ""))
3224 ;; Retrieve the arity
3225 (if (looking-at prolog-left-paren)
3226 (let ((endp (save-excursion
3227 (prolog-forward-list) (point))))
3228 (setq arity 1)
3229 (forward-char 1) ; Skip the opening paren
3230 (while (progn
3231 (skip-chars-forward "^[({,'\"")
3232 (< (point) endp))
3233 (if (looking-at ",")
3234 (progn
3235 (setq arity (1+ arity))
3236 (forward-char 1) ; Skip the comma
3237 )
3238 ;; We found a string, list or something else we want
3239 ;; to skip over. Always use prolog-tokenize,
3240 ;; parse-partial-sexp does not have a 'skipover mode.
3241 (goto-char (nth 5 (prolog-tokenize (point) endp 'skipover))))
3242 )))
3243 (list predname arity)
3244 ))))
3245
3246(defun prolog-in-object ()
3247 "Return object name if the point is inside a SICStus object definition."
3248 ;; Return object name if the last line that starts with a character
3249 ;; that is neither white space nor a comment start
3250 (save-excursion
3251 (if (save-excursion
3252 (beginning-of-line)
3253 (looking-at "\\([^\n ]+\\)[ \t]*::[ \t]*{"))
3254 ;; We were in the head of the object
3255 (match-string 1)
3256 ;; We were not in the head
3257 (if (and (re-search-backward "^[a-z$'}]" nil t)
3258 (looking-at "\\([^\n ]+\\)[ \t]*::[ \t]*{"))
3259 (match-string 1)
3260 nil))))
3261
3262(defun prolog-forward-list ()
3263 "Move the point to the matching right parenthesis."
3264 (interactive)
3265 (if prolog-use-prolog-tokenizer-flag
3266 (let ((state (prolog-tokenize (point) (point-max) 'zerodepth)))
3267 (goto-char (nth 5 state)))
3268 (forward-list)))
3269
3270;; NB: This could be done more efficiently!
3271(defun prolog-backward-list ()
3272 "Move the point to the matching left parenthesis."
3273 (interactive)
3274 (if prolog-use-prolog-tokenizer-flag
3275 (let ((bal 0)
3276 (paren-regexp (concat prolog-left-paren "\\|" prolog-right-paren))
3277 (notdone t))
3278 (while (and notdone (re-search-backward paren-regexp nil t))
3279 (cond
3280 ((looking-at prolog-left-paren)
3281 (if (not (prolog-in-string-or-comment))
3282 (setq bal (1+ bal)))
3283 (if (= bal 0)
3284 (setq notdone nil)))
3285 ((looking-at prolog-right-paren)
3286 (if (not (prolog-in-string-or-comment))
3287 (setq bal (1- bal))))
3288 )))
3289 (backward-list)))
3290
3291(defun prolog-beginning-of-clause ()
3292 "Move to the beginning of current clause.
3293If already at the beginning of clause, move to previous clause."
3294 (interactive)
3295 (let ((point (point))
3296 (new-point (prolog-clause-start)))
3297 (if (and (>= new-point point)
3298 (> point 1))
3299 (progn
3300 (goto-char (1- point))
3301 (goto-char (prolog-clause-start)))
3302 (goto-char new-point)
3303 (skip-chars-forward " \t"))))
3304
3305;; (defun prolog-previous-clause ()
3306;; "Move to the beginning of the previous clause."
3307;; (interactive)
3308;; (forward-char -1)
3309;; (prolog-beginning-of-clause))
3310
3311(defun prolog-end-of-clause ()
3312 "Move to the end of clause.
3313If already at the end of clause, move to next clause."
3314 (interactive)
3315 (let ((point (point))
3316 (new-point (prolog-clause-end)))
3317 (if (and (<= new-point point)
3318 (not (eq new-point (point-max))))
3319 (progn
3320 (goto-char (1+ point))
3321 (goto-char (prolog-clause-end)))
3322 (goto-char new-point))))
3323
3324;; (defun prolog-next-clause ()
3325;; "Move to the beginning of the next clause."
3326;; (interactive)
3327;; (prolog-end-of-clause)
3328;; (forward-char)
3329;; (prolog-end-of-clause)
3330;; (prolog-beginning-of-clause))
3331
3332(defun prolog-beginning-of-predicate ()
3333 "Go to the nearest beginning of predicate before current point.
3334Return the final point or nil if no such a beginning was found."
3335 (interactive)
3336 (let ((op (point))
3337 (pos (prolog-pred-start)))
3338 (if pos
3339 (if (= op pos)
3340 (if (not (bobp))
3341 (progn
3342 (goto-char pos)
3343 (backward-char 1)
3344 (setq pos (prolog-pred-start))
3345 (if pos
3346 (progn
3347 (goto-char pos)
3348 (point)))))
3349 (goto-char pos)
3350 (point)))))
3351
3352(defun prolog-end-of-predicate ()
3353 "Go to the end of the current predicate."
3354 (interactive)
3355 (let ((op (point)))
3356 (goto-char (prolog-pred-end))
3357 (if (= op (point))
3358 (progn
3359 (forward-line 1)
3360 (prolog-end-of-predicate)))))
3361
3362(defun prolog-insert-predspec ()
3363 "Insert the predspec for the current predicate."
3364 (interactive)
3365 (let* ((pinfo (prolog-clause-info))
3366 (predname (nth 0 pinfo))
3367 (arity (nth 1 pinfo)))
3368 (insert (format "%s/%d" predname arity))))
3369
3370(defun prolog-view-predspec ()
3371 "Insert the predspec for the current predicate."
3372 (interactive)
3373 (let* ((pinfo (prolog-clause-info))
3374 (predname (nth 0 pinfo))
3375 (arity (nth 1 pinfo)))
3376 (message (format "%s/%d" predname arity))))
3377
3378(defun prolog-insert-predicate-template ()
3379 "Insert the template for the current clause."
3380 (interactive)
3381 (let* ((n 1)
3382 oldp
3383 (pinfo (prolog-clause-info))
3384 (predname (nth 0 pinfo))
3385 (arity (nth 1 pinfo)))
3386 (insert predname)
3387 (if (> arity 0)
3388 (progn
3389 (insert "(")
3390 (when prolog-electric-dot-full-predicate-template
3391 (setq oldp (point))
3392 (while (< n arity)
3393 (insert ",")
3394 (setq n (1+ n)))
3395 (insert ")")
3396 (goto-char oldp))
3397 ))
3398 ))
3399
3400(defun prolog-insert-next-clause ()
3401 "Insert newline and the name of the current clause."
3402 (interactive)
3403 (insert "\n")
3404 (prolog-insert-predicate-template))
3405
3406(defun prolog-insert-module-modeline ()
3407 "Insert a modeline for module specification.
3408This line should be first in the buffer.
3409The module name should be written manually just before the semi-colon."
3410 (interactive)
3411 (insert "%%% -*- Module: ; -*-\n")
3412 (backward-char 6))
3413
3414(defalias 'prolog-uncomment-region
3415 (if (fboundp 'uncomment-region) #'uncomment-region
3416 (lambda (beg end)
3417 "Uncomment the region between BEG and END."
3418 (interactive "r")
3419 (comment-region beg end -1))))
3420
3421(defun prolog-goto-comment-column (&optional nocreate)
3422 "Move comments on the current line to the correct position.
3423If NOCREATE is nil (or omitted) and there is no comment on the line, then
3424a new comment is created."
3425 (interactive)
3426 (beginning-of-line)
3427 (if (or (not nocreate)
3428 (and
3429 (re-search-forward
3430 (format "^\\(\\(%s\\|%s\\|[^\n\'\"%%]\\)*\\)%% *"
3431 prolog-quoted-atom-regexp prolog-string-regexp)
3432 (save-excursion (end-of-line) (point)) 'limit)
3433 (progn
3434 (goto-char (match-beginning 0))
3435 (not (eq (prolog-in-string-or-comment) 'txt)))))
3436 (indent-for-comment)))
3437
3438(defun prolog-indent-predicate ()
3439 "*Indent the current predicate."
3440 (interactive)
3441 (indent-region (prolog-pred-start) (prolog-pred-end) nil))
3442
3443(defun prolog-indent-buffer ()
3444 "*Indent the entire buffer."
3445 (interactive)
3446 (indent-region (point-min) (point-max) nil))
3447
3448(defun prolog-mark-clause ()
3449 "Put mark at the end of this clause and move point to the beginning."
3450 (interactive)
3451 (let ((pos (point)))
3452 (goto-char (prolog-clause-end))
3453 (forward-line 1)
3454 (beginning-of-line)
3455 (set-mark (point))
3456 (goto-char pos)
3457 (goto-char (prolog-clause-start))))
3458
3459(defun prolog-mark-predicate ()
3460 "Put mark at the end of this predicate and move point to the beginning."
3461 (interactive)
3462 (let (pos)
3463 (goto-char (prolog-pred-end))
3464 (setq pos (point))
3465 (forward-line 1)
3466 (beginning-of-line)
3467 (set-mark (point))
3468 (goto-char pos)
3469 (goto-char (prolog-pred-start))))
3470
3471;; Stolen from `cc-mode.el':
3472(defun prolog-electric-delete (arg)
3473 "Delete preceding character or whitespace.
3474If `prolog-hungry-delete-key-flag' is non-nil, then all preceding whitespace is
3475consumed. If however an ARG is supplied, or `prolog-hungry-delete-key-flag' is
3476nil, or point is inside a literal then the function in the variable
3477`backward-delete-char' is called."
3478 (interactive "P")
3479 (if (or (not prolog-hungry-delete-key-flag)
3480 arg
3481 (prolog-in-string-or-comment))
3482 (funcall 'backward-delete-char (prefix-numeric-value arg))
3483 (let ((here (point)))
3484 (skip-chars-backward " \t\n")
3485 (if (/= (point) here)
3486 (delete-region (point) here)
3487 (funcall 'backward-delete-char 1)
3488 ))))
3489
3490;; For XEmacs compatibility (suggested by Per Mildner)
3491(put 'prolog-electric-delete 'pending-delete 'supersede)
3492
3493(defun prolog-electric-if-then-else (arg)
3494 "If `prolog-electric-if-then-else-flag' is non-nil, indent if-then-else constructs.
3495Bound to the >, ; and ( keys."
3496 (interactive "P")
3497 (self-insert-command (prefix-numeric-value arg))
3498 (if prolog-electric-if-then-else-flag (prolog-insert-spaces-after-paren)))
3499
3500(defun prolog-electric-colon (arg)
3501 "If `prolog-electric-colon-flag' is non-nil, insert the electric `:' construct.
3502That is, insert space (if appropriate), `:-' and newline if colon is pressed
3503at the end of a line that starts in the first column (i.e., clause
3504heads)."
3505 (interactive "P")
3506 (if (and prolog-electric-colon-flag
3507 (null arg)
3508 (eolp)
3509 ;(not (string-match "^\\s " (thing-at-point 'line))))
3510 (not (string-match "^\\(\\s \\|%\\)" (thing-at-point 'line))))
3511 (progn
3512 (unless (save-excursion (backward-char 1) (looking-at "\\s "))
3513 (insert " "))
3514 (insert ":-\n")
3515 (prolog-indent-line))
3516 (self-insert-command (prefix-numeric-value arg))))
3517
3518(defun prolog-electric-dash (arg)
3519 "If `prolog-electric-dash-flag' is non-nil, insert the electric `-' construct.
3520that is, insert space (if appropriate), `-->' and newline if dash is pressed
3521at the end of a line that starts in the first column (i.e., DCG
3522heads)."
3523 (interactive "P")
3524 (if (and prolog-electric-dash-flag
3525 (null arg)
3526 (eolp)
3527 ;(not (string-match "^\\s " (thing-at-point 'line))))
3528 (not (string-match "^\\(\\s \\|%\\)" (thing-at-point 'line))))
3529 (progn
3530 (unless (save-excursion (backward-char 1) (looking-at "\\s "))
3531 (insert " "))
3532 (insert "-->\n")
3533 (prolog-indent-line))
3534 (self-insert-command (prefix-numeric-value arg))))
3535
3536(defun prolog-electric-dot (arg)
3537 "Insert dot and newline or a head of a new clause.
3538
3539If `prolog-electric-dot-flag' is nil, then simply insert dot.
3540Otherwise::
3541When invoked at the end of nonempty line, insert dot and newline.
3542When invoked at the end of an empty line, insert a recursive call to
3543the current predicate.
3544When invoked at the beginning of line, insert a head of a new clause
3545of the current predicate.
3546
3547When called with prefix argument ARG, insert just dot."
3548 (interactive "P")
3549 ;; Check for situations when the electricity should not be active
3550 (if (or (not prolog-electric-dot-flag)
3551 arg
3552 (prolog-in-string-or-comment)
3553 ;; Do not be electric in a floating point number or an operator
3554 (not
3555 (or
3556 ;; (re-search-backward
3557 ;; ######
3558 ;; "\\(^\\|[])}a-zA-Z_!'0-9]+\\)[ \t]*\\=" nil t)))
3559 (save-excursion
3560 (re-search-backward
3561 ;; "\\(^\\|[])}_!'0-9]+\\)[ \t]*\\=" nil t)))
3562 "\\(^\\|[])}_!'0-9]+\\)[ \t]*\\="
3563 nil t))
3564 (save-excursion
3565 (re-search-backward
3566 ;; "\\(^\\|[])}a-zA-Z]+\\)[ \t]*\\=" nil t)))
3567 (format "\\(^\\|[])}%s]+\\)[ \t]*\\="
3568 prolog-lower-case-string) ;FIXME: [:lower:]
3569 nil t))
3570 (save-excursion
3571 (re-search-backward
3572 ;; "\\(^\\|[])}a-zA-Z]+\\)[ \t]*\\=" nil t)))
3573 (format "\\(^\\|[])}%s]+\\)[ \t]*\\="
3574 prolog-upper-case-string) ;FIXME: [:upper:]
3575 nil t))
3576 )
3577 )
3578 ;; Do not be electric if inside a parenthesis pair.
3579 (not (= (prolog-region-paren-balance (prolog-clause-start) (point))
3580 0))
3581 )
3582 (funcall 'self-insert-command (prefix-numeric-value arg))
3583 (cond
3584 ;; Beginning of line
3585 ((bolp)
3586 (prolog-insert-predicate-template))
3587 ;; At an empty line with at least one whitespace
3588 ((save-excursion
3589 (beginning-of-line)
3590 (looking-at "[ \t]+$"))
3591 (prolog-insert-predicate-template)
3592 (when prolog-electric-dot-full-predicate-template
3593 (save-excursion
3594 (end-of-line)
3595 (insert ".\n"))))
3596 ;; Default
3597 (t
3598 (insert ".\n"))
3599 )))
3600
3601(defun prolog-electric-underscore ()
3602 "Replace variable with an underscore.
3603If `prolog-electric-underscore-flag' is non-nil and the point is
3604on a variable then replace the variable with underscore and skip
3605the following comma and whitespace, if any.
3606If the point is not on a variable then insert underscore."
3607 (interactive)
3608 (if prolog-electric-underscore-flag
3609 (let (;start
3610 (oldcase case-fold-search)
3611 (oldp (point)))
3612 (setq case-fold-search nil)
3613 ;; ######
3614 ;;(skip-chars-backward "a-zA-Z_")
3615 (skip-chars-backward
3616 (format "%s%s_"
3617 ;; FIXME: Why not "a-zA-Z"?
3618 prolog-lower-case-string
3619 prolog-upper-case-string))
3620
3621 ;(setq start (point))
3622 (if (and (not (prolog-in-string-or-comment))
3623 ;; ######
3624 ;; (looking-at "\\<[_A-Z][a-zA-Z_0-9]*\\>"))
3625 (looking-at (format "\\<[_%s][%s%s_0-9]*\\>"
3626 ;; FIXME: Use [:upper:] and friends.
3627 prolog-upper-case-string
3628 prolog-lower-case-string
3629 prolog-upper-case-string)))
3630 (progn
3631 (replace-match "_")
3632 (skip-chars-forward ", \t\n"))
3633 (goto-char oldp)
3634 (self-insert-command 1))
3635 (setq case-fold-search oldcase)
3636 )
3637 (self-insert-command 1))
3638 )
3639
3640
3641(defun prolog-find-term (functor arity &optional prefix)
3642 "Go to the position at the start of the next occurance of a term.
3643The term is specified with FUNCTOR and ARITY. The optional argument
3644PREFIX is the prefix of the search regexp."
3645 (let* (;; If prefix is not set then use the default "\\<"
3646 (prefix (if (not prefix)
3647 "\\<"
3648 prefix))
3649 (regexp (concat prefix functor))
3650 (i 1))
3651
3652 ;; Build regexp for the search if the arity is > 0
3653 (if (= arity 0)
3654 ;; Add that the functor must be at the end of a word. This
3655 ;; does not work if the arity is > 0 since the closing )
3656 ;; is not a word constituent.
3657 (setq regexp (concat regexp "\\>"))
3658 ;; Arity is > 0, add parens and commas
3659 (setq regexp (concat regexp "("))
3660 (while (< i arity)
3661 (setq regexp (concat regexp ".+,"))
3662 (setq i (1+ i)))
3663 (setq regexp (concat regexp ".+)")))
3664
3665 ;; Search, and return position
3666 (if (re-search-forward regexp nil t)
3667 (goto-char (match-beginning 0))
3668 (error "Term not found"))
3669 ))
3670
3671(defun prolog-variables-to-anonymous (beg end)
3672 "Replace all variables within a region BEG to END by anonymous variables."
3673 (interactive "r")
3674 (save-excursion
3675 (let ((oldcase case-fold-search))
3676 (setq case-fold-search nil)
3677 (goto-char end)
3678 (while (re-search-backward "\\<[A-Z_][a-zA-Z_0-9]*\\>" beg t)
3679 (progn
3680 (replace-match "_")
3681 (backward-char)))
3682 (setq case-fold-search oldcase)
3683 )))
3684
3685
3686(defun prolog-set-atom-regexps ()
3687 "Set the `prolog-atom-char-regexp' and `prolog-atom-regexp' variables.
3688Must be called after `prolog-build-case-strings'."
3689 (setq prolog-atom-char-regexp
3690 (format "[%s%s0-9_$]"
3691 ;; FIXME: why not a-zA-Z?
3692 prolog-lower-case-string
3693 prolog-upper-case-string))
3694 (setq prolog-atom-regexp
3695 (format "[%s$]%s*"
3696 prolog-lower-case-string
3697 prolog-atom-char-regexp))
3698 )
3699
3700(defun prolog-build-case-strings ()
3701 "Set `prolog-upper-case-string' and `prolog-lower-case-string'.
3702Uses the current case-table for extracting the relevant information."
3703 (let ((up_string "")
3704 (low_string ""))
3705 ;; Use `map-char-table' if it is defined. Otherwise enumerate all
3706 ;; numbers between 0 and 255. `map-char-table' is probably safer.
3707 ;;
3708 ;; `map-char-table' causes problems under Emacs 23.0.0.1, the
3709 ;; while loop seems to do its job well (Ryszard Szopa)
3710 ;;
3711 ;;(if (and (not (featurep 'xemacs))
3712 ;; (fboundp 'map-char-table))
3713 ;; (map-char-table
3714 ;; (lambda (key value)
3715 ;; (cond
3716 ;; ((and
3717 ;; (eq (prolog-int-to-char key) (downcase key))
3718 ;; (eq (prolog-int-to-char key) (upcase key)))
3719 ;; ;; Do nothing if upper and lower case are the same
3720 ;; )
3721 ;; ((eq (prolog-int-to-char key) (downcase key))
3722 ;; ;; The char is lower case
3723 ;; (setq low_string (format "%s%c" low_string key)))
3724 ;; ((eq (prolog-int-to-char key) (upcase key))
3725 ;; ;; The char is upper case
3726 ;; (setq up_string (format "%s%c" up_string key)))
3727 ;; ))
3728 ;; (current-case-table))
3729 ;; `map-char-table' was undefined.
3730 (let ((key 0))
3731 (while (< key 256)
3732 (cond
3733 ((and
3734 (eq (prolog-int-to-char key) (downcase key))
3735 (eq (prolog-int-to-char key) (upcase key)))
3736 ;; Do nothing if upper and lower case are the same
3737 )
3738 ((eq (prolog-int-to-char key) (downcase key))
3739 ;; The char is lower case
3740 (setq low_string (format "%s%c" low_string key)))
3741 ((eq (prolog-int-to-char key) (upcase key))
3742 ;; The char is upper case
3743 (setq up_string (format "%s%c" up_string key)))
3744 )
3745 (setq key (1+ key))))
3746 ;; )
3747 ;; The strings are single-byte strings
3748 (setq prolog-upper-case-string (prolog-dash-letters up_string))
3749 (setq prolog-lower-case-string (prolog-dash-letters low_string))
3750 ))
3751
3752;(defun prolog-regexp-dash-continuous-chars (chars)
3753; (let ((ints (mapcar #'prolog-char-to-int (string-to-list chars)))
3754; (beg 0)
3755; (end 0))
3756; (if (null ints)
3757; chars
3758; (while (and (< (+ beg 1) (length chars))
3759; (not (or (= (+ (nth beg ints) 1) (nth (+ beg 1) ints))
3760; (= (nth beg ints) (nth (+ beg 1) ints)))))
3761; (setq beg (+ beg 1)))
3762; (setq beg (+ beg 1)
3763; end beg)
3764; (while (and (< (+ end 1) (length chars))
3765; (or (= (+ (nth end ints) 1) (nth (+ end 1) ints))
3766; (= (nth end ints) (nth (+ end 1) ints))))
3767; (setq end (+ end 1)))
3768; (if (equal (substring chars end) "")
3769; (substring chars 0 beg)
3770; (concat (substring chars 0 beg) "-"
3771; (prolog-regexp-dash-continuous-chars (substring chars end))))
3772; )))
3773
3774(defun prolog-ints-intervals (ints)
3775 "Return a list of intervals (from . to) covering INTS."
3776 (when ints
3777 (setq ints (sort ints '<))
3778 (let ((prev (car ints))
3779 (interval-start (car ints))
3780 intervals)
3781 (while ints
3782 (let ((next (car ints)))
3783 (when (> next (1+ prev)) ; start of new interval
3784 (setq intervals (cons (cons interval-start prev) intervals))
3785 (setq interval-start next))
3786 (setq prev next)
3787 (setq ints (cdr ints))))
3788 (setq intervals (cons (cons interval-start prev) intervals))
3789 (reverse intervals))))
3790
3791(defun prolog-dash-letters (string)
3792 "Return a condensed regexp covering all letters in STRING."
3793 (let ((intervals (prolog-ints-intervals (mapcar #'prolog-char-to-int
3794 (string-to-list string))))
3795 codes)
3796 (while intervals
3797 (let* ((i (car intervals))
3798 (from (car i))
3799 (to (cdr i))
3800 (c (cond ((= from to) `(,from))
3801 ((= (1+ from) to) `(,from ,to))
3802 (t `(,from ?- ,to)))))
3803 (setq codes (cons c codes)))
3804 (setq intervals (cdr intervals)))
3805 (apply 'concat (reverse codes))))
3806
3807;(defun prolog-condense-character-sets (regexp)
3808; "Condense adjacent characters in character sets of REGEXP."
3809; (let ((next -1))
3810; (while (setq next (string-match "\\[\\(.*?\\)\\]" regexp (1+ next)))
3811; (setq regexp (replace-match (prolog-dash-letters (match-string 1 regexp))
3812; t t regexp 1))))
3813; regexp)
3814
3815;; GNU Emacs compatibility: GNU Emacs does not differentiate between
3816;; ints and chars, or at least these two are interchangeable.
3817(defalias 'prolog-int-to-char
3818 (if (fboundp 'int-to-char) #'int-to-char #'identity))
3819
3820(defalias 'prolog-char-to-int
3821 (if (fboundp 'char-to-int) #'char-to-int #'identity))
3822
3823;;-------------------------------------------------------------------
3824;; Menu stuff (both for the editing buffer and for the inferior
3825;; prolog buffer)
3826;;-------------------------------------------------------------------
3827
3828(unless (fboundp 'region-exists-p)
3829 (defun region-exists-p ()
3830 "Non-nil iff the mark is set. Lobotomized version for Emacsen that do not provide their own."
3831 (mark)))
3832
3833(defun prolog-menu ()
3834 "Create the menus for the Prolog editing buffers.
3835These menus are dynamically created because one may change systems
3836during the life of an Emacs session, and because GNU Emacs wants them
3837so by ignoring `easy-menu-add'."
3838
3839 ;; GNU Emacs ignores `easy-menu-add' so the order in which the menus
3840 ;; are defined _is_ important!
3841
3842 (easy-menu-define
3843 prolog-edit-menu-help (current-local-map)
3844 "Help menu for the Prolog mode."
3845 (append
3846 (if (featurep 'xemacs) '("Help") '("Prolog-help"))
3847 (cond
3848 ((eq prolog-system 'sicstus)
3849 '(["On predicate" prolog-help-on-predicate t]
3850 "---"))
3851 ((eq prolog-system 'swi)
3852 '(["On predicate" prolog-help-on-predicate t]
3853 ["Apropos" prolog-help-apropos t]
3854 "---")))
3855 '(["Describe mode" describe-mode t])))
3856
3857 (easy-menu-define
3858 prolog-edit-menu-runtime (current-local-map)
3859 "Runtime Prolog commands available from the editing buffer"
3860 (append
3861 ;; runtime menu name
3862 (list (cond ((eq prolog-system 'eclipse)
3863 "ECLiPSe")
3864 ((eq prolog-system 'mercury)
3865 "Mercury")
3866 (t
3867 "Prolog")))
3868 ;; consult items, NIL for mercury
3869 (unless (eq prolog-system 'mercury)
3870 '("---"
3871 ["Consult file" prolog-consult-file t]
3872 ["Consult buffer" prolog-consult-buffer t]
3873 ["Consult region" prolog-consult-region (region-exists-p)]
3874 ["Consult predicate" prolog-consult-predicate t]
3875 ))
3876 ;; compile items, NIL for everything but SICSTUS
3877 (when (eq prolog-system 'sicstus)
3878 '("---"
3879 ["Compile file" prolog-compile-file t]
3880 ["Compile buffer" prolog-compile-buffer t]
3881 ["Compile region" prolog-compile-region (region-exists-p)]
3882 ["Compile predicate" prolog-compile-predicate t]
3883 ))
3884 ;; debug items, NIL for mercury
3885 (cond
3886 ((eq prolog-system 'sicstus)
3887 ;; In SICStus, these are pairwise disjunctive,
3888 ;; so it's enough with one "off"-command
3889 (if (prolog-atleast-version '(3 . 7))
3890 (list "---"
3891 ["Debug" prolog-debug-on t]
3892 ["Trace" prolog-trace-on t]
3893 ["Zip" prolog-zip-on t]
3894 ["All debug off" prolog-debug-off t]
3895 '("Source level debugging"
3896 ["Enable" prolog-enable-sicstus-sd t]
3897 ["Disable" prolog-disable-sicstus-sd t]))
3898 (list "---"
3899 ["Debug" prolog-debug-on t]
3900 ["Trace" prolog-trace-on t]
3901 ["All debug off" prolog-debug-off t])))
3902 ((not (eq prolog-system 'mercury))
3903 '("---"
3904 ["Debug" prolog-debug-on t]
3905 ["Debug off" prolog-debug-off t]
3906 ["Trace" prolog-trace-on t]
3907 ["Trace off" prolog-trace-off t]))
3908 ;; default (mercury) nil
3909 )
3910 (list "---"
3911 (if (featurep 'xemacs)
3912 [(concat "Run " (cond ((eq prolog-system 'eclipse) "ECLiPSe")
3913 ((eq prolog-system 'mercury) "Mercury")
3914 (t "Prolog")))
3915 run-prolog t]
3916 ["Run Prolog" run-prolog t]))))
3917
3918 (easy-menu-define
3919 prolog-edit-menu-insert-move (current-local-map)
3920 "Commands for Prolog code manipulation."
3921 (append
3922 (list "Code"
3923 ["Comment region" comment-region (region-exists-p)]
3924 ["Uncomment region" prolog-uncomment-region (region-exists-p)]
3925 ["Add comment/move to comment" indent-for-comment t])
3926 (unless (eq prolog-system 'mercury)
3927 (list ["Convert variables in region to '_'" prolog-variables-to-anonymous (region-exists-p)]))
3928 (list "---"
3929 ["Insert predicate template" prolog-insert-predicate-template t]
3930 ["Insert next clause head" prolog-insert-next-clause t]
3931 ["Insert predicate spec" prolog-insert-predspec t]
3932 ["Insert module modeline" prolog-insert-module-modeline t]
3933 "---"
3934 ["Beginning of clause" prolog-beginning-of-clause t]
3935 ["End of clause" prolog-end-of-clause t]
3936 ["Beginning of predicate" prolog-beginning-of-predicate t]
3937 ["End of predicate" prolog-end-of-predicate t]
3938 "---"
3939 ["Indent line" prolog-indent-line t]
3940 ["Indent region" indent-region (region-exists-p)]
3941 ["Indent predicate" prolog-indent-predicate t]
3942 ["Indent buffer" prolog-indent-buffer t]
3943 ["Align region" align (region-exists-p)]
3944 "---"
3945 ["Mark clause" prolog-mark-clause t]
3946 ["Mark predicate" prolog-mark-predicate t]
3947 ["Mark paragraph" mark-paragraph t]
3948 ;"---"
3949 ;["Fontify buffer" font-lock-fontify-buffer t]
3950 )))
3951
3952 (easy-menu-add prolog-edit-menu-insert-move)
3953 (easy-menu-add prolog-edit-menu-runtime)
3954
3955 ;; Add predicate index menu
3956 ;(make-variable-buffer-local 'imenu-create-index-function)
3957 (make-local-variable 'imenu-create-index-function)
3958 (setq imenu-create-index-function 'imenu-default-create-index-function)
3959 ;;Milan (this has problems with object methods...) ###### Does it? (Stefan)
3960 (setq imenu-prev-index-position-function 'prolog-beginning-of-predicate)
3961 (setq imenu-extract-index-name-function 'prolog-get-predspec)
3962
3963 (if (and prolog-imenu-flag
3964 (< (count-lines (point-min) (point-max)) prolog-imenu-max-lines))
3965 (imenu-add-to-menubar "Predicates"))
3966
3967 (easy-menu-add prolog-edit-menu-help))
3968
3969(defun prolog-inferior-menu ()
3970 "Create the menus for the Prolog inferior buffer.
3971This menu is dynamically created because one may change systems during
3972the life of an Emacs session."
3973
3974 (easy-menu-define
3975 prolog-inferior-menu-help (current-local-map)
3976 "Help menu for the Prolog inferior mode."
3977 (append
3978 (if (featurep 'xemacs) '("Help") '("Prolog-help"))
3979 (cond
3980 ((eq prolog-system 'sicstus)
3981 '(["On predicate" prolog-help-on-predicate t]
3982 "---"))
3983 ((eq prolog-system 'swi)
3984 '(["On predicate" prolog-help-on-predicate t]
3985 ["Apropos" prolog-help-apropos t]
3986 "---")))
3987 '(["Describe mode" describe-mode t])))
3988
3989 (easy-menu-define
3990 prolog-inferior-menu-all (current-local-map)
3991 "Menu for the inferior Prolog buffer."
3992 (append
3993 ;; menu name
3994 (list (cond ((eq prolog-system 'eclipse)
3995 "ECLiPSe")
3996 ((eq prolog-system 'mercury)
3997 "Mercury")
3998 (t
3999 "Prolog")))
4000 ;; debug items, NIL for mercury
4001 (cond
4002 ((eq prolog-system 'sicstus)
4003 ;; In SICStus, these are pairwise disjunctive,
4004 ;; so it's enough with one "off"-command
4005 (if (prolog-atleast-version '(3 . 7))
4006 (list "---"
4007 ["Debug" prolog-debug-on t]
4008 ["Trace" prolog-trace-on t]
4009 ["Zip" prolog-zip-on t]
4010 ["All debug off" prolog-debug-off t]
4011 '("Source level debugging"
4012 ["Enable" prolog-enable-sicstus-sd t]
4013 ["Disable" prolog-disable-sicstus-sd t]))
4014 (list "---"
4015 ["Debug" prolog-debug-on t]
4016 ["Trace" prolog-trace-on t]
4017 ["All debug off" prolog-debug-off t])))
4018 ((not (eq prolog-system 'mercury))
4019 '("---"
4020 ["Debug" prolog-debug-on t]
4021 ["Debug off" prolog-debug-off t]
4022 ["Trace" prolog-trace-on t]
4023 ["Trace off" prolog-trace-off t]))
4024 ;; default (mercury) nil
4025 )
4026 ;; runtime
4027 '("---"
4028 ["Interrupt Prolog" comint-interrupt-subjob t]
4029 ["Quit Prolog" comint-quit-subjob t]
4030 ["Kill Prolog" comint-kill-subjob t])
4031 ))
4032
4033 (easy-menu-add prolog-inferior-menu-all)
4034 (easy-menu-add prolog-inferior-menu-help))
4035
4036(add-hook 'prolog-mode-hook 'prolog-menu) ;FIXME.
4037(add-hook 'prolog-inferior-mode-hook 'prolog-inferior-menu) ;FIXME.
4038
4039(defun prolog-mode-version ()
4040 "Echo the current version of Prolog mode in the minibuffer."
4041 (interactive)
4042 (message "Using Prolog mode version %s" prolog-mode-version))
427 4043
428(provide 'prolog) 4044(provide 'prolog)
429 4045
diff --git a/lisp/subr.el b/lisp/subr.el
index 0f65fb7fbb0..293d71b8915 100644
--- a/lisp/subr.el
+++ b/lisp/subr.el
@@ -1,7 +1,7 @@
1;;; subr.el --- basic lisp subroutines for Emacs 1;;; subr.el --- basic lisp subroutines for Emacs
2 2
3;; Copyright (C) 1985, 1986, 1992, 1994, 1995, 1999, 2000, 2001, 2002, 2003, 3;; Copyright (C) 1985, 1986, 1992, 1994, 1995, 1999, 2000, 2001, 2002, 2003,
4;; 2004, 2005, 2006, 2007, 2008, 2009, 2010 4;; 2004, 2005, 2006, 2007, 2008, 2009, 2010, 2011
5;; Free Software Foundation, Inc. 5;; Free Software Foundation, Inc.
6 6
7;; Maintainer: FSF 7;; Maintainer: FSF
@@ -60,7 +60,7 @@ function-definitions that `check-declare' does not recognize, e.g.
60`defstruct'. 60`defstruct'.
61 61
62To specify a value for FILEONLY without passing an argument list, 62To specify a value for FILEONLY without passing an argument list,
63set ARGLIST to `t'. This is necessary because `nil' means an 63set ARGLIST to t. This is necessary because nil means an
64empty argument list, rather than an unspecified one. 64empty argument list, rather than an unspecified one.
65 65
66Note that for the purposes of `check-declare', this statement 66Note that for the purposes of `check-declare', this statement
@@ -483,6 +483,7 @@ saving keyboard macros (see `edmacro-mode')."
483 (read-kbd-macro keys)) 483 (read-kbd-macro keys))
484 484
485(defun undefined () 485(defun undefined ()
486 "Beep to tell the user this binding is undefined."
486 (interactive) 487 (interactive)
487 (ding)) 488 (ding))
488 489
@@ -1599,11 +1600,7 @@ extension for a compressed format \(e.g. \".gz\") on FILE will not affect
1599this name matching. 1600this name matching.
1600 1601
1601Alternatively, FILE can be a feature (i.e. a symbol), in which case FORM 1602Alternatively, FILE can be a feature (i.e. a symbol), in which case FORM
1602is evaluated whenever that feature is `provide'd. Note that although 1603is evaluated at the end of any file that `provide's this feature.
1603provide statements are usually at the end of files, this is not always
1604the case (e.g., sometimes they are at the start to avoid a recursive
1605load error). If your FORM should not be evaluated until the code in
1606FILE has been, do not use the symbol form for FILE in such cases.
1607 1604
1608Usually FILE is just a library name like \"font-lock\" or a feature name 1605Usually FILE is just a library name like \"font-lock\" or a feature name
1609like 'font-lock. 1606like 'font-lock.
@@ -1612,11 +1609,27 @@ This function makes or adds to an entry on `after-load-alist'."
1612 ;; Add this FORM into after-load-alist (regardless of whether we'll be 1609 ;; Add this FORM into after-load-alist (regardless of whether we'll be
1613 ;; evaluating it now). 1610 ;; evaluating it now).
1614 (let* ((regexp-or-feature 1611 (let* ((regexp-or-feature
1615 (if (stringp file) (setq file (purecopy (load-history-regexp file))) file)) 1612 (if (stringp file)
1613 (setq file (purecopy (load-history-regexp file)))
1614 file))
1616 (elt (assoc regexp-or-feature after-load-alist))) 1615 (elt (assoc regexp-or-feature after-load-alist)))
1617 (unless elt 1616 (unless elt
1618 (setq elt (list regexp-or-feature)) 1617 (setq elt (list regexp-or-feature))
1619 (push elt after-load-alist)) 1618 (push elt after-load-alist))
1619 (when (symbolp regexp-or-feature)
1620 ;; For features, the after-load-alist elements get run when `provide' is
1621 ;; called rather than at the end of the file. So add an indirection to
1622 ;; make sure that `form' is really run "after-load" in case the provide
1623 ;; call happens early.
1624 (setq form
1625 `(when load-file-name
1626 (let ((fun (make-symbol "eval-after-load-helper")))
1627 (fset fun `(lambda (file)
1628 (if (not (equal file ',load-file-name))
1629 nil
1630 (remove-hook 'after-load-functions ',fun)
1631 ,',form)))
1632 (add-hook 'after-load-functions fun)))))
1620 ;; Add FORM to the element unless it's already there. 1633 ;; Add FORM to the element unless it's already there.
1621 (unless (member form (cdr elt)) 1634 (unless (member form (cdr elt))
1622 (nconc elt (purecopy (list form)))) 1635 (nconc elt (purecopy (list form))))
@@ -1872,7 +1885,7 @@ This function echoes `.' for each character that the user types.
1872The user ends with RET, LFD, or ESC. DEL or C-h rubs out. 1885The user ends with RET, LFD, or ESC. DEL or C-h rubs out.
1873C-y yanks the current kill. C-u kills line. 1886C-y yanks the current kill. C-u kills line.
1874C-g quits; if `inhibit-quit' was non-nil around this function, 1887C-g quits; if `inhibit-quit' was non-nil around this function,
1875then it returns nil if the user types C-g, but quit-flag remains set. 1888then it returns nil if the user types C-g, but `quit-flag' remains set.
1876 1889
1877Once the caller uses the password, it can erase the password 1890Once the caller uses the password, it can erase the password
1878by doing (clear-string STRING)." 1891by doing (clear-string STRING)."
@@ -1985,7 +1998,7 @@ keyboard-quit events while waiting for a valid input."
1985 (unless (get-text-property 0 'face prompt) 1998 (unless (get-text-property 0 'face prompt)
1986 (setq prompt (propertize prompt 'face 'minibuffer-prompt))) 1999 (setq prompt (propertize prompt 'face 'minibuffer-prompt)))
1987 (setq char (let ((inhibit-quit inhibit-keyboard-quit)) 2000 (setq char (let ((inhibit-quit inhibit-keyboard-quit))
1988 (read-event prompt))) 2001 (read-key prompt)))
1989 (cond 2002 (cond
1990 ((not (numberp char))) 2003 ((not (numberp char)))
1991 ((memq char chars) 2004 ((memq char chars)
@@ -2043,8 +2056,11 @@ floating point support."
2043 2056
2044(defun y-or-n-p (prompt &rest args) 2057(defun y-or-n-p (prompt &rest args)
2045 "Ask user a \"y or n\" question. Return t if answer is \"y\". 2058 "Ask user a \"y or n\" question. Return t if answer is \"y\".
2046The argument PROMPT is the string to display to ask the question. 2059The string to display to ask the question is obtained by
2047It should end in a space; `y-or-n-p' adds `(y or n) ' to it. 2060formatting the string PROMPT with arguments ARGS (see `format').
2061The result should end in a space; `y-or-n-p' adds \"(y or n) \"
2062to it.
2063
2048No confirmation of the answer is requested; a single character is enough. 2064No confirmation of the answer is requested; a single character is enough.
2049Also accepts Space to mean yes, or Delete to mean no. \(Actually, it uses 2065Also accepts Space to mean yes, or Delete to mean no. \(Actually, it uses
2050the bindings in `query-replace-map'; see the documentation of that variable 2066the bindings in `query-replace-map'; see the documentation of that variable
@@ -2493,7 +2509,7 @@ Replaces `category' properties with their defined properties."
2493(defvar yank-undo-function) 2509(defvar yank-undo-function)
2494 2510
2495(defun insert-for-yank (string) 2511(defun insert-for-yank (string)
2496 "Calls `insert-for-yank-1' repetitively for each `yank-handler' segment. 2512 "Call `insert-for-yank-1' repetitively for each `yank-handler' segment.
2497 2513
2498See `insert-for-yank-1' for more details." 2514See `insert-for-yank-1' for more details."
2499 (let (to) 2515 (let (to)
@@ -3177,7 +3193,7 @@ is non-nil, start replacements at that index in STRING.
3177REP is either a string used as the NEWTEXT arg of `replace-match' or a 3193REP is either a string used as the NEWTEXT arg of `replace-match' or a
3178function. If it is a function, it is called with the actual text of each 3194function. If it is a function, it is called with the actual text of each
3179match, and its value is used as the replacement text. When REP is called, 3195match, and its value is used as the replacement text. When REP is called,
3180the match-data are the result of matching REGEXP against a substring 3196the match data are the result of matching REGEXP against a substring
3181of STRING. 3197of STRING.
3182 3198
3183To replace only the first match (if any), make REGEXP match up to \\' 3199To replace only the first match (if any), make REGEXP match up to \\'
diff --git a/lisp/tool-bar.el b/lisp/tool-bar.el
index fa16381bf29..51d13fe3920 100644
--- a/lisp/tool-bar.el
+++ b/lisp/tool-bar.el
@@ -254,7 +254,7 @@ holds a keymap."
254 (tool-bar-add-item-from-menu 'save-buffer "save" nil 254 (tool-bar-add-item-from-menu 'save-buffer "save" nil
255 :label "Save") 255 :label "Save")
256 (define-key-after (default-value 'tool-bar-map) [separator-1] menu-bar-separator) 256 (define-key-after (default-value 'tool-bar-map) [separator-1] menu-bar-separator)
257 (tool-bar-add-item-from-menu 'undo "undo" nil :vert-only t) 257 (tool-bar-add-item-from-menu 'undo "undo" nil)
258 (define-key-after (default-value 'tool-bar-map) [separator-2] menu-bar-separator) 258 (define-key-after (default-value 'tool-bar-map) [separator-2] menu-bar-separator)
259 (tool-bar-add-item-from-menu (lookup-key menu-bar-edit-menu [cut]) 259 (tool-bar-add-item-from-menu (lookup-key menu-bar-edit-menu [cut])
260 "cut" nil :vert-only t) 260 "cut" nil :vert-only t)
@@ -263,25 +263,22 @@ holds a keymap."
263 (tool-bar-add-item-from-menu (lookup-key menu-bar-edit-menu [paste]) 263 (tool-bar-add-item-from-menu (lookup-key menu-bar-edit-menu [paste])
264 "paste" nil :vert-only t) 264 "paste" nil :vert-only t)
265 (define-key-after (default-value 'tool-bar-map) [separator-3] menu-bar-separator) 265 (define-key-after (default-value 'tool-bar-map) [separator-3] menu-bar-separator)
266 (tool-bar-add-item-from-menu 'nonincremental-search-forward "search" 266 (tool-bar-add-item-from-menu 'isearch-forward "search"
267 nil :label "Search") 267 nil :label "Search" :vert-only t)
268 ;;(tool-bar-add-item-from-menu 'ispell-buffer "spell") 268 ;;(tool-bar-add-item-from-menu 'ispell-buffer "spell")
269 269
270 ;; There's no icon appropriate for News and we need a command rather 270 ;; There's no icon appropriate for News and we need a command rather
271 ;; than a lambda for Read Mail. 271 ;; than a lambda for Read Mail.
272 ;;(tool-bar-add-item-from-menu 'compose-mail "mail/compose") 272 ;;(tool-bar-add-item-from-menu 'compose-mail "mail/compose")
273 273
274 274 ;; Help button on a tool bar is rather non-standard...
275 ;; tool-bar-add-item-from-menu itself operates on 275 ;; (let ((tool-bar-map (default-value 'tool-bar-map)))
276 ;; (default-value 'tool-bar-map), but when we don't use that function, 276 ;; (tool-bar-add-item "help" (lambda ()
277 ;; we must explicitly operate on the default value. 277 ;; (interactive)
278 278 ;; (popup-menu menu-bar-help-menu))
279 (let ((tool-bar-map (default-value 'tool-bar-map))) 279 ;; 'help
280 (tool-bar-add-item "help" (lambda () 280 ;; :help "Pop up the Help menu"))
281 (interactive) 281)
282 (popup-menu menu-bar-help-menu))
283 'help
284 :help "Pop up the Help menu")))
285 282
286(if (featurep 'move-toolbar) 283(if (featurep 'move-toolbar)
287 (defcustom tool-bar-position 'top 284 (defcustom tool-bar-position 'top
diff --git a/lisp/vc/vc-dir.el b/lisp/vc/vc-dir.el
index cd40468199f..0335614a6ac 100644
--- a/lisp/vc/vc-dir.el
+++ b/lisp/vc/vc-dir.el
@@ -196,7 +196,7 @@ See `run-hooks'."
196 '(menu-item "Show Incoming Log" vc-log-incoming 196 '(menu-item "Show Incoming Log" vc-log-incoming
197 :help "Show a log of changes that will be received with a pull operation")) 197 :help "Show a log of changes that will be received with a pull operation"))
198 (define-key map [log] 198 (define-key map [log]
199 '(menu-item "Show history" vc-print-log 199 '(menu-item "Show History" vc-print-log
200 :help "List the change log of the current file set in a window")) 200 :help "List the change log of the current file set in a window"))
201 (define-key map [rlog] 201 (define-key map [rlog]
202 '(menu-item "Show Top of the Tree History " vc-print-root-log 202 '(menu-item "Show Top of the Tree History " vc-print-root-log
@@ -307,33 +307,36 @@ If BODY uses EVENT, it should be a variable,
307 307
308(defvar vc-dir-tool-bar-map 308(defvar vc-dir-tool-bar-map
309 (let ((map (make-sparse-keymap))) 309 (let ((map (make-sparse-keymap)))
310 (tool-bar-local-item-from-menu 'vc-dir-find-file "open" 310 (tool-bar-local-item-from-menu 'find-file "new" map nil
311 map vc-dir-mode-map) 311 :label "New File" :vert-only t)
312 (tool-bar-local-item "bookmark_add" 312 (tool-bar-local-item-from-menu 'menu-find-file-existing "open" map nil
313 'vc-dir-toggle-mark 'vc-dir-toggle-mark map 313 :label "Open" :vert-only t)
314 :help "Toggle mark on current item" 314 (tool-bar-local-item-from-menu 'dired "diropen" map nil
315 :label "Toggle Mark") 315 :vert-only t)
316 (tool-bar-local-item-from-menu 'vc-dir-previous-line "left-arrow" 316 (tool-bar-local-item-from-menu 'quit-window "close" map vc-dir-mode-map
317 map vc-dir-mode-map 317 :vert-only t)
318 :rtl "right-arrow") 318 (tool-bar-local-item-from-menu 'vc-next-action "saveas" map
319 (tool-bar-local-item-from-menu 'vc-dir-next-line "right-arrow" 319 vc-dir-mode-map :label "Commit")
320 map vc-dir-mode-map
321 :rtl "left-arrow")
322 (tool-bar-local-item-from-menu 'vc-print-log "info" 320 (tool-bar-local-item-from-menu 'vc-print-log "info"
323 map vc-dir-mode-map) 321 map vc-dir-mode-map
324 (tool-bar-local-item-from-menu 'revert-buffer "refresh" 322 :label "Log")
325 map vc-dir-mode-map) 323 (define-key-after map [separator-1] menu-bar-separator)
326 (tool-bar-local-item-from-menu 'nonincremental-search-forward
327 "search" map nil
328 :label "Search")
329 (tool-bar-local-item-from-menu 'vc-dir-query-replace-regexp
330 "search-replace" map vc-dir-mode-map
331 :label "Replace")
332 (tool-bar-local-item-from-menu 'vc-dir-kill-dir-status-process "cancel" 324 (tool-bar-local-item-from-menu 'vc-dir-kill-dir-status-process "cancel"
333 map vc-dir-mode-map 325 map vc-dir-mode-map
334 :label "Cancel") 326 :label "Stop" :vert-only t)
335 (tool-bar-local-item-from-menu 'quit-window "exit" 327 (tool-bar-local-item-from-menu 'revert-buffer "refresh"
336 map vc-dir-mode-map) 328 map vc-dir-mode-map :vert-only t)
329 (define-key-after map [separator-2] menu-bar-separator)
330 (tool-bar-local-item-from-menu (lookup-key menu-bar-edit-menu [cut])
331 "cut" map nil :vert-only t)
332 (tool-bar-local-item-from-menu (lookup-key menu-bar-edit-menu [copy])
333 "copy" map nil :vert-only t)
334 (tool-bar-local-item-from-menu (lookup-key menu-bar-edit-menu [paste])
335 "paste" map nil :vert-only t)
336 (define-key-after map [separator-3] menu-bar-separator)
337 (tool-bar-local-item-from-menu 'isearch-forward
338 "search" map nil
339 :label "Search" :vert-only t)
337 map)) 340 map))
338 341
339(defun vc-dir-node-directory (node) 342(defun vc-dir-node-directory (node)
diff --git a/lisp/wid-edit.el b/lisp/wid-edit.el
index 5b6bc97db2c..f82039585b2 100644
--- a/lisp/wid-edit.el
+++ b/lisp/wid-edit.el
@@ -2162,21 +2162,13 @@ when he invoked the menu."
2162 2162
2163(defun widget-toggle-value-create (widget) 2163(defun widget-toggle-value-create (widget)
2164 "Insert text representing the `on' and `off' states." 2164 "Insert text representing the `on' and `off' states."
2165 (if (widget-value widget) 2165 (let* ((val (widget-value widget))
2166 (let ((image (widget-get widget :on-glyph))) 2166 (text (widget-get widget (if val :on :off)))
2167 (and (display-graphic-p) 2167 (img (widget-image-find
2168 (listp image) 2168 (widget-get widget (if val :on-glyph :off-glyph)))))
2169 (not (eq (car image) 'image)) 2169 (widget-image-insert widget (or text "")
2170 (widget-put widget :on-glyph (setq image (eval image)))) 2170 (if img
2171 (widget-image-insert widget 2171 (append img '(:ascent center))))))
2172 (widget-get widget :on)
2173 image))
2174 (let ((image (widget-get widget :off-glyph)))
2175 (and (display-graphic-p)
2176 (listp image)
2177 (not (eq (car image) 'image))
2178 (widget-put widget :off-glyph (setq image (eval image))))
2179 (widget-image-insert widget (widget-get widget :off) image))))
2180 2172
2181(defun widget-toggle-action (widget &optional event) 2173(defun widget-toggle-action (widget &optional event)
2182 ;; Toggle value. 2174 ;; Toggle value.
@@ -2816,34 +2808,22 @@ Return an alist of (TYPE MATCH)."
2816 "An indicator and manipulator for hidden items. 2808 "An indicator and manipulator for hidden items.
2817 2809
2818The following properties have special meanings for this widget: 2810The following properties have special meanings for this widget:
2819:on-image Image filename or spec to display when the item is visible. 2811:on-glyph Image filename or spec to display when the item is visible.
2820:on Text shown if the \"on\" image is nil or cannot be displayed. 2812:on Text shown if the \"on\" image is nil or cannot be displayed.
2821:off-image Image filename or spec to display when the item is hidden. 2813:off-glyph Image filename or spec to display when the item is hidden.
2822:off Text shown if the \"off\" image is nil cannot be displayed." 2814:off Text shown if the \"off\" image is nil cannot be displayed."
2823 :format "%[%v%]" 2815 :format "%[%v%]"
2824 :button-prefix "" 2816 :button-prefix ""
2825 :button-suffix "" 2817 :button-suffix ""
2826 :on-image "down" 2818 :on-glyph "down"
2827 :on "Hide" 2819 :on "Hide"
2828 :off-image "right" 2820 :off-glyph "right"
2829 :off "Show" 2821 :off "Show"
2830 :value-create 'widget-visibility-value-create 2822 :value-create 'widget-visibility-value-create
2831 :action 'widget-toggle-action 2823 :action 'widget-toggle-action
2832 :match (lambda (widget value) t)) 2824 :match (lambda (widget value) t))
2833 2825
2834(defun widget-visibility-value-create (widget) 2826(defalias 'widget-visibility-value-create 'widget-toggle-value-create)
2835 ;; Insert text representing the `on' and `off' states.
2836 (let* ((val (widget-value widget))
2837 (text (widget-get widget (if val :on :off)))
2838 (img (widget-image-find
2839 (widget-get widget (if val :on-image :off-image)))))
2840 (widget-image-insert widget
2841 (if text
2842 (concat widget-push-button-prefix text
2843 widget-push-button-suffix)
2844 "")
2845 (if img
2846 (append img '(:ascent center))))))
2847 2827
2848;;; The `documentation-link' Widget. 2828;;; The `documentation-link' Widget.
2849;; 2829;;
diff --git a/src/ChangeLog b/src/ChangeLog
index 353f9c2d64a..b68c375b4a6 100644
--- a/src/ChangeLog
+++ b/src/ChangeLog
@@ -1,4 +1,4 @@
12011-01-09 Paul Eggert <eggert@cs.ucla.edu> 12011-01-11 Paul Eggert <eggert@cs.ucla.edu>
2 2
3 Give a name FLOAT_TO_STRING_BUFSIZE to the constant 350. 3 Give a name FLOAT_TO_STRING_BUFSIZE to the constant 350.
4 * lisp.h (FLOAT_TO_STRING_BUFSIZE): New macro. 4 * lisp.h (FLOAT_TO_STRING_BUFSIZE): New macro.
@@ -27,14 +27,50 @@
27 (float_to_string): Use dtoastr rather than rolling our own code, 27 (float_to_string): Use dtoastr rather than rolling our own code,
28 which had an off-by-one bug on non-IEEE hosts. 28 which had an off-by-one bug on non-IEEE hosts.
29 29
302011-01-08 Paul Eggert <eggert@cs.ucla.edu>
31
32 Automate syncing from gnulib. 30 Automate syncing from gnulib.
33 * Makefile.in (lib): New macro. 31 * Makefile.in (lib): New macro.
34 (ALL_CFLAGS): Add -I$(lib) -I$(srcdir)/../lib. 32 (ALL_CFLAGS): Add -I$(lib) -I$(srcdir)/../lib.
35 ($(lib)/libgnu.a): New rule. 33 ($(lib)/libgnu.a): New rule.
36 (temacs$(EXEEXT)): Also link $(lib)/libgnu.a. 34 (temacs$(EXEEXT)): Also link $(lib)/libgnu.a.
37 35
362011-01-11 Tassilo Horn <tassilo@member.fsf.org>
37
38 * image.c (imagemagick_load_image, Finit_image_library): Free
39 intermediate image after creating a MagickWand from it. Terminate
40 MagickWand environment after image loading.
41
422011-01-10 Michael Albinus <michael.albinus@gmx.de>
43
44 * dbusbind.c (Fdbus_register_service): Raise an error in case of
45 unexpected return values.
46 (Fdbus_register_method): Remove connection initialization.
47
482011-01-10 Jan Moringen <jan.moringen@uni-bielefeld.de>
49
50 * dbusbind.c (QCdbus_request_name_allow_replacement): New symbol;
51 used by Fdbus_register_service.
52 (QCdbus_request_name_replace_existing): Likewise.
53 (QCdbus_request_name_do_not_queue): Likewise.
54 (QCdbus_request_name_reply_primary_owner): Likewise.
55 (QCdbus_request_name_reply_in_queue): Likewise.
56 (QCdbus_request_name_reply_exists): Likewise.
57 (QCdbus_request_name_reply_already_owner): Likewise.
58 (Fdbus_register_service): New function.
59 (Fdbus_register_method): Use Fdbus_register_service to do the name
60 registration.
61 (syms_of_dbusbind): Add symbols dbus-register-service,
62 :allow-replacement, :replace-existing, :do-not-queue,
63 :primary-owner, :existing, :in-queue and :already-owner.
64
652011-01-09 Chong Yidong <cyd@stupidchicken.com>
66
67 * gtkutil.c (update_frame_tool_bar): Don't advance tool-bar index
68 when removing extra buttons.
69
702011-01-08 Chong Yidong <cyd@stupidchicken.com>
71
72 * fns.c (Fyes_or_no_p): Doc fix.
73
382011-01-08 Andreas Schwab <schwab@linux-m68k.org> 742011-01-08 Andreas Schwab <schwab@linux-m68k.org>
39 75
40 * fns.c (Fyes_or_no_p): Add usage. 76 * fns.c (Fyes_or_no_p): Add usage.
diff --git a/src/dbusbind.c b/src/dbusbind.c
index 4ef962d1507..0c59c08f5b7 100644
--- a/src/dbusbind.c
+++ b/src/dbusbind.c
@@ -38,6 +38,7 @@ Lisp_Object Qdbus_call_method_asynchronously;
38Lisp_Object Qdbus_method_return_internal; 38Lisp_Object Qdbus_method_return_internal;
39Lisp_Object Qdbus_method_error_internal; 39Lisp_Object Qdbus_method_error_internal;
40Lisp_Object Qdbus_send_signal; 40Lisp_Object Qdbus_send_signal;
41Lisp_Object Qdbus_register_service;
41Lisp_Object Qdbus_register_signal; 42Lisp_Object Qdbus_register_signal;
42Lisp_Object Qdbus_register_method; 43Lisp_Object Qdbus_register_method;
43 44
@@ -50,6 +51,17 @@ Lisp_Object QCdbus_system_bus, QCdbus_session_bus;
50/* Lisp symbol for method call timeout. */ 51/* Lisp symbol for method call timeout. */
51Lisp_Object QCdbus_timeout; 52Lisp_Object QCdbus_timeout;
52 53
54/* Lisp symbols for name request flags. */
55Lisp_Object QCdbus_request_name_allow_replacement;
56Lisp_Object QCdbus_request_name_replace_existing;
57Lisp_Object QCdbus_request_name_do_not_queue;
58
59/* Lisp symbols for name request replies. */
60Lisp_Object QCdbus_request_name_reply_primary_owner;
61Lisp_Object QCdbus_request_name_reply_in_queue;
62Lisp_Object QCdbus_request_name_reply_exists;
63Lisp_Object QCdbus_request_name_reply_already_owner;
64
53/* Lisp symbols of D-Bus types. */ 65/* Lisp symbols of D-Bus types. */
54Lisp_Object QCdbus_type_byte, QCdbus_type_boolean; 66Lisp_Object QCdbus_type_byte, QCdbus_type_boolean;
55Lisp_Object QCdbus_type_int16, QCdbus_type_uint16; 67Lisp_Object QCdbus_type_int16, QCdbus_type_uint16;
@@ -1835,6 +1847,114 @@ xd_read_queued_messages (int fd, void *data, int for_read)
1835 xd_in_read_queued_messages = 0; 1847 xd_in_read_queued_messages = 0;
1836} 1848}
1837 1849
1850DEFUN ("dbus-register-service", Fdbus_register_service, Sdbus_register_service,
1851 2, MANY, 0,
1852 doc: /* Register known name SERVICE on the D-Bus BUS.
1853
1854BUS is either a Lisp symbol, `:system' or `:session', or a string
1855denoting the bus address.
1856
1857SERVICE is the D-Bus service name that should be registered. It must
1858be a known name.
1859
1860FLAGS are keywords, which control how the service name is registered.
1861The following keywords are recognized:
1862
1863`:allow-replacement': Allow another service to become the primary
1864owner if requested.
1865
1866`:replace-existing': Request to replace the current primary owner.
1867
1868`:do-not-queue': If we can not become the primary owner do not place
1869us in the queue.
1870
1871The function returns a keyword, indicating the result of the
1872operation. One of the following keywords is returned:
1873
1874`:primary-owner': Service has become the primary owner of the
1875requested name.
1876
1877`:in-queue': Service could not become the primary owner and has been
1878placed in the queue.
1879
1880`:exists': Service is already in the queue.
1881
1882`:already-owner': Service is already the primary owner.
1883
1884Example:
1885
1886\(dbus-register-service :session dbus-service-emacs)
1887
1888 => :primary-owner.
1889
1890\(dbus-register-service
1891 :session "org.freedesktop.TextEditor"
1892 dbus-service-allow-replacement dbus-service-replace-existing)
1893
1894 => :already-owner.
1895
1896usage: (dbus-register-service BUS SERVICE &rest FLAGS) */)
1897 (int nargs, register Lisp_Object *args)
1898{
1899 Lisp_Object bus, service;
1900 struct gcpro gcpro1, gcpro2;
1901 DBusConnection *connection;
1902 unsigned int i;
1903 unsigned int value;
1904 unsigned int flags = 0;
1905 int result;
1906 DBusError derror;
1907
1908 bus = args[0];
1909 service = args[1];
1910
1911 /* Check parameters. */
1912 CHECK_STRING (service);
1913
1914 /* Process flags. */
1915 for (i = 2; i < nargs; ++i) {
1916 value = ((EQ (args[i], QCdbus_request_name_replace_existing))
1917 ? DBUS_NAME_FLAG_REPLACE_EXISTING
1918 : (EQ (args[i], QCdbus_request_name_allow_replacement))
1919 ? DBUS_NAME_FLAG_ALLOW_REPLACEMENT
1920 : (EQ (args[i], QCdbus_request_name_do_not_queue))
1921 ? DBUS_NAME_FLAG_DO_NOT_QUEUE
1922 : -1);
1923 if (value == -1)
1924 XD_SIGNAL2 (build_string ("Unrecognized name request flag"), args[i]);
1925 flags |= value;
1926 }
1927
1928 /* Open a connection to the bus. */
1929 connection = xd_initialize (bus, TRUE);
1930
1931 /* Request the known name from the bus. */
1932 dbus_error_init (&derror);
1933 result = dbus_bus_request_name (connection, SDATA (service), flags,
1934 &derror);
1935 if (dbus_error_is_set (&derror))
1936 XD_ERROR (derror);
1937
1938 /* Cleanup. */
1939 dbus_error_free (&derror);
1940
1941 /* Return object. */
1942 switch (result)
1943 {
1944 case DBUS_REQUEST_NAME_REPLY_PRIMARY_OWNER:
1945 return QCdbus_request_name_reply_primary_owner;
1946 case DBUS_REQUEST_NAME_REPLY_IN_QUEUE:
1947 return QCdbus_request_name_reply_in_queue;
1948 case DBUS_REQUEST_NAME_REPLY_EXISTS:
1949 return QCdbus_request_name_reply_exists;
1950 case DBUS_REQUEST_NAME_REPLY_ALREADY_OWNER:
1951 return QCdbus_request_name_reply_already_owner;
1952 default:
1953 /* This should not happen. */
1954 XD_SIGNAL2 (build_string ("Could not register service"), service);
1955 }
1956}
1957
1838DEFUN ("dbus-register-signal", Fdbus_register_signal, Sdbus_register_signal, 1958DEFUN ("dbus-register-signal", Fdbus_register_signal, Sdbus_register_signal,
1839 6, MANY, 0, 1959 6, MANY, 0,
1840 doc: /* Register for signal SIGNAL on the D-Bus BUS. 1960 doc: /* Register for signal SIGNAL on the D-Bus BUS.
@@ -2011,9 +2131,8 @@ discovering the still incomplete interface.*/)
2011 Lisp_Object dont_register_service) 2131 Lisp_Object dont_register_service)
2012{ 2132{
2013 Lisp_Object key, key1, value; 2133 Lisp_Object key, key1, value;
2014 DBusConnection *connection;
2015 int result;
2016 DBusError derror; 2134 DBusError derror;
2135 Lisp_Object args[2] = { bus, service };
2017 2136
2018 /* Check parameters. */ 2137 /* Check parameters. */
2019 CHECK_STRING (service); 2138 CHECK_STRING (service);
@@ -2025,21 +2144,9 @@ discovering the still incomplete interface.*/)
2025 /* TODO: We must check for a valid service name, otherwise there is 2144 /* TODO: We must check for a valid service name, otherwise there is
2026 a segmentation fault. */ 2145 a segmentation fault. */
2027 2146
2028 /* Open a connection to the bus. */ 2147 /* Request the name. */
2029 connection = xd_initialize (bus, TRUE);
2030
2031 /* Request the known name from the bus. We can ignore the result,
2032 it is set to -1 if there is an error - kind of redundancy. */
2033 if (NILP (dont_register_service)) 2148 if (NILP (dont_register_service))
2034 { 2149 Fdbus_register_service (2, args);
2035 dbus_error_init (&derror);
2036 result = dbus_bus_request_name (connection, SDATA (service), 0, &derror);
2037 if (dbus_error_is_set (&derror))
2038 XD_ERROR (derror);
2039
2040 /* Cleanup. */
2041 dbus_error_free (&derror);
2042 }
2043 2150
2044 /* Create a hash table entry. We use nil for the unique name, 2151 /* Create a hash table entry. We use nil for the unique name,
2045 because the method might be called from anybody. */ 2152 because the method might be called from anybody. */
@@ -2091,6 +2198,10 @@ syms_of_dbusbind (void)
2091 staticpro (&Qdbus_send_signal); 2198 staticpro (&Qdbus_send_signal);
2092 defsubr (&Sdbus_send_signal); 2199 defsubr (&Sdbus_send_signal);
2093 2200
2201 Qdbus_register_service = intern_c_string ("dbus-register-service");
2202 staticpro (&Qdbus_register_service);
2203 defsubr (&Sdbus_register_service);
2204
2094 Qdbus_register_signal = intern_c_string ("dbus-register-signal"); 2205 Qdbus_register_signal = intern_c_string ("dbus-register-signal");
2095 staticpro (&Qdbus_register_signal); 2206 staticpro (&Qdbus_register_signal);
2096 defsubr (&Sdbus_register_signal); 2207 defsubr (&Sdbus_register_signal);
@@ -2112,6 +2223,27 @@ syms_of_dbusbind (void)
2112 QCdbus_session_bus = intern_c_string (":session"); 2223 QCdbus_session_bus = intern_c_string (":session");
2113 staticpro (&QCdbus_session_bus); 2224 staticpro (&QCdbus_session_bus);
2114 2225
2226 QCdbus_request_name_allow_replacement = intern_c_string (":allow-replacement");
2227 staticpro (&QCdbus_request_name_allow_replacement);
2228
2229 QCdbus_request_name_replace_existing = intern_c_string (":replace-existing");
2230 staticpro (&QCdbus_request_name_replace_existing);
2231
2232 QCdbus_request_name_do_not_queue = intern_c_string (":do-not-queue");
2233 staticpro (&QCdbus_request_name_do_not_queue);
2234
2235 QCdbus_request_name_reply_primary_owner = intern_c_string (":primary-owner");
2236 staticpro (&QCdbus_request_name_reply_primary_owner);
2237
2238 QCdbus_request_name_reply_exists = intern_c_string (":exists");
2239 staticpro (&QCdbus_request_name_reply_exists);
2240
2241 QCdbus_request_name_reply_in_queue = intern_c_string (":in-queue");
2242 staticpro (&QCdbus_request_name_reply_in_queue);
2243
2244 QCdbus_request_name_reply_already_owner = intern_c_string (":already-owner");
2245 staticpro (&QCdbus_request_name_reply_already_owner);
2246
2115 QCdbus_timeout = intern_c_string (":timeout"); 2247 QCdbus_timeout = intern_c_string (":timeout");
2116 staticpro (&QCdbus_timeout); 2248 staticpro (&QCdbus_timeout);
2117 2249
diff --git a/src/fns.c b/src/fns.c
index 8fd5c7d291a..cd95f6c27fd 100644
--- a/src/fns.c
+++ b/src/fns.c
@@ -2460,10 +2460,13 @@ do_yes_or_no_p (Lisp_Object prompt)
2460 2460
2461DEFUN ("yes-or-no-p", Fyes_or_no_p, Syes_or_no_p, 1, MANY, 0, 2461DEFUN ("yes-or-no-p", Fyes_or_no_p, Syes_or_no_p, 1, MANY, 0,
2462 doc: /* Ask user a yes-or-no question. Return t if answer is yes. 2462 doc: /* Ask user a yes-or-no question. Return t if answer is yes.
2463Takes one argument, which is the string to display to ask the question. 2463The string to display to ask the question is obtained by
2464It should end in a space; `yes-or-no-p' adds `(yes or no) ' to it. 2464formatting the string PROMPT with arguments ARGS (see `format').
2465The user must confirm the answer with RET, 2465The result should end in a space; `yes-or-no-p' adds
2466and can edit it until it has been confirmed. 2466\"(yes or no) \" to it.
2467
2468The user must confirm the answer with RET, and can edit it until it
2469has been confirmed.
2467 2470
2468Under a windowing system a dialog box will be used if `last-nonmenu-event' 2471Under a windowing system a dialog box will be used if `last-nonmenu-event'
2469is nil, and `use-dialog-box' is non-nil. 2472is nil, and `use-dialog-box' is non-nil.
diff --git a/src/gtkutil.c b/src/gtkutil.c
index fb003749493..905bbb1561d 100644
--- a/src/gtkutil.c
+++ b/src/gtkutil.c
@@ -4439,7 +4439,7 @@ update_frame_tool_bar (FRAME_PTR f)
4439 /* Remove buttons not longer needed. */ 4439 /* Remove buttons not longer needed. */
4440 do 4440 do
4441 { 4441 {
4442 ti = gtk_toolbar_get_nth_item (GTK_TOOLBAR (wtoolbar), j++); 4442 ti = gtk_toolbar_get_nth_item (GTK_TOOLBAR (wtoolbar), j);
4443 if (ti) 4443 if (ti)
4444 gtk_container_remove (GTK_CONTAINER (wtoolbar), GTK_WIDGET (ti)); 4444 gtk_container_remove (GTK_CONTAINER (wtoolbar), GTK_WIDGET (ti));
4445 } while (ti != NULL); 4445 } while (ti != NULL);
diff --git a/src/image.c b/src/image.c
index bff56b5f961..1125309a9f7 100644
--- a/src/image.c
+++ b/src/image.c
@@ -7518,6 +7518,9 @@ imagemagick_load_image (/* Pointer to emacs frame structure. */
7518 image. Interface :index is same as for GIF. First we "ping" the 7518 image. Interface :index is same as for GIF. First we "ping" the
7519 image to see how many sub-images it contains. Pinging is faster 7519 image to see how many sub-images it contains. Pinging is faster
7520 than loading the image to find out things about it. */ 7520 than loading the image to find out things about it. */
7521
7522 /* MagickWandGenesis() initializes the imagemagick library. */
7523 MagickWandGenesis ();
7521 image = image_spec_value (img->spec, QCindex, NULL); 7524 image = image_spec_value (img->spec, QCindex, NULL);
7522 ino = INTEGERP (image) ? XFASTINT (image) : 0; 7525 ino = INTEGERP (image) ? XFASTINT (image) : 0;
7523 ping_wand = NewMagickWand (); 7526 ping_wand = NewMagickWand ();
@@ -7546,6 +7549,7 @@ imagemagick_load_image (/* Pointer to emacs frame structure. */
7546 img->data.lisp_val)); 7549 img->data.lisp_val));
7547 7550
7548 DestroyMagickWand (ping_wand); 7551 DestroyMagickWand (ping_wand);
7552
7549 /* Now, after pinging, we know how many images are inside the 7553 /* Now, after pinging, we know how many images are inside the
7550 file. If its not a bundle, just one. */ 7554 file. If its not a bundle, just one. */
7551 7555
@@ -7563,6 +7567,7 @@ imagemagick_load_image (/* Pointer to emacs frame structure. */
7563 if (im_image != NULL) 7567 if (im_image != NULL)
7564 { 7568 {
7565 image_wand = NewMagickWandFromImage (im_image); 7569 image_wand = NewMagickWandFromImage (im_image);
7570 DestroyImage(im_image);
7566 status = MagickTrue; 7571 status = MagickTrue;
7567 } 7572 }
7568 else 7573 else
@@ -7573,7 +7578,7 @@ imagemagick_load_image (/* Pointer to emacs frame structure. */
7573 image_wand = NewMagickWand (); 7578 image_wand = NewMagickWand ();
7574 status = MagickReadImageBlob (image_wand, contents, size); 7579 status = MagickReadImageBlob (image_wand, contents, size);
7575 } 7580 }
7576 image_error ("im read failed", Qnil, Qnil); 7581
7577 if (status == MagickFalse) goto imagemagick_error; 7582 if (status == MagickFalse) goto imagemagick_error;
7578 7583
7579 /* If width and/or height is set in the display spec assume we want 7584 /* If width and/or height is set in the display spec assume we want
@@ -7802,11 +7807,13 @@ imagemagick_load_image (/* Pointer to emacs frame structure. */
7802 7807
7803 /* Final cleanup. image_wand should be the only resource left. */ 7808 /* Final cleanup. image_wand should be the only resource left. */
7804 DestroyMagickWand (image_wand); 7809 DestroyMagickWand (image_wand);
7810 MagickWandTerminus ();
7805 7811
7806 return 1; 7812 return 1;
7807 7813
7808 imagemagick_error: 7814 imagemagick_error:
7809 DestroyMagickWand (image_wand); 7815 DestroyMagickWand (image_wand);
7816 MagickWandTerminus ();
7810 /* TODO more cleanup. */ 7817 /* TODO more cleanup. */
7811 image_error ("Error parsing IMAGEMAGICK image `%s'", img->spec, Qnil); 7818 image_error ("Error parsing IMAGEMAGICK image `%s'", img->spec, Qnil);
7812 return 0; 7819 return 0;
@@ -8678,8 +8685,6 @@ of `dynamic-library-alist', which see). */)
8678#if defined (HAVE_IMAGEMAGICK) 8685#if defined (HAVE_IMAGEMAGICK)
8679 if (EQ (type, Qimagemagick)) 8686 if (EQ (type, Qimagemagick))
8680 { 8687 {
8681 /* MagickWandGenesis() initializes the imagemagick library. */
8682 MagickWandGenesis ();
8683 return CHECK_LIB_AVAILABLE (&imagemagick_type, init_imagemagick_functions, 8688 return CHECK_LIB_AVAILABLE (&imagemagick_type, init_imagemagick_functions,
8684 libraries); 8689 libraries);
8685 } 8690 }