emacs-elpa-diffs
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

[nongnu] elpa/sweeprolog 1ede2d3f5e 4/4: ENHANCED: Guess argument names


From: ELPA Syncer
Subject: [nongnu] elpa/sweeprolog 1ede2d3f5e 4/4: ENHANCED: Guess argument names for DCG grammar rules
Date: Sun, 11 Jun 2023 16:02:32 -0400 (EDT)

branch: elpa/sweeprolog
commit 1ede2d3f5eaf5f877f91af71a083f827aa48c6c2
Author: Eshel Yaron <me@eshelyaron.com>
Commit: Eshel Yaron <me@eshelyaron.com>

    ENHANCED: Guess argument names for DCG grammar rules
    
    * sweeprolog.el (sweeprolog-predicate-completion-at-point)
    (sweeprolog-insert-clause): Support guessing argument names from
    documentation also for DCG grammar rules.
---
 sweep.pl            | 160 +++++++++++++++++++++++-----------------------------
 sweeprolog-tests.el |  43 ++++++++++++++
 sweeprolog.el       |  23 +++++---
 3 files changed, 127 insertions(+), 99 deletions(-)

diff --git a/sweep.pl b/sweep.pl
index a7c5c1a709..ab4d5d6c95 100644
--- a/sweep.pl
+++ b/sweep.pl
@@ -65,7 +65,7 @@
             sweep_beginning_of_last_predicate/2,
             sweep_atom_collection/2,
             sweep_context_callable/2,
-            sweep_predicate_completion_candidates/2,
+            sweep_heads_collection/2,
             sweep_exportable_predicates/2,
             sweep_interrupt/0,
             sweep_string_to_atom/2,
@@ -429,72 +429,57 @@ sweep_predicate_location_(M, H, Path, Line) :-
     predicate_property(M:H, line_count(Line)),
     atom_string(Path0, Path).
 
+sweep_matching_predicates(S, D, PIs) :-
+    setof(M:F/A, sweep_matching_predicate(S, D, M, F, A), PIs).
 
-sweep_predicates_collection(Sub, Preds) :-
-    findall(M:F/N,
-            ( current_predicate(M:F/N),
-              pi_head(F/N, H),
-              (   M == system
-              ->  true
-              ;   \+ (predicate_property(M:H, imported_from(M1)), M \= M1)
-              )
-            ),
-            Preds0,
-            Tail0),
-    findall(M:F/N,
-            ( '$autoload':library_index(H, M, _),
-              pi_head(F/N, H)
-            ),
-            Tail0,
-            Tail1),
-    findall(M:F/N,
-            ( xref_defined(SourceId, H, local(_)),
-              (   xref_module(SourceId, M)
-              ->  true
-              ;   M = user
-              ),
-              \+ (predicate_property(M:H, imported_from(M1)), M \= M1),
-              pi_head(F/N, H)
-            ),
-            Tail1,
-            Tail),
-    findall(M:F/N,
-            ( xref_defined(_, H, imported(SourceId)),
-              (   xref_module(SourceId, M)
-              ->  true
-              ;   M = user
-              ),
-              pi_head(F/N, H)
-            ),
-            Tail),
-    list_to_set(Preds0, Preds1),
-    maplist(sweep_predicate_description, Preds1, Preds2),
-    include(sweep_predicate_non_hidden, Preds2, Preds3),
-    (   Sub == []
-    ->  Preds = Preds3
-    ;   include(sweep_predicate_matches(Sub), Preds3, Preds)
-    ).
+sweep_matching_predicate(S, D, M, F, A) :-
+    sweep_known_predicate(M, F, A),
+    once(sub_atom(F, _, _, _, S)),
+    A >= D.
 
-sweep_predicate_matches(Sub, [String|_]) :-
-    sub_string(String, _, _, _, Sub).
+sweep_known_predicate(M, F, A) :-
+    current_predicate(M:F/A),
+    (   M == system
+    ->  true
+    ;   pi_head(F/A, H),
+        \+ (predicate_property(M:H, imported_from(M1)), M \= M1)
+    ).
+sweep_known_predicate(M, F, A) :-
+    '$autoload':library_index(H, M, _),
+    pi_head(F/A, H).
+sweep_known_predicate(M, F, A) :-
+    xref_defined(SourceId, H, How),
+    xref_definition_line(How, _),
+    (   xref_module(SourceId, M)
+    ->  true
+    ;   M = user
+    ),
+    pi_head(F/A, H).
 
-sweep_predicate_non_hidden([String|_]) :-
-    \+ sub_string(String, _, _, _, ":'$").
+sweep_predicates_collection(S0, Ps) :-
+    (   S0 == []
+    ->  S = ""
+    ;   S = S0
+    ),
+    sweep_matching_predicates(S, 0, PIs),
+    maplist(sweep_format_pi, PIs, Ps).
 
