]> git.eshelyaron.com Git - sweep.git/commitdiff
ADDED: implemented all xref backend callback functions
authorEshel Yaron <me@eshelyaron.com>
Mon, 5 Sep 2022 19:25:06 +0000 (22:25 +0300)
committerEshel Yaron <me@eshelyaron.com>
Tue, 6 Sep 2022 07:11:49 +0000 (10:11 +0300)
sweep.el
sweep.pl

index 9603c17fdf5de22824d2e4abcd277b287f5d4673..9304d2b6d4772848890ae72e41755057c9910ddc 100644 (file)
--- a/sweep.el
+++ b/sweep.el
@@ -26,6 +26,7 @@
 ;;; Code:
 
 (require 'comint)
+(require 'xref)
 
 (defgroup sweep nil
   "SWI-Prolog Embedded in Emacs."
     (when (sweep-true-p sol)
       (cdr sol))))
 
+(defun sweep-predicate-references (mfn)
+  (sweep-open-query "user" "sweep" "sweep_predicate_references" mfn)
+  (let ((sol (sweep-next-solution)))
+    (sweep-close-query)
+    (when (sweep-true-p sol)
+      (cdr sol))))
+
 (defun sweep-predicate-location (mfn)
   (sweep-open-query "user" "sweep" "sweep_predicate_location" mfn)
   (let ((sol (sweep-next-solution)))
     (when (sweep-true-p sol)
       (cdr sol))))
 
+(defun sweep-predicate-apropos (pattern)
+  (sweep-open-query "user" "sweep" "sweep_predicate_apropos" pattern)
+  (let ((sol (sweep-next-solution)))
+    (sweep-close-query)
+    (when (sweep-true-p sol)
+      (cdr sol))))
+
 (defun sweep-read-predicate ()
   "Read a Prolog predicate (M:F/N) from the minibuffer, with completion."
   (let* ((col (sweep-predicates-collection))
@@ -227,7 +242,7 @@ module name, F is a functor name and N is its arity."
   (interactive (list (sweep-read-predicate)))
   (let* ((loc (sweep-predicate-location mfn))
          (path (car loc))
-         (line (cdr loc)))
+         (line (or (cdr loc) 1)))
     (find-file path)
     (goto-char (point-min))
     (forward-line (1- line))))
@@ -1015,23 +1030,39 @@ Interactively, a prefix arg means to prompt for BUFFER."
   "Hook for `xref-backend-functions'."
   'sweep)
 
-
 (cl-defmethod xref-backend-identifier-at-point ((_backend (eql 'sweep)))
   (sweep-identifier-at-point))
 
 (cl-defmethod xref-backend-identifier-completion-table ((_backend (eql 'sweep)))
-  (sweep-identifier-completion-table))
+  (completion-table-with-cache #'sweep-predicates-collection))
 
 (cl-defmethod xref-backend-identifier-completion-ignore-case ((_backend (eql 'sweep)))
   "Case is always significant for Prolog identifiers, so return nil."
   nil)
 
-(cl-defmethod xref-backend-definitions ((_backend (eql 'sweep)) symbol))
-
-(cl-defmethod xref-backend-references ((_backend (eql 'sweep)) symbol))
-
-(cl-defmethod xref-backend-apropos ((_backend (eql 'sweep)) pattern))
-
+(cl-defmethod xref-backend-definitions ((_backend (eql 'sweep)) mfn)
+  (when-let ((loc (sweep-predicate-location mfn))
+             (path (car loc))
+             (line (or (cdr loc) 1)))
+    (list (xref-make (concat path ":" (number-to-string line)) (xref-make-file-location path line 0)))))
+
+(cl-defmethod xref-backend-references ((_backend (eql 'sweep)) mfn)
+  (let ((refs (sweep-predicate-references mfn)))
+    (seq-map (lambda (loc)
+               (let ((path (car loc))
+                     (line (or (cdr loc) 1)))
+                 (xref-make (concat path ":" (number-to-string line)) (xref-make-file-location path line 0))))
+             refs)))
+
+(cl-defmethod xref-backend-apropos ((_backend (eql 'sweep)) pattern)
+  (let ((matches (sweep-predicate-apropos pattern)))
+    (seq-map (lambda (match)
+               (let ((mfn (car match))
+                     (path (cadr match))
+                     (line (or (cddr match) 1)))
+                 (xref-make mfn
+                            (xref-make-file-location path line 0))))
+             matches)))
 
 ;;;###autoload
 (define-derived-mode sweep-mode prog-mode "sweep"
index 179d5be528dfdee52db13e0de78120704c6fbced..823f6e5f99cfad68bef2198b4a4ef02b999281c5 100644 (file)
--- a/sweep.pl
+++ b/sweep.pl
             sweep_expand_file_name/2,
             sweep_path_module/2,
             sweep_colourise_query/2,
+            sweep_predicate_references/2,
             sweep_predicate_location/2,
+            sweep_predicate_apropos/2,
             sweep_predicates_collection/2,
+            sweep_local_predicate_completion/2,
             sweep_modules_collection/2,
             sweep_packs_collection/2,
             sweep_pack_install/2,
@@ -57,6 +60,7 @@
 :- use_module(library(pldoc/man_index)).
 :- use_module(library(lynx/html_text)).
 :- use_module(library(prolog_pack)).
+:- use_module(library(help)).
 :- use_module(library(prolog_server)).
 
 :- dynamic sweep_current_color/3,
@@ -336,11 +340,71 @@ sweep_module_description([M0|P], [M|[P|D]]) :-
    atom_string(D0, D).
 sweep_module_description([M0|P], [M|[P]]) :- atom_string(M0, M).
 
+sweep_predicate_references(MFN, Refs) :-
+    term_string(M:F/N, MFN),
+    pi_head(F/N, H),
+    findall([Path|Line],
+            (xref_called(Path0, H, _, _, Line),
+             atom_string(Path0, Path)),
+            Refs,
+            Tail),
+    findall([Path|Line],
+            (xref_called(Path0, M:H, _, _, Line),
+             atom_string(Path0, Path)),
+            Tail).
+
+
 sweep_predicate_location(MFN, [Path|Line]) :-
+    !,
     term_string(M:F/N, MFN),
     pi_head(F/N, H),
+    sweep_predicate_location_(M, H, Path, Line).
+sweep_predicate_location(FN, [Path|Line]) :-
+    !,
+    term_string(F/N, FN),
+    pi_head(F/N, H),
+    sweep_predicate_location_(H, Path, Line).
+
+sweep_predicate_apropos(Query0, Matches) :-
+    atom_string(Query, Query0),
+    findall([S,Path|Line],
+            (prolog_help:apropos(Query, M:F/N, _, _),
+             format(string(S), '~w:~W/~w', [M, F, [quoted(true), character_escapes(true)], N]),
+             pi_head(F/N, Head),
+             sweep_predicate_location_(M, Head, Path, Line)),
+            Matches, Tail),
+    findall([S,Path],
+            (prolog_help:apropos(Query, F/N, _, _),
+             format(string(S), '~W/~w', [F, [quoted(true), character_escapes(true)], N]),
+             pi_head(F/N, Head),
+             sweep_predicate_location_(Head, Path, Line)),
+            Tail).
+
+sweep_predicate_location_(H, Path, Line) :-
+    predicate_property(H, file(Path0)),
+    predicate_property(H, line_count(Line)),
+    !,
+    atom_string(Path0, Path).
+sweep_predicate_location_(H, Path, Line) :-
+    xref_defined(Path0, H, How),
+    atom_string(Path0, Path),
+    (   xref_definition_line(How, Line)
+    ->  true
+    ;   Line = []
+    ).
+
+sweep_predicate_location_(M, H, Path, Line) :-
+    predicate_property(M:H, file(Path0)),
     predicate_property(M:H, line_count(Line)),
-    predicate_property(M:H, file(Path0)), atom_string(Path0, Path).
+    !,
+    atom_string(Path0, Path).
+sweep_predicate_location_(M, H, Path, Line) :-
+    xref_defined(Path0, M:H, How),
+    atom_string(Path0, Path),
+    (   xref_definition_line(How, Line)
+    ->  true
+    ;   Line = []
+    ).
 
 sweep_local_predicate_completion([Mod|Sub], Preds) :-
     atom_string(M, Mod),
@@ -399,11 +463,25 @@ sweep_predicates_collection(Sub, Preds) :-
               \+ (predicate_property(M:H, imported_from(M1)), M \= M1)
             ),
             Preds0,
-            Tail),
+            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),
+              pi_head(F/N, H)
+            ),
+            Tail1,
+            Tail),
+    findall(M:F/N,
+            ( xref_defined(_, H, imported(SourceId)),
+              xref_module(SourceId, M),
+              pi_head(F/N, H)
+            ),
             Tail),
     list_to_set(Preds0, Preds1),
     maplist(sweep_predicate_description, Preds1, Preds2),