aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorStefan Monnier2013-10-25 11:23:45 -0400
committerStefan Monnier2013-10-25 11:23:45 -0400
commiteb89dc14d9367b3f2dbb265dedf2e781a4105b03 (patch)
treeb525a908e83f27f297dbac4a843f2137161d8e0d
parent8b022e34fd15fbfd191c2dd79ff24d43ddac23a6 (diff)
downloademacs-eb89dc14d9367b3f2dbb265dedf2e781a4105b03.tar.gz
emacs-eb89dc14d9367b3f2dbb265dedf2e781a4105b03.zip
* lisp/progmodes/prolog.el: Remove old indent; use post-self-insert-hook.
(prolog-align-comments-flag, prolog-indent-mline-comments-flag) (prolog-object-end-to-0-flag, prolog-electric-newline-flag) (prolog-electric-tab-flag, prolog-use-prolog-tokenizer-flag): Remove vars, they do not apply any more. (prolog-mode-abbrev-table): Remove redundant declaration. (prolog-upper-case-string, prolog-lower-case-string): Remove. (prolog-use-smie): Remove. (prolog-smie-rules): Add indentation rule for the if-then-else layout supported by prolog-electric-if-then-else-flag. (prolog-mode-variables, prolog-menu): Use setq-local. (prolog-mode-keybindings-edit): Don't rebind M-C-p and M-C-n. Remove binding to `Backspace' since this key doesn't exist anyway. Remove bindings for electric self-inserting keys. (prog-mode): Assume it's defined. (prolog-post-self-insert): New function. (prolog-mode): Use it. (prolog-indent-line, prolog-indent-level) (prolog-find-indent-of-matching-paren) (prolog-indentation-level-of-line, prolog-goto-comment-column) (prolog-paren-is-the-first-on-line-p, prolog-region-paren-balance) (prolog-goto-next-paren, prolog-in-string-or-comment) (prolog-tokenize, prolog-inside-mline-comment) (prolog-find-start-of-mline-comment): Remove functions. (prolog-find-unmatched-paren, prolog-clause-end) (prolog-guess-fill-prefix, prolog-get-predspec): Use syntax-ppss. (prolog-electric--if-then-else): Rename from prolog-insert-spaces-after-paren; use prolog-electric-if-then-else-flag. (prolog-tokenize-searchkey): Remove const. (prolog-clause-info): Use forward-sexp. (prolog-forward-list, prolog-backward-list, prolog-electric-delete) (prolog-electric-if-then-else): Remove commands. (prolog-electric--colon): Rename from prolog-electric-colon; adapt it for use in post-self-insert-hook. (prolog-electric--dash): Rename from prolog-electric-dash; adapt it for use in post-self-insert-hook. (prolog-electric--dot): Rename from prolog-electric-dot; adapt it for use in post-self-insert-hook. (prolog-electric--underscore): Rename from prolog-electric--underscore; adapt it for use in post-self-insert-hook.
-rw-r--r--etc/NEWS2
-rw-r--r--lisp/ChangeLog47
-rw-r--r--lisp/progmodes/prolog.el1634
3 files changed, 447 insertions, 1236 deletions
diff --git a/etc/NEWS b/etc/NEWS
index 232a1bc8a4b..3d0811abff4 100644
--- a/etc/NEWS
+++ b/etc/NEWS
@@ -216,6 +216,8 @@ You can pick the name of the function and the variables with `C-x 4 a'.
216 216
217* Changes in Specialized Modes and Packages in Emacs 24.4 217* Changes in Specialized Modes and Packages in Emacs 24.4
218 218
219** prolog-use-smie has been remvoed, along with the non-SMIE indentation code.
220
219** SMIE indentation can be customized via `smie-config'. 221** SMIE indentation can be customized via `smie-config'.
220The customizaton can be guessed by Emacs by providing a sample indented 222The customizaton can be guessed by Emacs by providing a sample indented
221file and letting SMIE learn from it. 223file and letting SMIE learn from it.
diff --git a/lisp/ChangeLog b/lisp/ChangeLog
index 031e0e40697..82e03a48da4 100644
--- a/lisp/ChangeLog
+++ b/lisp/ChangeLog
@@ -1,3 +1,46 @@
12013-10-25 Stefan Monnier <monnier@iro.umontreal.ca>
2
3 * progmodes/prolog.el: Remove old indent; use post-self-insert-hook.
4 (prolog-align-comments-flag, prolog-indent-mline-comments-flag)
5 (prolog-object-end-to-0-flag, prolog-electric-newline-flag)
6 (prolog-electric-tab-flag, prolog-use-prolog-tokenizer-flag):
7 Remove vars, they do not apply any more.
8 (prolog-mode-abbrev-table): Remove redundant declaration.
9 (prolog-upper-case-string, prolog-lower-case-string): Remove.
10 (prolog-use-smie): Remove.
11 (prolog-smie-rules): Add indentation rule for the if-then-else layout
12 supported by prolog-electric-if-then-else-flag.
13 (prolog-mode-variables, prolog-menu): Use setq-local.
14 (prolog-mode-keybindings-edit): Don't rebind M-C-p and M-C-n.
15 Remove binding to `Backspace' since this key doesn't exist anyway.
16 Remove bindings for electric self-inserting keys.
17 (prog-mode): Assume it's defined.
18 (prolog-post-self-insert): New function.
19 (prolog-mode): Use it.
20 (prolog-indent-line, prolog-indent-level)
21 (prolog-find-indent-of-matching-paren)
22 (prolog-indentation-level-of-line, prolog-goto-comment-column)
23 (prolog-paren-is-the-first-on-line-p, prolog-region-paren-balance)
24 (prolog-goto-next-paren, prolog-in-string-or-comment)
25 (prolog-tokenize, prolog-inside-mline-comment)
26 (prolog-find-start-of-mline-comment): Remove functions.
27 (prolog-find-unmatched-paren, prolog-clause-end)
28 (prolog-guess-fill-prefix, prolog-get-predspec): Use syntax-ppss.
29 (prolog-electric--if-then-else): Rename from
30 prolog-insert-spaces-after-paren; use prolog-electric-if-then-else-flag.
31 (prolog-tokenize-searchkey): Remove const.
32 (prolog-clause-info): Use forward-sexp.
33 (prolog-forward-list, prolog-backward-list, prolog-electric-delete)
34 (prolog-electric-if-then-else): Remove commands.
35 (prolog-electric--colon): Rename from prolog-electric-colon; adapt it
36 for use in post-self-insert-hook.
37 (prolog-electric--dash): Rename from prolog-electric-dash; adapt it
38 for use in post-self-insert-hook.
39 (prolog-electric--dot): Rename from prolog-electric-dot; adapt it
40 for use in post-self-insert-hook.
41 (prolog-electric--underscore): Rename from prolog-electric--underscore;
42 adapt it for use in post-self-insert-hook.
43
12013-10-25 Michael Albinus <michael.albinus@gmx.de> 442013-10-25 Michael Albinus <michael.albinus@gmx.de>
2 45
3 * emacs-lisp/ert.el (ert-run-tests-interactively): 46 * emacs-lisp/ert.el (ert-run-tests-interactively):
@@ -13,8 +56,8 @@
132013-10-25 Dmitry Gutov <dgutov@yandex.ru> 562013-10-25 Dmitry Gutov <dgutov@yandex.ru>
14 57
15 * progmodes/ruby-mode.el (ruby-mode-menu): Use proper 58 * progmodes/ruby-mode.el (ruby-mode-menu): Use proper
16 capitalization. Use :visible instead of :active. Fix 59 capitalization. Use :visible instead of :active.
17 `ruby-indent-exp' reference. Add menu items for the generic 60 Fix `ruby-indent-exp' reference. Add menu items for the generic
18 commands that are used with SMIE. 61 commands that are used with SMIE.
19 (ruby-do-end-to-brace): Insert space after `{'. 62 (ruby-do-end-to-brace): Insert space after `{'.
20 63
diff --git a/lisp/progmodes/prolog.el b/lisp/progmodes/prolog.el
index 0f3c1504ee9..5a2d7c1cf0e 100644
--- a/lisp/progmodes/prolog.el
+++ b/lisp/progmodes/prolog.el
@@ -1,4 +1,4 @@
1;;; prolog.el --- major mode for Prolog (and Mercury) -*- coding: utf-8 -*- 1;;; prolog.el --- major mode for Prolog (and Mercury) -*- lexical-binding:t -*-
2 2
3;; Copyright (C) 1986-1987, 1997-1999, 2002-2003, 2011-2013 Free 3;; Copyright (C) 1986-1987, 1997-1999, 2002-2003, 2011-2013 Free
4;; Software Foundation, Inc. 4;; Software Foundation, Inc.
@@ -376,29 +376,8 @@ The version numbers are of the format (Major . Minor)."
376 :group 'prolog-indentation 376 :group 'prolog-indentation
377 :type 'integer) 377 :type 'integer)
378 378
379(defcustom prolog-align-comments-flag t
380 "Non-nil means automatically align comments when indenting."
381 :version "24.1"
382 :group 'prolog-indentation
383 :type 'boolean)
384
385(defcustom prolog-indent-mline-comments-flag t
386 "Non-nil means indent contents of /* */ comments.
387Otherwise leave such lines as they are."
388 :version "24.1"
389 :group 'prolog-indentation
390 :type 'boolean)
391
392(defcustom prolog-object-end-to-0-flag t
393 "Non-nil means indent closing '}' in SICStus object definitions to level 0.
394Otherwise indent to `prolog-indent-width'."
395 :version "24.1"
396 :group 'prolog-indentation
397 :type 'boolean)
398
399(defcustom prolog-left-indent-regexp "\\(;\\|\\*?->\\)" 379(defcustom prolog-left-indent-regexp "\\(;\\|\\*?->\\)"
400 "Regexp for character sequences after which next line is indented. 380 "Regexp for `prolog-electric-if-then-else-flag'."
401Next line after such a regexp is indented to the opening parenthesis level."
402 :version "24.1" 381 :version "24.1"
403 :group 'prolog-indentation 382 :group 'prolog-indentation
404 :type 'regexp) 383 :type 'regexp)
@@ -503,12 +482,6 @@ Legal values:
503 482
504;; Keyboard 483;; Keyboard
505 484
506(defcustom prolog-electric-newline-flag (not (fboundp 'electric-indent-mode))
507 "Non-nil means automatically indent the next line when the user types RET."
508 :version "24.1"
509 :group 'prolog-keyboard
510 :type 'boolean)
511
512(defcustom prolog-hungry-delete-key-flag nil 485(defcustom prolog-hungry-delete-key-flag nil
513 "Non-nil means delete key consumes all preceding spaces." 486 "Non-nil means delete key consumes all preceding spaces."
514 :version "24.1" 487 :version "24.1"
@@ -545,14 +518,6 @@ If underscore is pressed not on a variable then it behaves as usual."
545 :group 'prolog-keyboard 518 :group 'prolog-keyboard
546 :type 'boolean) 519 :type 'boolean)
547 520
548(defcustom prolog-electric-tab-flag nil
549 "Non-nil means make TAB key electric.
550Electric TAB inserts spaces after parentheses, ->, and ;
551in ( If -> Then ; Else) and ( Disj1 ; Disj2 ) style expressions."
552 :version "24.1"
553 :group 'prolog-keyboard
554 :type 'boolean)
555
556(defcustom prolog-electric-if-then-else-flag nil 521(defcustom prolog-electric-if-then-else-flag nil
557 "Non-nil makes `(', `>' and `;' electric 522 "Non-nil makes `(', `>' and `;' electric
558to automatically indent if-then-else constructs." 523to automatically indent if-then-else constructs."
@@ -739,14 +704,6 @@ is non-nil for this variable."
739 704
740;; Miscellaneous 705;; Miscellaneous
741 706
742(defcustom prolog-use-prolog-tokenizer-flag
743 (not (fboundp 'syntax-propertize-rules))
744 "Non-nil means use the internal prolog tokenizer for indentation etc.
745Otherwise use `parse-partial-sexp' which is faster but sometimes incorrect."
746 :version "24.1"
747 :group 'prolog-other
748 :type 'boolean)
749
750(defcustom prolog-imenu-flag t 707(defcustom prolog-imenu-flag t
751 "Non-nil means add a clause index menu for all prolog files." 708 "Non-nil means add a clause index menu for all prolog files."
752 :version "24.1" 709 :version "24.1"
@@ -831,117 +788,12 @@ This is really kludgy, and unneeded (i.e. obsolete) in Emacs>=24."
831 (modify-syntax-entry ?/ ". 14" table) 788 (modify-syntax-entry ?/ ". 14" table)
832 ) 789 )
833 table)) 790 table))
834(defvar prolog-mode-abbrev-table nil)
835
836(if (eval-when-compile
837 (and (string-match "[[:upper:]]" "A")
838 (with-temp-buffer
839 (insert "A") (skip-chars-backward "[:upper:]") (bolp))))
840 (progn
841 (defconst prolog-upper-case-string "[:upper:]"
842 "A string containing a char-range matching all upper case characters.")
843 (defconst prolog-lower-case-string "[:lower:]"
844 "A string containing a char-range matching all lower case characters."))
845
846 ;; GNU Emacs compatibility: GNU Emacs does not differentiate between
847 ;; ints and chars, or at least these two are interchangeable.
848 (defalias 'prolog-int-to-char
849 (if (fboundp 'int-to-char) #'int-to-char #'identity))
850
851 (defalias 'prolog-char-to-int
852 (if (fboundp 'char-to-int) #'char-to-int #'identity))
853
854 (defun prolog-ints-intervals (ints)
855 "Return a list of intervals (from . to) covering INTS."
856 (when ints
857 (setq ints (sort ints '<))
858 (let ((prev (car ints))
859 (interval-start (car ints))
860 intervals)
861 (while ints
862 (let ((next (car ints)))
863 (when (> next (1+ prev)) ; start of new interval
864 (setq intervals (cons (cons interval-start prev) intervals))
865 (setq interval-start next))
866 (setq prev next)
867 (setq ints (cdr ints))))
868 (setq intervals (cons (cons interval-start prev) intervals))
869 (reverse intervals))))
870
871 (defun prolog-dash-letters (string)
872 "Return a condensed regexp covering all letters in STRING."
873 (let ((intervals (prolog-ints-intervals (mapcar #'prolog-char-to-int
874 (string-to-list string))))
875 codes)
876 (while intervals
877 (let* ((i (car intervals))
878 (from (car i))
879 (to (cdr i))
880 (c (cond ((= from to) `(,from))
881 ((= (1+ from) to) `(,from ,to))
882 (t `(,from ?- ,to)))))
883 (setq codes (cons c codes)))
884 (setq intervals (cdr intervals)))
885 (apply 'concat (reverse codes))))
886
887 (let ((up_string "")
888 (low_string ""))
889 ;; Use `map-char-table' if it is defined. Otherwise enumerate all
890 ;; numbers between 0 and 255. `map-char-table' is probably safer.
891 ;;
892 ;; `map-char-table' causes problems under Emacs 23.0.0.1, the
893 ;; while loop seems to do its job well (Ryszard Szopa)
894 ;;
895 ;;(if (and (not (featurep 'xemacs))
896 ;; (fboundp 'map-char-table))
897 ;; (map-char-table
898 ;; (lambda (key value)
899 ;; (cond
900 ;; ((and
901 ;; (eq (prolog-int-to-char key) (downcase key))
902 ;; (eq (prolog-int-to-char key) (upcase key)))
903 ;; ;; Do nothing if upper and lower case are the same
904 ;; )
905 ;; ((eq (prolog-int-to-char key) (downcase key))
906 ;; ;; The char is lower case
907 ;; (setq low_string (format "%s%c" low_string key)))
908 ;; ((eq (prolog-int-to-char key) (upcase key))
909 ;; ;; The char is upper case
910 ;; (setq up_string (format "%s%c" up_string key)))
911 ;; ))
912 ;; (current-case-table))
913 ;; `map-char-table' was undefined.
914 (let ((key 0))
915 (while (< key 256)
916 (cond
917 ((and
918 (eq (prolog-int-to-char key) (downcase key))
919 (eq (prolog-int-to-char key) (upcase key)))
920 ;; Do nothing if upper and lower case are the same
921 )
922 ((eq (prolog-int-to-char key) (downcase key))
923 ;; The char is lower case
924 (setq low_string (format "%s%c" low_string key)))
925 ((eq (prolog-int-to-char key) (upcase key))
926 ;; The char is upper case
927 (setq up_string (format "%s%c" up_string key)))
928 )
929 (setq key (1+ key))))
930 ;; )
931 ;; The strings are single-byte strings.
932 (defconst prolog-upper-case-string (prolog-dash-letters up_string)
933 "A string containing a char-range matching all upper case characters.")
934 (defconst prolog-lower-case-string (prolog-dash-letters low_string)
935 "A string containing a char-range matching all lower case characters.")
936 ))
937 791
938(defconst prolog-atom-char-regexp 792(defconst prolog-atom-char-regexp
939 (if (string-match "[[:alnum:]]" "0") 793 "[[:alnum:]_$]"
940 "[[:alnum:]_$]"
941 (format "[%s%s0-9_$]" prolog-lower-case-string prolog-upper-case-string))
942 "Regexp specifying characters which constitute atoms without quoting.") 794 "Regexp specifying characters which constitute atoms without quoting.")
943(defconst prolog-atom-regexp 795(defconst prolog-atom-regexp
944 (format "[%s$]%s*" prolog-lower-case-string prolog-atom-char-regexp)) 796 (format "[[:lower:]$]%s*" prolog-atom-char-regexp))
945 797
946(defconst prolog-left-paren "[[({]" ;FIXME: Why not \\s(? 798(defconst prolog-left-paren "[[({]" ;FIXME: Why not \\s(?
947 "The characters used as left parentheses for the indentation code.") 799 "The characters used as left parentheses for the indentation code.")
@@ -988,8 +840,6 @@ This is really kludgy, and unneeded (i.e. obsolete) in Emacs>=24."
988 840
989(require 'smie) 841(require 'smie)
990 842
991(defvar prolog-use-smie t)
992
993(defun prolog-smie-forward-token () 843(defun prolog-smie-forward-token ()
994 ;; FIXME: Add support for 0'<char>, if needed after adding it to 844 ;; FIXME: Add support for 0'<char>, if needed after adding it to
995 ;; syntax-propertize-functions. 845 ;; syntax-propertize-functions.
@@ -1073,6 +923,13 @@ This is really kludgy, and unneeded (i.e. obsolete) in Emacs>=24."
1073 (pcase (cons kind token) 923 (pcase (cons kind token)
1074 (`(:elem . basic) prolog-indent-width) 924 (`(:elem . basic) prolog-indent-width)
1075 (`(:after . ".") '(column . 0)) ;; To work around smie-closer-alist. 925 (`(:after . ".") '(column . 0)) ;; To work around smie-closer-alist.
926 ;; Allow indentation of if-then-else as:
927 ;; ( test
928 ;; -> thenrule
929 ;; ; elserule
930 ;; )
931 (`(:before . ,(or `"->" `";"))
932 (and (smie-rule-bolp) (smie-rule-parent-p "(") (smie-rule-parent 1)))
1076 (`(:after . ,(or `":-" `"->" `"-->")) prolog-indent-width))) 933 (`(:after . ,(or `":-" `"->" `"-->")) prolog-indent-width)))
1077 934
1078 935
@@ -1140,17 +997,16 @@ VERSION is of the format (Major . Minor)"
1140 997
1141(defun prolog-mode-variables () 998(defun prolog-mode-variables ()
1142 "Set some common variables to Prolog code specific values." 999 "Set some common variables to Prolog code specific values."
1143 (setq local-abbrev-table prolog-mode-abbrev-table) 1000 (setq-local local-abbrev-table prolog-mode-abbrev-table)
1144 (set (make-local-variable 'paragraph-start) 1001 (setq-local paragraph-start (concat "[ \t]*$\\|" page-delimiter)) ;'%%..'
1145 (concat "[ \t]*$\\|" page-delimiter)) ;'%%..' 1002 (setq-local paragraph-separate paragraph-start)
1146 (set (make-local-variable 'paragraph-separate) paragraph-start) 1003 (setq-local paragraph-ignore-fill-prefix t)
1147 (set (make-local-variable 'paragraph-ignore-fill-prefix) t) 1004 (setq-local normal-auto-fill-function 'prolog-do-auto-fill)
1148 (set (make-local-variable 'normal-auto-fill-function) 'prolog-do-auto-fill) 1005 (setq-local comment-start "%")
1149 (set (make-local-variable 'comment-start) "%") 1006 (setq-local comment-end "")
1150 (set (make-local-variable 'comment-end) "") 1007 (setq-local comment-add 1)
1151 (set (make-local-variable 'comment-add) 1) 1008 (setq-local comment-start-skip "\\(?:/\\*+ *\\|%%+ *\\)")
1152 (set (make-local-variable 'comment-start-skip) "\\(?:/\\*+ *\\|%%+ *\\)") 1009 (setq-local parens-require-spaces nil)
1153 (set (make-local-variable 'parens-require-spaces) nil)
1154 ;; Initialize Prolog system specific variables 1010 ;; Initialize Prolog system specific variables
1155 (dolist (var '(prolog-keywords prolog-types prolog-mode-specificators 1011 (dolist (var '(prolog-keywords prolog-types prolog-mode-specificators
1156 prolog-determinism-specificators prolog-directives 1012 prolog-determinism-specificators prolog-directives
@@ -1160,19 +1016,14 @@ VERSION is of the format (Major . Minor)"
1160 (set (intern (concat (symbol-name var) "-i")) 1016 (set (intern (concat (symbol-name var) "-i"))
1161 (prolog-find-value-by-system (symbol-value var)))) 1017 (prolog-find-value-by-system (symbol-value var))))
1162 (when (null (prolog-program-name)) 1018 (when (null (prolog-program-name))
1163 (set (make-local-variable 'compile-command) (prolog-compile-string))) 1019 (setq-local compile-command (prolog-compile-string)))
1164 (set (make-local-variable 'font-lock-defaults) 1020 (setq-local font-lock-defaults
1165 '(prolog-font-lock-keywords nil nil ((?_ . "w")))) 1021 '(prolog-font-lock-keywords nil nil ((?_ . "w"))))
1166 (set (make-local-variable 'syntax-propertize-function) 1022 (setq-local syntax-propertize-function prolog-syntax-propertize-function)
1167 prolog-syntax-propertize-function) 1023
1168 1024 (smie-setup prolog-smie-grammar #'prolog-smie-rules
1169 (if prolog-use-smie 1025 :forward-token #'prolog-smie-forward-token
1170 ;; Setup SMIE. 1026 :backward-token #'prolog-smie-backward-token))
1171 (smie-setup prolog-smie-grammar #'prolog-smie-rules
1172 :forward-token #'prolog-smie-forward-token
1173 :backward-token #'prolog-smie-backward-token)
1174 (set (make-local-variable 'indent-line-function) 'prolog-indent-line))
1175 )
1176 1027
1177(defun prolog-mode-keybindings-common (map) 1028(defun prolog-mode-keybindings-common (map)
1178 "Define keybindings common to both Prolog modes in MAP." 1029 "Define keybindings common to both Prolog modes in MAP."
@@ -1193,25 +1044,12 @@ VERSION is of the format (Major . Minor)"
1193 (define-key map "\C-\M-e" 'prolog-end-of-predicate) 1044 (define-key map "\C-\M-e" 'prolog-end-of-predicate)
1194 (define-key map "\M-\C-c" 'prolog-mark-clause) 1045 (define-key map "\M-\C-c" 'prolog-mark-clause)
1195 (define-key map "\M-\C-h" 'prolog-mark-predicate) 1046 (define-key map "\M-\C-h" 'prolog-mark-predicate)
1196 (define-key map "\M-\C-n" 'prolog-forward-list)
1197 (define-key map "\M-\C-p" 'prolog-backward-list)
1198 (define-key map "\C-c\C-n" 'prolog-insert-predicate-template) 1047 (define-key map "\C-c\C-n" 'prolog-insert-predicate-template)
1199 (define-key map "\C-c\C-s" 'prolog-insert-predspec) 1048 (define-key map "\C-c\C-s" 'prolog-insert-predspec)
1200 (define-key map "\M-\r" 'prolog-insert-next-clause) 1049 (define-key map "\M-\r" 'prolog-insert-next-clause)
1201 (define-key map "\C-c\C-va" 'prolog-variables-to-anonymous) 1050 (define-key map "\C-c\C-va" 'prolog-variables-to-anonymous)
1202 (define-key map "\C-c\C-v\C-s" 'prolog-view-predspec) 1051 (define-key map "\C-c\C-v\C-s" 'prolog-view-predspec)
1203 1052
1204 (define-key map [Backspace] 'prolog-electric-delete)
1205 (define-key map "." 'prolog-electric-dot)
1206 (define-key map "_" 'prolog-electric-underscore)
1207 (define-key map "(" 'prolog-electric-if-then-else)
1208 (define-key map ";" 'prolog-electric-if-then-else)
1209 (define-key map ">" 'prolog-electric-if-then-else)
1210 (define-key map ":" 'prolog-electric-colon)
1211 (define-key map "-" 'prolog-electric-dash)
1212 (if prolog-electric-newline-flag
1213 (define-key map "\r" 'newline-and-indent))
1214
1215 ;; If we're running SICStus, then map C-c C-c e/d to enabling 1053 ;; If we're running SICStus, then map C-c C-c e/d to enabling
1216 ;; and disabling of the source-level debugging facilities. 1054 ;; and disabling of the source-level debugging facilities.
1217 ;(if (and (eq prolog-system 'sicstus) 1055 ;(if (and (eq prolog-system 'sicstus)
@@ -1258,8 +1096,6 @@ VERSION is of the format (Major . Minor)"
1258(defvar prolog-mode-hook nil 1096(defvar prolog-mode-hook nil
1259 "List of functions to call after the prolog mode has initialized.") 1097 "List of functions to call after the prolog mode has initialized.")
1260 1098
1261(unless (fboundp 'prog-mode)
1262 (defalias 'prog-mode 'fundamental-mode))
1263;;;###autoload 1099;;;###autoload
1264(define-derived-mode prolog-mode prog-mode "Prolog" 1100(define-derived-mode prolog-mode prog-mode "Prolog"
1265 "Major mode for editing Prolog code. 1101 "Major mode for editing Prolog code.
@@ -1285,7 +1121,7 @@ if that value is non-nil."
1285 (t "")))) 1121 (t ""))))
1286 (prolog-mode-variables) 1122 (prolog-mode-variables)
1287 (dolist (ar prolog-align-rules) (add-to-list 'align-rules-list ar)) 1123 (dolist (ar prolog-align-rules) (add-to-list 'align-rules-list ar))
1288 1124 (add-hook 'post-self-insert-hook #'prolog-post-self-insert nil t)
1289 ;; `imenu' entry moved to the appropriate hook for consistency. 1125 ;; `imenu' entry moved to the appropriate hook for consistency.
1290 1126
1291 ;; Load SICStus debugger if suitable 1127 ;; Load SICStus debugger if suitable
@@ -1305,7 +1141,7 @@ if that value is non-nil."
1305(define-derived-mode mercury-mode prolog-mode "Prolog[Mercury]" 1141(define-derived-mode mercury-mode prolog-mode "Prolog[Mercury]"
1306 "Major mode for editing Mercury programs. 1142 "Major mode for editing Mercury programs.
1307Actually this is just customized `prolog-mode'." 1143Actually this is just customized `prolog-mode'."
1308 (set (make-local-variable 'prolog-system) 'mercury)) 1144 (setq-local prolog-system 'mercury))
1309 1145
1310 1146
1311;;------------------------------------------------------------------- 1147;;-------------------------------------------------------------------
@@ -1393,9 +1229,9 @@ To find out what version of Prolog mode you are running, enter
1393 (setq mode-line-process '(": %s")) 1229 (setq mode-line-process '(": %s"))
1394 (prolog-mode-variables) 1230 (prolog-mode-variables)
1395 (setq comint-prompt-regexp (prolog-prompt-regexp)) 1231 (setq comint-prompt-regexp (prolog-prompt-regexp))
1396 (set (make-local-variable 'shell-dirstack-query) "pwd.") 1232 (setq-local shell-dirstack-query "pwd.")
1397 (set (make-local-variable 'compilation-error-regexp-alist) 1233 (setq-local compilation-error-regexp-alist
1398 prolog-inferior-error-regexp-alist) 1234 prolog-inferior-error-regexp-alist)
1399 (compilation-shell-minor-mode) 1235 (compilation-shell-minor-mode)
1400 (prolog-inferior-menu)) 1236 (prolog-inferior-menu))
1401 1237
@@ -1430,22 +1266,22 @@ With prefix argument ARG, restart the Prolog process if running before."
1430 )) 1266 ))
1431 1267
1432(defun prolog-inferior-guess-flavor (&optional ignored) 1268(defun prolog-inferior-guess-flavor (&optional ignored)
1433 (setq prolog-system 1269 (setq-local prolog-system
1434 (when (or (numberp prolog-system) (markerp prolog-system)) 1270 (when (or (numberp prolog-system) (markerp prolog-system))
1435 (save-excursion 1271 (save-excursion
1436 (goto-char (1+ prolog-system)) 1272 (goto-char (1+ prolog-system))
1437 (cond 1273 (cond
1438 ((looking-at "GNU Prolog") 'gnu) 1274 ((looking-at "GNU Prolog") 'gnu)
1439 ((looking-at "Welcome to SWI-Prolog\\|%.*\\<swi_") 'swi) 1275 ((looking-at "Welcome to SWI-Prolog\\|%.*\\<swi_") 'swi)
1440 ((looking-at ".*\n") nil) ;There's at least one line. 1276 ((looking-at ".*\n") nil) ;There's at least one line.
1441 (t prolog-system))))) 1277 (t prolog-system)))))
1442 (when (symbolp prolog-system) 1278 (when (symbolp prolog-system)
1443 (remove-hook 'comint-output-filter-functions 1279 (remove-hook 'comint-output-filter-functions
1444 'prolog-inferior-guess-flavor t) 1280 'prolog-inferior-guess-flavor t)
1445 (when prolog-system 1281 (when prolog-system
1446 (setq comint-prompt-regexp (prolog-prompt-regexp)) 1282 (setq comint-prompt-regexp (prolog-prompt-regexp))
1447 (if (eq prolog-system 'gnu) 1283 (if (eq prolog-system 'gnu)
1448 (set (make-local-variable 'comint-process-echoes) t))))) 1284 (setq-local comint-process-echoes t)))))
1449 1285
1450(defun prolog-ensure-process (&optional wait) 1286(defun prolog-ensure-process (&optional wait)
1451 "If Prolog process is not running, run it. 1287 "If Prolog process is not running, run it.
@@ -1461,21 +1297,22 @@ the variable `prolog-prompt-regexp'."
1461 (prolog-program-name) nil (prolog-program-switches)) 1297 (prolog-program-name) nil (prolog-program-switches))
1462 (unless prolog-system 1298 (unless prolog-system
1463 ;; Setup auto-detection. 1299 ;; Setup auto-detection.
1464 (set (make-local-variable 'prolog-system) 1300 (setq-local
1465 ;; Force re-detection. 1301 prolog-system
1466 (let* ((proc (get-buffer-process (current-buffer))) 1302 ;; Force re-detection.
1467 (pmark (and proc (marker-position (process-mark proc))))) 1303 (let* ((proc (get-buffer-process (current-buffer)))
1468 (cond 1304 (pmark (and proc (marker-position (process-mark proc)))))
1469 ((null pmark) (1- (point-min))) 1305 (cond
1470 ;; The use of insert-before-markers in comint.el together with 1306 ((null pmark) (1- (point-min)))
1471 ;; the potential use of comint-truncate-buffer in the output 1307 ;; The use of insert-before-markers in comint.el together with
1472 ;; filter, means that it's difficult to reliably keep track of 1308 ;; the potential use of comint-truncate-buffer in the output
1473 ;; the buffer position where the process's output started. 1309 ;; filter, means that it's difficult to reliably keep track of
1474 ;; If possible we use a marker at "start - 1", so that 1310 ;; the buffer position where the process's output started.
1475 ;; insert-before-marker at `start' won't shift it. And if not, 1311 ;; If possible we use a marker at "start - 1", so that
1476 ;; we fall back on using a plain integer. 1312 ;; insert-before-marker at `start' won't shift it. And if not,
1477 ((> pmark (point-min)) (copy-marker (1- pmark))) 1313 ;; we fall back on using a plain integer.
1478 (t (1- pmark))))) 1314 ((> pmark (point-min)) (copy-marker (1- pmark)))
1315 (t (1- pmark)))))
1479 (add-hook 'comint-output-filter-functions 1316 (add-hook 'comint-output-filter-functions
1480 'prolog-inferior-guess-flavor nil t)) 1317 'prolog-inferior-guess-flavor nil t))
1481 (if wait 1318 (if wait
@@ -1742,16 +1579,16 @@ This function must be called from the source code buffer."
1742 (compilation-mode) 1579 (compilation-mode)
1743 ;; FIXME: This doesn't seem to cooperate well with new(ish) compile.el. 1580 ;; FIXME: This doesn't seem to cooperate well with new(ish) compile.el.
1744 ;; Setting up font-locking for this buffer 1581 ;; Setting up font-locking for this buffer
1745 (set (make-local-variable 'font-lock-defaults) 1582 (setq-local font-lock-defaults
1746 '(prolog-font-lock-keywords nil nil ((?_ . "w")))) 1583 '(prolog-font-lock-keywords nil nil ((?_ . "w"))))
1747 (if (eq prolog-system 'sicstus) 1584 (if (eq prolog-system 'sicstus)
1748 ;; FIXME: This looks really problematic: not only is this using 1585 ;; FIXME: This looks really problematic: not only is this using
1749 ;; the old compilation-parse-errors-function, but 1586 ;; the old compilation-parse-errors-function, but
1750 ;; prolog-parse-sicstus-compilation-errors only accepts one argument 1587 ;; prolog-parse-sicstus-compilation-errors only accepts one argument
1751 ;; whereas compile.el calls it with 2 (and did so at least since 1588 ;; whereas compile.el calls it with 2 (and did so at least since
1752 ;; Emacs-20). 1589 ;; Emacs-20).
1753 (set (make-local-variable 'compilation-parse-errors-function) 1590 (setq-local compilation-parse-errors-function
1754 'prolog-parse-sicstus-compilation-errors)) 1591 'prolog-parse-sicstus-compilation-errors))
1755 (setq buffer-read-only nil) 1592 (setq buffer-read-only nil)
1756 (insert command-string "\n")) 1593 (insert command-string "\n"))
1757 (display-buffer buffer) 1594 (display-buffer buffer)
@@ -1978,663 +1815,272 @@ Argument BOUND is a buffer position limiting searching."
1978;; Set everything up 1815;; Set everything up
1979(defun prolog-font-lock-keywords () 1816(defun prolog-font-lock-keywords ()
1980 "Set up font lock keywords for the current Prolog system." 1817 "Set up font lock keywords for the current Prolog system."
1981 ;(when window-system 1818 ;;(when window-system
1982 (require 'font-lock) 1819 (require 'font-lock)
1983 1820
1984 ;; Define Prolog faces 1821 ;; Define Prolog faces
1985 (defface prolog-redo-face 1822 (defface prolog-redo-face
1986 '((((class grayscale)) (:italic t)) 1823 '((((class grayscale)) (:italic t))
1987 (((class color)) (:foreground "darkorchid")) 1824 (((class color)) (:foreground "darkorchid"))
1988 (t (:italic t))) 1825 (t (:italic t)))
1989 "Prolog mode face for highlighting redo trace lines." 1826 "Prolog mode face for highlighting redo trace lines."
1990 :group 'prolog-faces) 1827 :group 'prolog-faces)
1991 (defface prolog-exit-face 1828 (defface prolog-exit-face
1992 '((((class grayscale)) (:underline t)) 1829 '((((class grayscale)) (:underline t))
1993 (((class color) (background dark)) (:foreground "green")) 1830 (((class color) (background dark)) (:foreground "green"))
1994 (((class color) (background light)) (:foreground "ForestGreen")) 1831 (((class color) (background light)) (:foreground "ForestGreen"))
1995 (t (:underline t))) 1832 (t (:underline t)))
1996 "Prolog mode face for highlighting exit trace lines." 1833 "Prolog mode face for highlighting exit trace lines."
1997 :group 'prolog-faces) 1834 :group 'prolog-faces)
1998 (defface prolog-exception-face 1835 (defface prolog-exception-face
1999 '((((class grayscale)) (:bold t :italic t :underline t)) 1836 '((((class grayscale)) (:bold t :italic t :underline t))
2000 (((class color)) (:bold t :foreground "black" :background "Khaki")) 1837 (((class color)) (:bold t :foreground "black" :background "Khaki"))
2001 (t (:bold t :italic t :underline t))) 1838 (t (:bold t :italic t :underline t)))
2002 "Prolog mode face for highlighting exception trace lines." 1839 "Prolog mode face for highlighting exception trace lines."
2003 :group 'prolog-faces) 1840 :group 'prolog-faces)
2004 (defface prolog-warning-face 1841 (defface prolog-warning-face
2005 '((((class grayscale)) (:underline t)) 1842 '((((class grayscale)) (:underline t))
2006 (((class color) (background dark)) (:foreground "blue")) 1843 (((class color) (background dark)) (:foreground "blue"))
2007 (((class color) (background light)) (:foreground "MidnightBlue")) 1844 (((class color) (background light)) (:foreground "MidnightBlue"))
2008 (t (:underline t))) 1845 (t (:underline t)))
2009 "Face name to use for compiler warnings." 1846 "Face name to use for compiler warnings."
2010 :group 'prolog-faces) 1847 :group 'prolog-faces)
2011 (defface prolog-builtin-face 1848 (defface prolog-builtin-face
2012 '((((class color) (background light)) (:foreground "Purple")) 1849 '((((class color) (background light)) (:foreground "Purple"))
2013 (((class color) (background dark)) (:foreground "Cyan")) 1850 (((class color) (background dark)) (:foreground "Cyan"))
2014 (((class grayscale) (background light)) 1851 (((class grayscale) (background light))
2015 :foreground "LightGray" :bold t) 1852 :foreground "LightGray" :bold t)
2016 (((class grayscale) (background dark)) (:foreground "DimGray" :bold t)) 1853 (((class grayscale) (background dark)) (:foreground "DimGray" :bold t))
2017 (t (:bold t))) 1854 (t (:bold t)))
2018 "Face name to use for compiler warnings." 1855 "Face name to use for compiler warnings."
2019 :group 'prolog-faces) 1856 :group 'prolog-faces)
2020 (defvar prolog-warning-face 1857 (defvar prolog-warning-face
2021 (if (prolog-face-name-p 'font-lock-warning-face) 1858 (if (prolog-face-name-p 'font-lock-warning-face)
2022 'font-lock-warning-face 1859 'font-lock-warning-face
2023 'prolog-warning-face) 1860 'prolog-warning-face)
2024 "Face name to use for built in predicates.") 1861 "Face name to use for built in predicates.")
2025 (defvar prolog-builtin-face 1862 (defvar prolog-builtin-face
2026 (if (prolog-face-name-p 'font-lock-builtin-face) 1863 (if (prolog-face-name-p 'font-lock-builtin-face)
2027 'font-lock-builtin-face 1864 'font-lock-builtin-face
2028 'prolog-builtin-face) 1865 'prolog-builtin-face)
2029 "Face name to use for built in predicates.") 1866 "Face name to use for built in predicates.")
2030 (defvar prolog-redo-face 'prolog-redo-face 1867 (defvar prolog-redo-face 'prolog-redo-face
2031 "Face name to use for redo trace lines.") 1868 "Face name to use for redo trace lines.")
2032 (defvar prolog-exit-face 'prolog-exit-face 1869 (defvar prolog-exit-face 'prolog-exit-face
2033 "Face name to use for exit trace lines.") 1870 "Face name to use for exit trace lines.")
2034 (defvar prolog-exception-face 'prolog-exception-face 1871 (defvar prolog-exception-face 'prolog-exception-face
2035 "Face name to use for exception trace lines.") 1872 "Face name to use for exception trace lines.")
2036 1873
2037 ;; Font Lock Patterns 1874 ;; Font Lock Patterns
2038 (let ( 1875 (let (
2039 ;; "Native" Prolog patterns 1876 ;; "Native" Prolog patterns
2040 (head-predicates 1877 (head-predicates
2041 (list (format "^\\(%s\\)\\((\\|[ \t]*:-\\)" prolog-atom-regexp) 1878 (list (format "^\\(%s\\)\\((\\|[ \t]*:-\\)" prolog-atom-regexp)
2042 1 font-lock-function-name-face))
2043 ;(list (format "^%s" prolog-atom-regexp)
2044 ; 0 font-lock-function-name-face))
2045 (head-predicates-1
2046 (list (format "\\.[ \t]*\\(%s\\)" prolog-atom-regexp)
2047 1 font-lock-function-name-face) )
2048 (variables
2049 '("\\<\\([_A-Z][a-zA-Z0-9_]*\\)"
2050 1 font-lock-variable-name-face))
2051 (important-elements
2052 (list (if (eq prolog-system 'mercury)
2053 "[][}{;|]\\|\\\\[+=]\\|<?=>?"
2054 "[][}{!;|]\\|\\*->")
2055 0 'font-lock-keyword-face))
2056 (important-elements-1
2057 '("[^-*]\\(->\\)" 1 font-lock-keyword-face))
2058 (predspecs ; module:predicate/cardinality
2059 (list (format "\\<\\(%s:\\|\\)%s/[0-9]+"
2060 prolog-atom-regexp prolog-atom-regexp)
2061 0 font-lock-function-name-face 'prepend))
2062 (keywords ; directives (queries)
2063 (list
2064 (if (eq prolog-system 'mercury)
2065 (concat
2066 "\\<\\("
2067 (regexp-opt prolog-keywords-i)
2068 "\\|"
2069 (regexp-opt
2070 prolog-determinism-specificators-i)
2071 "\\)\\>")
2072 (concat
2073 "^[?:]- *\\("
2074 (regexp-opt prolog-keywords-i)
2075 "\\)\\>"))
2076 1 prolog-builtin-face))
2077 ;; SICStus specific patterns
2078 (sicstus-object-methods
2079 (if (eq prolog-system 'sicstus)
2080 '(prolog-font-lock-object-matcher
2081 1 font-lock-function-name-face)))
2082 ;; Mercury specific patterns
2083 (types
2084 (if (eq prolog-system 'mercury)
2085 (list
2086 (regexp-opt prolog-types-i 'words)
2087 0 'font-lock-type-face)))
2088 (modes
2089 (if (eq prolog-system 'mercury)
2090 (list
2091 (regexp-opt prolog-mode-specificators-i 'words)
2092 0 'font-lock-constant-face)))
2093 (directives
2094 (if (eq prolog-system 'mercury)
2095 (list
2096 (regexp-opt prolog-directives-i 'words)
2097 0 'prolog-warning-face)))
2098 ;; Inferior mode specific patterns
2099 (prompt
2100 ;; FIXME: Should be handled by comint already.
2101 (list (prolog-prompt-regexp) 0 'font-lock-keyword-face))
2102 (trace-exit
2103 ;; FIXME: Add to compilation-error-regexp-alist instead.
2104 (cond
2105 ((eq prolog-system 'sicstus)
2106 '("[ \t]*[0-9]+[ \t]+[0-9]+[ \t]*\\(Exit\\):"
2107 1 prolog-exit-face))
2108 ((eq prolog-system 'swi)
2109 '("[ \t]*\\(Exit\\):[ \t]*([ \t0-9]*)" 1 prolog-exit-face))
2110 (t nil)))
2111 (trace-fail
2112 ;; FIXME: Add to compilation-error-regexp-alist instead.
2113 (cond
2114 ((eq prolog-system 'sicstus)
2115 '("[ \t]*[0-9]+[ \t]+[0-9]+[ \t]*\\(Fail\\):"
2116 1 prolog-warning-face))
2117 ((eq prolog-system 'swi)
2118 '("[ \t]*\\(Fail\\):[ \t]*([ \t0-9]*)" 1 prolog-warning-face))
2119 (t nil)))
2120 (trace-redo
2121 ;; FIXME: Add to compilation-error-regexp-alist instead.
2122 (cond
2123 ((eq prolog-system 'sicstus)
2124 '("[ \t]*[0-9]+[ \t]+[0-9]+[ \t]*\\(Redo\\):"
2125 1 prolog-redo-face))
2126 ((eq prolog-system 'swi)
2127 '("[ \t]*\\(Redo\\):[ \t]*([ \t0-9]*)" 1 prolog-redo-face))
2128 (t nil)))
2129 (trace-call
2130 ;; FIXME: Add to compilation-error-regexp-alist instead.
2131 (cond
2132 ((eq prolog-system 'sicstus)
2133 '("[ \t]*[0-9]+[ \t]+[0-9]+[ \t]*\\(Call\\):"
2134 1 font-lock-function-name-face))
2135 ((eq prolog-system 'swi)
2136 '("[ \t]*\\(Call\\):[ \t]*([ \t0-9]*)"
2137 1 font-lock-function-name-face)) 1879 1 font-lock-function-name-face))
2138 (t nil))) 1880 ;(list (format "^%s" prolog-atom-regexp)
2139 (trace-exception 1881 ; 0 font-lock-function-name-face))
2140 ;; FIXME: Add to compilation-error-regexp-alist instead. 1882 (head-predicates-1
2141 (cond 1883 (list (format "\\.[ \t]*\\(%s\\)" prolog-atom-regexp)
2142 ((eq prolog-system 'sicstus) 1884 1 font-lock-function-name-face) )
2143 '("[ \t]*[0-9]+[ \t]+[0-9]+[ \t]*\\(Exception\\):" 1885 (variables
2144 1 prolog-exception-face)) 1886 '("\\<\\([_A-Z][a-zA-Z0-9_]*\\)"
2145 ((eq prolog-system 'swi) 1887 1 font-lock-variable-name-face))
2146 '("[ \t]*\\(Exception\\):[ \t]*([ \t0-9]*)" 1888 (important-elements
2147 1 prolog-exception-face)) 1889 (list (if (eq prolog-system 'mercury)
2148 (t nil))) 1890 "[][}{;|]\\|\\\\[+=]\\|<?=>?"
2149 (error-message-identifier 1891 "[][}{!;|]\\|\\*->")
2150 ;; FIXME: Add to compilation-error-regexp-alist instead. 1892 0 'font-lock-keyword-face))
2151 (cond 1893 (important-elements-1
2152 ((eq prolog-system 'sicstus) 1894 '("[^-*]\\(->\\)" 1 font-lock-keyword-face))
2153 '("{\\([A-Z]* ?ERROR:\\)" 1 prolog-exception-face prepend)) 1895 (predspecs ; module:predicate/cardinality
2154 ((eq prolog-system 'swi) 1896 (list (format "\\<\\(%s:\\|\\)%s/[0-9]+"
2155 '("^[[]\\(WARNING:\\)" 1 prolog-builtin-face prepend)) 1897 prolog-atom-regexp prolog-atom-regexp)
2156 (t nil))) 1898 0 font-lock-function-name-face 'prepend))
2157 (error-whole-messages 1899 (keywords ; directives (queries)
2158 ;; FIXME: Add to compilation-error-regexp-alist instead.
2159 (cond
2160 ((eq prolog-system 'sicstus)
2161 '("{\\([A-Z]* ?ERROR:.*\\)}[ \t]*$"
2162 1 font-lock-comment-face append))
2163 ((eq prolog-system 'swi)
2164 '("^[[]WARNING:[^]]*[]]$" 0 font-lock-comment-face append))
2165 (t nil)))
2166 (error-warning-messages
2167 ;; FIXME: Add to compilation-error-regexp-alist instead.
2168 ;; Mostly errors that SICStus asks the user about how to solve,
2169 ;; such as "NAME CLASH:" for example.
2170 (cond
2171 ((eq prolog-system 'sicstus)
2172 '("^[A-Z ]*[A-Z]+:" 0 prolog-warning-face))
2173 (t nil)))
2174 (warning-messages
2175 ;; FIXME: Add to compilation-error-regexp-alist instead.
2176 (cond
2177 ((eq prolog-system 'sicstus)
2178 '("\\({ ?\\(Warning\\|WARNING\\) ?:.*}\\)[ \t]*$"
2179 2 prolog-warning-face prepend))
2180 (t nil))))
2181
2182 ;; Make font lock list
2183 (delq
2184 nil
2185 (cond
2186 ((eq major-mode 'prolog-mode)
2187 (list 1900 (list
2188 head-predicates 1901 (if (eq prolog-system 'mercury)
2189 head-predicates-1 1902 (concat
2190 variables 1903 "\\<\\("
2191 important-elements 1904 (regexp-opt prolog-keywords-i)
2192 important-elements-1 1905 "\\|"
2193 predspecs 1906 (regexp-opt
2194 keywords 1907 prolog-determinism-specificators-i)
2195 sicstus-object-methods 1908 "\\)\\>")
2196 types 1909 (concat
2197 modes 1910 "^[?:]- *\\("
2198 directives)) 1911 (regexp-opt prolog-keywords-i)
2199 ((eq major-mode 'prolog-inferior-mode) 1912 "\\)\\>"))
2200 (list 1913 1 prolog-builtin-face))
2201 prompt 1914 ;; SICStus specific patterns
2202 error-message-identifier 1915 (sicstus-object-methods
2203 error-whole-messages 1916 (if (eq prolog-system 'sicstus)
2204 error-warning-messages 1917 '(prolog-font-lock-object-matcher
2205 warning-messages 1918 1 font-lock-function-name-face)))
2206 predspecs 1919 ;; Mercury specific patterns
2207 trace-exit 1920 (types
2208 trace-fail 1921 (if (eq prolog-system 'mercury)
2209 trace-redo 1922 (list
2210 trace-call 1923 (regexp-opt prolog-types-i 'words)
2211 trace-exception)) 1924 0 'font-lock-type-face)))
2212 ((eq major-mode 'compilation-mode) 1925 (modes
2213 (list 1926 (if (eq prolog-system 'mercury)
2214 error-message-identifier 1927 (list
2215 error-whole-messages 1928 (regexp-opt prolog-mode-specificators-i 'words)
2216 error-warning-messages 1929 0 'font-lock-constant-face)))
2217 warning-messages 1930 (directives
2218 predspecs)))) 1931 (if (eq prolog-system 'mercury)
2219 )) 1932 (list
2220 1933 (regexp-opt prolog-directives-i 'words)
2221 1934 0 'prolog-warning-face)))
2222;;------------------------------------------------------------------- 1935 ;; Inferior mode specific patterns
2223;; Indentation stuff 1936 (prompt
2224;;------------------------------------------------------------------- 1937 ;; FIXME: Should be handled by comint already.
2225 1938 (list (prolog-prompt-regexp) 0 'font-lock-keyword-face))
2226;; NB: This function *MUST* have this optional argument since XEmacs 1939 (trace-exit
2227;; assumes it. This does not mean we have to use it... 1940 ;; FIXME: Add to compilation-error-regexp-alist instead.
2228(defun prolog-indent-line (&optional _whole-exp) 1941 (cond
2229 "Indent current line as Prolog code. 1942 ((eq prolog-system 'sicstus)
2230With argument, indent any additional lines of the same clause 1943 '("[ \t]*[0-9]+[ \t]+[0-9]+[ \t]*\\(Exit\\):"
2231rigidly along with this one (not yet)." 1944 1 prolog-exit-face))
2232 (interactive "p") 1945 ((eq prolog-system 'swi)
2233 (let ((indent (prolog-indent-level)) 1946 '("[ \t]*\\(Exit\\):[ \t]*([ \t0-9]*)" 1 prolog-exit-face))
2234 (pos (- (point-max) (point)))) 1947 (t nil)))
2235 (beginning-of-line) 1948 (trace-fail
2236 (skip-chars-forward " \t") 1949 ;; FIXME: Add to compilation-error-regexp-alist instead.
2237 (indent-line-to indent) 1950 (cond
2238 (if (> (- (point-max) pos) (point)) 1951 ((eq prolog-system 'sicstus)
2239 (goto-char (- (point-max) pos))) 1952 '("[ \t]*[0-9]+[ \t]+[0-9]+[ \t]*\\(Fail\\):"
2240 1953 1 prolog-warning-face))
2241 ;; Align comments 1954 ((eq prolog-system 'swi)
2242 (if (and prolog-align-comments-flag 1955 '("[ \t]*\\(Fail\\):[ \t]*([ \t0-9]*)" 1 prolog-warning-face))
2243 (save-excursion 1956 (t nil)))
2244 (line-beginning-position) 1957 (trace-redo
2245 ;; (let ((start (comment-search-forward (line-end-position) t))) 1958 ;; FIXME: Add to compilation-error-regexp-alist instead.
2246 ;; (and start ;There's a comment to indent. 1959 (cond
2247 ;; ;; If it's first on the line, we've indented it already 1960 ((eq prolog-system 'sicstus)
2248 ;; ;; and prolog-goto-comment-column would inf-loop. 1961 '("[ \t]*[0-9]+[ \t]+[0-9]+[ \t]*\\(Redo\\):"
2249 ;; (progn (goto-char start) (skip-chars-backward " \t") 1962 1 prolog-redo-face))
2250 ;; (not (bolp))))))) 1963 ((eq prolog-system 'swi)
2251 (and (looking-at comment-start-skip) 1964 '("[ \t]*\\(Redo\\):[ \t]*([ \t0-9]*)" 1 prolog-redo-face))
2252 ;; The definition of comment-start-skip used in this 1965 (t nil)))
2253 ;; mode is unusual in that it only matches at BOL. 1966 (trace-call
2254 (progn (skip-chars-forward " \t") 1967 ;; FIXME: Add to compilation-error-regexp-alist instead.
2255 (not (eq (point) (match-end 1))))))) 1968 (cond
2256 (save-excursion 1969 ((eq prolog-system 'sicstus)
2257 (prolog-goto-comment-column t))) 1970 '("[ \t]*[0-9]+[ \t]+[0-9]+[ \t]*\\(Call\\):"
2258 1971 1 font-lock-function-name-face))
2259 ;; Insert spaces if needed 1972 ((eq prolog-system 'swi)
2260 (if (or prolog-electric-tab-flag prolog-electric-if-then-else-flag) 1973 '("[ \t]*\\(Call\\):[ \t]*([ \t0-9]*)"
2261 (prolog-insert-spaces-after-paren)) 1974 1 font-lock-function-name-face))
1975 (t nil)))
1976 (trace-exception
1977 ;; FIXME: Add to compilation-error-regexp-alist instead.
1978 (cond
1979 ((eq prolog-system 'sicstus)
1980 '("[ \t]*[0-9]+[ \t]+[0-9]+[ \t]*\\(Exception\\):"
1981 1 prolog-exception-face))
1982 ((eq prolog-system 'swi)
1983 '("[ \t]*\\(Exception\\):[ \t]*([ \t0-9]*)"
1984 1 prolog-exception-face))
1985 (t nil)))
1986 (error-message-identifier
1987 ;; FIXME: Add to compilation-error-regexp-alist instead.
1988 (cond
1989 ((eq prolog-system 'sicstus)
1990 '("{\\([A-Z]* ?ERROR:\\)" 1 prolog-exception-face prepend))
1991 ((eq prolog-system 'swi)
1992 '("^[[]\\(WARNING:\\)" 1 prolog-builtin-face prepend))
1993 (t nil)))
1994 (error-whole-messages
1995 ;; FIXME: Add to compilation-error-regexp-alist instead.
1996 (cond
1997 ((eq prolog-system 'sicstus)
1998 '("{\\([A-Z]* ?ERROR:.*\\)}[ \t]*$"
1999 1 font-lock-comment-face append))
2000 ((eq prolog-system 'swi)
2001 '("^[[]WARNING:[^]]*[]]$" 0 font-lock-comment-face append))
2002 (t nil)))
2003 (error-warning-messages
2004 ;; FIXME: Add to compilation-error-regexp-alist instead.
2005 ;; Mostly errors that SICStus asks the user about how to solve,
2006 ;; such as "NAME CLASH:" for example.
2007 (cond
2008 ((eq prolog-system 'sicstus)
2009 '("^[A-Z ]*[A-Z]+:" 0 prolog-warning-face))
2010 (t nil)))
2011 (warning-messages
2012 ;; FIXME: Add to compilation-error-regexp-alist instead.
2013 (cond
2014 ((eq prolog-system 'sicstus)
2015 '("\\({ ?\\(Warning\\|WARNING\\) ?:.*}\\)[ \t]*$"
2016 2 prolog-warning-face prepend))
2017 (t nil))))
2018
2019 ;; Make font lock list
2020 (delq
2021 nil
2022 (cond
2023 ((eq major-mode 'prolog-mode)
2024 (list
2025 head-predicates
2026 head-predicates-1
2027 variables
2028 important-elements
2029 important-elements-1
2030 predspecs
2031 keywords
2032 sicstus-object-methods
2033 types
2034 modes
2035 directives))
2036 ((eq major-mode 'prolog-inferior-mode)
2037 (list
2038 prompt
2039 error-message-identifier
2040 error-whole-messages
2041 error-warning-messages
2042 warning-messages
2043 predspecs
2044 trace-exit
2045 trace-fail
2046 trace-redo
2047 trace-call
2048 trace-exception))
2049 ((eq major-mode 'compilation-mode)
2050 (list
2051 error-message-identifier
2052 error-whole-messages
2053 error-warning-messages
2054 warning-messages
2055 predspecs))))
2262 )) 2056 ))
2263 2057
2264(defun prolog-indent-level () 2058
2265 "Compute prolog indentation level."
2266 (save-excursion
2267 (beginning-of-line)
2268 (let ((totbal (prolog-region-paren-balance
2269 (prolog-clause-start t) (point)))
2270 (oldpoint (point)))
2271 (skip-chars-forward " \t")
2272 (cond
2273 ((looking-at "%%%") (prolog-indentation-level-of-line))
2274 ;Large comment starts
2275 ((looking-at "%[^%]") comment-column) ;Small comment starts
2276 ((bobp) 0) ;Beginning of buffer
2277
2278 ;; If we found '}' then we must check if it's the
2279 ;; end of an object declaration or something else.
2280 ((and (looking-at "}")
2281 (save-excursion
2282 (forward-char 1)
2283 ;; Goto to matching {
2284 (if prolog-use-prolog-tokenizer-flag
2285 (prolog-backward-list)
2286 (backward-list))
2287 (skip-chars-backward " \t")
2288 (backward-char 2)
2289 (looking-at "::")))
2290 ;; It was an object
2291 (if prolog-object-end-to-0-flag
2292 0
2293 prolog-indent-width))
2294
2295 ;;End of /* */ comment
2296 ((looking-at "\\*/")
2297 (save-excursion
2298 (prolog-find-start-of-mline-comment)
2299 (skip-chars-backward " \t")
2300 (- (current-column) 2)))
2301
2302 ;; Here we check if the current line is within a /* */ pair
2303 ((and (looking-at "[^%/]")
2304 (eq (prolog-in-string-or-comment) 'cmt))
2305 (if prolog-indent-mline-comments-flag
2306 (prolog-find-start-of-mline-comment)
2307 ;; Same as before
2308 (prolog-indentation-level-of-line)))
2309
2310 (t
2311 (let ((empty t) ind linebal)
2312 ;; See previous indentation
2313 (while empty
2314 (forward-line -1)
2315 (beginning-of-line)
2316 (if (bobp)
2317 (setq empty nil)
2318 (skip-chars-forward " \t")
2319 (if (not (or (not (member (prolog-in-string-or-comment)
2320 '(nil txt)))
2321 (looking-at "%")
2322 (looking-at "\n")))
2323 (setq empty nil))))
2324
2325 ;; Store this line's indentation
2326 (setq ind (if (bobp)
2327 0 ;Beginning of buffer.
2328 (current-column))) ;Beginning of clause.
2329
2330 ;; Compute the balance of the line
2331 (setq linebal (prolog-paren-balance))
2332 ;;(message "bal of previous line %d totbal %d" linebal totbal)
2333 (if (< linebal 0)
2334 (progn
2335 ;; Add 'indent-level' mode to find-unmatched-paren instead?
2336 (end-of-line)
2337 (setq ind (prolog-find-indent-of-matching-paren))))
2338
2339 ;;(message "ind %d" ind)
2340 (beginning-of-line)
2341
2342 ;; Check if the line ends with ":-", ".", ":: {", "}" (might be
2343 ;; unnecessary), "&" or ")" (The last four concerns SICStus objects)
2344 (cond
2345 ;; If the last char of the line is a '&' then set the indent level
2346 ;; to prolog-indent-width (used in SICStus objects)
2347 ((and (eq prolog-system 'sicstus)
2348 (looking-at ".+&[ \t]*\\(%.*\\|\\)$"))
2349 (setq ind prolog-indent-width))
2350
2351 ;; Increase indentation if the previous line was the head of a rule
2352 ;; and does not contain a '.'
2353 ((and (looking-at (format ".*%s[^\\.]*[ \t]*\\(%%.*\\|\\)$"
2354 prolog-head-delimiter))
2355 ;; We must check that the match is at a paren balance of 0.
2356 (save-excursion
2357 (let ((p (point)))
2358 (re-search-forward prolog-head-delimiter)
2359 (>= 0 (prolog-region-paren-balance p (point))))))
2360 (let ((headindent
2361 (if (< (prolog-paren-balance) 0)
2362 (save-excursion
2363 (end-of-line)
2364 (prolog-find-indent-of-matching-paren))
2365 (prolog-indentation-level-of-line))))
2366 (setq ind (+ headindent prolog-indent-width))))
2367
2368 ;; The previous line was the head of an object
2369 ((looking-at ".+ *::.*{[ \t]*$")
2370 (setq ind prolog-indent-width))
2371
2372 ;; If a '.' is found at the end of the previous line, then
2373 ;; decrease the indentation. (The \\(%.*\\|\\) part of the
2374 ;; regexp is for comments at the end of the line)
2375 ((and (looking-at "^.+\\.[ \t]*\\(%.*\\|\\)$")
2376 ;; Make sure that the '.' found is not in a comment or string
2377 (save-excursion
2378 (end-of-line)
2379 (re-search-backward "\\.[ \t]*\\(%.*\\|\\)$" (point-min))
2380 ;; Guard against the real '.' being followed by a
2381 ;; commented '.'.
2382 (if (eq (prolog-in-string-or-comment) 'cmt)
2383 ;; commented out '.'
2384 (let ((here (line-beginning-position)))
2385 (end-of-line)
2386 (re-search-backward "\\.[ \t]*%.*$" here t))
2387 (not (prolog-in-string-or-comment))
2388 )
2389 ))
2390 (setq ind 0))
2391
2392 ;; If a '.' is found at the end of the previous line, then
2393 ;; decrease the indentation. (The /\\*.*\\*/ part of the
2394 ;; regexp is for C-like comments at the end of the
2395 ;; line--can we merge with the case above?).
2396 ((and (looking-at "^.+\\.[ \t]*\\(/\\*.*\\|\\)$")
2397 ;; Make sure that the '.' found is not in a comment or string
2398 (save-excursion
2399 (end-of-line)
2400 (re-search-backward "\\.[ \t]*\\(/\\*.*\\|\\)$" (point-min))
2401 ;; Guard against the real '.' being followed by a
2402 ;; commented '.'.
2403 (if (eq (prolog-in-string-or-comment) 'cmt)
2404 ;; commented out '.'
2405 (let ((here (line-beginning-position)))
2406 (end-of-line)
2407 (re-search-backward "\\.[ \t]*/\\*.*$" here t))
2408 (not (prolog-in-string-or-comment))
2409 )
2410 ))
2411 (setq ind 0))
2412
2413 )
2414
2415 ;; If the last non comment char is a ',' or left paren or a left-
2416 ;; indent-regexp then indent to open parenthesis level
2417 (if (and
2418 (> totbal 0)
2419 ;; SICStus objects have special syntax rules if point is
2420 ;; not inside additional parens (objects are defined
2421 ;; within {...})
2422 (not (and (eq prolog-system 'sicstus)
2423 (= totbal 1)
2424 (prolog-in-object))))
2425 (if (looking-at
2426 (format "\\(%s\\|%s\\|0'.\\|[0-9]+'[0-9a-zA-Z]+\\|[^\n\'\"%%]\\)*\\(,\\|%s\\|%s\\)\[ \t]*\\(%%.*\\|\\)$"
2427 prolog-quoted-atom-regexp prolog-string-regexp
2428 prolog-left-paren prolog-left-indent-regexp))
2429 (progn
2430 (goto-char oldpoint)
2431 (setq ind (prolog-find-unmatched-paren
2432 (if prolog-paren-indent-p
2433 'termdependent
2434 'skipwhite)))
2435 ;;(setq ind (prolog-find-unmatched-paren 'termdependent))
2436 )
2437 (goto-char oldpoint)
2438 (setq ind (prolog-find-unmatched-paren nil))
2439 ))
2440
2441
2442 ;; Return the indentation level
2443 ind
2444 ))))))
2445
2446(defun prolog-find-indent-of-matching-paren ()
2447 "Find the indentation level based on the matching parenthesis.
2448Indentation level is set to the one the point is after when the function is
2449called."
2450 (save-excursion
2451 ;; Go to the matching paren
2452 (if prolog-use-prolog-tokenizer-flag
2453 (prolog-backward-list)
2454 (backward-list))
2455
2456 ;; If this was the first paren on the line then return this line's
2457 ;; indentation level
2458 (if (prolog-paren-is-the-first-on-line-p)
2459 (prolog-indentation-level-of-line)
2460 ;; It was not the first one
2461 (progn
2462 ;; Find the next paren
2463 (prolog-goto-next-paren 0)
2464
2465 ;; If this paren is a left one then use its column as indent level,
2466 ;; if not then recurse this function
2467 (if (looking-at prolog-left-paren)
2468 (+ (current-column) 1)
2469 (progn
2470 (forward-char 1)
2471 (prolog-find-indent-of-matching-paren)))
2472 ))
2473 ))
2474 2059
2475(defun prolog-indentation-level-of-line () 2060(defun prolog-find-unmatched-paren ()
2476 "Return the indentation level of the current line." 2061 "Return the column of the last unmatched left parenthesis."
2477 (save-excursion 2062 (save-excursion
2478 (beginning-of-line) 2063 (goto-char (or (car (nth 9 (syntax-ppss))) (point-min)))
2479 (skip-chars-forward " \t")
2480 (current-column))) 2064 (current-column)))
2481 2065
2482(defun prolog-paren-is-the-first-on-line-p ()
2483 "Return t if the parenthesis under the point is the first one on the line.
2484Return nil otherwise.
2485Note: does not check if the point is actually at a parenthesis!"
2486 (save-excursion
2487 (let ((begofline (line-beginning-position)))
2488 (if (= begofline (point))
2489 t
2490 (if (prolog-goto-next-paren begofline)
2491 nil
2492 t)))))
2493
2494(defun prolog-find-unmatched-paren (&optional mode)
2495 "Return the column of the last unmatched left parenthesis.
2496If MODE is `skipwhite' then any white space after the parenthesis is added to
2497the answer.
2498If MODE is `plusone' then the parenthesis' column +1 is returned.
2499If MODE is `termdependent' then if the unmatched parenthesis is part of
2500a compound term the function will work as `skipwhite', otherwise
2501it will return the column paren plus the value of `prolog-paren-indent'.
2502If MODE is nil or not set then the parenthesis' exact column is returned."
2503 (save-excursion
2504 ;; If the next paren we find is a left one we're finished, if it's
2505 ;; a right one then we go back one step and recurse
2506 (prolog-goto-next-paren 0)
2507
2508 (let ((roundparen (looking-at "(")))
2509 (if (looking-at prolog-left-paren)
2510 (let ((not-part-of-term
2511 (save-excursion
2512 (backward-char 1)
2513 (looking-at "[ \t]"))))
2514 (if (eq mode nil)
2515 (current-column)
2516 (if (and roundparen
2517 (eq mode 'termdependent)
2518 not-part-of-term)
2519 (+ (current-column)
2520 (if prolog-electric-tab-flag
2521 ;; Electric TAB
2522 prolog-paren-indent
2523 ;; Not electric TAB
2524 (if (looking-at ".[ \t]*$")
2525 2
2526 prolog-paren-indent))
2527 )
2528
2529 (forward-char 1)
2530 (if (or (eq mode 'skipwhite) (eq mode 'termdependent) )
2531 (skip-chars-forward " \t"))
2532 (current-column))))
2533 ;; Not looking at left paren
2534 (progn
2535 (forward-char 1)
2536 ;; Go to the matching paren. When we get there we have a total
2537 ;; balance of 0.
2538 (if prolog-use-prolog-tokenizer-flag
2539 (prolog-backward-list)
2540 (backward-list))
2541 (prolog-find-unmatched-paren mode)))
2542 )))
2543
2544 2066
2545(defun prolog-paren-balance () 2067(defun prolog-paren-balance ()
2546 "Return the parenthesis balance of the current line. 2068 "Return the parenthesis balance of the current line.
2547A return value of n means n more left parentheses than right ones." 2069A return value of N means N more left parentheses than right ones."
2548 (save-excursion 2070 (save-excursion
2549 (end-of-line) 2071 (car (parse-partial-sexp (line-beginning-position)
2550 (prolog-region-paren-balance (line-beginning-position) (point)))) 2072 (line-end-position)))))
2551
2552(defun prolog-region-paren-balance (beg end)
2553 "Return the summed parenthesis balance in the region.
2554The region is limited by BEG and END positions."
2555 (save-excursion
2556 (let ((state (if prolog-use-prolog-tokenizer-flag
2557 (prolog-tokenize beg end)
2558 (parse-partial-sexp beg end))))
2559 (nth 0 state))))
2560
2561(defun prolog-goto-next-paren (limit-pos)
2562 "Move the point to the next parenthesis earlier in the buffer.
2563Return t if a match was found before LIMIT-POS. Return nil otherwise."
2564 (let ((retval (re-search-backward
2565 (concat prolog-left-paren "\\|" prolog-right-paren)
2566 limit-pos t)))
2567
2568 ;; If a match was found but it was in a string or comment, then recurse
2569 (if (and retval (prolog-in-string-or-comment))
2570 (prolog-goto-next-paren limit-pos)
2571 retval)
2572 ))
2573 2073
2574(defun prolog-in-string-or-comment () 2074(defun prolog-electric--if-then-else ()
2575 "Check whether string, atom, or comment is under current point.
2576Return:
2577 `txt' if the point is in a string, atom, or character code expression
2578 `cmt' if the point is in a comment
2579 nil otherwise."
2580 (save-excursion
2581 (let* ((start
2582 (if (eq prolog-parse-mode 'beg-of-line)
2583 ;; 'beg-of-line
2584 (save-excursion
2585 (let (safepoint)
2586 (beginning-of-line)
2587 (setq safepoint (point))
2588 (while (and (> (point) (point-min))
2589 (progn
2590 (forward-line -1)
2591 (end-of-line)
2592 (if (not (bobp))
2593 (backward-char 1))
2594 (looking-at "\\\\"))
2595 )
2596 (beginning-of-line)
2597 (setq safepoint (point)))
2598 safepoint))
2599 ;; 'beg-of-clause
2600 (prolog-clause-start)))
2601 (end (point))
2602 (state (if prolog-use-prolog-tokenizer-flag
2603 (prolog-tokenize start end)
2604 (if (fboundp 'syntax-ppss)
2605 (syntax-ppss)
2606 (parse-partial-sexp start end)))))
2607 (cond
2608 ((nth 3 state) 'txt) ; String
2609 ((nth 4 state) 'cmt) ; Comment
2610 (t
2611 (cond
2612 ((looking-at "%") 'cmt) ; Start of a comment
2613 ((looking-at "/\\*") 'cmt) ; Start of a comment
2614 ((looking-at "\'") 'txt) ; Start of an atom
2615 ((looking-at "\"") 'txt) ; Start of a string
2616 (t nil)
2617 ))))
2618 ))
2619
2620(defun prolog-find-start-of-mline-comment ()
2621 "Return the start column of a /* */ comment.
2622This assumes that the point is inside a comment."
2623 (re-search-backward "/\\*" (point-min) t)
2624 (forward-char 2)
2625 (skip-chars-forward " \t")
2626 (current-column))
2627
2628(defun prolog-insert-spaces-after-paren ()
2629 "Insert spaces after the opening parenthesis, \"then\" (->) and \"else\" (;) branches. 2075 "Insert spaces after the opening parenthesis, \"then\" (->) and \"else\" (;) branches.
2630Spaces are inserted if all preceding objects on the line are 2076Spaces are inserted if all preceding objects on the line are
2631whitespace characters, parentheses, or then/else branches." 2077whitespace characters, parentheses, or then/else branches."
2632 (save-excursion 2078 (when prolog-electric-if-then-else-flag
2633 (let ((regexp (concat "(\\|" prolog-left-indent-regexp)) 2079 (save-excursion
2634 level) 2080 (let ((regexp (concat "(\\|" prolog-left-indent-regexp))
2635 (beginning-of-line) 2081 level)
2636 (skip-chars-forward " \t") 2082 (beginning-of-line)
2637 (when (looking-at regexp) 2083 (skip-chars-forward " \t")
2638 ;; Treat "( If -> " lines specially. 2084 ;; Treat "( If -> " lines specially.
2639 ;;(setq incr (if (looking-at "(.*->") 2085 ;;(setq incr (if (looking-at "(.*->")
2640 ;; 2 2086 ;; 2
@@ -2651,12 +2097,12 @@ whitespace characters, parentheses, or then/else branches."
2651 (delete-region start (point))) 2097 (delete-region start (point)))
2652 (indent-to level) 2098 (indent-to level)
2653 (skip-chars-forward " \t")) 2099 (skip-chars-forward " \t"))
2654 ))) 2100 ))
2655 (when (save-excursion 2101 (when (save-excursion
2656 (backward-char 2) 2102 (backward-char 2)
2657 (looking-at "\\s ;\\|\\s (\\|->")) ; (looking-at "\\s \\((\\|;\\)")) 2103 (looking-at "\\s ;\\|\\s (\\|->")) ; (looking-at "\\s \\((\\|;\\)"))
2658 (skip-chars-forward " \t")) 2104 (skip-chars-forward " \t"))
2659 ) 2105 ))
2660 2106
2661;;;; Comment filling 2107;;;; Comment filling
2662 2108
@@ -2741,7 +2187,7 @@ between them)."
2741 ;; fill 'txt entities? 2187 ;; fill 'txt entities?
2742 (when (save-excursion 2188 (when (save-excursion
2743 (end-of-line) 2189 (end-of-line)
2744 (equal (prolog-in-string-or-comment) 'cmt)) 2190 (nth 4 (syntax-ppss)))
2745 (let* ((bounds (prolog-comment-limits)) 2191 (let* ((bounds (prolog-comment-limits))
2746 (cbeg (car bounds)) 2192 (cbeg (car bounds))
2747 (type (nth 2 bounds)) 2193 (type (nth 2 bounds))
@@ -2810,162 +2256,6 @@ In effect it sets the `fill-prefix' when inside comments and then calls
2810 (replace-regexp-in-string regexp newtext str nil literal)))) 2256 (replace-regexp-in-string regexp newtext str nil literal))))
2811 2257
2812;;------------------------------------------------------------------- 2258;;-------------------------------------------------------------------
2813;; The tokenizer
2814;;-------------------------------------------------------------------
2815
2816(defconst prolog-tokenize-searchkey
2817 (concat "[0-9]+'"
2818 "\\|"
2819 "['\"]"
2820 "\\|"
2821 prolog-left-paren
2822 "\\|"
2823 prolog-right-paren
2824 "\\|"
2825 "%"
2826 "\\|"
2827 "/\\*"
2828 ))
2829
2830(defun prolog-tokenize (beg end &optional stopcond)
2831 "Tokenize a region of prolog code between BEG and END.
2832STOPCOND decides the stop condition of the parsing. Valid values
2833are 'zerodepth which stops the parsing at the first right parenthesis
2834where the parenthesis depth is zero, 'skipover which skips over
2835the current entity (e.g. a list, a string, etc.) and nil.
2836
2837The function returns a list with the following information:
2838 0. parenthesis depth
2839 3. 'atm if END is inside an atom
2840 'str if END is inside a string
2841 'chr if END is in a character code expression (0'x)
2842 nil otherwise
2843 4. non-nil if END is inside a comment
2844 5. end position (always equal to END if STOPCOND is nil)
2845The rest of the elements are undefined."
2846 (save-excursion
2847 (let* ((end2 (1+ end))
2848 oldp
2849 (depth 0)
2850 (quoted nil)
2851 inside_cmt
2852 (endpos end2)
2853 skiptype ; The type of entity we'll skip over
2854 )
2855 (goto-char beg)
2856
2857 (if (and (eq stopcond 'skipover)
2858 (looking-at "[^[({'\"]"))
2859 (setq endpos (point)) ; Stay where we are
2860 (while (and
2861 (re-search-forward prolog-tokenize-searchkey end2 t)
2862 (< (point) end2))
2863 (progn
2864 (setq oldp (point))
2865 (goto-char (match-beginning 0))
2866 (cond
2867 ;; Atoms and strings
2868 ((looking-at "'")
2869 ;; Find end of atom
2870 (if (re-search-forward "[^\\]'" end2 'limit)
2871 ;; Found end of atom
2872 (progn
2873 (setq oldp end2)
2874 (if (and (eq stopcond 'skipover)
2875 (not skiptype))
2876 (setq endpos (point))
2877 (setq oldp (point)))) ; Continue tokenizing
2878 (setq quoted 'atm)))
2879
2880 ((looking-at "\"")
2881 ;; Find end of string
2882 (if (re-search-forward "[^\\]\"" end2 'limit)
2883 ;; Found end of string
2884 (progn
2885 (setq oldp end2)
2886 (if (and (eq stopcond 'skipover)
2887 (not skiptype))
2888 (setq endpos (point))
2889 (setq oldp (point)))) ; Continue tokenizing
2890 (setq quoted 'str)))
2891
2892 ;; Paren stuff
2893 ((looking-at prolog-left-paren)
2894 (setq depth (1+ depth))
2895 (setq skiptype 'paren))
2896
2897 ((looking-at prolog-right-paren)
2898 (setq depth (1- depth))
2899 (if (and
2900 (or (eq stopcond 'zerodepth)
2901 (and (eq stopcond 'skipover)
2902 (eq skiptype 'paren)))
2903 (= depth 0))
2904 (progn
2905 (setq endpos (1+ (point)))
2906 (setq oldp end2))))
2907
2908 ;; Comment stuff
2909 ((looking-at comment-start)
2910 (end-of-line)
2911 ;; (if (>= (point) end2)
2912 (if (>= (point) end)
2913 (progn
2914 (setq inside_cmt t)
2915 (setq oldp end2))
2916 (setq oldp (point))))
2917
2918 ((looking-at "/\\*")
2919 (if (re-search-forward "\\*/" end2 'limit)
2920 (setq oldp (point))
2921 (setq inside_cmt t)
2922 (setq oldp end2)))
2923
2924 ;; 0'char
2925 ((looking-at "0'")
2926 (setq oldp (1+ (match-end 0)))
2927 (if (> oldp end)
2928 (setq quoted 'chr)))
2929
2930 ;; base'number
2931 ((looking-at "[0-9]+'")
2932 (goto-char (match-end 0))
2933 (skip-chars-forward "0-9a-zA-Z")
2934 (setq oldp (point)))
2935
2936
2937 )
2938 (goto-char oldp)
2939 )) ; End of while
2940 )
2941
2942 ;; Deal with multi-line comments
2943 (and (prolog-inside-mline-comment end)
2944 (setq inside_cmt t))
2945
2946 ;; Create return list
2947 (list depth nil nil quoted inside_cmt endpos)
2948 )))
2949
2950(defun prolog-inside-mline-comment (here)
2951 (save-excursion
2952 (goto-char here)
2953 (let* ((next-close (save-excursion (search-forward "*/" nil t)))
2954 (next-open (save-excursion (search-forward "/*" nil t)))
2955 (prev-open (save-excursion (search-backward "/*" nil t)))
2956 (prev-close (save-excursion (search-backward "*/" nil t)))
2957 (unmatched-next-close (and next-close
2958 (or (not next-open)
2959 (> next-open next-close))))
2960 (unmatched-prev-open (and prev-open
2961 (or (not prev-close)
2962 (> prev-open prev-close))))
2963 )
2964 (or unmatched-next-close unmatched-prev-open)
2965 )))
2966
2967
2968;;-------------------------------------------------------------------
2969;; Online help 2259;; Online help
2970;;------------------------------------------------------------------- 2260;;-------------------------------------------------------------------
2971 2261
@@ -3357,7 +2647,7 @@ When called with prefix argument ARG, disable zipping instead."
3357 (let ((state (prolog-clause-info)) 2647 (let ((state (prolog-clause-info))
3358 (object (prolog-in-object))) 2648 (object (prolog-in-object)))
3359 (if (or (equal (nth 0 state) "") 2649 (if (or (equal (nth 0 state) "")
3360 (equal (prolog-in-string-or-comment) 'cmt)) 2650 (nth 4 (syntax-ppss)))
3361 nil 2651 nil
3362 (if (and (eq prolog-system 'sicstus) 2652 (if (and (eq prolog-system 'sicstus)
3363 object) 2653 object)
@@ -3465,7 +2755,7 @@ STRING should be given if the last search was by `string-match' on STRING."
3465(defun prolog-clause-start (&optional not-allow-methods) 2755(defun prolog-clause-start (&optional not-allow-methods)
3466 "Return the position at the start of the head of the current clause. 2756 "Return the position at the start of the head of the current clause.
3467If NOTALLOWMETHODS is non-nil then do not match on methods in 2757If NOTALLOWMETHODS is non-nil then do not match on methods in
3468objects (relevant only if 'prolog-system' is set to 'sicstus)." 2758objects (relevant only if `prolog-system' is set to `sicstus')."
3469 (save-excursion 2759 (save-excursion
3470 (let ((notdone t) 2760 (let ((notdone t)
3471 (retval (point-min))) 2761 (retval (point-min)))
@@ -3501,11 +2791,8 @@ objects (relevant only if 'prolog-system' is set to 'sicstus)."
3501 ;; ###### 2791 ;; ######
3502 ;; (re-search-backward "^[a-z$']" nil t)) 2792 ;; (re-search-backward "^[a-z$']" nil t))
3503 (let ((case-fold-search nil)) 2793 (let ((case-fold-search nil))
3504 (re-search-backward 2794 (re-search-backward "^\\([[:lower:]$']\\|[:?]-\\)"
3505 ;; (format "^[%s$']" prolog-lower-case-string) 2795 nil t)))
3506 ;; FIXME: Use [:lower:]
3507 (format "^\\([%s$']\\|[:?]-\\)" prolog-lower-case-string)
3508 nil t)))
3509 (let ((bal (prolog-paren-balance))) 2796 (let ((bal (prolog-paren-balance)))
3510 (cond 2797 (cond
3511 ((> bal 0) 2798 ((> bal 0)
@@ -3531,7 +2818,7 @@ objects (relevant only if 'prolog-system' is set to 'sicstus)."
3531(defun prolog-clause-end (&optional not-allow-methods) 2818(defun prolog-clause-end (&optional not-allow-methods)
3532 "Return the position at the end of the current clause. 2819 "Return the position at the end of the current clause.
3533If NOTALLOWMETHODS is non-nil then do not match on methods in 2820If NOTALLOWMETHODS is non-nil then do not match on methods in
3534objects (relevant only if 'prolog-system' is set to 'sicstus)." 2821objects (relevant only if `prolog-system' is set to `sicstus')."
3535 (save-excursion 2822 (save-excursion
3536 (beginning-of-line) ; Necessary since we use "^...." for the search. 2823 (beginning-of-line) ; Necessary since we use "^...." for the search.
3537 (if (re-search-forward 2824 (if (re-search-forward
@@ -3545,7 +2832,7 @@ objects (relevant only if 'prolog-system' is set to 'sicstus)."
3545 "^\\(%s\\|%s\\|[^\n\'\"%%]\\)*\\.[ \t]*\\(\\|%%.*\\)$" 2832 "^\\(%s\\|%s\\|[^\n\'\"%%]\\)*\\.[ \t]*\\(\\|%%.*\\)$"
3546 prolog-quoted-atom-regexp prolog-string-regexp)) 2833 prolog-quoted-atom-regexp prolog-string-regexp))
3547 nil t) 2834 nil t)
3548 (if (and (prolog-in-string-or-comment) 2835 (if (and (nth 8 (syntax-ppss))
3549 (not (eobp))) 2836 (not (eobp)))
3550 (progn 2837 (progn
3551 (forward-char) 2838 (forward-char)
@@ -3568,7 +2855,7 @@ objects (relevant only if 'prolog-system' is set to 'sicstus)."
3568 ;; Retrieve the arity. 2855 ;; Retrieve the arity.
3569 (if (looking-at prolog-left-paren) 2856 (if (looking-at prolog-left-paren)
3570 (let ((endp (save-excursion 2857 (let ((endp (save-excursion
3571 (prolog-forward-list) (point)))) 2858 (forward-list) (point))))
3572 (setq arity 1) 2859 (setq arity 1)
3573 (forward-char 1) ; Skip the opening paren. 2860 (forward-char 1) ; Skip the opening paren.
3574 (while (progn 2861 (while (progn
@@ -3580,9 +2867,8 @@ objects (relevant only if 'prolog-system' is set to 'sicstus)."
3580 (forward-char 1) ; Skip the comma. 2867 (forward-char 1) ; Skip the comma.
3581 ) 2868 )
3582 ;; We found a string, list or something else we want 2869 ;; We found a string, list or something else we want
3583 ;; to skip over. Always use prolog-tokenize, 2870 ;; to skip over.
3584 ;; parse-partial-sexp does not have a 'skipover mode. 2871 (forward-sexp 1))
3585 (goto-char (nth 5 (prolog-tokenize (point) endp 'skipover))))
3586 ))) 2872 )))
3587 (list predname arity)))) 2873 (list predname arity))))
3588 2874
@@ -3602,36 +2888,6 @@ objects (relevant only if 'prolog-system' is set to 'sicstus)."
3602 (match-string 1) 2888 (match-string 1)
3603 nil)))) 2889 nil))))
3604 2890
3605(defun prolog-forward-list ()
3606 "Move the point to the matching right parenthesis."
3607 (interactive)
3608 (if prolog-use-prolog-tokenizer-flag
3609 (let ((state (prolog-tokenize (point) (point-max) 'zerodepth)))
3610 (goto-char (nth 5 state)))
3611 (forward-list)))
3612
3613;; NB: This could be done more efficiently!
3614(defun prolog-backward-list ()
3615 "Move the point to the matching left parenthesis."
3616 (interactive)
3617 (if prolog-use-prolog-tokenizer-flag
3618 (let ((bal 0)
3619 (paren-regexp (concat prolog-left-paren "\\|" prolog-right-paren))
3620 (notdone t))
3621 ;; FIXME: Doesn't this incorrectly count 0'( and 0') ?
3622 (while (and notdone (re-search-backward paren-regexp nil t))
3623 (cond
3624 ((looking-at prolog-left-paren)
3625 (if (not (prolog-in-string-or-comment))
3626 (setq bal (1+ bal)))
3627 (if (= bal 0)
3628 (setq notdone nil)))
3629 ((looking-at prolog-right-paren)
3630 (if (not (prolog-in-string-or-comment))
3631 (setq bal (1- bal))))
3632 )))
3633 (backward-list)))
3634
3635(defun prolog-beginning-of-clause () 2891(defun prolog-beginning-of-clause ()
3636 "Move to the beginning of current clause. 2892 "Move to the beginning of current clause.
3637If already at the beginning of clause, move to previous clause." 2893If already at the beginning of clause, move to previous clause."
@@ -3764,23 +3020,6 @@ The module name should be written manually just before the semi-colon."
3764 (interactive "r") 3020 (interactive "r")
3765 (comment-region beg end -1)))) 3021 (comment-region beg end -1))))
3766 3022
3767(defun prolog-goto-comment-column (&optional nocreate)
3768 "Move comments on the current line to the correct position.
3769If NOCREATE is nil (or omitted) and there is no comment on the line, then
3770a new comment is created."
3771 (interactive)
3772 (beginning-of-line)
3773 (if (or (not nocreate)
3774 (and
3775 (re-search-forward
3776 (format "^\\(\\(%s\\|%s\\|[^\n\'\"%%]\\)*\\)%% *"
3777 prolog-quoted-atom-regexp prolog-string-regexp)
3778 (line-end-position) 'limit)
3779 (progn
3780 (goto-char (match-beginning 0))
3781 (not (eq (prolog-in-string-or-comment) 'txt)))))
3782 (indent-for-comment)))
3783
3784(defun prolog-indent-predicate () 3023(defun prolog-indent-predicate ()
3785 "Indent the current predicate." 3024 "Indent the current predicate."
3786 (interactive) 3025 (interactive)
@@ -3813,130 +3052,72 @@ a new comment is created."
3813 (goto-char pos) 3052 (goto-char pos)
3814 (goto-char (prolog-pred-start)))) 3053 (goto-char (prolog-pred-start))))
3815 3054
3816;; Stolen from `cc-mode.el': 3055(defun prolog-electric--colon ()
3817(defun prolog-electric-delete (arg)
3818 "Delete preceding character or whitespace.
3819If `prolog-hungry-delete-key-flag' is non-nil, then all preceding whitespace is
3820consumed. If however an ARG is supplied, or `prolog-hungry-delete-key-flag' is
3821nil, or point is inside a literal then the function
3822`backward-delete-char' is called."
3823 (interactive "P")
3824 (if (or (not prolog-hungry-delete-key-flag)
3825 arg
3826 (prolog-in-string-or-comment))
3827 (funcall 'backward-delete-char (prefix-numeric-value arg))
3828 (let ((here (point)))
3829 (skip-chars-backward " \t\n")
3830 (if (/= (point) here)
3831 (delete-region (point) here)
3832 (funcall 'backward-delete-char 1)
3833 ))))
3834
3835;; For XEmacs compatibility (suggested by Per Mildner)
3836(put 'prolog-electric-delete 'pending-delete 'supersede)
3837
3838(defun prolog-electric-if-then-else (arg)
3839 "If `prolog-electric-if-then-else-flag' is non-nil, indent if-then-else constructs.
3840Bound to the >, ; and ( keys."
3841 ;; FIXME: Use post-self-insert-hook or electric-indent-mode.
3842 (interactive "P")
3843 (self-insert-command (prefix-numeric-value arg))
3844 (if prolog-electric-if-then-else-flag (prolog-insert-spaces-after-paren)))
3845
3846(defun prolog-electric-colon (arg)
3847 "If `prolog-electric-colon-flag' is non-nil, insert the electric `:' construct. 3056 "If `prolog-electric-colon-flag' is non-nil, insert the electric `:' construct.
3848That is, insert space (if appropriate), `:-' and newline if colon is pressed 3057That is, insert space (if appropriate), `:-' and newline if colon is pressed
3849at the end of a line that starts in the first column (i.e., clause 3058at the end of a line that starts in the first column (i.e., clause heads)."
3850heads)." 3059 (when (and prolog-electric-colon-flag
3851 ;; FIXME: Use post-self-insert-hook. 3060 (eq (char-before) ?:)
3852 (interactive "P") 3061 (not current-prefix-arg)
3853 (if (and prolog-electric-colon-flag 3062 (eolp)
3854 (null arg) 3063 (not (memq (char-after (line-beginning-position))
3855 (eolp) 3064 '(?\s ?\t ?\%))))
3856 ;(not (string-match "^\\s " (thing-at-point 'line)))) 3065 (unless (memq (char-before (1- (point))) '(?\s ?\t))
3857 (not (string-match "^\\(\\s \\|%\\)" (thing-at-point 'line)))) 3066 (save-excursion (forward-char -1) (insert " ")))
3858 (progn 3067 (insert "-\n")
3859 (unless (save-excursion (backward-char 1) (looking-at "\\s ")) 3068 (indent-according-to-mode)))
3860 (insert " ")) 3069
3861 (insert ":-\n") 3070(defun prolog-electric--dash ()
3862 (indent-according-to-mode))
3863 (self-insert-command (prefix-numeric-value arg))))
3864
3865(defun prolog-electric-dash (arg)
3866 "If `prolog-electric-dash-flag' is non-nil, insert the electric `-' construct. 3071 "If `prolog-electric-dash-flag' is non-nil, insert the electric `-' construct.
3867that is, insert space (if appropriate), `-->' and newline if dash is pressed 3072that is, insert space (if appropriate), `-->' and newline if dash is pressed
3868at the end of a line that starts in the first column (i.e., DCG 3073at the end of a line that starts in the first column (i.e., DCG heads)."
3869heads)." 3074 (when (and prolog-electric-dash-flag
3870 ;; FIXME: Use post-self-insert-hook. 3075 (eq (char-before) ?-)
3871 (interactive "P") 3076 (not current-prefix-arg)
3872 (if (and prolog-electric-dash-flag 3077 (eolp)
3873 (null arg) 3078 (not (memq (char-after (line-beginning-position))
3874 (eolp) 3079 '(?\s ?\t ?\%))))
3875 ;(not (string-match "^\\s " (thing-at-point 'line)))) 3080 (unless (memq (char-before (1- (point))) '(?\s ?\t))
3876 (not (string-match "^\\(\\s \\|%\\)" (thing-at-point 'line)))) 3081 (save-excursion (forward-char -1) (insert " ")))
3877 (progn 3082 (insert "->\n")
3878 (unless (save-excursion (backward-char 1) (looking-at "\\s ")) 3083 (indent-according-to-mode)))
3879 (insert " ")) 3084
3880 (insert "-->\n") 3085(defun prolog-electric--dot ()
3881 (indent-according-to-mode)) 3086 "Make dot electric, if `prolog-electric-dot-flag' is non-nil.
3882 (self-insert-command (prefix-numeric-value arg))))
3883
3884(defun prolog-electric-dot (arg)
3885 "Insert dot and newline or a head of a new clause.
3886
3887If `prolog-electric-dot-flag' is nil, then simply insert dot.
3888Otherwise::
3889When invoked at the end of nonempty line, insert dot and newline. 3087When invoked at the end of nonempty line, insert dot and newline.
3890When invoked at the end of an empty line, insert a recursive call to 3088When invoked at the end of an empty line, insert a recursive call to
3891the current predicate. 3089the current predicate.
3892When invoked at the beginning of line, insert a head of a new clause 3090When invoked at the beginning of line, insert a head of a new clause
3893of the current predicate. 3091of the current predicate."
3894
3895When called with prefix argument ARG, insert just dot."
3896 ;; FIXME: Use post-self-insert-hook.
3897 (interactive "P")
3898 ;; Check for situations when the electricity should not be active 3092 ;; Check for situations when the electricity should not be active
3899 (if (or (not prolog-electric-dot-flag) 3093 (if (or (not prolog-electric-dot-flag)
3900 arg 3094 (not (eq (char-before) ?\.))
3901 (prolog-in-string-or-comment) 3095 current-prefix-arg
3096 (nth 8 (syntax-ppss))
3902 ;; Do not be electric in a floating point number or an operator 3097 ;; Do not be electric in a floating point number or an operator
3903 (not 3098 (not
3904 (or 3099 (save-excursion
3905 ;; (re-search-backward 3100 (forward-char -1)
3906 ;; ###### 3101 (skip-chars-backward " \t")
3907 ;; "\\(^\\|[])}a-zA-Z_!'0-9]+\\)[ \t]*\\=" nil t))) 3102 (let ((num (> (skip-chars-backward "0-9") 0)))
3908 (save-excursion 3103 (or (bolp)
3909 (re-search-backward 3104 (memq (char-syntax (char-before))
3910 ;; "\\(^\\|[])}_!'0-9]+\\)[ \t]*\\=" nil t))) 3105 (if num '(?w ?_) '(?\) ?w ?_)))))))
3911 "\\(^\\|[])}_!'0-9]+\\)[ \t]*\\="
3912 nil t))
3913 (save-excursion
3914 (re-search-backward
3915 ;; "\\(^\\|[])}a-zA-Z]+\\)[ \t]*\\=" nil t)))
3916 (format "\\(^\\|[])}%s]+\\)[ \t]*\\="
3917 prolog-lower-case-string) ;FIXME: [:lower:]
3918 nil t))
3919 (save-excursion
3920 (re-search-backward
3921 ;; "\\(^\\|[])}a-zA-Z]+\\)[ \t]*\\=" nil t)))
3922 (format "\\(^\\|[])}%s]+\\)[ \t]*\\="
3923 prolog-upper-case-string) ;FIXME: [:upper:]
3924 nil t))
3925 )
3926 )
3927 ;; Do not be electric if inside a parenthesis pair. 3106 ;; Do not be electric if inside a parenthesis pair.
3928 (not (= (prolog-region-paren-balance (prolog-clause-start) (point)) 3107 (not (= (car (syntax-ppss))
3929 0)) 3108 0))
3930 ) 3109 )
3931 (funcall 'self-insert-command (prefix-numeric-value arg)) 3110 nil ;;Not electric.
3932 (cond 3111 (cond
3933 ;; Beginning of line 3112 ;; Beginning of line
3934 ((bolp) 3113 ((save-excursion (forward-char -1) (bolp))
3114 (delete-region (1- (point)) (point)) ;Delete the dot that called us.
3935 (prolog-insert-predicate-template)) 3115 (prolog-insert-predicate-template))
3936 ;; At an empty line with at least one whitespace 3116 ;; At an empty line with at least one whitespace
3937 ((save-excursion 3117 ((save-excursion
3938 (beginning-of-line) 3118 (beginning-of-line)
3939 (looking-at "[ \t]+$")) 3119 (looking-at "[ \t]+\\.$"))
3120 (delete-region (1- (point)) (point)) ;Delete the dot that called us.
3940 (prolog-insert-predicate-template) 3121 (prolog-insert-predicate-template)
3941 (when prolog-electric-dot-full-predicate-template 3122 (when prolog-electric-dot-full-predicate-template
3942 (save-excursion 3123 (save-excursion
@@ -3944,47 +3125,31 @@ When called with prefix argument ARG, insert just dot."
3944 (insert ".\n")))) 3125 (insert ".\n"))))
3945 ;; Default 3126 ;; Default
3946 (t 3127 (t
3947 (insert ".\n")) 3128 (insert "\n"))
3948 ))) 3129 )))
3949 3130
3950(defun prolog-electric-underscore () 3131(defun prolog-electric--underscore ()
3951 "Replace variable with an underscore. 3132 "Replace variable with an underscore.
3952If `prolog-electric-underscore-flag' is non-nil and the point is 3133If `prolog-electric-underscore-flag' is non-nil and the point is
3953on a variable then replace the variable with underscore and skip 3134on a variable then replace the variable with underscore and skip
3954the following comma and whitespace, if any. 3135the following comma and whitespace, if any."
3955If the point is not on a variable then insert underscore." 3136 (when prolog-electric-underscore-flag
3956 ;; FIXME: Use post-self-insert-hook. 3137 (let ((case-fold-search nil))
3957 (interactive) 3138 (when (and (not (nth 8 (syntax-ppss)))
3958 (if prolog-electric-underscore-flag 3139 (eq (char-before) ?_)
3959 (let (;start 3140 (save-excursion
3960 (case-fold-search nil) 3141 (skip-chars-backward "[:alpha:]_")
3961 (oldp (point))) 3142 (looking-at "\\<_[_[:upper:]][[:alnum:]_]*\\_>")))
3962 ;; ###### 3143 (replace-match "_")
3963 ;;(skip-chars-backward "a-zA-Z_") 3144 (skip-chars-forward ", \t\n")))))
3964 (skip-chars-backward 3145
3965 (format "%s%s_" 3146(defun prolog-post-self-insert ()
3966 ;; FIXME: Why not "a-zA-Z"? 3147 (pcase last-command-event
3967 prolog-lower-case-string 3148 (`?_ (prolog-electric--underscore))
3968 prolog-upper-case-string)) 3149 (`?- (prolog-electric--dash))
3969 3150 (`?: (prolog-electric--colon))
3970 ;(setq start (point)) 3151 ((or `?\( `?\; `?>) (prolog-electric--if-then-else))
3971 (if (and (not (prolog-in-string-or-comment)) 3152 (`?. (prolog-electric--dot))))
3972 ;; ######
3973 ;; (looking-at "\\<[_A-Z][a-zA-Z_0-9]*\\>"))
3974 (looking-at (format "\\<[_%s][%s%s_0-9]*\\>"
3975 ;; FIXME: Use [:upper:] and friends.
3976 prolog-upper-case-string
3977 prolog-lower-case-string
3978 prolog-upper-case-string)))
3979 (progn
3980 (replace-match "_")
3981 (skip-chars-forward ", \t\n"))
3982 (goto-char oldp)
3983 (self-insert-command 1))
3984 )
3985 (self-insert-command 1))
3986 )
3987
3988 3153
3989(defun prolog-find-term (functor arity &optional prefix) 3154(defun prolog-find-term (functor arity &optional prefix)
3990 "Go to the position at the start of the next occurrence of a term. 3155 "Go to the position at the start of the next occurrence of a term.
@@ -4188,11 +3353,12 @@ PREFIX is the prefix of the search regexp."
4188 (easy-menu-add prolog-edit-menu-runtime) 3353 (easy-menu-add prolog-edit-menu-runtime)
4189 3354
4190 ;; Add predicate index menu 3355 ;; Add predicate index menu
4191 (set (make-local-variable 'imenu-create-index-function) 3356 (setq-local imenu-create-index-function
4192 'imenu-default-create-index-function) 3357 'imenu-default-create-index-function)
4193 ;;Milan (this has problems with object methods...) ###### Does it? (Stefan) 3358 ;;Milan (this has problems with object methods...) ###### Does it? (Stefan)
4194 (setq imenu-prev-index-position-function 'prolog-beginning-of-predicate) 3359 (setq-local imenu-prev-index-position-function
4195 (setq imenu-extract-index-name-function 'prolog-get-predspec) 3360 #'prolog-beginning-of-predicate)
3361 (setq-local imenu-extract-index-name-function #'prolog-get-predspec)
4196 3362
4197 (if (and prolog-imenu-flag 3363 (if (and prolog-imenu-flag
4198 (< (count-lines (point-min) (point-max)) prolog-imenu-max-lines)) 3364 (< (count-lines (point-min) (point-max)) prolog-imenu-max-lines))