-sweep_predicate_description(M:F/N, [S|T]) :-
+sweep_format_pi(M:F/N, [S|T]) :-
     sweep_module_functor_arity_pi_(M, F, N, MFA),
     format(string(S),
            '~W',
            [MFA, [quoted(true), character_escapes(true)]]),
-    sweep_predicate_description_(MFA, T).
+    (   sweep_predicate_summary(MFA, Summary)
+    ->  atom_string(Summary, T)
+    ;   T = []
+    ).
 
-sweep_predicate_description_(MFA, [D]) :-
-    doc_comment(MFA, _, D0, _), !, atom_string(D0, D).
-sweep_predicate_description_(MFA, [D]) :-
-    man_object_property(MFA, summary(D0)), !, atom_string(D0, D).
-sweep_predicate_description_(_:FA, [D]) :-
-    man_object_property(FA, summary(D0)), !, atom_string(D0, D).
-sweep_predicate_description_(_, []).
+sweep_predicate_summary(MFA, D) :-
+    doc_comment(MFA, _, D, _).
+sweep_predicate_summary(MFA, D) :-
+    man_object_property(MFA, summary(D)).
+sweep_predicate_summary(_:FA, D) :-
+    man_object_property(FA, summary(D)).
 
 sweep_packs_collection(SearchString, Packs) :-
     prolog_pack:query_pack_server(search(SearchString), true(Packs0), []),
@@ -885,27 +870,15 @@ sweep_atom_collection(Sub, Col) :-
             ),
             Col).
 
-sweep_predicate_completion_candidates([D|Sub], Ps) :-
-    integer(D),
-    sweep_current_module(M),
-    findall(H,
-            (   (   @(predicate_property(H, visible), M)
-                ;   xref_defined(_, H, _)
-                ),
-                pi_head(F/N, H),
-                once(sub_atom(F, _, _, _, Sub)),
-                N - D >= 0
-            ),
-            Hs),
-    maplist(sweep_format_predicate(M, D), Hs, Ps).
+sweep_heads_collection([D|Sub], Ps) :-
+    sweep_matching_predicates(Sub, D, PIs),
+    maplist(sweep_format_head_(D), PIs, Ps).
 
-sweep_format_predicate(M0, D, H0, [S|SP]) :-
-    pi_head(F/N0, H0),
-    N is N0 - D,
+sweep_format_head_(D, M:F/A, [S|SP]) :-
+    N is A - D,
     length(NamedArgs, N),
     append(NamedArgs, _, OpenNamedArgs),
-    (   @(predicate_property(H0, implementation_module(M)), M0),
-        predicate_argument_names(M:F/N0, As)
+    (   predicate_argument_names(M:F/A, As)
     ->  maplist(name_variable, As, Vs), OpenNamedArgs = Vs
     ;   maplist(=('$VAR'('_')), NamedArgs)
     ),
@@ -1012,12 +985,21 @@ sweep_file_path_in_library(Path, Spec) :-
     ;   term_string(Spec1, Spec)
     ).
 
+
 predicate_argument_names(M:F/A, Args) :-
-    (   M == system
+    sweep_module_functor_arity_pi_(M, F, A, M:PI),
+    (   predicate_argument_names_from_man(M, PI, Args0)
     ->  true
-    ;   sub_atom(M, 0, 1, _, '$')
+    ;   predicate_argument_names_from_pldoc(M, PI, Args0)),
+    arg(2, PI, N),
+    predicate_argument_names_(N, Args0, Args).
+
+
+predicate_argument_names_from_man(M, PI, Args) :-
+    (   pldoc_man:load_man_object(M:PI, _, _, DOM0)
+    ->  true
+    ;   pldoc_man:load_man_object(PI, _, _, DOM0)
     ),
-    pldoc_man:load_man_object(F/A, _, _, DOM0),
     memberchk(element(dt, _, DOM1), DOM0),
     memberchk(element(a, _, DOM2), DOM1),
     catch(findall(Arg,
@@ -1031,17 +1013,16 @@ predicate_argument_names(M:F/A, Args) :-
                       comma_list(CommaSeparatedArgs, ArgsList),
                       member(Arg, ArgsList)
                   ),
-                  Args0),
+                  Args),
           error(syntax_error(_),_),
-          fail),
-    predicate_argument_names_(A, Args0, Args).
-predicate_argument_names(M:F/A, Args) :-
-    doc_comment(M:F/A, _, _, C),
+          fail).
+
+predicate_argument_names_from_pldoc(M, PI, Args) :-
+    doc_comment(M:PI, _, _, C),
     comment_modes(C, ModeAndDets),
     member(ModeAndDet, ModeAndDets),
     strip_det(ModeAndDet, Head),
-    Head =.. [_|Args0],
-    predicate_argument_names_(A, Args0, Args).
+    Head =.. [_|Args].
 
 predicate_argument_names_(Arity, Args0, Args) :-
     length(Args0, Arity),
@@ -1086,11 +1067,10 @@ dep_import(Path, Kind, PI0) -->
     [[Path, PI, Kind]].
 
 
