]> git.eshelyaron.com Git - sweep.git/commitdiff
ADDED: minor mode for automatic whitespace insertion
authorEshel Yaron <me@eshelyaron.com>
Mon, 14 Nov 2022 16:19:31 +0000 (18:19 +0200)
committerEshel Yaron <me@eshelyaron.com>
Mon, 14 Nov 2022 16:19:31 +0000 (18:19 +0200)
* sweep.pl (sweep_context_callable/2): only consider the context to be
callable if a neck is present up the tree, i.e. not in the head.
* sweeprolog.el (sweeprolog-context-callable-p): new function,
extracted from (sweeprolog-predicate-completion-at-point)
(sweeprolog-electric-layout-post-self-insert-function): new function.
(sweeprolog-electric-layout-mode): new minor mode.

sweep.pl
sweeprolog-tests.el
sweeprolog.el

index fbbddf8891f2d152115c5eb124a2f67aa71324a9..13933d890077e9ae8c0f1306cc2345b84bf82b51 100644 (file)
--- a/sweep.pl
+++ b/sweep.pl
@@ -758,22 +758,36 @@ sweep_format_predicate(H, S) :-
                        spacing(next_argument),
                        numbervars(true)]).
 
-sweep_context_callable([], true) :- !.
-sweep_context_callable([[":"|2]], true) :- !.
 sweep_context_callable([H|T], R) :-
+    H = [F0|_],
+    atom_string(F, F0),
+    (   xref_op(_, op(1200, _, F))
+    ->  true
+    ;   current_op(1200, _, F)
+    ),
+    !,
+    sweep_context_callable_(T, R).
+sweep_context_callable([_|T], R) :-
+    sweep_context_callable(T, R).
+
+sweep_context_callable_([], true) :- !.
+sweep_context_callable_([[":"|2]], true) :- !.
+sweep_context_callable_([["("|_]|T], R) :-
+    sweep_context_callable_(T, R).
+sweep_context_callable_([H|T], R) :-
     H = [F0|N],
     atom_string(F, F0),
-    (   sweep_context_callable_(F, N)
-    ->  sweep_context_callable(T, R)
+    (   sweep_context_callable_arg(F, N)
+    ->  sweep_context_callable_(T, R)
     ;   R = []
     ).
 
-sweep_context_callable_(Neck, _) :-
+sweep_context_callable_arg(Neck, _) :-
     (   xref_op(_, op(1200, _, Neck))
     ->  true
     ;   current_op(1200, _, Neck)
     ).
-sweep_context_callable_(F, N) :-
+sweep_context_callable_arg(F, N) :-
     (   current_predicate(F/M), pi_head(F/M,Head)
     ;   xref_defined(_, Head, _), pi_head(F/M,Head)
     ),
index f5b295ea7759985eadf99eb2deaa8074e8afeeae..518c79617a4baa8e8301ca7b269381a5518bba29 100644 (file)
@@ -111,7 +111,7 @@ foo(Foo) :- bar.
                               nil
                               ".pl"
                               "
-baz(Baz) :- Baz = emacsc
+baz(Baz) :- Baz = opa
 "
                               )))
     (find-file-literally temp)
@@ -121,7 +121,7 @@ baz(Baz) :- Baz = emacsc
     (call-interactively #'completion-at-point)
     (should (string= (buffer-string)
                      "
-baz(Baz) :- Baz = emacsclient
+baz(Baz) :- Baz = opaque
 "
                      ))))
 
index 09c680c1308b3579dd1c97751493180813d7c2c6..2d8a691c368082b48de146970a9d7e1f21e03aad 100644 (file)
@@ -1015,7 +1015,9 @@ resulting list even when found in the current clause."
                     (ppre (sweeprolog-op-prefix-precedence op)))
                (cond
                 ((and (string= "." op)
-                      (member (char-syntax (char-after (1+ obeg))) '(?> ? )))
+                      (or (not (char-after (1+ obeg)))
+                          (member (char-syntax (char-after (1+ obeg)))
+                                  '(?> ? ))))
                  nil)
                 ((string= "," op)
                  (setq pos
@@ -1038,6 +1040,10 @@ resulting list even when found in the current clause."
                  (setq commas 0)))))))
       context)))
 
