* lisp/progmodes/prolog.el: Fix various indentation cases

(prolog-operator-chars): New const (add \\).
(prolog-smie-forward-token, prolog-smie-backward-token): Use it.
(prolog-smie-rules): Add rules according to bug#21526.
This commit is contained in:
Stefan Monnier 2015-09-29 23:28:32 -04:00
parent 300bce3a09
commit e1877439d8
2 changed files with 70 additions and 18 deletions

View file

@ -840,6 +840,8 @@ This is really kludgy, and unneeded (i.e. obsolete) in Emacs>=24."
(require 'smie)
(defconst prolog-operator-chars "-\\\\#&*+./:<=>?@\\^`~")
(defun prolog-smie-forward-token ()
;; FIXME: Add support for 0'<char>, if needed after adding it to
;; syntax-propertize-functions.
@ -848,7 +850,7 @@ This is really kludgy, and unneeded (i.e. obsolete) in Emacs>=24."
(point)
(progn (cond
((looking-at "[!;]") (forward-char 1))
((not (zerop (skip-chars-forward "#&*+-./:<=>?@\\^`~"))))
((not (zerop (skip-chars-forward prolog-operator-chars))))
((not (zerop (skip-syntax-forward "w_'"))))
;; In case of non-ASCII punctuation.
((not (zerop (skip-syntax-forward ".")))))
@ -861,8 +863,8 @@ This is really kludgy, and unneeded (i.e. obsolete) in Emacs>=24."
(buffer-substring-no-properties
(point)
(progn (cond
((memq (char-before) '(?! ?\;)) (forward-char -1))
((not (zerop (skip-chars-backward "#&*+-./:<=>?@\\^`~"))))
((memq (char-before) '(?! ?\; ?\,)) (forward-char -1))
((not (zerop (skip-chars-backward prolog-operator-chars))))
((not (zerop (skip-syntax-backward "w_'"))))
;; In case of non-ASCII punctuation.
((not (zerop (skip-syntax-backward ".")))))
@ -947,12 +949,36 @@ This is really kludgy, and unneeded (i.e. obsolete) in Emacs>=24."
;; ; c)
;;
;; based on the space between the open paren and the "a".
(unless (and (smie-rule-parent-p "(")
(unless (and (smie-rule-parent-p "(" ";")
(save-excursion
(smie-indent-forward-token)
(smie-backward-sexp 'halfsexp)
(not (eq ?\( (char-before)))))
(if (smie-rule-parent-p "(")
(not (eq (char-before) ?\())
(smie-indent-backward-token)
(smie-rule-bolp))))
prolog-indent-width))
(`(:after . ";")
;; Align with same-line comment as in:
;; ; %% Toto
;; foo
(and (smie-rule-bolp)
(looking-at ";[ \t]*\\(%\\)")
(let ((offset (- (save-excursion (goto-char (match-beginning 1))
(current-column))
(current-column))))
;; Only do it for small offsets, since the comment may actually be
;; an "end-of-line" comment at comment-column!
(if (<= offset prolog-indent-width) offset))))
(`(:after . ",")
;; Special indent for:
;; foopredicate(x) :- !,
;; toto.
(and (eq (char-before) ?!)
(save-excursion
(smie-indent-backward-token) ;Skip !
(equal ":-" (car (smie-indent-backward-token))))
(smie-rule-parent prolog-indent-width)))
(`(:after . ,(or `":-" `"-->")) prolog-indent-width)))

View file

@ -1,16 +1,18 @@
%% -*- mode: prolog; coding: utf-8; fill-column: 78 -*-
%% bug#21526
test1 :-
test21526_1 :-
( a ->
( a ->
b
; c
)
; c
( a ->
b
; c
)
; % Toto
c ->
d
).
test2 :-
test21526_2 :-
( a
-> ( a,
b
@ -19,7 +21,31 @@ test2 :-
b2
; c1,
c2
)
).
test21526_3 :-
X \= Y,
\+ a,
b,
\+ \+ c,
d.
test21526_4 :-
( \+ a ->
b
; \+ c,
\+ d
).
test21526_5 :-
(a;
b ->
c).
test21526_predicate(c) :- !,
test_goal1,
test_goal2.
%% Testing correct tokenizing.
foo(X) :- 0'= = X.
@ -74,11 +100,11 @@ subst(X, V, FV, lambda(Y, Ti, Bi), lambda(Y1, To, Bo)) :-
%% If X is equal to Y, X is shadowed, so no subst can take place.
-> Y1 = Y, Bo = Bi
; (member((Y, _), FV)
%% If Y appears in FV, it can appear in V, so we need to
%% rename it to avoid name capture.
-> new_atom(Y, Y1),
subst(Y, Y1, [], Bi, Bi1)
; Y1 = Y, Bi1 = Bi),
%% If Y appears in FV, it can appear in V, so we need to
%% rename it to avoid name capture.
-> new_atom(Y, Y1),
subst(Y, Y1, [], Bi, Bi1)
; Y1 = Y, Bi1 = Bi),
%% Perform substitution on the body.
subst(X, V, FV, Bi1, Bo)
).