-sweep_format_head([F0|A], R) :-
+sweep_format_head([M0,F0,A,D], R) :-
+    atom_string(M, M0),
     atom_string(F, F0),
-    pi_head(F/A, H),
-    sweep_current_module(M),
-    sweep_format_predicate(M, 0, H, R).
+    sweep_format_head_(D, M:F/A, R).
 
 sweep_format_term([F0,N,P], [S|SP]) :-
     atom_string(F, F0),
diff --git a/sweeprolog-tests.el b/sweeprolog-tests.el
index ee6ec40903..48cce16292 100644
--- a/sweeprolog-tests.el
+++ b/sweeprolog-tests.el
@@ -714,6 +714,21 @@ foo(Bar) --> bar(Bar).")))
     (should (equal (sweeprolog-identifier-at-point)
                    "foobarbaz:foo//1"))))
 
+(ert-deftest dcg-completion-at-point ()
+  "Test completing DCG grammar rule invocation."
+  (let ((temp (make-temp-file "sweeprolog-test"
+                              nil
+                              "pl"
+                              ":- use_module(library(dcg/high_order)).
+foo(Bar) --> optiona")))
+    (find-file-literally temp)
+    (sweeprolog-mode)
+    (goto-char (point-max))
+    (complete-symbol nil)
+    (should (string= (buffer-string)
+                     ":- use_module(library(dcg/high_order)).
+foo(Bar) --> optional(Match, Default)"))))
+
 (ert-deftest definition-at-point ()
   "Test recognizing predicate definitions."
   (let ((temp (make-temp-file "sweeprolog-test"
@@ -896,6 +911,34 @@ foo --> bar.
 foo --> Body.
 "))))
 
+
+(ert-deftest dwim-next-clause-dcg-with-pldoc ()
+  "Test completing DCG grammar rule invocation."
+  (let ((temp (make-temp-file "sweeprolog-test"
+                              nil
+                              "pl"
+                              "
+:- module(dcg_completion_at_point_with, []).
+
+%!  foo(+Bar)// is det.
+
+foo(bar) --> baz(bar).
+")))
+    (find-file-literally temp)
+    (sweeprolog-mode)
+    (goto-char (point-max))
+    (sweeprolog-insert-term-dwim)
+    (should (string= (buffer-string)
+                     "
+:- module(dcg_completion_at_point_with, []).
+
+%!  foo(+Bar)// is det.
+
+foo(bar) --> baz(bar).
+foo(Bar) --> Body.
+
+"))))
+
 (ert-deftest dwim-next-clause-ssu ()
   "Tests inserting an SSU rule with `sweeprolog-insert-term-dwim'."
   (with-temp-buffer
diff --git a/sweeprolog.el b/sweeprolog.el
index 92c0829890..653076aacd 100644
--- a/sweeprolog.el
+++ b/sweeprolog.el
@@ -1355,9 +1355,10 @@ resulting list even when found in the current clause."
                  (not (or (sweeprolog--char-uppercase-p first)
                           (= first ?_)))))
       (when-let
-          ((col (sweeprolog--query-once
-                 "sweep" "sweep_predicate_completion_candidates"
-                 (cons (sweeprolog-context-callable-p)
+          ((extra-args (sweeprolog-context-callable-p))
+           (col (sweeprolog--query-once
+                 "sweep" "sweep_heads_collection"
+                 (cons extra-args
                        (buffer-substring-no-properties beg end)))))
         (list beg end col
               :exclusive 'no
@@ -3551,10 +3552,14 @@ of the prefix argument."
       (sweeprolog-forward-hole))))
 
 (defun sweeprolog-insert-clause (functor arity &optional neck module)
-  (let ((point (point))
-        (neck (or neck ":-"))
-        (head-format (sweeprolog--query-once "sweep" "sweep_format_head"
-                                             (cons functor arity))))
+  (let* ((point (point))
+         (neck (or neck ":-"))
+         (mod (or module (sweeprolog-buffer-module)))
+         (head-format (sweeprolog--query-once "sweep" "sweep_format_head"
+                                              (list mod
+                                                    functor
+                                                    arity
+                                                    (if (string= neck "-->") 2 
0)))))
     (combine-after-change-calls
       (insert "\n"
               (if module
@@ -3595,7 +3600,7 @@ of the prefix argument."
       (goto-char end)
       (end-of-line)
       (sweeprolog-insert-clause functor
-                                (- arity (if (string= neck "-->") 2 0))
+                                arity
                                 neck
                                 module)
       t)))
@@ -3636,7 +3641,7 @@ of the prefix argument."
       (funcall sweeprolog-new-predicate-location-function
                functor arity neck)
       (sweeprolog-insert-clause functor
-                                (- arity (if (string= neck "-->") 2 0))
+                                arity
                                 neck)
       t)))
 



reply via email to

[Prev in Thread] Current Thread [Next in Thread]