+(defun sweeprolog-context-callable-p ()
+  (sweeprolog--query-once "sweep" "sweep_context_callable"
+                          (sweeprolog--parse-context)))
+
 (defun sweeprolog-predicate-completion-at-point ()
   "Prolog predicate completion backend for `completion-at-point'."
   (when-let ((bounds (bounds-of-thing-at-point 'symbol))
@@ -1047,9 +1053,7 @@ resulting list even when found in the current clause."
                (let ((first (char-after beg)))
                  (not (or (sweeprolog--char-uppercase-p first)
                           (= first ?_))))
-               (sweeprolog--query-once "sweep"
-                                       "sweep_context_callable"
-                                       (sweeprolog--parse-context)))
+               (sweeprolog-context-callable-p))
       (when-let
           ((col (sweeprolog--query-once "sweep" "sweep_predicate_completion_candidates"
                                         nil)))
@@ -1833,8 +1837,8 @@ resulting list even when found in the current clause."
            (setq cur (point)))
          (skip-chars-forward " \t\n")
          (push (list cur (point) nil) ws)
-         (cons  (list beg end nil)
-                (cons (list beg end (sweeprolog-fullstop-face))
+         (cons (list beg (point) nil)
+               (cons (list beg end (sweeprolog-fullstop-face))
                       ws)))))
     ("functor"
      (list (list beg end (sweeprolog-functor-face))))
@@ -2884,7 +2888,9 @@ predicate definition at or directly above POINT."
                      oend)))
       (`(operator ,obeg ,oend)
        (if (and (string= "." (buffer-substring-no-properties obeg oend))
-                (member (char-syntax (char-after (1+ obeg))) '(?> ? )))
+                (or (not (char-after (1+ obeg)))
+                    (member (char-syntax (char-after (1+ obeg)))
+                            '(?> ? ))))
            (signal 'scan-error
                    (list "Cannot scan backwards beyond fullstop."
                          obeg
@@ -3122,6 +3128,34 @@ if-then-else constructs in SWI-Prolog."
                (delete-horizontal-space)
                (insert (make-string num ? ))))))))))
 
+(defun sweeprolog-electric-layout-post-self-insert-function ()
+  (if (nth 8 (syntax-ppss))
+      (when (member (buffer-substring-no-properties (line-beginning-position)
+                                                    (point))
+                    '("%%" "%!"))
+        (insert "  "))
+    (when (member (char-before) (string-to-list "(;>"))
+     (pcase (sweeprolog-last-token-boundaries)
+       ((or `(open     ,beg ,end)
+            `(operator ,beg ,end))
+        (when (and (member (buffer-substring-no-properties beg end)
+                           '("(" ";" "->" "*->"))
+                   (sweeprolog-context-callable-p))
+          (insert (make-string (+ 4 beg (- end)) ? ))))))))
+
+;;;###autoload
+(define-minor-mode sweeprolog-electric-layout-mode
+  "Automatically insert whitespace in `sweeprolog-mode' buffers."
+  :group 'sweeprolog
+  (if sweeprolog-electric-layout-mode
+      (progn
+        (add-hook 'post-self-insert-hook
+                  #'sweeprolog-electric-layout-post-self-insert-function
+                  nil t))
+    (remove-hook 'post-self-insert-hook
+                 #'sweeprolog-electric-layout-post-self-insert-function
+                 t)))
+
 (defun sweeprolog--update-buffer-last-modified-time (&rest _)
   (setq sweeprolog--buffer-last-modified-time (float-time)
         sweeprolog--buffer-modified t))